gmt-python-sdk 0.27.0__tar.gz → 0.28.0__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.
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/.gitignore +1 -0
- gmt_python_sdk-0.28.0/.release-please-manifest.json +3 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/CHANGELOG.md +21 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/PKG-INFO +1 -1
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/pyproject.toml +1 -1
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/__init__.py +1 -0
- gmt_python_sdk-0.28.0/src/gmt/_utils/_path.py +127 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_version.py +1 -1
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/accounts.py +3 -3
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/purchases/bulk.py +5 -5
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/purchases/purchases.py +7 -7
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_retrieve_response.py +4 -1
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral_retrieve_response.py +4 -3
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_create_response.py +3 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_list_response.py +3 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_refund_response.py +3 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_request_verification_code_response.py +3 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_retrieve_response.py +3 -0
- gmt_python_sdk-0.28.0/tests/test_utils/test_path.py +89 -0
- gmt_python_sdk-0.27.0/.release-please-manifest.json +0 -3
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/CONTRIBUTING.md +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/LICENSE +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/README.md +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/SECURITY.md +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/api.md +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/bin/check-release-environment +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/bin/publish-pypi +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/examples/.keep +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/release-please-config.json +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/requirements-dev.lock +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_base_client.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_client.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_compat.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_constants.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_exceptions.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_files.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_models.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_qs.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_resource.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_streaming.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_types.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_compat.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_datetime_parse.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_json.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_logs.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_proxy.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_reflection.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_resources_proxy.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_streams.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_sync.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_transform.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_typing.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/_utils/_utils.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/lib/.keep +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/pagination.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/py.typed +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/discount.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/profile.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/referral/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/referral/referral.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/referral/transaction.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/purchases/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/service.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/webhooks.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_list_countries_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_list_countries_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_list_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_list_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/discount_retrieve_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral/transaction_list_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral/transaction_list_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral_transfer_balance_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral_transfer_balance_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_login_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_login_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_password_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_password_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_retrieve_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_unbind_telegram_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_create_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_list_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchase_request_verification_code_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/bulk_create_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/bulk_create_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/bulk_retrieve_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/service_get_server_time_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/service_health_check_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/webhook_test_params.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/webhook_test_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/referral/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/referral/test_transaction.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/test_discount.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/test_referral.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/purchases/__init__.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/purchases/test_bulk.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/test_accounts.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/test_profile.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/test_purchases.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/test_service.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/test_webhooks.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/conftest.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/sample_file.txt +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_client.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_deepcopy.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_extract_files.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_files.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_models.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_qs.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_required_args.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_response.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_streaming.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_transform.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_utils/test_datetime_parse.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_utils/test_json.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_utils/test_proxy.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/test_utils/test_typing.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/utils.py +0 -0
- {gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/uv.lock +0 -0
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.28.0 (2026-03-24)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.27.1...v0.28.0](https://github.com/cameo6/gmt-python-sdk/compare/v0.27.1...v0.28.0)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **api:** api update ([d8f345c](https://github.com/cameo6/gmt-python-sdk/commit/d8f345cd620595d0869cc34711f768201695d7d8))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Chores
|
|
13
|
+
|
|
14
|
+
* **internal:** update gitignore ([c2e249c](https://github.com/cameo6/gmt-python-sdk/commit/c2e249c38f976c3eca69c196d97191927da36540))
|
|
15
|
+
|
|
16
|
+
## 0.27.1 (2026-03-20)
|
|
17
|
+
|
|
18
|
+
Full Changelog: [v0.27.0...v0.27.1](https://github.com/cameo6/gmt-python-sdk/compare/v0.27.0...v0.27.1)
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* sanitize endpoint path params ([6d2a959](https://github.com/cameo6/gmt-python-sdk/commit/6d2a959bae599064b628dfeb5bb5069b337c0cdf))
|
|
23
|
+
|
|
3
24
|
## 0.27.0 (2026-03-19)
|
|
4
25
|
|
|
5
26
|
Full Changelog: [v0.26.0...v0.27.0](https://github.com/cameo6/gmt-python-sdk/compare/v0.26.0...v0.27.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: gmt-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.28.0
|
|
4
4
|
Summary: The official Python library for the gmt API
|
|
5
5
|
Project-URL: Homepage, https://github.com/cameo6/gmt-python-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/cameo6/gmt-python-sdk
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Mapping,
|
|
7
|
+
Callable,
|
|
8
|
+
)
|
|
9
|
+
from urllib.parse import quote
|
|
10
|
+
|
|
11
|
+
# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
|
|
12
|
+
_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
|
|
13
|
+
|
|
14
|
+
_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _quote_path_segment_part(value: str) -> str:
|
|
18
|
+
"""Percent-encode `value` for use in a URI path segment.
|
|
19
|
+
|
|
20
|
+
Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
|
|
21
|
+
https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
|
|
22
|
+
"""
|
|
23
|
+
# quote() already treats unreserved characters (letters, digits, and -._~)
|
|
24
|
+
# as safe, so we only need to add sub-delims, ':', and '@'.
|
|
25
|
+
# Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
|
|
26
|
+
return quote(value, safe="!$&'()*+,;=:@")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _quote_query_part(value: str) -> str:
|
|
30
|
+
"""Percent-encode `value` for use in a URI query string.
|
|
31
|
+
|
|
32
|
+
Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
|
|
33
|
+
https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
|
|
34
|
+
"""
|
|
35
|
+
return quote(value, safe="!$'()*+,;:@/?")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _quote_fragment_part(value: str) -> str:
|
|
39
|
+
"""Percent-encode `value` for use in a URI fragment.
|
|
40
|
+
|
|
41
|
+
Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
|
|
42
|
+
https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
|
|
43
|
+
"""
|
|
44
|
+
return quote(value, safe="!$&'()*+,;=:@/?")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _interpolate(
|
|
48
|
+
template: str,
|
|
49
|
+
values: Mapping[str, Any],
|
|
50
|
+
quoter: Callable[[str], str],
|
|
51
|
+
) -> str:
|
|
52
|
+
"""Replace {name} placeholders in `template`, quoting each value with `quoter`.
|
|
53
|
+
|
|
54
|
+
Placeholder names are looked up in `values`.
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
KeyError: If a placeholder is not found in `values`.
|
|
58
|
+
"""
|
|
59
|
+
# re.split with a capturing group returns alternating
|
|
60
|
+
# [text, name, text, name, ..., text] elements.
|
|
61
|
+
parts = _PLACEHOLDER_RE.split(template)
|
|
62
|
+
|
|
63
|
+
for i in range(1, len(parts), 2):
|
|
64
|
+
name = parts[i]
|
|
65
|
+
if name not in values:
|
|
66
|
+
raise KeyError(f"a value for placeholder {{{name}}} was not provided")
|
|
67
|
+
val = values[name]
|
|
68
|
+
if val is None:
|
|
69
|
+
parts[i] = "null"
|
|
70
|
+
elif isinstance(val, bool):
|
|
71
|
+
parts[i] = "true" if val else "false"
|
|
72
|
+
else:
|
|
73
|
+
parts[i] = quoter(str(values[name]))
|
|
74
|
+
|
|
75
|
+
return "".join(parts)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def path_template(template: str, /, **kwargs: Any) -> str:
|
|
79
|
+
"""Interpolate {name} placeholders in `template` from keyword arguments.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
template: The template string containing {name} placeholders.
|
|
83
|
+
**kwargs: Keyword arguments to interpolate into the template.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
The template with placeholders interpolated and percent-encoded.
|
|
87
|
+
|
|
88
|
+
Safe characters for percent-encoding are dependent on the URI component.
|
|
89
|
+
Placeholders in path and fragment portions are percent-encoded where the `segment`
|
|
90
|
+
and `fragment` sets from RFC 3986 respectively are considered safe.
|
|
91
|
+
Placeholders in the query portion are percent-encoded where the `query` set from
|
|
92
|
+
RFC 3986 §3.3 is considered safe except for = and & characters.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
KeyError: If a placeholder is not found in `kwargs`.
|
|
96
|
+
ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
|
|
97
|
+
"""
|
|
98
|
+
# Split the template into path, query, and fragment portions.
|
|
99
|
+
fragment_template: str | None = None
|
|
100
|
+
query_template: str | None = None
|
|
101
|
+
|
|
102
|
+
rest = template
|
|
103
|
+
if "#" in rest:
|
|
104
|
+
rest, fragment_template = rest.split("#", 1)
|
|
105
|
+
if "?" in rest:
|
|
106
|
+
rest, query_template = rest.split("?", 1)
|
|
107
|
+
path_template = rest
|
|
108
|
+
|
|
109
|
+
# Interpolate each portion with the appropriate quoting rules.
|
|
110
|
+
path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
|
|
111
|
+
|
|
112
|
+
# Reject dot-segments (. and ..) in the final assembled path. The check
|
|
113
|
+
# runs after interpolation so that adjacent placeholders or a mix of static
|
|
114
|
+
# text and placeholders that together form a dot-segment are caught.
|
|
115
|
+
# Also reject percent-encoded dot-segments to protect against incorrectly
|
|
116
|
+
# implemented normalization in servers/proxies.
|
|
117
|
+
for segment in path_result.split("/"):
|
|
118
|
+
if _DOT_SEGMENT_RE.match(segment):
|
|
119
|
+
raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
|
|
120
|
+
|
|
121
|
+
result = path_result
|
|
122
|
+
if query_template is not None:
|
|
123
|
+
result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
|
|
124
|
+
if fragment_template is not None:
|
|
125
|
+
result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
|
|
126
|
+
|
|
127
|
+
return result
|
|
@@ -8,7 +8,7 @@ import httpx
|
|
|
8
8
|
|
|
9
9
|
from ..types import account_list_params, account_list_countries_params
|
|
10
10
|
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
|
|
11
|
-
from .._utils import maybe_transform
|
|
11
|
+
from .._utils import path_template, maybe_transform
|
|
12
12
|
from .._compat import cached_property
|
|
13
13
|
from .._resource import SyncAPIResource, AsyncAPIResource
|
|
14
14
|
from .._response import (
|
|
@@ -100,7 +100,7 @@ class AccountsResource(SyncAPIResource):
|
|
|
100
100
|
if not country_code:
|
|
101
101
|
raise ValueError(f"Expected a non-empty value for `country_code` but received {country_code!r}")
|
|
102
102
|
return self._get(
|
|
103
|
-
|
|
103
|
+
path_template("/v1/accounts/{country_code}", country_code=country_code),
|
|
104
104
|
options=make_request_options(
|
|
105
105
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
106
106
|
),
|
|
@@ -322,7 +322,7 @@ class AsyncAccountsResource(AsyncAPIResource):
|
|
|
322
322
|
if not country_code:
|
|
323
323
|
raise ValueError(f"Expected a non-empty value for `country_code` but received {country_code!r}")
|
|
324
324
|
return await self._get(
|
|
325
|
-
|
|
325
|
+
path_template("/v1/accounts/{country_code}", country_code=country_code),
|
|
326
326
|
options=make_request_options(
|
|
327
327
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
328
328
|
),
|
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import httpx
|
|
6
6
|
|
|
7
7
|
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
|
|
8
|
-
from ..._utils import maybe_transform, async_maybe_transform
|
|
8
|
+
from ..._utils import path_template, maybe_transform, async_maybe_transform
|
|
9
9
|
from ..._compat import cached_property
|
|
10
10
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
11
11
|
from ..._response import (
|
|
@@ -145,7 +145,7 @@ class BulkResource(SyncAPIResource):
|
|
|
145
145
|
if not purchase_id:
|
|
146
146
|
raise ValueError(f"Expected a non-empty value for `purchase_id` but received {purchase_id!r}")
|
|
147
147
|
return self._get(
|
|
148
|
-
|
|
148
|
+
path_template("/v1/purchases/bulk/{purchase_id}", purchase_id=purchase_id),
|
|
149
149
|
options=make_request_options(
|
|
150
150
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
151
151
|
),
|
|
@@ -180,7 +180,7 @@ class BulkResource(SyncAPIResource):
|
|
|
180
180
|
raise ValueError(f"Expected a non-empty value for `purchase_id` but received {purchase_id!r}")
|
|
181
181
|
extra_headers = {"Accept": "application/zip", **(extra_headers or {})}
|
|
182
182
|
return self._get(
|
|
183
|
-
|
|
183
|
+
path_template("/v1/purchases/bulk/{purchase_id}/download", purchase_id=purchase_id),
|
|
184
184
|
options=make_request_options(
|
|
185
185
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
186
186
|
),
|
|
@@ -303,7 +303,7 @@ class AsyncBulkResource(AsyncAPIResource):
|
|
|
303
303
|
if not purchase_id:
|
|
304
304
|
raise ValueError(f"Expected a non-empty value for `purchase_id` but received {purchase_id!r}")
|
|
305
305
|
return await self._get(
|
|
306
|
-
|
|
306
|
+
path_template("/v1/purchases/bulk/{purchase_id}", purchase_id=purchase_id),
|
|
307
307
|
options=make_request_options(
|
|
308
308
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
309
309
|
),
|
|
@@ -338,7 +338,7 @@ class AsyncBulkResource(AsyncAPIResource):
|
|
|
338
338
|
raise ValueError(f"Expected a non-empty value for `purchase_id` but received {purchase_id!r}")
|
|
339
339
|
extra_headers = {"Accept": "application/zip", **(extra_headers or {})}
|
|
340
340
|
return await self._get(
|
|
341
|
-
|
|
341
|
+
path_template("/v1/purchases/bulk/{purchase_id}/download", purchase_id=purchase_id),
|
|
342
342
|
options=make_request_options(
|
|
343
343
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
344
344
|
),
|
|
@@ -16,7 +16,7 @@ from .bulk import (
|
|
|
16
16
|
)
|
|
17
17
|
from ...types import purchase_list_params, purchase_create_params, purchase_request_verification_code_params
|
|
18
18
|
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
|
|
19
|
-
from ..._utils import maybe_transform, async_maybe_transform
|
|
19
|
+
from ..._utils import path_template, maybe_transform, async_maybe_transform
|
|
20
20
|
from ..._compat import cached_property
|
|
21
21
|
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
22
22
|
from ..._response import (
|
|
@@ -141,7 +141,7 @@ class PurchasesResource(SyncAPIResource):
|
|
|
141
141
|
timeout: Override the client-level default timeout for this request, in seconds
|
|
142
142
|
"""
|
|
143
143
|
return self._get(
|
|
144
|
-
|
|
144
|
+
path_template("/v1/purchases/{purchase_id}", purchase_id=purchase_id),
|
|
145
145
|
options=make_request_options(
|
|
146
146
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
147
147
|
),
|
|
@@ -254,7 +254,7 @@ class PurchasesResource(SyncAPIResource):
|
|
|
254
254
|
timeout: Override the client-level default timeout for this request, in seconds
|
|
255
255
|
"""
|
|
256
256
|
return self._post(
|
|
257
|
-
|
|
257
|
+
path_template("/v1/purchases/{purchase_id}/refund", purchase_id=purchase_id),
|
|
258
258
|
options=make_request_options(
|
|
259
259
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
260
260
|
),
|
|
@@ -314,7 +314,7 @@ class PurchasesResource(SyncAPIResource):
|
|
|
314
314
|
timeout: Override the client-level default timeout for this request, in seconds
|
|
315
315
|
"""
|
|
316
316
|
return self._post(
|
|
317
|
-
|
|
317
|
+
path_template("/v1/purchases/{purchase_id}/request-code", purchase_id=purchase_id),
|
|
318
318
|
body=maybe_transform(
|
|
319
319
|
{"callback_url": callback_url},
|
|
320
320
|
purchase_request_verification_code_params.PurchaseRequestVerificationCodeParams,
|
|
@@ -433,7 +433,7 @@ class AsyncPurchasesResource(AsyncAPIResource):
|
|
|
433
433
|
timeout: Override the client-level default timeout for this request, in seconds
|
|
434
434
|
"""
|
|
435
435
|
return await self._get(
|
|
436
|
-
|
|
436
|
+
path_template("/v1/purchases/{purchase_id}", purchase_id=purchase_id),
|
|
437
437
|
options=make_request_options(
|
|
438
438
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
439
439
|
),
|
|
@@ -546,7 +546,7 @@ class AsyncPurchasesResource(AsyncAPIResource):
|
|
|
546
546
|
timeout: Override the client-level default timeout for this request, in seconds
|
|
547
547
|
"""
|
|
548
548
|
return await self._post(
|
|
549
|
-
|
|
549
|
+
path_template("/v1/purchases/{purchase_id}/refund", purchase_id=purchase_id),
|
|
550
550
|
options=make_request_options(
|
|
551
551
|
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
552
552
|
),
|
|
@@ -606,7 +606,7 @@ class AsyncPurchasesResource(AsyncAPIResource):
|
|
|
606
606
|
timeout: Override the client-level default timeout for this request, in seconds
|
|
607
607
|
"""
|
|
608
608
|
return await self._post(
|
|
609
|
-
|
|
609
|
+
path_template("/v1/purchases/{purchase_id}/request-code", purchase_id=purchase_id),
|
|
610
610
|
body=await async_maybe_transform(
|
|
611
611
|
{"callback_url": callback_url},
|
|
612
612
|
purchase_request_verification_code_params.PurchaseRequestVerificationCodeParams,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
-
from typing import List
|
|
3
|
+
from typing import List, Optional
|
|
4
4
|
from typing_extensions import Literal
|
|
5
5
|
|
|
6
6
|
from .._models import BaseModel
|
|
@@ -50,3 +50,6 @@ class AccountRetrieveResponse(BaseModel):
|
|
|
50
50
|
|
|
51
51
|
tags: List[Literal["HIGH_QUALITY", "HIGH_DEMAND"]]
|
|
52
52
|
"""Account tags (e.g., HIGH_QUALITY for premium accounts)."""
|
|
53
|
+
|
|
54
|
+
available_count: Optional[float] = None
|
|
55
|
+
"""Number of available accounts for this country."""
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/referral_retrieve_response.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
3
|
from typing import List, Optional
|
|
4
|
+
from typing_extensions import Literal
|
|
4
5
|
|
|
5
6
|
from ..._models import BaseModel
|
|
6
7
|
|
|
@@ -26,7 +27,7 @@ class CurrentLevelProgress(BaseModel):
|
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class CurrentLevel(BaseModel):
|
|
29
|
-
name:
|
|
30
|
+
name: Literal["bronze", "silver", "gold", "platinum"]
|
|
30
31
|
"""Name of the current referral level"""
|
|
31
32
|
|
|
32
33
|
percent: float
|
|
@@ -36,7 +37,7 @@ class CurrentLevel(BaseModel):
|
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
class Level(BaseModel):
|
|
39
|
-
name:
|
|
40
|
+
name: Literal["bronze", "silver", "gold", "platinum"]
|
|
40
41
|
"""Name of the referral level"""
|
|
41
42
|
|
|
42
43
|
percent: float
|
|
@@ -66,7 +67,7 @@ class NextLevelRequirements(BaseModel):
|
|
|
66
67
|
class NextLevel(BaseModel):
|
|
67
68
|
"""Next level information. Null if already at max level"""
|
|
68
69
|
|
|
69
|
-
name:
|
|
70
|
+
name: Literal["bronze", "silver", "gold", "platinum"]
|
|
70
71
|
"""Name of the next referral level"""
|
|
71
72
|
|
|
72
73
|
percent: float
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from gmt._utils._path import path_template
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.mark.parametrize(
|
|
11
|
+
"template, kwargs, expected",
|
|
12
|
+
[
|
|
13
|
+
("/v1/{id}", dict(id="abc"), "/v1/abc"),
|
|
14
|
+
("/v1/{a}/{b}", dict(a="x", b="y"), "/v1/x/y"),
|
|
15
|
+
("/v1/{a}{b}/path/{c}?val={d}#{e}", dict(a="x", b="y", c="z", d="u", e="v"), "/v1/xy/path/z?val=u#v"),
|
|
16
|
+
("/{w}/{w}", dict(w="echo"), "/echo/echo"),
|
|
17
|
+
("/v1/static", {}, "/v1/static"),
|
|
18
|
+
("", {}, ""),
|
|
19
|
+
("/v1/?q={n}&count=10", dict(n=42), "/v1/?q=42&count=10"),
|
|
20
|
+
("/v1/{v}", dict(v=None), "/v1/null"),
|
|
21
|
+
("/v1/{v}", dict(v=True), "/v1/true"),
|
|
22
|
+
("/v1/{v}", dict(v=False), "/v1/false"),
|
|
23
|
+
("/v1/{v}", dict(v=".hidden"), "/v1/.hidden"), # dot prefix ok
|
|
24
|
+
("/v1/{v}", dict(v="file.txt"), "/v1/file.txt"), # dot in middle ok
|
|
25
|
+
("/v1/{v}", dict(v="..."), "/v1/..."), # triple dot ok
|
|
26
|
+
("/v1/{a}{b}", dict(a=".", b="txt"), "/v1/.txt"), # dot var combining with adjacent to be ok
|
|
27
|
+
("/items?q={v}#{f}", dict(v=".", f=".."), "/items?q=.#.."), # dots in query/fragment are fine
|
|
28
|
+
(
|
|
29
|
+
"/v1/{a}?query={b}",
|
|
30
|
+
dict(a="../../other/endpoint", b="a&bad=true"),
|
|
31
|
+
"/v1/..%2F..%2Fother%2Fendpoint?query=a%26bad%3Dtrue",
|
|
32
|
+
),
|
|
33
|
+
("/v1/{val}", dict(val="a/b/c"), "/v1/a%2Fb%2Fc"),
|
|
34
|
+
("/v1/{val}", dict(val="a/b/c?query=value"), "/v1/a%2Fb%2Fc%3Fquery=value"),
|
|
35
|
+
("/v1/{val}", dict(val="a/b/c?query=value&bad=true"), "/v1/a%2Fb%2Fc%3Fquery=value&bad=true"),
|
|
36
|
+
("/v1/{val}", dict(val="%20"), "/v1/%2520"), # escapes escape sequences in input
|
|
37
|
+
# Query: slash and ? are safe, # is not
|
|
38
|
+
("/items?q={v}", dict(v="a/b"), "/items?q=a/b"),
|
|
39
|
+
("/items?q={v}", dict(v="a?b"), "/items?q=a?b"),
|
|
40
|
+
("/items?q={v}", dict(v="a#b"), "/items?q=a%23b"),
|
|
41
|
+
("/items?q={v}", dict(v="a b"), "/items?q=a%20b"),
|
|
42
|
+
# Fragment: slash and ? are safe
|
|
43
|
+
("/docs#{v}", dict(v="a/b"), "/docs#a/b"),
|
|
44
|
+
("/docs#{v}", dict(v="a?b"), "/docs#a?b"),
|
|
45
|
+
# Path: slash, ? and # are all encoded
|
|
46
|
+
("/v1/{v}", dict(v="a/b"), "/v1/a%2Fb"),
|
|
47
|
+
("/v1/{v}", dict(v="a?b"), "/v1/a%3Fb"),
|
|
48
|
+
("/v1/{v}", dict(v="a#b"), "/v1/a%23b"),
|
|
49
|
+
# same var encoded differently by component
|
|
50
|
+
(
|
|
51
|
+
"/v1/{v}?q={v}#{v}",
|
|
52
|
+
dict(v="a/b?c#d"),
|
|
53
|
+
"/v1/a%2Fb%3Fc%23d?q=a/b?c%23d#a/b?c%23d",
|
|
54
|
+
),
|
|
55
|
+
("/v1/{val}", dict(val="x?admin=true"), "/v1/x%3Fadmin=true"), # query injection
|
|
56
|
+
("/v1/{val}", dict(val="x#admin"), "/v1/x%23admin"), # fragment injection
|
|
57
|
+
],
|
|
58
|
+
)
|
|
59
|
+
def test_interpolation(template: str, kwargs: dict[str, Any], expected: str) -> None:
|
|
60
|
+
assert path_template(template, **kwargs) == expected
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_missing_kwarg_raises_key_error() -> None:
|
|
64
|
+
with pytest.raises(KeyError, match="org_id"):
|
|
65
|
+
path_template("/v1/{org_id}")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@pytest.mark.parametrize(
|
|
69
|
+
"template, kwargs",
|
|
70
|
+
[
|
|
71
|
+
("{a}/path", dict(a=".")),
|
|
72
|
+
("{a}/path", dict(a="..")),
|
|
73
|
+
("/v1/{a}", dict(a=".")),
|
|
74
|
+
("/v1/{a}", dict(a="..")),
|
|
75
|
+
("/v1/{a}/path", dict(a=".")),
|
|
76
|
+
("/v1/{a}/path", dict(a="..")),
|
|
77
|
+
("/v1/{a}{b}", dict(a=".", b=".")), # adjacent vars → ".."
|
|
78
|
+
("/v1/{a}.", dict(a=".")), # var + static → ".."
|
|
79
|
+
("/v1/{a}{b}", dict(a="", b=".")), # empty + dot → "."
|
|
80
|
+
("/v1/%2e/{x}", dict(x="ok")), # encoded dot in static text
|
|
81
|
+
("/v1/%2e./{x}", dict(x="ok")), # mixed encoded ".." in static
|
|
82
|
+
("/v1/.%2E/{x}", dict(x="ok")), # mixed encoded ".." in static
|
|
83
|
+
("/v1/{v}?q=1", dict(v="..")),
|
|
84
|
+
("/v1/{v}#frag", dict(v="..")),
|
|
85
|
+
],
|
|
86
|
+
)
|
|
87
|
+
def test_dot_segment_rejected(template: str, kwargs: dict[str, Any]) -> None:
|
|
88
|
+
with pytest.raises(ValueError, match="dot-segment"):
|
|
89
|
+
path_template(template, **kwargs)
|
|
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
|
|
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
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/referral/__init__.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/referral/referral.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/resources/profile/referral/transaction.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_list_countries_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/account_list_countries_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile/discount_retrieve_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_login_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_login_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_password_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_change_password_response.py
RENAMED
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/profile_unbind_telegram_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/bulk_create_params.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/bulk_create_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/purchases/bulk_retrieve_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/service_get_server_time_response.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/src/gmt/types/service_health_check_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/referral/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/test_discount.py
RENAMED
|
File without changes
|
{gmt_python_sdk-0.27.0 → gmt_python_sdk-0.28.0}/tests/api_resources/profile/test_referral.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
|