cuenca 2.0.0.dev5__tar.gz → 2.0.0.dev7__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.
Files changed (111) hide show
  1. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/PKG-INFO +4 -4
  2. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/__init__.py +1 -3
  3. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/__init__.py +0 -2
  4. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/api_keys.py +6 -7
  5. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/arpc.py +3 -4
  6. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/base.py +67 -51
  7. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/card_activations.py +2 -5
  8. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/card_transactions.py +0 -1
  9. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/card_validations.py +2 -4
  10. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/cards.py +4 -5
  11. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/clabes.py +2 -2
  12. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/curp_validations.py +10 -14
  13. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/endpoints.py +5 -11
  14. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/file_batches.py +4 -5
  15. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/files.py +4 -15
  16. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/identities.py +2 -2
  17. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/kyc_validations.py +3 -4
  18. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/kyc_verifications.py +7 -8
  19. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/limited_wallets.py +5 -5
  20. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/login_tokens.py +3 -8
  21. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/otps.py +5 -4
  22. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/platforms.py +5 -7
  23. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/questionnaires.py +3 -4
  24. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/resources.py +1 -2
  25. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/savings.py +4 -6
  26. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/sessions.py +10 -14
  27. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/transfers.py +4 -5
  28. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/user_credentials.py +3 -8
  29. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/user_events.py +1 -0
  30. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/user_lists_validation.py +6 -10
  31. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/user_logins.py +3 -4
  32. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/users.py +11 -16
  33. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/verifications.py +5 -10
  34. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/wallet_transactions.py +2 -2
  35. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/webhooks.py +2 -6
  36. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/version.py +1 -1
  37. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca.egg-info/PKG-INFO +4 -4
  38. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca.egg-info/SOURCES.txt +0 -1
  39. cuenca-2.0.0.dev7/cuenca.egg-info/requires.txt +3 -0
  40. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/setup.py +8 -8
  41. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_api_keys.py +2 -2
  42. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_cards.py +0 -8
  43. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_endpoints.py +1 -1
  44. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_login_tokens.py +1 -1
  45. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_otps.py +1 -1
  46. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_sessions.py +1 -5
  47. cuenca-2.0.0.dev5/cuenca/resources/jwt.py +0 -12
  48. cuenca-2.0.0.dev5/cuenca.egg-info/requires.txt +0 -3
  49. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/LICENSE +0 -0
  50. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/README.md +0 -0
  51. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/exc.py +0 -0
  52. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/http/__init__.py +0 -0
  53. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/http/client.py +0 -0
  54. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/jwt.py +0 -0
  55. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/py.typed +0 -0
  56. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/accounts.py +0 -0
  57. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/balance_entries.py +0 -0
  58. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/bill_payments.py +0 -0
  59. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/cash_references.py +0 -0
  60. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/commissions.py +0 -0
  61. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/deposits.py +0 -0
  62. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/identity_events.py +0 -0
  63. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/service_providers.py +0 -0
  64. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/statements.py +0 -0
  65. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca/resources/whatsapp_transfers.py +0 -0
  66. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca.egg-info/dependency_links.txt +0 -0
  67. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/cuenca.egg-info/top_level.txt +0 -0
  68. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/setup.cfg +0 -0
  69. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/__init__.py +0 -0
  70. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/conftest.py +0 -0
  71. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/http/__init__.py +0 -0
  72. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/http/conftest.py +0 -0
  73. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/http/test_client.py +0 -0
  74. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/__init__.py +0 -0
  75. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_accounts.py +0 -0
  76. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_arpc.py +0 -0
  77. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_balance_entries.py +0 -0
  78. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_bill_payments.py +0 -0
  79. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_card_activations.py +0 -0
  80. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_card_transactions.py +0 -0
  81. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_card_validations.py +0 -0
  82. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_cash_references.py +0 -0
  83. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_clabes.py +0 -0
  84. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_commissions.py +0 -0
  85. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_curp_validations.py +0 -0
  86. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_deposits.py +0 -0
  87. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_file_batches.py +0 -0
  88. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_files.py +0 -0
  89. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_identities.py +0 -0
  90. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_identity_events.py +0 -0
  91. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_kyc_validations.py +0 -0
  92. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_kyc_verifications.py +0 -0
  93. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_limited_wallets.py +0 -0
  94. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_platforms.py +0 -0
  95. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_questionnaires.py +0 -0
  96. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_resources.py +0 -0
  97. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_savings.py +0 -0
  98. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_service_providers.py +0 -0
  99. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_statements.py +0 -0
  100. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_transfers.py +0 -0
  101. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_user_credentials.py +0 -0
  102. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_user_events.py +0 -0
  103. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_user_lists_validation.py +0 -0
  104. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_user_logins.py +0 -0
  105. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_users.py +0 -0
  106. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_verifications.py +0 -0
  107. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_wallet_transactions.py +0 -0
  108. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_webhooks.py +0 -0
  109. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/resources/test_whatsapp_transfers.py +0 -0
  110. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/test_cuenca.py +0 -0
  111. {cuenca-2.0.0.dev5 → cuenca-2.0.0.dev7}/tests/test_jwt.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cuenca
