cuenca 2.0.0.dev3__tar.gz → 2.0.0.dev5__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.
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/PKG-INFO +12 -3
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/exc.py +5 -4
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/__init__.py +2 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/api_keys.py +3 -3
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/base.py +6 -6
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/card_activations.py +2 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/card_transactions.py +4 -6
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/cards.py +2 -2
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/endpoints.py +10 -7
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/file_batches.py +5 -5
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/files.py +1 -1
- cuenca-2.0.0.dev5/cuenca/resources/jwt.py +12 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/kyc_validations.py +4 -4
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/kyc_verifications.py +3 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/limited_wallets.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/login_tokens.py +7 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/otps.py +2 -2
- cuenca-2.0.0.dev5/cuenca/resources/resources.py +26 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/savings.py +4 -2
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/service_providers.py +2 -2
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/sessions.py +15 -10
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/transfers.py +4 -4
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/user_credentials.py +2 -2
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/user_logins.py +3 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/users.py +3 -3
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/wallet_transactions.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/webhooks.py +2 -2
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/version.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca.egg-info/PKG-INFO +12 -3
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca.egg-info/SOURCES.txt +1 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca.egg-info/requires.txt +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/setup.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/conftest.py +3 -4
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_api_keys.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_card_activations.py +4 -4
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_commissions.py +2 -2
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_endpoints.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_login_tokens.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_otps.py +1 -1
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_sessions.py +6 -6
- cuenca-2.0.0.dev3/cuenca/resources/resources.py +0 -21
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/LICENSE +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/README.md +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/__init__.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/http/__init__.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/http/client.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/jwt.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/py.typed +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/accounts.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/arpc.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/balance_entries.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/bill_payments.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/card_validations.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/cash_references.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/clabes.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/commissions.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/curp_validations.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/deposits.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/identities.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/identity_events.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/platforms.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/questionnaires.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/statements.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/user_events.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/user_lists_validation.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/verifications.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca/resources/whatsapp_transfers.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca.egg-info/dependency_links.txt +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/cuenca.egg-info/top_level.txt +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/setup.cfg +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/__init__.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/http/__init__.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/http/conftest.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/http/test_client.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/__init__.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_accounts.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_arpc.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_balance_entries.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_bill_payments.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_card_transactions.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_card_validations.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_cards.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_cash_references.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_clabes.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_curp_validations.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_deposits.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_file_batches.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_files.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_identities.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_identity_events.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_kyc_validations.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_kyc_verifications.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_limited_wallets.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_platforms.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_questionnaires.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_resources.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_savings.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_service_providers.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_statements.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_transfers.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_user_credentials.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_user_events.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_user_lists_validation.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_user_logins.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_users.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_verifications.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_wallet_transactions.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_webhooks.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/resources/test_whatsapp_transfers.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/test_cuenca.py +0 -0
- {cuenca-2.0.0.dev3 → cuenca-2.0.0.dev5}/tests/test_jwt.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: cuenca
|
|
3
|
-
Version: 2.0.0.
|
|
3
|
+
Version: 2.0.0.dev5
|
|
4
4
|
Summary: Cuenca API Client
|
|
5
5
|
Home-page: https://github.com/cuenca-mx/cuenca-python
|
|
6
6
|
Author: Cuenca
|
|
@@ -16,8 +16,17 @@ Requires-Python: >=3.9
|
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: requests>=2.32.3
|
|
19
|
-
Requires-Dist: cuenca-validations==2.0.0.
|
|
19
|
+
Requires-Dist: cuenca-validations==2.0.0.dev12
|
|
20
20
|
Requires-Dist: pydantic-extra-types>=2.10.1
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: requires-dist
|
|
28
|
+
Dynamic: requires-python
|
|
29
|
+
Dynamic: summary
|
|
21
30
|
|
|
22
31
|
# Cuenca – Python client library
|
|
23
32
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
1
3
|
from cuenca_validations.typing import DictStrAny
|
|
2
4
|
|
|
3
5
|
|
|
@@ -17,11 +19,10 @@ class MultipleResultsFound(CuencaException):
|
|
|
17
19
|
"""One result was expected but multiple were returned"""
|
|
18
20
|
|
|
19
21
|
|
|
22
|
+
@dataclass
|
|
20
23
|
class CuencaResponseException(CuencaException):
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
self.status_code = status_code
|
|
24
|
-
super().__init__()
|
|
24
|
+
json: DictStrAny
|
|
25
|
+
status_code: int
|
|
25
26
|
|
|
26
27
|
def __str__(self) -> str:
|
|
27
28
|
return repr(self)
|
|
@@ -38,6 +38,7 @@ __all__ = [
|
|
|
38
38
|
'WalletTransaction',
|
|
39
39
|
'Webhook',
|
|
40
40
|
'WhatsappTransfer',
|
|
41
|
+
'Jwt',
|
|
41
42
|
]
|
|
42
43
|
|
|
43
44
|
from .accounts import Account
|
|
@@ -59,6 +60,7 @@ from .file_batches import FileBatch
|
|
|
59
60
|
from .files import File
|
|
60
61
|
from .identities import Identity
|
|
61
62
|
from .identity_events import IdentityEvent
|
|
63
|
+
from .jwt import Jwt
|
|
62
64
|
from .kyc_validations import KYCValidation
|
|
63
65
|
from .kyc_verifications import KYCVerification
|
|
64
66
|
from .limited_wallets import LimitedWallet
|
|
@@ -2,7 +2,7 @@ import datetime as dt
|
|
|
2
2
|
from typing import ClassVar, Optional, cast
|
|
3
3
|
|
|
4
4
|
from cuenca_validations.types import ApiKeyQuery, ApiKeyUpdateRequest
|
|
5
|
-
from pydantic import ConfigDict
|
|
5
|
+
from pydantic import ConfigDict, SecretStr
|
|
6
6
|
|
|
7
7
|
from ..http import Session, session as global_session
|
|
8
8
|
from .base import Creatable, Queryable, Retrievable, Updateable
|
|
@@ -12,7 +12,7 @@ class ApiKey(Creatable, Queryable, Retrievable, Updateable):
|
|
|
12
12
|
_resource: ClassVar = 'api_keys'
|
|
13
13
|
_query_params: ClassVar = ApiKeyQuery
|
|
14
14
|
|
|
15
|
-
secret:
|
|
15
|
+
secret: SecretStr
|
|
16
16
|
deactivated_at: Optional[dt.datetime] = None
|
|
17
17
|
user_id: Optional[str] = None
|
|
18
18
|
model_config = ConfigDict(
|
|
@@ -75,5 +75,5 @@ class ApiKey(Creatable, Queryable, Retrievable, Updateable):
|
|
|
75
75
|
req = ApiKeyUpdateRequest(
|
|
76
76
|
metadata=metadata, user_id=user_id, platform_id=platform_id
|
|
77
77
|
)
|
|
78
|
-
resp = cls._update(api_key_id, **req.
|
|
78
|
+
resp = cls._update(api_key_id, **req.model_dump(), session=session)
|
|
79
79
|
return cast('ApiKey', resp)
|
|
@@ -2,7 +2,7 @@ import base64
|
|
|
2
2
|
import datetime as dt
|
|
3
3
|
import json
|
|
4
4
|
from io import BytesIO
|
|
5
|
-
from typing import Any, ClassVar,
|
|
5
|
+
from typing import Any, ClassVar, Generator, Optional
|
|
6
6
|
from urllib.parse import urlencode
|
|
7
7
|
|
|
8
8
|
from cuenca_validations.types import (
|
|
@@ -24,7 +24,7 @@ class Resource(BaseModel):
|
|
|
24
24
|
id: str
|
|
25
25
|
|
|
26
26
|
@classmethod
|
|
27
|
-
def _from_dict(cls, obj_dict:
|
|
27
|
+
def _from_dict(cls, obj_dict: dict[str, Any]) -> 'Resource':
|
|
28
28
|
cls._filter_excess_fields(obj_dict)
|
|
29
29
|
return cls(**obj_dict)
|
|
30
30
|
|
|
@@ -151,7 +151,7 @@ class Queryable(Resource):
|
|
|
151
151
|
cls, *, session: Session = global_session, **query_params
|
|
152
152
|
) -> Resource:
|
|
153
153
|
q = cls._query_params(limit=2, **query_params)
|
|
154
|
-
resp = session.get(cls._resource, q.
|
|
154
|
+
resp = session.get(cls._resource, q.model_dump())
|
|
155
155
|
items = resp['items']
|
|
156
156
|
len_items = len(items)
|
|
157
157
|
if not len_items:
|
|
@@ -165,7 +165,7 @@ class Queryable(Resource):
|
|
|
165
165
|
cls, *, session: Session = global_session, **query_params
|
|
166
166
|
) -> Optional[Resource]:
|
|
167
167
|
q = cls._query_params(limit=1, **query_params)
|
|
168
|
-
resp = session.get(cls._resource, q.
|
|
168
|
+
resp = session.get(cls._resource, q.model_dump())
|
|
169
169
|
try:
|
|
170
170
|
item = resp['items'][0]
|
|
171
171
|
except IndexError:
|
|
@@ -179,7 +179,7 @@ class Queryable(Resource):
|
|
|
179
179
|
cls, *, session: Session = global_session, **query_params
|
|
180
180
|
) -> int:
|
|
181
181
|
q = cls._query_params(count=True, **query_params)
|
|
182
|
-
resp = session.get(cls._resource, q.
|
|
182
|
+
resp = session.get(cls._resource, q.model_dump())
|
|
183
183
|
return resp['count']
|
|
184
184
|
|
|
185
185
|
@classmethod
|
|
@@ -188,7 +188,7 @@ class Queryable(Resource):
|
|
|
188
188
|
) -> Generator[Resource, None, None]:
|
|
189
189
|
session = session or global_session
|
|
190
190
|
q = cls._query_params(**query_params)
|
|
191
|
-
next_page_uri = f'{cls._resource}?{urlencode(q.
|
|
191
|
+
next_page_uri = f'{cls._resource}?{urlencode(q.model_dump())}'
|
|
192
192
|
while next_page_uri:
|
|
193
193
|
page = session.get(next_page_uri)
|
|
194
194
|
yield from (cls._from_dict(item) for item in page['items'])
|
|
@@ -2,6 +2,7 @@ import datetime as dt
|
|
|
2
2
|
from typing import ClassVar, Optional, cast
|
|
3
3
|
|
|
4
4
|
from cuenca_validations.types.requests import CardActivationRequest
|
|
5
|
+
from pydantic_extra_types.payment import PaymentCardNumber
|
|
5
6
|
|
|
6
7
|
from ..http import Session, session as global_session
|
|
7
8
|
from .base import Creatable
|
|
@@ -21,7 +22,7 @@ class CardActivation(Creatable):
|
|
|
21
22
|
@classmethod
|
|
22
23
|
def create(
|
|
23
24
|
cls,
|
|
24
|
-
number:
|
|
25
|
+
number: PaymentCardNumber,
|
|
25
26
|
exp_month: int,
|
|
26
27
|
exp_year: int,
|
|
27
28
|
cvv2: str,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import ClassVar,
|
|
1
|
+
from typing import ClassVar, Optional, cast
|
|
2
2
|
|
|
3
3
|
from cuenca_validations.types import (
|
|
4
4
|
CardErrorType,
|
|
@@ -14,15 +14,13 @@ from .resources import retrieve_uri, retrieve_uris
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class CardTransaction(Transaction):
|
|
17
|
-
def __init__(self, *args, **kwargs):
|
|
18
|
-
super(CardTransaction, self).__init__(*args, **kwargs)
|
|
19
17
|
|
|
20
18
|
_resource: ClassVar = 'card_transactions'
|
|
21
19
|
_query_params: ClassVar = CardTransactionQuery
|
|
22
20
|
|
|
23
21
|
type: CardTransactionType
|
|
24
22
|
network: CardNetwork
|
|
25
|
-
related_card_transaction_uris:
|
|
23
|
+
related_card_transaction_uris: list[str]
|
|
26
24
|
card_uri: str
|
|
27
25
|
card_last4: str
|
|
28
26
|
card_type: CardType
|
|
@@ -30,11 +28,11 @@ class CardTransaction(Transaction):
|
|
|
30
28
|
error_type: Optional[CardErrorType] = None
|
|
31
29
|
|
|
32
30
|
@property # type: ignore
|
|
33
|
-
def related_card_transactions(self) -> Optional[
|
|
31
|
+
def related_card_transactions(self) -> Optional[list['CardTransaction']]:
|
|
34
32
|
if not self.related_card_transaction_uris:
|
|
35
33
|
return []
|
|
36
34
|
return cast(
|
|
37
|
-
|
|
35
|
+
list['CardTransaction'],
|
|
38
36
|
retrieve_uris(self.related_card_transaction_uris),
|
|
39
37
|
)
|
|
40
38
|
|
|
@@ -81,7 +81,7 @@ class Card(Retrievable, Queryable, Creatable, Updateable):
|
|
|
81
81
|
card_holder_user_id=card_holder_user_id,
|
|
82
82
|
is_dynamic_cvv=is_dynamic_cvv,
|
|
83
83
|
)
|
|
84
|
-
return cast('Card', cls._create(session=session, **req.
|
|
84
|
+
return cast('Card', cls._create(session=session, **req.model_dump()))
|
|
85
85
|
|
|
86
86
|
@classmethod
|
|
87
87
|
def update(
|
|
@@ -106,7 +106,7 @@ class Card(Retrievable, Queryable, Creatable, Updateable):
|
|
|
106
106
|
req = CardUpdateRequest(
|
|
107
107
|
status=status, pin_block=pin_block, is_dynamic_cvv=is_dynamic_cvv
|
|
108
108
|
)
|
|
109
|
-
resp = cls._update(card_id, session=session, **req.
|
|
109
|
+
resp = cls._update(card_id, session=session, **req.model_dump())
|
|
110
110
|
return cast('Card', resp)
|
|
111
111
|
|
|
112
112
|
@classmethod
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import ClassVar,
|
|
1
|
+
from typing import ClassVar, Optional, cast
|
|
2
2
|
|
|
3
|
+
from cuenca_validations.types import HttpUrlString
|
|
3
4
|
from cuenca_validations.types.enums import WebhookEvent
|
|
4
5
|
from cuenca_validations.types.requests import (
|
|
5
6
|
EndpointRequest,
|
|
@@ -14,7 +15,7 @@ from .base import Creatable, Deactivable, Queryable, Retrievable, Updateable
|
|
|
14
15
|
class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
|
|
15
16
|
_resource: ClassVar = 'endpoints'
|
|
16
17
|
|
|
17
|
-
url:
|
|
18
|
+
url: HttpUrlString = Field(..., description='HTTPS url to send webhooks')
|
|
18
19
|
secret: str = Field(
|
|
19
20
|
...,
|
|
20
21
|
description='token to verify the webhook is sent by Cuenca '
|
|
@@ -25,7 +26,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
|
|
|
25
26
|
description='Allows user to turn-off the endpoint without the '
|
|
26
27
|
'need of deleting it',
|
|
27
28
|
)
|
|
28
|
-
events:
|
|
29
|
+
events: list[WebhookEvent] = Field(
|
|
29
30
|
...,
|
|
30
31
|
description='list of enabled events. If None, all events will '
|
|
31
32
|
'be enabled for this Endpoint',
|
|
@@ -55,7 +56,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
|
|
|
55
56
|
def create(
|
|
56
57
|
cls,
|
|
57
58
|
url: HttpUrl,
|
|
58
|
-
events: Optional[
|
|
59
|
+
events: Optional[list[WebhookEvent]] = None,
|
|
59
60
|
*,
|
|
60
61
|
session: Session = global_session,
|
|
61
62
|
) -> 'Endpoint':
|
|
@@ -69,14 +70,16 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
|
|
|
69
70
|
:return: New active endpoint
|
|
70
71
|
"""
|
|
71
72
|
req = EndpointRequest(url=url, events=events)
|
|
72
|
-
return cast(
|
|
73
|
+
return cast(
|
|
74
|
+
'Endpoint', cls._create(session=session, **req.model_dump())
|
|
75
|
+
)
|
|
73
76
|
|
|
74
77
|
@classmethod
|
|
75
78
|
def update(
|
|
76
79
|
cls,
|
|
77
80
|
endpoint_id: str,
|
|
78
81
|
url: Optional[HttpUrl] = None,
|
|
79
|
-
events: Optional[
|
|
82
|
+
events: Optional[list[WebhookEvent]] = None,
|
|
80
83
|
is_enable: Optional[bool] = None,
|
|
81
84
|
*,
|
|
82
85
|
session: Session = global_session,
|
|
@@ -93,5 +96,5 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
|
|
|
93
96
|
req = EndpointUpdateRequest(
|
|
94
97
|
url=url, is_enable=is_enable, events=events
|
|
95
98
|
)
|
|
96
|
-
resp = cls._update(endpoint_id, session=session, **req.
|
|
99
|
+
resp = cls._update(endpoint_id, session=session, **req.model_dump())
|
|
97
100
|
return cast('Endpoint', resp)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import ClassVar,
|
|
1
|
+
from typing import ClassVar, cast
|
|
2
2
|
|
|
3
3
|
from cuenca_validations.types import (
|
|
4
4
|
BatchFileMetadata,
|
|
@@ -13,20 +13,20 @@ from .base import Creatable, Queryable
|
|
|
13
13
|
class FileBatch(Creatable, Queryable):
|
|
14
14
|
_resource: ClassVar = 'file_batches'
|
|
15
15
|
|
|
16
|
-
received_files:
|
|
17
|
-
uploaded_files:
|
|
16
|
+
received_files: list[BatchFileMetadata]
|
|
17
|
+
uploaded_files: list[BatchFileMetadata]
|
|
18
18
|
user_id: str
|
|
19
19
|
|
|
20
20
|
@classmethod
|
|
21
21
|
def create(
|
|
22
22
|
cls,
|
|
23
|
-
files:
|
|
23
|
+
files: list[dict],
|
|
24
24
|
user_id: str,
|
|
25
25
|
*,
|
|
26
26
|
session: Session = global_session,
|
|
27
27
|
) -> 'FileBatch':
|
|
28
28
|
req = FileBatchUploadRequest(
|
|
29
|
-
files=cast(
|
|
29
|
+
files=cast(list[FileRequest], files), user_id=user_id
|
|
30
30
|
)
|
|
31
31
|
return cast(
|
|
32
32
|
'FileBatch', cls._create(session=session, **req.model_dump())
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import ClassVar,
|
|
1
|
+
from typing import ClassVar, Optional, cast
|
|
2
2
|
|
|
3
3
|
from cuenca_validations.types import KYCFile, KYCValidationRequest
|
|
4
4
|
from pydantic import ConfigDict
|
|
@@ -12,7 +12,7 @@ class KYCValidation(Creatable, Retrievable, Queryable):
|
|
|
12
12
|
platform_id: str
|
|
13
13
|
attemps: Optional[int] = None
|
|
14
14
|
verification_id: Optional[str] = None
|
|
15
|
-
files_uri: Optional[
|
|
15
|
+
files_uri: Optional[list[str]] = None
|
|
16
16
|
model_config = ConfigDict(
|
|
17
17
|
json_schema_extra={
|
|
18
18
|
'example': {
|
|
@@ -31,7 +31,7 @@ class KYCValidation(Creatable, Retrievable, Queryable):
|
|
|
31
31
|
cls,
|
|
32
32
|
user_id: str,
|
|
33
33
|
force: bool = False,
|
|
34
|
-
documents:
|
|
34
|
+
documents: list[KYCFile] = [],
|
|
35
35
|
session: Session = global_session,
|
|
36
36
|
) -> 'KYCValidation':
|
|
37
37
|
req = KYCValidationRequest(
|
|
@@ -40,5 +40,5 @@ class KYCValidation(Creatable, Retrievable, Queryable):
|
|
|
40
40
|
documents=documents,
|
|
41
41
|
)
|
|
42
42
|
return cast(
|
|
43
|
-
'KYCValidation', cls._create(**req.
|
|
43
|
+
'KYCValidation', cls._create(**req.model_dump(), session=session)
|
|
44
44
|
)
|
|
@@ -49,4 +49,6 @@ class KYCVerification(Creatable, Retrievable, Updateable):
|
|
|
49
49
|
curp: CurpField,
|
|
50
50
|
) -> 'KYCVerification':
|
|
51
51
|
req = KYCVerificationUpdateRequest(curp=curp)
|
|
52
|
-
return cast(
|
|
52
|
+
return cast(
|
|
53
|
+
'KYCVerification', cls._update(id=kyc_id, **req.model_dump())
|
|
54
|
+
)
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
from typing import ClassVar, cast
|
|
2
2
|
|
|
3
|
-
from pydantic import ConfigDict
|
|
3
|
+
from pydantic import ConfigDict, SecretStr
|
|
4
4
|
|
|
5
5
|
from ..http import Session, session as global_session
|
|
6
6
|
from .base import Creatable
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
# mypy: disable-error-code=override
|
|
9
10
|
class LoginToken(Creatable):
|
|
10
11
|
_resource: ClassVar = 'login_tokens'
|
|
12
|
+
|
|
13
|
+
# Override the `id` field to be a `SecretStr`
|
|
14
|
+
# To ensure sensitive data is not exposed in logs.
|
|
15
|
+
id: SecretStr # type: ignore
|
|
16
|
+
|
|
11
17
|
model_config = ConfigDict(
|
|
12
18
|
json_schema_extra={'example': {'id': 'LTNEUInh69SuKXXmK95sROwQ'}}
|
|
13
19
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import ClassVar, cast
|
|
2
2
|
|
|
3
|
-
from pydantic import ConfigDict
|
|
3
|
+
from pydantic import ConfigDict, SecretStr
|
|
4
4
|
|
|
5
5
|
from ..http import Session, session as global_session
|
|
6
6
|
from .base import Creatable
|
|
@@ -8,7 +8,7 @@ from .base import Creatable
|
|
|
8
8
|
|
|
9
9
|
class Otp(Creatable):
|
|
10
10
|
_resource: ClassVar = 'otps'
|
|
11
|
-
secret:
|
|
11
|
+
secret: SecretStr
|
|
12
12
|
model_config = ConfigDict(
|
|
13
13
|
json_schema_extra={
|
|
14
14
|
'example': {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import cast
|
|
3
|
+
|
|
4
|
+
from .base import Retrievable
|
|
5
|
+
|
|
6
|
+
ENDPOINT_RE = re.compile(r'.*/(?P<resource>[a-z_]+)/(?P<id>.+)$')
|
|
7
|
+
RESOURCES: dict[str, Retrievable] = {} # set in ./__init__.py after imports
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def retrieve_uri(uri: str) -> Retrievable:
|
|
11
|
+
m = ENDPOINT_RE.match(uri)
|
|
12
|
+
if not m:
|
|
13
|
+
raise ValueError(f'uri is not a valid format: {uri}')
|
|
14
|
+
resource, id_ = m.groups()
|
|
15
|
+
return cast(Retrievable, RESOURCES[resource].retrieve(id_))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def retrieve_uris(uris: list[str]) -> list[Retrievable]:
|
|
19
|
+
# Changed the implementation to use a simple for loop instead of
|
|
20
|
+
# ThreadPoolExecutor. The list of URIs is small, so the performance
|
|
21
|
+
# difference is negligible. Additionally, using ThreadPoolExecutor
|
|
22
|
+
# caused issues with VCR tests, as the recordings were not retrieved
|
|
23
|
+
# in the correct order, leading to unexpected HTTP calls instead of
|
|
24
|
+
# using the mocked recordings.
|
|
25
|
+
|
|
26
|
+
return [retrieve_uri(uri) for uri in uris]
|
|
@@ -34,7 +34,7 @@ class Saving(Wallet, Updateable):
|
|
|
34
34
|
goal_amount=goal_amount,
|
|
35
35
|
goal_date=goal_date,
|
|
36
36
|
)
|
|
37
|
-
return cast('Saving', cls._create(**request.
|
|
37
|
+
return cast('Saving', cls._create(**request.model_dump()))
|
|
38
38
|
|
|
39
39
|
@classmethod
|
|
40
40
|
def update(
|
|
@@ -51,4 +51,6 @@ class Saving(Wallet, Updateable):
|
|
|
51
51
|
goal_amount=goal_amount,
|
|
52
52
|
goal_date=goal_date,
|
|
53
53
|
)
|
|
54
|
-
return cast(
|
|
54
|
+
return cast(
|
|
55
|
+
'Saving', cls._update(id=saving_id, **request.model_dump())
|
|
56
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import ClassVar
|
|
1
|
+
from typing import ClassVar
|
|
2
2
|
|
|
3
3
|
from cuenca_validations.types import ServiceProviderCategory
|
|
4
4
|
|
|
@@ -10,4 +10,4 @@ class ServiceProvider(Retrievable, Queryable):
|
|
|
10
10
|
|
|
11
11
|
name: str
|
|
12
12
|
provider_key: str
|
|
13
|
-
categories:
|
|
13
|
+
categories: list[ServiceProviderCategory]
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import datetime as dt
|
|
2
2
|
from typing import ClassVar, Optional, cast
|
|
3
3
|
|
|
4
|
-
from cuenca_validations.types import SessionRequest, SessionType
|
|
5
|
-
from pydantic import
|
|
4
|
+
from cuenca_validations.types import AnyUrlString, SessionRequest, SessionType
|
|
5
|
+
from pydantic import ConfigDict, SecretStr
|
|
6
6
|
|
|
7
7
|
from .. import http
|
|
8
8
|
from .base import Creatable, Queryable, Retrievable
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
# mypy: disable-error-code=override
|
|
11
12
|
class Session(Creatable, Retrievable, Queryable):
|
|
12
13
|
_resource: ClassVar = 'sessions'
|
|
13
14
|
|
|
14
|
-
id
|
|
15
|
+
# Override the `id` field to be a `SecretStr`
|
|
16
|
+
# To ensure sensitive data is not exposed in logs.
|
|
17
|
+
id: SecretStr = None # type: ignore
|
|
15
18
|
created_at: dt.datetime
|
|
16
19
|
user_id: str
|
|
17
20
|
platform_id: str
|
|
18
21
|
expires_at: dt.datetime
|
|
19
|
-
success_url: Optional[
|
|
20
|
-
failure_url: Optional[
|
|
22
|
+
success_url: Optional[AnyUrlString] = None
|
|
23
|
+
failure_url: Optional[AnyUrlString] = None
|
|
21
24
|
type: Optional[SessionType] = None
|
|
22
25
|
model_config = ConfigDict(
|
|
23
26
|
json_schema_extra={
|
|
@@ -39,15 +42,17 @@ class Session(Creatable, Retrievable, Queryable):
|
|
|
39
42
|
cls,
|
|
40
43
|
user_id: str,
|
|
41
44
|
type: SessionType,
|
|
42
|
-
success_url
|
|
43
|
-
failure_url
|
|
45
|
+
success_url: Optional[str] = None,
|
|
46
|
+
failure_url: Optional[str] = None,
|
|
44
47
|
*,
|
|
45
48
|
session: http.Session = http.session,
|
|
46
49
|
) -> 'Session':
|
|
47
50
|
req = SessionRequest(
|
|
48
51
|
user_id=user_id,
|
|
49
52
|
type=type,
|
|
50
|
-
success_url=success_url,
|
|
51
|
-
failure_url=failure_url,
|
|
53
|
+
success_url=success_url, # type: ignore
|
|
54
|
+
failure_url=failure_url, # type: ignore
|
|
55
|
+
)
|
|
56
|
+
return cast(
|
|
57
|
+
'Session', cls._create(session=session, **req.model_dump())
|
|
52
58
|
)
|
|
53
|
-
return cast('Session', cls._create(session=session, **req.dict()))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import datetime as dt
|
|
2
|
-
from typing import ClassVar,
|
|
2
|
+
from typing import ClassVar, Optional, cast
|
|
3
3
|
|
|
4
4
|
from clabe import Clabe
|
|
5
5
|
from cuenca_validations.types import (
|
|
@@ -70,14 +70,14 @@ class Transfer(Transaction, Creatable):
|
|
|
70
70
|
idempotency_key=idempotency_key,
|
|
71
71
|
user_id=user_id,
|
|
72
72
|
)
|
|
73
|
-
return cast('Transfer', cls._create(**req.
|
|
73
|
+
return cast('Transfer', cls._create(**req.model_dump()))
|
|
74
74
|
|
|
75
75
|
@classmethod
|
|
76
|
-
def create_many(cls, requests:
|
|
76
|
+
def create_many(cls, requests: list[TransferRequest]) -> DictStrAny:
|
|
77
77
|
transfers: DictStrAny = dict(submitted=[], errors=[])
|
|
78
78
|
for req in requests:
|
|
79
79
|
try:
|
|
80
|
-
transfer = cls._create(**req.
|
|
80
|
+
transfer = cls._create(**req.model_dump())
|
|
81
81
|
except (CuencaException, HTTPError) as e:
|
|
82
82
|
transfers['errors'].append(dict(request=req, error=e))
|
|
83
83
|
else:
|
|
@@ -26,7 +26,7 @@ class UserCredential(Creatable, Updateable):
|
|
|
26
26
|
) -> 'UserCredential':
|
|
27
27
|
req = UserCredentialRequest(password=password, user_id=user_id)
|
|
28
28
|
return cast(
|
|
29
|
-
'UserCredential', cls._create(**req.
|
|
29
|
+
'UserCredential', cls._create(**req.model_dump(), session=session)
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
@classmethod
|
|
@@ -44,5 +44,5 @@ class UserCredential(Creatable, Updateable):
|
|
|
44
44
|
)
|
|
45
45
|
return cast(
|
|
46
46
|
'UserCredential',
|
|
47
|
-
cls._update(id=user_id, **req.
|
|
47
|
+
cls._update(id=user_id, **req.model_dump(), session=session),
|
|
48
48
|
)
|
|
@@ -32,7 +32,9 @@ class UserLogin(Creatable):
|
|
|
32
32
|
session: Session = global_session,
|
|
33
33
|
) -> 'UserLogin':
|
|
34
34
|
req = UserLoginRequest(password=password, user_id=user_id)
|
|
35
|
-
login = cast(
|
|
35
|
+
login = cast(
|
|
36
|
+
'UserLogin', cls._create(session=session, **req.model_dump())
|
|
37
|
+
)
|
|
36
38
|
if login.success:
|
|
37
39
|
session.headers['X-Cuenca-LoginId'] = login.id
|
|
38
40
|
return login
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import datetime as dt
|
|
2
|
-
from typing import ClassVar,
|
|
2
|
+
from typing import ClassVar, Optional, cast
|
|
3
3
|
|
|
4
4
|
from clabe import Clabe
|
|
5
5
|
from cuenca_validations.types import (
|
|
@@ -52,7 +52,7 @@ class User(Creatable, Retrievable, Updateable, Queryable):
|
|
|
52
52
|
proof_of_life: Optional[KYCFile] = Field(
|
|
53
53
|
None, description='Detail of selfie video validation'
|
|
54
54
|
)
|
|
55
|
-
beneficiaries: Optional[
|
|
55
|
+
beneficiaries: Optional[list[Beneficiary]] = Field(
|
|
56
56
|
None, description='Beneficiaries of account in case of death'
|
|
57
57
|
)
|
|
58
58
|
platform_id: Optional[str] = None
|
|
@@ -140,7 +140,7 @@ class User(Creatable, Retrievable, Updateable, Queryable):
|
|
|
140
140
|
email_address: Optional[str] = None,
|
|
141
141
|
profession: Optional[str] = None,
|
|
142
142
|
address: Optional[Address] = None,
|
|
143
|
-
beneficiaries: Optional[
|
|
143
|
+
beneficiaries: Optional[list[Beneficiary]] = None,
|
|
144
144
|
govt_id: Optional[KYCFile] = None,
|
|
145
145
|
proof_of_address: Optional[KYCFile] = None,
|
|
146
146
|
proof_of_life: Optional[KYCFile] = None,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any, ClassVar
|
|
1
|
+
from typing import Any, ClassVar
|
|
2
2
|
|
|
3
3
|
from cuenca_validations.types.enums import WebhookEvent
|
|
4
4
|
from pydantic import Field
|
|
@@ -9,7 +9,7 @@ from .base import Queryable, Retrievable
|
|
|
9
9
|
class Webhook(Retrievable, Queryable):
|
|
10
10
|
_resource: ClassVar = 'webhooks'
|
|
11
11
|
|
|
12
|
-
payload:
|
|
12
|
+
payload: dict[str, Any] = Field(
|
|
13
13
|
..., description='object sent by the webhook'
|
|
14
14
|
)
|
|
15
15
|
event: WebhookEvent = Field(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: cuenca
|
|
3
|
-
Version: 2.0.0.
|
|
3
|
+
Version: 2.0.0.dev5
|
|
4
4
|
Summary: Cuenca API Client
|
|
5
5
|
Home-page: https://github.com/cuenca-mx/cuenca-python
|
|
6
6
|
Author: Cuenca
|
|
@@ -16,8 +16,17 @@ Requires-Python: >=3.9
|
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: requests>=2.32.3
|
|
19
|
-
Requires-Dist: cuenca-validations==2.0.0.
|
|
19
|
+
Requires-Dist: cuenca-validations==2.0.0.dev12
|
|
20
20
|
Requires-Dist: pydantic-extra-types>=2.10.1
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: requires-dist
|
|
28
|
+
Dynamic: requires-python
|
|
29
|
+
Dynamic: summary
|
|
21
30
|
|
|
22
31
|
# Cuenca – Python client library
|
|
23
32
|
|
|
@@ -35,6 +35,7 @@ cuenca/resources/file_batches.py
|
|
|
35
35
|
cuenca/resources/files.py
|
|
36
36
|
cuenca/resources/identities.py
|
|
37
37
|
cuenca/resources/identity_events.py
|
|
38
|
+
cuenca/resources/jwt.py
|
|
38
39
|
cuenca/resources/kyc_validations.py
|
|
39
40
|
cuenca/resources/kyc_verifications.py
|
|
40
41
|
cuenca/resources/limited_wallets.py
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import datetime as dt
|
|
2
2
|
from io import BytesIO
|
|
3
|
-
from typing import Dict
|
|
4
3
|
|
|
5
4
|
import pytest
|
|
6
5
|
from cuenca_validations.types import Country, Gender, State
|
|
@@ -31,7 +30,7 @@ def transfer():
|
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
@pytest.fixture
|
|
34
|
-
def curp_validation_request() ->
|
|
33
|
+
def curp_validation_request() -> dict:
|
|
35
34
|
curp_validation = dict(
|
|
36
35
|
names='José',
|
|
37
36
|
first_surname='López',
|
|
@@ -45,7 +44,7 @@ def curp_validation_request() -> Dict:
|
|
|
45
44
|
|
|
46
45
|
|
|
47
46
|
@pytest.fixture
|
|
48
|
-
def user_request() ->
|
|
47
|
+
def user_request() -> dict:
|
|
49
48
|
user_dict = dict(
|
|
50
49
|
curp='LOHJ660606HDFPRS02',
|
|
51
50
|
phone_number='+525511223344',
|
|
@@ -64,7 +63,7 @@ def user_request() -> Dict:
|
|
|
64
63
|
|
|
65
64
|
|
|
66
65
|
@pytest.fixture
|
|
67
|
-
def user_lists_request() ->
|
|
66
|
+
def user_lists_request() -> dict:
|
|
68
67
|
user_dict = dict(
|
|
69
68
|
curp='LOHJ660606HDFPRS02',
|
|
70
69
|
names='Alejandro',
|
|
@@ -18,7 +18,7 @@ def test_api_keys_retrieve():
|
|
|
18
18
|
id_key = 'AKMPSxy2UeSKqU1J6spDNwqA'
|
|
19
19
|
api_key: ApiKey = ApiKey.retrieve(id_key)
|
|
20
20
|
assert api_key.id == id_key
|
|
21
|
-
assert api_key.secret == '********'
|
|
21
|
+
assert api_key.secret.get_secret_value() == '********'
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
@pytest.mark.vcr
|
|
@@ -8,17 +8,17 @@ from cuenca.resources import CardActivation
|
|
|
8
8
|
@pytest.mark.vcr
|
|
9
9
|
def test_card_activation():
|
|
10
10
|
values = dict(
|
|
11
|
-
number='
|
|
11
|
+
number='5448750001621241',
|
|
12
12
|
exp_month=11,
|
|
13
13
|
exp_year=24,
|
|
14
|
-
cvv2='
|
|
14
|
+
cvv2='111',
|
|
15
15
|
)
|
|
16
16
|
card_activation = CardActivation.create(**values)
|
|
17
17
|
assert card_activation.success
|
|
18
|
-
assert card_activation.user_id == '
|
|
18
|
+
assert card_activation.user_id == 'US1w9BJ0DZ9kSdac39ur14Nf'
|
|
19
19
|
card = card_activation.card
|
|
20
20
|
assert all(getattr(card, key) == value for key, value in values.items())
|
|
21
|
-
assert card.user_id == '
|
|
21
|
+
assert card.user_id == 'US1w9BJ0DZ9kSdac39ur14Nf'
|
|
22
22
|
assert card.status is CardStatus.active
|
|
23
23
|
|
|
24
24
|
|
|
@@ -17,7 +17,7 @@ def test_commission_retrieve_with_cash_deposit():
|
|
|
17
17
|
assert commission.id == id_commission
|
|
18
18
|
related_transaction = commission.related_transaction
|
|
19
19
|
assert related_transaction
|
|
20
|
-
assert
|
|
20
|
+
assert isinstance(related_transaction, Deposit)
|
|
21
21
|
assert related_transaction.network == 'cash'
|
|
22
22
|
|
|
23
23
|
|
|
@@ -28,5 +28,5 @@ def test_commission_retrieve_with_cash_transfer():
|
|
|
28
28
|
assert commission.id == id_commission
|
|
29
29
|
related_transaction = commission.related_transaction
|
|
30
30
|
assert related_transaction
|
|
31
|
-
assert
|
|
31
|
+
assert isinstance(related_transaction, Transfer)
|
|
32
32
|
assert related_transaction.network == 'spei'
|
|
@@ -43,7 +43,7 @@ def test_endpoint_update():
|
|
|
43
43
|
)
|
|
44
44
|
assert endpoint.id == id_endpoint
|
|
45
45
|
assert len(endpoint.events) == 2
|
|
46
|
-
assert
|
|
46
|
+
assert endpoint.url == 'https://url.io/'
|
|
47
47
|
assert not endpoint.is_enable
|
|
48
48
|
assert endpoint.is_active
|
|
49
49
|
|
|
@@ -20,5 +20,5 @@ def test_login_token(session):
|
|
|
20
20
|
UserLogin.create('222222', session=session)
|
|
21
21
|
login_token = LoginToken.create(session=session)
|
|
22
22
|
session.headers.pop('X-Cuenca-LoginId')
|
|
23
|
-
session.configure(login_token=login_token.id)
|
|
23
|
+
session.configure(login_token=login_token.id.get_secret_value())
|
|
24
24
|
Transfer.count(session=session)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Dict
|
|
2
|
-
|
|
3
1
|
import pytest
|
|
4
2
|
from cuenca_validations.types import SessionType
|
|
5
3
|
from pydantic import ValidationError
|
|
@@ -9,7 +7,7 @@ from cuenca.resources import CurpValidation, Session, User
|
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
@pytest.mark.vcr
|
|
12
|
-
def test_session_create(curp_validation_request:
|
|
10
|
+
def test_session_create(curp_validation_request: dict, user_request: dict):
|
|
13
11
|
curp_valdation = CurpValidation.create(**curp_validation_request)
|
|
14
12
|
user_request['curp'] = curp_valdation.validated_curp
|
|
15
13
|
user = User.create(**user_request)
|
|
@@ -34,10 +32,12 @@ def test_session_create(curp_validation_request: Dict, user_request: Dict):
|
|
|
34
32
|
|
|
35
33
|
assert user_session.user_id == user.id
|
|
36
34
|
assert user_session.type == SessionType.registration
|
|
37
|
-
assert
|
|
38
|
-
assert
|
|
35
|
+
assert user_session.success_url == success_url
|
|
36
|
+
assert user_session.failure_url == failure_url
|
|
39
37
|
|
|
40
38
|
ephimeral_cuenca_session = cuenca.http.Session()
|
|
41
|
-
ephimeral_cuenca_session.configure(
|
|
39
|
+
ephimeral_cuenca_session.configure(
|
|
40
|
+
session_token=user_session.id.get_secret_value()
|
|
41
|
+
)
|
|
42
42
|
user = User.update(user.id, email_address='manu@example.com')
|
|
43
43
|
assert user.email_address == 'manu@example.com'
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
3
|
-
from typing import Dict, List, cast
|
|
4
|
-
|
|
5
|
-
from .base import Retrievable
|
|
6
|
-
|
|
7
|
-
ENDPOINT_RE = re.compile(r'.*/(?P<resource>[a-z_]+)/(?P<id>.+)$')
|
|
8
|
-
RESOURCES: Dict[str, Retrievable] = {} # set in ./__init__.py after imports
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def retrieve_uri(uri: str) -> Retrievable:
|
|
12
|
-
m = ENDPOINT_RE.match(uri)
|
|
13
|
-
if not m:
|
|
14
|
-
raise ValueError(f'uri is not a valid format: {uri}')
|
|
15
|
-
resource, id_ = m.groups()
|
|
16
|
-
return cast(Retrievable, RESOURCES[resource].retrieve(id_))
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def retrieve_uris(uris: List[str]) -> List[Retrievable]:
|
|
20
|
-
with ThreadPoolExecutor(max_workers=len(uris)) as executor:
|
|
21
|
-
return [obj for obj in executor.map(retrieve_uri, uris)]
|
|
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
|
|
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
|