fragment-python 1.4.0__tar.gz → 1.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fragment_python-1.4.0 → fragment_python-1.4.1}/PKG-INFO +1 -2
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/client/async_client.py +7 -7
- fragment_python-1.4.1/fragment/client/oauth.py +75 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/client/sync_client.py +7 -5
- fragment_python-1.4.1/fragment/exceptions.py +24 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/async_client.py +7 -7
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/async_client.py +7 -7
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/sync_client.py +7 -5
- {fragment_python-1.4.0 → fragment_python-1.4.1}/pyproject.toml +1 -2
- fragment_python-1.4.0/fragment/exceptions.py +0 -12
- {fragment_python-1.4.0 → fragment_python-1.4.1}/LICENSE +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/README.md +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/__init__.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/client/__init__.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/__init__.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/helpers.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/main.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/__init__.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/generate_client_method.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/generate_typed_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/get_file_comment.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/typed_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/logger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/py.typed +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/__init__.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/add_ledger_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/add_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/add_ledger_entry_runtime.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/base_model.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/client.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/create_custom_currency.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/create_custom_link.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/create_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/create_payment.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/delete_custom_txs.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/delete_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/delete_schema.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/enums.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_account_data_migrations.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_entries_to_migrate_for_ledger_account_data_migration.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_entries_to_migrate_for_ledger_entry_data_migration.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_entry_data_migrations.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_ledger_account_balance.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_ledger_account_balance_with_child_rollup.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_ledger_account_lines.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_payment.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_schema.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/get_workspace.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/input_types.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/instantiate_ledger_account.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_ledger_account_balances.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_ledger_accounts.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_ledger_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_ledger_entry_group_balances.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_multi_currency_ledger_account_balances.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_payments.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/migrate_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/reconcile_tx.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/reconcile_tx_runtime.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/reverse_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/store_schema.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/sync_custom_accounts.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/sync_custom_txs.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/typed_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/update_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/update_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/std_queries/queries.graphql +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/__init__.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/add_ledger_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/add_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/add_ledger_entry_runtime.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/base_model.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/client.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/create_custom_currency.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/create_custom_link.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/create_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/create_payment.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/delete_custom_txs.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/delete_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/delete_schema.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/enums.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_account_data_migrations.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_entries_to_migrate_for_ledger_account_data_migration.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_entries_to_migrate_for_ledger_entry_data_migration.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_entry_data_migrations.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger_account_balance.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger_account_balance_with_child_rollup.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger_account_lines.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_payment.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_schema.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_workspace.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/input_types.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/instantiate_ledger_account.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_ledger_account_balances.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_ledger_accounts.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_ledger_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_ledger_entry_group_balances.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_multi_currency_ledger_account_balances.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_payments.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/migrate_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/reconcile_tx.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/reconcile_tx_runtime.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/reverse_ledger_entry.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/store_schema.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/sync_custom_accounts.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/sync_custom_txs.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/typed_entries.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/update_ledger.py +0 -0
- {fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/update_ledger_entry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fragment-python
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.1
|
|
4
4
|
Summary: Python SDK for https://fragment.dev/
|
|
5
5
|
License: Apache 2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -15,7 +15,6 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.14
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.15
|
|
17
17
|
Requires-Dist: ariadne-codegen (>=0.17.2,<0.18.0)
|
|
18
|
-
Requires-Dist: authlib (>=1.6.12,<2.0.0)
|
|
19
18
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
20
19
|
Requires-Dist: graphql-core (>=3.2.3,<4.0.0)
|
|
21
20
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# Ignore untyped authlib
|
|
2
|
-
# mypy: disable-error-code="import-untyped"
|
|
3
1
|
import time
|
|
4
2
|
from typing import Any, Dict, Optional
|
|
5
3
|
|
|
@@ -7,8 +5,8 @@ import httpx
|
|
|
7
5
|
from ariadne_codegen.client_generators.dependencies.async_base_client import (
|
|
8
6
|
AsyncBaseClient,
|
|
9
7
|
)
|
|
10
|
-
from authlib.integrations.httpx_client import AsyncOAuth2Client
|
|
11
8
|
|
|
9
|
+
from fragment.client.oauth import fetch_token_async
|
|
12
10
|
from fragment.exceptions import MissingArgumentException, MissingTokenException
|
|
13
11
|
|
|
14
12
|
|
|
@@ -37,16 +35,18 @@ class AsyncFragmentClient(AsyncBaseClient):
|
|
|
37
35
|
self.auth_url = auth_url
|
|
38
36
|
self.expiration_time: Optional[float] = None
|
|
39
37
|
self.token: Optional[Dict[str, Any]] = None
|
|
40
|
-
self.
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
self.client_id = client_id
|
|
39
|
+
self.client_secret = client_secret
|
|
40
|
+
self.auth_scope = auth_scope
|
|
43
41
|
|
|
44
42
|
async def refresh_token(self) -> None:
|
|
45
43
|
now = time.time()
|
|
46
44
|
if self.expiration_time is None or self.expiration_time <= now:
|
|
47
45
|
# Held in a local because `self.token` is declared `dict | None`,
|
|
48
46
|
# so reading the attribute back is not narrowed by the assignment.
|
|
49
|
-
token = await
|
|
47
|
+
token = await fetch_token_async(
|
|
48
|
+
self.auth_url, self.client_id, self.client_secret, self.auth_scope
|
|
49
|
+
)
|
|
50
50
|
self.token = token
|
|
51
51
|
self.expiration_time = now + token["expires_in"]
|
|
52
52
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""OAuth2 client-credentials token request against the Fragment auth endpoint.
|
|
2
|
+
|
|
3
|
+
The SDK needs exactly one OAuth2 call: exchange a client ID and secret for an
|
|
4
|
+
access token. That is a single form POST, so it is made with httpx directly
|
|
5
|
+
rather than through an OAuth library, whose much larger surface (JOSE, OIDC,
|
|
6
|
+
server-side grants) customers would otherwise inherit, along with its
|
|
7
|
+
advisories.
|
|
8
|
+
|
|
9
|
+
The request matches what authlib's httpx `OAuth2Client.fetch_token` sent:
|
|
10
|
+
HTTP Basic client authentication (`client_secret_basic`) and a form body of
|
|
11
|
+
`grant_type=client_credentials` and `scope`.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from typing import Any, Dict
|
|
15
|
+
|
|
16
|
+
import httpx
|
|
17
|
+
|
|
18
|
+
from fragment.exceptions import TokenRequestException
|
|
19
|
+
|
|
20
|
+
_HEADERS = {
|
|
21
|
+
"Accept": "application/json",
|
|
22
|
+
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _token_request_kwargs(
|
|
27
|
+
client_id: str, client_secret: str, scope: str
|
|
28
|
+
) -> Dict[str, Any]:
|
|
29
|
+
return dict(
|
|
30
|
+
data={"grant_type": "client_credentials", "scope": scope},
|
|
31
|
+
auth=httpx.BasicAuth(client_id, client_secret),
|
|
32
|
+
headers=_HEADERS,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _parse_token_response(response: httpx.Response) -> Dict[str, Any]:
|
|
37
|
+
if response.status_code >= 500:
|
|
38
|
+
response.raise_for_status()
|
|
39
|
+
try:
|
|
40
|
+
token = response.json()
|
|
41
|
+
except ValueError as e:
|
|
42
|
+
raise TokenRequestException(
|
|
43
|
+
f"token endpoint returned a non-JSON response "
|
|
44
|
+
f"(HTTP {response.status_code})"
|
|
45
|
+
) from e
|
|
46
|
+
if not isinstance(token, dict):
|
|
47
|
+
raise TokenRequestException("token endpoint returned a non-object response")
|
|
48
|
+
if "error" in token:
|
|
49
|
+
raise TokenRequestException(token["error"], token.get("error_description"))
|
|
50
|
+
if "access_token" not in token or "expires_in" not in token:
|
|
51
|
+
raise TokenRequestException(
|
|
52
|
+
f"token endpoint response is missing access_token or expires_in "
|
|
53
|
+
f"(HTTP {response.status_code})"
|
|
54
|
+
)
|
|
55
|
+
return token
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def fetch_token(
|
|
59
|
+
auth_url: str, client_id: str, client_secret: str, scope: str
|
|
60
|
+
) -> Dict[str, Any]:
|
|
61
|
+
with httpx.Client() as client:
|
|
62
|
+
response = client.post(
|
|
63
|
+
auth_url, **_token_request_kwargs(client_id, client_secret, scope)
|
|
64
|
+
)
|
|
65
|
+
return _parse_token_response(response)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def fetch_token_async(
|
|
69
|
+
auth_url: str, client_id: str, client_secret: str, scope: str
|
|
70
|
+
) -> Dict[str, Any]:
|
|
71
|
+
async with httpx.AsyncClient() as client:
|
|
72
|
+
response = await client.post(
|
|
73
|
+
auth_url, **_token_request_kwargs(client_id, client_secret, scope)
|
|
74
|
+
)
|
|
75
|
+
return _parse_token_response(response)
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
# Ignore untyped authlib
|
|
2
|
-
# mypy: disable-error-code="import-untyped"
|
|
3
1
|
import time
|
|
4
2
|
from typing import Any, Dict, Optional
|
|
5
3
|
|
|
6
4
|
import httpx
|
|
7
5
|
from ariadne_codegen.client_generators.dependencies.base_client import BaseClient
|
|
8
|
-
from authlib.integrations.httpx_client import OAuth2Client
|
|
9
6
|
|
|
7
|
+
from fragment.client.oauth import fetch_token
|
|
10
8
|
from fragment.exceptions import MissingArgumentException, MissingTokenException
|
|
11
9
|
|
|
12
10
|
|
|
@@ -35,14 +33,18 @@ class SyncFragmentClient(BaseClient):
|
|
|
35
33
|
self.auth_url = auth_url
|
|
36
34
|
self.expiration_time: Optional[float] = None
|
|
37
35
|
self.token: Optional[Dict[str, Any]] = None
|
|
38
|
-
self.
|
|
36
|
+
self.client_id = client_id
|
|
37
|
+
self.client_secret = client_secret
|
|
38
|
+
self.auth_scope = auth_scope
|
|
39
39
|
|
|
40
40
|
def refresh_token(self) -> None:
|
|
41
41
|
now = time.time()
|
|
42
42
|
if self.expiration_time is None or self.expiration_time <= now:
|
|
43
43
|
# Held in a local because `self.token` is declared `dict | None`,
|
|
44
44
|
# so reading the attribute back is not narrowed by the assignment.
|
|
45
|
-
token =
|
|
45
|
+
token = fetch_token(
|
|
46
|
+
self.auth_url, self.client_id, self.client_secret, self.auth_scope
|
|
47
|
+
)
|
|
46
48
|
self.token = token
|
|
47
49
|
self.expiration_time = now + token["expires_in"]
|
|
48
50
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class MissingTokenException(ValueError):
|
|
5
|
+
"""Token not found."""
|
|
6
|
+
|
|
7
|
+
def __init__(self) -> None:
|
|
8
|
+
super().__init__("Token is None")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MissingArgumentException(ValueError):
|
|
12
|
+
"""Argument not present."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, argument: str) -> None:
|
|
15
|
+
super().__init__(f"{argument} must be provided")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TokenRequestException(Exception):
|
|
19
|
+
"""The auth endpoint did not return an access token."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, error: str, description: Optional[str] = None) -> None:
|
|
22
|
+
self.error = error
|
|
23
|
+
self.description = description
|
|
24
|
+
super().__init__(f"{error}: {description}" if description else error)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# Generated by fragment (with the help of ariadne-codegen)
|
|
2
2
|
|
|
3
|
-
# Ignore untyped authlib
|
|
4
|
-
# mypy: disable-error-code="import-untyped"
|
|
5
3
|
import time
|
|
6
4
|
from typing import Any, Dict, Optional
|
|
7
5
|
|
|
@@ -9,8 +7,8 @@ import httpx
|
|
|
9
7
|
from ariadne_codegen.client_generators.dependencies.async_base_client import (
|
|
10
8
|
AsyncBaseClient,
|
|
11
9
|
)
|
|
12
|
-
from authlib.integrations.httpx_client import AsyncOAuth2Client
|
|
13
10
|
|
|
11
|
+
from fragment.client.oauth import fetch_token_async
|
|
14
12
|
from fragment.exceptions import MissingArgumentException, MissingTokenException
|
|
15
13
|
|
|
16
14
|
|
|
@@ -39,16 +37,18 @@ class AsyncFragmentClient(AsyncBaseClient):
|
|
|
39
37
|
self.auth_url = auth_url
|
|
40
38
|
self.expiration_time: Optional[float] = None
|
|
41
39
|
self.token: Optional[Dict[str, Any]] = None
|
|
42
|
-
self.
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
self.client_id = client_id
|
|
41
|
+
self.client_secret = client_secret
|
|
42
|
+
self.auth_scope = auth_scope
|
|
45
43
|
|
|
46
44
|
async def refresh_token(self) -> None:
|
|
47
45
|
now = time.time()
|
|
48
46
|
if self.expiration_time is None or self.expiration_time <= now:
|
|
49
47
|
# Held in a local because `self.token` is declared `dict | None`,
|
|
50
48
|
# so reading the attribute back is not narrowed by the assignment.
|
|
51
|
-
token = await
|
|
49
|
+
token = await fetch_token_async(
|
|
50
|
+
self.auth_url, self.client_id, self.client_secret, self.auth_scope
|
|
51
|
+
)
|
|
52
52
|
self.token = token
|
|
53
53
|
self.expiration_time = now + token["expires_in"]
|
|
54
54
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# Generated by fragment (with the help of ariadne-codegen)
|
|
2
2
|
|
|
3
|
-
# Ignore untyped authlib
|
|
4
|
-
# mypy: disable-error-code="import-untyped"
|
|
5
3
|
import time
|
|
6
4
|
from typing import Any, Dict, Optional
|
|
7
5
|
|
|
@@ -9,8 +7,8 @@ import httpx
|
|
|
9
7
|
from ariadne_codegen.client_generators.dependencies.async_base_client import (
|
|
10
8
|
AsyncBaseClient,
|
|
11
9
|
)
|
|
12
|
-
from authlib.integrations.httpx_client import AsyncOAuth2Client
|
|
13
10
|
|
|
11
|
+
from fragment.client.oauth import fetch_token_async
|
|
14
12
|
from fragment.exceptions import MissingArgumentException, MissingTokenException
|
|
15
13
|
|
|
16
14
|
|
|
@@ -39,16 +37,18 @@ class AsyncFragmentClient(AsyncBaseClient):
|
|
|
39
37
|
self.auth_url = auth_url
|
|
40
38
|
self.expiration_time: Optional[float] = None
|
|
41
39
|
self.token: Optional[Dict[str, Any]] = None
|
|
42
|
-
self.
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
self.client_id = client_id
|
|
41
|
+
self.client_secret = client_secret
|
|
42
|
+
self.auth_scope = auth_scope
|
|
45
43
|
|
|
46
44
|
async def refresh_token(self) -> None:
|
|
47
45
|
now = time.time()
|
|
48
46
|
if self.expiration_time is None or self.expiration_time <= now:
|
|
49
47
|
# Held in a local because `self.token` is declared `dict | None`,
|
|
50
48
|
# so reading the attribute back is not narrowed by the assignment.
|
|
51
|
-
token = await
|
|
49
|
+
token = await fetch_token_async(
|
|
50
|
+
self.auth_url, self.client_id, self.client_secret, self.auth_scope
|
|
51
|
+
)
|
|
52
52
|
self.token = token
|
|
53
53
|
self.expiration_time = now + token["expires_in"]
|
|
54
54
|
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
# Generated by fragment (with the help of ariadne-codegen)
|
|
2
2
|
|
|
3
|
-
# Ignore untyped authlib
|
|
4
|
-
# mypy: disable-error-code="import-untyped"
|
|
5
3
|
import time
|
|
6
4
|
from typing import Any, Dict, Optional
|
|
7
5
|
|
|
8
6
|
import httpx
|
|
9
7
|
from ariadne_codegen.client_generators.dependencies.base_client import BaseClient
|
|
10
|
-
from authlib.integrations.httpx_client import OAuth2Client
|
|
11
8
|
|
|
9
|
+
from fragment.client.oauth import fetch_token
|
|
12
10
|
from fragment.exceptions import MissingArgumentException, MissingTokenException
|
|
13
11
|
|
|
14
12
|
|
|
@@ -37,14 +35,18 @@ class SyncFragmentClient(BaseClient):
|
|
|
37
35
|
self.auth_url = auth_url
|
|
38
36
|
self.expiration_time: Optional[float] = None
|
|
39
37
|
self.token: Optional[Dict[str, Any]] = None
|
|
40
|
-
self.
|
|
38
|
+
self.client_id = client_id
|
|
39
|
+
self.client_secret = client_secret
|
|
40
|
+
self.auth_scope = auth_scope
|
|
41
41
|
|
|
42
42
|
def refresh_token(self) -> None:
|
|
43
43
|
now = time.time()
|
|
44
44
|
if self.expiration_time is None or self.expiration_time <= now:
|
|
45
45
|
# Held in a local because `self.token` is declared `dict | None`,
|
|
46
46
|
# so reading the attribute back is not narrowed by the assignment.
|
|
47
|
-
token =
|
|
47
|
+
token = fetch_token(
|
|
48
|
+
self.auth_url, self.client_id, self.client_secret, self.auth_scope
|
|
49
|
+
)
|
|
48
50
|
self.token = token
|
|
49
51
|
self.expiration_time = now + token["expires_in"]
|
|
50
52
|
|
|
@@ -5,7 +5,7 @@ target_package_name = "fragment_graphql_client"
|
|
|
5
5
|
|
|
6
6
|
[tool.poetry]
|
|
7
7
|
name = "fragment-python"
|
|
8
|
-
version = "1.4.
|
|
8
|
+
version = "1.4.1"
|
|
9
9
|
description = "Python SDK for https://fragment.dev/"
|
|
10
10
|
authors = ["Fragment Foundries Inc"]
|
|
11
11
|
license = "Apache 2.0"
|
|
@@ -18,7 +18,6 @@ ariadne-codegen = "^0.17.2"
|
|
|
18
18
|
requests-oauth2client = "^1.6.0"
|
|
19
19
|
pydantic = "^2.8.0"
|
|
20
20
|
httpx = "^0.28.1"
|
|
21
|
-
authlib = "^1.6.12"
|
|
22
21
|
graphql-core = "^3.2.3"
|
|
23
22
|
click = "^8.1.7"
|
|
24
23
|
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
class MissingTokenException(ValueError):
|
|
2
|
-
"""Token not found."""
|
|
3
|
-
|
|
4
|
-
def __init__(self) -> None:
|
|
5
|
-
super().__init__("Token is None")
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class MissingArgumentException(ValueError):
|
|
9
|
-
"""Argument not present."""
|
|
10
|
-
|
|
11
|
-
def __init__(self, argument: str) -> None:
|
|
12
|
-
super().__init__(f"{argument} must be provided")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/generate_client_method.py
RENAMED
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/generate_typed_entries.py
RENAMED
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/codegen/plugins/get_file_comment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_ledger_account_balances.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sdk/list_ledger_entry_group_balances.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/add_ledger_entry_runtime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_account_data_migrations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_entry_data_migrations.py
RENAMED
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger_account_balance.py
RENAMED
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/get_ledger_account_lines.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/instantiate_ledger_account.py
RENAMED
|
File without changes
|
{fragment_python-1.4.0 → fragment_python-1.4.1}/fragment/sync_sdk/list_ledger_account_balances.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|