3
- Version: 2.0.0.dev5
3
+ Version: 2.0.0.dev7
4
4
  Summary: Cuenca API Client
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-python
6
6
  Author: Cuenca
@@ -15,9 +15,9 @@ Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.9
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: requests>=2.32.3
19
- Requires-Dist: cuenca-validations==2.0.0.dev12
20
- Requires-Dist: pydantic-extra-types>=2.10.1
18
+ Requires-Dist: requests>=2.32.0
19
+ Requires-Dist: cuenca-validations>=2.0.0
20
+ Requires-Dist: pydantic-extra-types>=2.10.0
21
21
  Dynamic: author
22
22
  Dynamic: author-email
23
23
  Dynamic: classifier
@@ -44,8 +44,6 @@ __all__ = [
44
44
  'get_balance',
45
45
  ]
46
46
 
47
- from typing import cast
48
-
49
47
  from . import http
50
48
  from .resources import (
51
49
  Account,
@@ -96,5 +94,5 @@ session = http.session
96
94
 
97
95
 
98
96
  def get_balance(session: http.Session = session) -> int:
99
- balance_entry = cast('BalanceEntry', BalanceEntry.first(session=session))
97
+ balance_entry = BalanceEntry.first(session=session)
100
98
  return balance_entry.rolling_balance if balance_entry else 0
@@ -38,7 +38,6 @@ __all__ = [
38
38
  'WalletTransaction',
39
39
  'Webhook',
40
40
  'WhatsappTransfer',
41
- 'Jwt',
42
41
  ]
43
42
 
44
43
  from .accounts import Account
@@ -60,7 +59,6 @@ from .file_batches import FileBatch
60
59
  from .files import File
61
60
  from .identities import Identity
62
61
  from .identity_events import IdentityEvent
63
- from .jwt import Jwt
64
62
  from .kyc_validations import KYCValidation
65
63
  from .kyc_verifications import KYCVerification
66
64
  from .limited_wallets import LimitedWallet
@@ -1,8 +1,8 @@
1
1
  import datetime as dt
2
- from typing import ClassVar, Optional, cast
2
+ from typing import ClassVar, Optional
3
3
 
4
4
  from cuenca_validations.types import ApiKeyQuery, ApiKeyUpdateRequest
5
- from pydantic import ConfigDict, SecretStr
5
+ from pydantic import ConfigDict
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: SecretStr
15
+ secret: str
16
16
  deactivated_at: Optional[dt.datetime] = None
17
17
  user_id: Optional[str] = None
18
18
  model_config = ConfigDict(
@@ -37,7 +37,7 @@ class ApiKey(Creatable, Queryable, Retrievable, Updateable):
37
37
 
38
38
  @classmethod
39
39
  def create(cls, *, session: Session = global_session) -> 'ApiKey':
40
- return cast('ApiKey', cls._create(session=session))
40
+ return cls._create(session=session)
41
41
 
42
42
  @classmethod
43
43
  def deactivate(
@@ -56,7 +56,7 @@ class ApiKey(Creatable, Queryable, Retrievable, Updateable):
56
56
  """
57
57
  url = cls._resource + f'/{api_key_id}'
58
58
  resp = session.delete(url, dict(minutes=minutes))
59
- return cast('ApiKey', cls._from_dict(resp))
59
+ return cls(**resp)
60
60
 
61
61
  @classmethod
62
62
  def update(
@@ -75,5 +75,4 @@ 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.model_dump(), session=session)
79
- return cast('ApiKey', resp)
78
+ return cls._update(api_key_id, **req.model_dump(), session=session)
@@ -1,7 +1,6 @@
1
1
  import datetime as dt
2
- from typing import ClassVar, Optional, cast
2
+ from typing import ClassVar, Optional
3
3
 
4
- from cuenca_validations.types.enums import TrackDataMethod
5
4
  from cuenca_validations.types.requests import ARPCRequest
6
5
 
7
6
  from ..http import Session, session as global_session
@@ -51,6 +50,6 @@ class Arpc(Creatable):
51
50
  transaction_counter=transaction_counter,
52
51
  pan_sequence=pan_sequence,
53
52
  unique_number=unique_number,
54
- track_data_method=cast(TrackDataMethod, track_data_method),
53
+ track_data_method=track_data_method,
55
54
  )
56
- return cast('Arpc', cls._create(session=session, **req.model_dump()))
55
+ return cls._create(session=session, **req.model_dump())
@@ -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, Generator, Optional
5
+ from typing import Any, ClassVar, Generator, Optional, Type, TypeVar, cast
6
6
  from urllib.parse import urlencode
7
7
 
8
8
  from cuenca_validations.types import (
@@ -12,34 +12,22 @@ from cuenca_validations.types import (
12
12
  TransactionQuery,
13
13
  TransactionStatus,
14
14
  )
15
- from pydantic import BaseModel
15
+ from pydantic import BaseModel, ConfigDict
16
16
 
17
17
  from ..exc import MultipleResultsFound, NoResultFound
18
18
  from ..http import Session, session as global_session
19
19
 
20
+ R_co = TypeVar('R_co', bound='Resource', covariant=True)
21
+
20
22
 
21
23
  class Resource(BaseModel):
22
24
  _resource: ClassVar[str]
23
25
 
24
26
  id: str
25
27
 
26
- @classmethod
27
- def _from_dict(cls, obj_dict: dict[str, Any]) -> 'Resource':
28
- cls._filter_excess_fields(obj_dict)
29
- return cls(**obj_dict)
30
-
31
- @classmethod
32
- def _filter_excess_fields(cls, obj_dict):
33
- """
34
- dataclasses don't allow __init__ to be called with excess fields. This
35
- method allows the API to add fields in the response body without
36
- breaking the client
37
- """
38
- excess = set(obj_dict.keys()) - set(
39
- cls.schema().get("properties").keys()
40
- )
41
- for f in excess:
42
- del obj_dict[f]
28
+ model_config = ConfigDict(
29
+ extra="ignore",
30
+ )
43
31
 
44
32
  def to_dict(self):
45
33
  return SantizedDict(self.model_dump())
@@ -48,12 +36,15 @@ class Resource(BaseModel):
48
36
  class Retrievable(Resource):
49
37
  @classmethod
50
38
  def retrieve(
51
- cls, id: str, *, session: Session = global_session
52
- ) -> Resource:
39
+ cls: Type[R_co],
40
+ id: str,
41
+ *,
42
+ session: Session = global_session,
43
+ ) -> R_co:
53
44
  resp = session.get(f'/{cls._resource}/{id}')
54
- return cls._from_dict(resp)
45
+ return cls(**resp)
55
46
 
56
- def refresh(self, *, session: Session = global_session):
47
+ def refresh(self, *, session: Session = global_session) -> None:
57
48
  new = self.retrieve(self.id, session=session)
58
49
  for attr, value in new.__dict__.items():
59
50
  setattr(self, attr, value)
@@ -61,9 +52,14 @@ class Retrievable(Resource):
61
52
 
62
53
  class Creatable(Resource):
63
54
  @classmethod
64
- def _create(cls, *, session: Session = global_session, **data) -> Resource:
55
+ def _create(
56
+ cls: Type[R_co],
57
+ *,
58
+ session: Session = global_session,
59
+ **data: Any,
60
+ ) -> R_co:
65
61
  resp = session.post(cls._resource, data)
66
- return cls._from_dict(resp)
62
+ return cls(**resp)
67
63
 
68
64
 
69
65
  class Updateable(Resource):
@@ -72,10 +68,14 @@ class Updateable(Resource):
72
68
 
73
69
  @classmethod
74
70
  def _update(
75
- cls, id: str, *, session: Session = global_session, **data
76
- ) -> Resource:
71
+ cls: Type[R_co],
72
+ id: str,
73
+ *,
74
+ session: Session = global_session,
75
+ **data: Any,
76
+ ) -> R_co:
77
77
  resp = session.patch(f'/{cls._resource}/{id}', data)
78
- return cls._from_dict(resp)
78
+ return cls(**resp)
79
79
 
80
80
 
81
81
  class Deactivable(Resource):
@@ -83,20 +83,24 @@ class Deactivable(Resource):
83
83
 
84
84
  @classmethod
85
85
  def deactivate(
86
- cls, id: str, *, session: Session = global_session, **data
87
- ) -> Resource:
86
+ cls: Type[R_co],
87
+ id: str,
88
+ *,
89
+ session: Session = global_session,
90
+ **data: Any,
91
+ ) -> R_co:
88
92
  resp = session.delete(f'/{cls._resource}/{id}', data)
89
- return cls._from_dict(resp)
93
+ return cls(**resp)
90
94
 
91
95
  @property
92
- def is_active(self):
96
+ def is_active(self) -> bool:
93
97
  return not self.deactivated_at
94
98
 
95
99
 
96
100
  class Downloadable(Resource):
97
101
  @classmethod
98
102
  def download(
99
- cls,
103
+ cls: Type[R_co],
100
104
  id: str,
101
105
  file_format: FileFormat = FileFormat.any,
102
106
  *,
@@ -121,13 +125,13 @@ class Downloadable(Resource):
121
125
  class Uploadable(Resource):
122
126
  @classmethod
123
127
  def _upload(
124
- cls,
128
+ cls: Type[R_co],
125
129
  file: bytes,
126
130
  user_id: str,
127
131
  *,
128
132
  session: Session = global_session,
129
- **data,
130
- ) -> Resource:
133
+ **data: Any,
134
+ ) -> R_co:
131
135
  encoded_file = base64.b64encode(file)
132
136
  resp = session.request(
133
137
  'post',
@@ -138,7 +142,7 @@ class Uploadable(Resource):
138
142
  **{k: (None, v) for k, v in data.items()},
139
143
  ),
140
144
  )
141
- return cls._from_dict(json.loads(resp))
145
+ return cls(**json.loads(resp))
142
146
 
143
147
 
144
148
  class Queryable(Resource):
@@ -148,9 +152,12 @@ class Queryable(Resource):
148
152
 
149
153
  @classmethod
150
154
  def one(
151
- cls, *, session: Session = global_session, **query_params
152
- ) -> Resource:
153
- q = cls._query_params(limit=2, **query_params)
155
+ cls: Type[R_co],
156
+ *,
157
+ session: Session = global_session,
158
+ **query_params: Any,
159
+ ) -> R_co:
160
+ q = cast(Queryable, cls)._query_params(limit=2, **query_params)
154
161
  resp = session.get(cls._resource, q.model_dump())
155
162
  items = resp['items']
156
163
  len_items = len(items)
@@ -158,40 +165,49 @@ class Queryable(Resource):
158
165
  raise NoResultFound
159
166
  if len_items > 1:
160
167
  raise MultipleResultsFound
161
- return cls._from_dict(items[0])
168
+ return cls(**items[0])
162
169
 
163
170
  @classmethod
164
171
  def first(
165
- cls, *, session: Session = global_session, **query_params
166
- ) -> Optional[Resource]:
167
- q = cls._query_params(limit=1, **query_params)
172
+ cls: Type[R_co],
173
+ *,
174
+ session: Session = global_session,
175
+ **query_params: Any,
176
+ ) -> Optional[R_co]:
177
+ q = cast(Queryable, cls)._query_params(limit=1, **query_params)
168
178
  resp = session.get(cls._resource, q.model_dump())
169
179
  try:
170
180
  item = resp['items'][0]
171
181
  except IndexError:
172
182
  rv = None
173
183
  else:
174
- rv = cls._from_dict(item)
184
+ rv = cls(**item)
175
185
  return rv
176
186
 
177
187
  @classmethod
178
188
  def count(
179
- cls, *, session: Session = global_session, **query_params
189
+ cls: Type[R_co],
190
+ *,
191
+ session: Session = global_session,
192
+ **query_params: Any,
180
193
  ) -> int:
181
- q = cls._query_params(count=True, **query_params)
194
+ q = cast(Queryable, cls)._query_params(count=True, **query_params)
182
195
  resp = session.get(cls._resource, q.model_dump())
183
196
  return resp['count']
184
197
 
185
198
  @classmethod
186
199
  def all(
187
- cls, *, session: Session = global_session, **query_params
188
- ) -> Generator[Resource, None, None]:
200
+ cls: Type[R_co],
201
+ *,
202
+ session: Session = global_session,
203
+ **query_params: Any,
204
+ ) -> Generator[R_co, None, None]:
189
205
  session = session or global_session
190
- q = cls._query_params(**query_params)
206
+ q = cast(Queryable, cls)._query_params(**query_params)
191
207
  next_page_uri = f'{cls._resource}?{urlencode(q.model_dump())}'
192
208
  while next_page_uri:
193
209
  page = session.get(next_page_uri)
194
- yield from (cls._from_dict(item) for item in page['items'])
210
+ yield from (cls(**item) for item in page['items'])
195
211
  next_page_uri = page['next_page_uri']
196
212
 
197
213
 
@@ -2,7 +2,6 @@ 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
6
5
 
7
6
  from ..http import Session, session as global_session
8
7
  from .base import Creatable
@@ -22,7 +21,7 @@ class CardActivation(Creatable):
22
21
  @classmethod
23
22
  def create(
24
23
  cls,
25
- number: PaymentCardNumber,
24
+ number: str,
26
25
  exp_month: int,
27
26
  exp_year: int,
28
27
  cvv2: str,
@@ -43,9 +42,7 @@ class CardActivation(Creatable):
43
42
  exp_year=exp_year,
44
43
  cvv2=cvv2,
45
44
  )
46
- return cast(
47
- 'CardActivation', cls._create(session=session, **req.model_dump())
48
- )
45
+ return cls._create(session=session, **req.model_dump())
49
46
 
50
47
  @property
51
48
  def card(self) -> Optional[Card]:
@@ -14,7 +14,6 @@ from .resources import retrieve_uri, retrieve_uris
14
14
 
15
15
 
16
16
  class CardTransaction(Transaction):
17
-
18
17
  _resource: ClassVar = 'card_transactions'
19
18
  _query_params: ClassVar = CardTransactionQuery
20
19
 
@@ -37,7 +37,7 @@ class CardValidation(Creatable):
37
37
  exp_month: Optional[int] = None,
38
38
  exp_year: Optional[int] = None,
39
39
  pin_block: Optional[str] = None,
40
- pin_attempts_exceeded: Optional[bool] = None,
40
+ pin_attempts_exceeded: Optional[str] = None,
41
41
  *,
42
42
  session: Session = global_session,
43
43
  ) -> 'CardValidation':
@@ -51,9 +51,7 @@ class CardValidation(Creatable):
51
51
  pin_block=pin_block,
52
52
  pin_attempts_exceeded=pin_attempts_exceeded,
53
53
  )
54
- return cast(
55
- 'CardValidation', cls._create(session=session, **req.model_dump())
56
- )
54
+ return cls._create(session=session, **req.model_dump())
57
55
 
58
56
  @property
59
57
  def card(self) -> Card:
@@ -1,5 +1,5 @@
1
1
  import datetime as dt
2
- from typing import ClassVar, Optional, cast
2
+ from typing import ClassVar, Optional
3
3
 
4
4
  from cuenca_validations.types import (
5
5
  CardFundingType,
@@ -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.model_dump()))
84
+ return cls._create(session=session, **req.model_dump())
85
85
 
86
86
  @classmethod
87
87
  def update(
@@ -106,8 +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.model_dump())
110
- return cast('Card', resp)
109
+ return cls._update(card_id, session=session, **req.model_dump())
111
110
 
112
111
  @classmethod
113
112
  def deactivate(
@@ -118,4 +117,4 @@ class Card(Retrievable, Queryable, Creatable, Updateable):
118
117
  """
119
118
  url = f'{cls._resource}/{card_id}'
120
119
  resp = session.delete(url)
121
- return cast('Card', cls._from_dict(resp))
120
+ return cls(**resp)
@@ -1,4 +1,4 @@
1
- from typing import ClassVar, cast
1
+ from typing import ClassVar
2
2
 
3
3
  from ..http import Session, session as global_session
4
4
  from .base import Creatable, Queryable, Retrievable
@@ -11,4 +11,4 @@ class Clabe(Creatable, Queryable, Retrievable):
11
11
 
12
12
  @classmethod
13
13
  def create(cls, session: Session = global_session):
14
- return cast('Clabe', cls._create(session=session))
14
+ return cls._create(session=session)
@@ -1,5 +1,5 @@
1
1
  import datetime as dt
2
- from typing import ClassVar, Optional, cast
2
+ from typing import ClassVar, Optional
3
3
 
4
4
  from cuenca_validations.types import (
5
5
  Country,
@@ -7,7 +7,7 @@ from cuenca_validations.types import (
7
7
  Gender,
8
8
  State,
9
9
  )
10
- from cuenca_validations.types.identities import CurpField
10
+ from cuenca_validations.types.identities import Curp
11
11
  from pydantic import ConfigDict, Field
12
12
 
13
13
  from ..http import Session, session as global_session
@@ -36,20 +36,19 @@ class CurpValidation(Creatable, Retrievable):
36
36
  nationality: Optional[Country] = Field(
37
37
  None, description='In format ISO 3166 Alpha-2'
38
38
  )
39
- manual_curp: Optional[CurpField] = Field(
39
+ manual_curp: Optional[Curp] = Field(
40
40
  None, description='curp provided in request'
41
41
  )
42
- calculated_curp: CurpField = Field(
43
- ..., description='Calculated CURP based on request data'
42
+ calculated_curp: Curp = Field(
43
+ description='Calculated CURP based on request data'
44
44
  )
45
- validated_curp: Optional[CurpField] = Field(
45
+ validated_curp: Optional[Curp] = Field(
46
46
  None, description='CURP validated in Renapo, null if not exists'
47
47
  )
48
48
  renapo_curp_match: bool = Field(
49
- ..., description='True if CURP exists and is valid'
49
+ description='True if CURP exists and is valid'
50
50
  )
51
51
  renapo_full_match: bool = Field(
52
- ...,
53
52
  description='True if all fields provided match the response from '
54
53
  'RENAPO. Accents in names are ignored',
55
54
  )
@@ -85,7 +84,7 @@ class CurpValidation(Creatable, Retrievable):
85
84
  state_of_birth: Optional[State] = None,
86
85
  gender: Optional[Gender] = None,
87
86
  second_surname: Optional[str] = None,
88
- manual_curp: Optional[CurpField] = None,
87
+ manual_curp: Optional[Curp] = None,
89
88
  *,
90
89
  session: Session = global_session,
91
90
  ) -> 'CurpValidation':
@@ -95,11 +94,8 @@ class CurpValidation(Creatable, Retrievable):
95
94
  second_surname=second_surname,
96
95
  date_of_birth=date_of_birth,
97
96
  state_of_birth=state_of_birth,
98
- country_of_birth=cast(Country, country_of_birth),
97
+ country_of_birth=country_of_birth,
99
98
  gender=gender,
100
99
  manual_curp=manual_curp,
101
100
  )
102
- return cast(
103
- 'CurpValidation',
104
- cls._create(session=session, **req.model_dump()),
105
- )
101
+ return cls._create(session=session, **req.model_dump())
@@ -1,6 +1,5 @@
1
- from typing import ClassVar, Optional, cast
1
+ from typing import ClassVar, Optional
2
2
 
3
- from cuenca_validations.types import HttpUrlString
4
3
  from cuenca_validations.types.enums import WebhookEvent
5
4
  from cuenca_validations.types.requests import (
6
5
  EndpointRequest,
@@ -15,19 +14,16 @@ from .base import Creatable, Deactivable, Queryable, Retrievable, Updateable
15
14
  class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
16
15
  _resource: ClassVar = 'endpoints'
17
16
 
18
- url: HttpUrlString = Field(..., description='HTTPS url to send webhooks')
17
+ url: HttpUrl = Field(description='HTTPS url to send webhooks')
19
18
  secret: str = Field(
20
- ...,
21
19
  description='token to verify the webhook is sent by Cuenca '
22
20
  'using HMAC algorithm',
23
21
  )
24
22
  is_enable: bool = Field(
25
- ...,
26
23
  description='Allows user to turn-off the endpoint without the '
27
24
  'need of deleting it',
28
25
  )
29
26
  events: list[WebhookEvent] = Field(
30
- ...,
31
27
  description='list of enabled events. If None, all events will '
32
28
  'be enabled for this Endpoint',
33
29
  )
@@ -70,9 +66,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
70
66
  :return: New active endpoint
71
67
  """
72
68
  req = EndpointRequest(url=url, events=events)
73
- return cast(
74
- 'Endpoint', cls._create(session=session, **req.model_dump())
75
- )
69
+ return cls._create(session=session, **req.model_dump())
76
70
 
77
71
  @classmethod
78
72
  def update(
@@ -89,6 +83,7 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
89
83
  like url and is_active.
90
84
  :param endpoint_id: existing endpoint_id
91
85
  :param url
86
+ :param events: Optional list of enabled events to update
92
87
  :param is_enable
93
88
  :param session
94
89
  :return: Updated endpoint object
@@ -96,5 +91,4 @@ class Endpoint(Creatable, Deactivable, Retrievable, Queryable, Updateable):
96
91
  req = EndpointUpdateRequest(
97
92
  url=url, is_enable=is_enable, events=events
98
93
  )
99
- resp = cls._update(endpoint_id, session=session, **req.model_dump())
100
- return cast('Endpoint', resp)
94
+ return cls._update(endpoint_id, session=session, **req.model_dump())
@@ -1,4 +1,4 @@
1
- from typing import ClassVar, cast
1
+ from typing import ClassVar
2
2
 
3
3
  from cuenca_validations.types import (
4
4
  BatchFileMetadata,
@@ -26,8 +26,7 @@ class FileBatch(Creatable, Queryable):
26
26
  session: Session = global_session,
27
27
  ) -> 'FileBatch':
28
28
  req = FileBatchUploadRequest(
29
- files=cast(list[FileRequest], files), user_id=user_id
30
- )
31
- return cast(
32
- 'FileBatch', cls._create(session=session, **req.model_dump())
29
+ files=[FileRequest(**f) for f in files],
30
+ user_id=user_id,
33
31
  )
32
+ return cls._create(session=session, **req.model_dump())
@@ -1,12 +1,7 @@
1
1
  from io import BytesIO
2
- from typing import ClassVar, Optional, cast
2
+ from typing import ClassVar, Optional
3
3
 
4
- from cuenca_validations.types import (
5
- FileExtension,
6
- FileQuery,
7
- FileUploadRequest,
8
- KYCFileType,
9
- )
4
+ from cuenca_validations.types import FileQuery, FileUploadRequest, KYCFileType
10
5
  from pydantic import HttpUrl
11
6
 
12
7
  from ..http import Session, session as global_session
@@ -45,17 +40,11 @@ class File(Downloadable, Queryable, Uploadable):
45
40
  req = FileUploadRequest(
46
41
  file=file.read(),
47
42
  type=file_type,
48
- extension=cast(FileExtension, extension),
43
+ extension=extension,
49
44
  is_back=is_back,
50
45
  user_id=user_id,
51
46
  )
52
- return cast(
53
- 'File',
54
- cls._upload(
55
- session=session,
56
- **req.model_dump(),
57
- ),
58
- )
47
+ return cls._upload(session=session, **req.model_dump())
59
48
 
60
49
  @property
61
50
  def file(self) -> bytes:
@@ -11,7 +11,7 @@ from cuenca_validations.types import (
11
11
  UserStatus,
12
12
  VerificationStatus,
13
13
  )
14
- from cuenca_validations.types.identities import CurpField
14
+ from cuenca_validations.types.identities import Curp
15
15
 
16
16
  from .base import Queryable, Retrievable
17
17
 
@@ -24,7 +24,7 @@ class Identity(Retrievable, Queryable):
24
24
  names: str
25
25
  first_surname: str
26
26
  second_surname: Optional[str] = None
27
- curp: Optional[CurpField] = None
27
+ curp: Optional[Curp] = None
28
28
  rfc: Optional[str] = None
29
29
  gender: Gender
30
30
  date_of_birth: Optional[dt.date] = None
@@ -1,4 +1,4 @@
1
- from typing import ClassVar, Optional, cast
1
+ from typing import ClassVar, Optional
2
2
 
3
3
  from cuenca_validations.types import KYCFile, KYCValidationRequest
4
4
  from pydantic import ConfigDict
@@ -13,6 +13,7 @@ class KYCValidation(Creatable, Retrievable, Queryable):
13
13
  attemps: Optional[int] = None
14
14
  verification_id: Optional[str] = None
15
15
  files_uri: Optional[list[str]] = None
16
+
16
17
  model_config = ConfigDict(
17
18
  json_schema_extra={
18
19
  'example': {
@@ -39,6 +40,4 @@ class KYCValidation(Creatable, Retrievable, Queryable):
39
40
  force=force,
40
41
  documents=documents,
41
42
  )
42
- return cast(
43
- 'KYCValidation', cls._create(**req.model_dump(), session=session)
44
- )
43
+ return cls._create(**req.model_dump(), session=session)