cuenca-validations 2.1.38.dev2__tar.gz → 2.1.39.dev1__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 (36) hide show
  1. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/PKG-INFO +1 -1
  2. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/__init__.py +8 -4
  3. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/enums.py +8 -7
  4. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/general.py +0 -14
  5. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/queries.py +5 -0
  6. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/requests.py +49 -7
  7. cuenca_validations-2.1.39.dev1/cuenca_validations/version.py +1 -0
  8. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations.egg-info/PKG-INFO +1 -1
  9. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_requests.py +16 -0
  10. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_types.py +10 -64
  11. cuenca_validations-2.1.38.dev2/cuenca_validations/version.py +0 -1
  12. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/LICENSE +0 -0
  13. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/README.md +0 -0
  14. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/__init__.py +0 -0
  15. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/card_bins.py +0 -0
  16. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/errors.py +0 -0
  17. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/py.typed +0 -0
  18. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/card.py +0 -0
  19. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/files.py +0 -0
  20. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/helpers.py +0 -0
  21. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/identities.py +0 -0
  22. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/types/morals.py +0 -0
  23. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/typing.py +0 -0
  24. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations/validators.py +0 -0
  25. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations.egg-info/SOURCES.txt +0 -0
  26. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations.egg-info/dependency_links.txt +0 -0
  27. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations.egg-info/requires.txt +0 -0
  28. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/cuenca_validations.egg-info/top_level.txt +0 -0
  29. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/setup.cfg +0 -0
  30. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/setup.py +0 -0
  31. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/__init__.py +0 -0
  32. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_card.py +0 -0
  33. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_errors.py +0 -0
  34. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_helpers.py +0 -0
  35. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_statement.py +0 -0
  36. {cuenca_validations-2.1.38.dev2 → cuenca_validations-2.1.39.dev1}/tests/test_validators.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuenca_validations
3
- Version: 2.1.38.dev2
3
+ Version: 2.1.39.dev1
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -2,13 +2,16 @@ __all__ = [
2
2
  'AccountUseType',
3
3
  'AccountQuery',
4
4
  'Address',
5
+ 'AgentQuery',
6
+ 'AgentRequest',
7
+ 'AgentStatus',
8
+ 'AgentUpdateRequest',
5
9
  'ApiKeyQuery',
6
10
  'ApiKeyUpdateRequest',
7
11
  'AuthorizerTransaction',
8
12
  'BalanceEntryQuery',
9
13
  'BankAccountValidationQuery',
10
14
  'BankAccountValidationRequest',
11
- 'BankCode',
12
15
  'PostalCodeQuery',
13
16
  'UsersTOSQuery',
14
17
  'TOSQuery',
@@ -46,7 +49,6 @@ __all__ = [
46
49
  'FileRequest',
47
50
  'FileUploadRequest',
48
51
  'FraudFundsTransferRequest',
49
- 'FraudFundsTransferTipoPago',
50
52
  'Gender',
51
53
  'IncomeType',
52
54
  'IssuerNetwork',
@@ -129,6 +131,7 @@ __all__ = [
129
131
  from .card import StrictPaymentCardNumber
130
132
  from .enums import (
131
133
  AccountUseType,
134
+ AgentStatus,
132
135
  AuthorizerTransaction,
133
136
  BankAccountStatus,
134
137
  CardErrorType,
@@ -147,7 +150,6 @@ from .enums import (
147
150
  EventType,
148
151
  FileExtension,
149
152
  FileFormat,
150
- FraudFundsTransferTipoPago,
151
153
  Gender,
152
154
  IncomeType,
153
155
  IssuerNetwork,
@@ -178,7 +180,6 @@ from .enums import (
178
180
  )
179
181
  from .files import BatchFileMetadata
180
182
  from .general import (
181
- BankCode,
182
183
  JSONEncoder,
183
184
  LogConfig,
184
185
  SantizedDict,
@@ -204,6 +205,7 @@ from .identities import (
204
205
  )
205
206
  from .queries import (
206
207
  AccountQuery,
208
+ AgentQuery,
207
209
  ApiKeyQuery,
208
210
  BalanceEntryQuery,
209
211
  BankAccountValidationQuery,
@@ -227,6 +229,8 @@ from .queries import (
227
229
  WalletTransactionQuery,
228
230
  )
229
231
  from .requests import (
232
+ AgentRequest,
233
+ AgentUpdateRequest,
230
234
  ApiKeyUpdateRequest,
231
235
  BankAccountValidationRequest,
232
236
  BeneficiaryRequest,
@@ -1,4 +1,4 @@
1
- from enum import Enum, IntEnum
1
+ from enum import Enum
2
2
 
3
3
 
4
4
  class CardNetwork(str, Enum):
@@ -589,6 +589,13 @@ class SessionType(str, Enum):
589
589
  account_entries = 'session.account_entries'
590
590
  download_file = 'session.download_file'
591
591
  upload_file = 'session.upload_file'
592
+ agent = 'session.agent'
593
+
594
+
595
+ class AgentStatus(str, Enum):
596
+ created = 'created'
597
+ succeeded = 'succeeded'
598
+ failed = 'failed'
592
599
 
593
600
 
594
601
  class WebhookObject(str, Enum):
@@ -743,9 +750,3 @@ class RequiredAction(str, Enum):
743
750
  level_up_required = 'level_up_required'
744
751
  level_up_invitation = 'level_up_invitation'
745
752
  fix_documents = 'fix_documents'
746
-
747
-
748
- class FraudFundsTransferTipoPago(IntEnum):
749
- participante_participante = 7
750
- devolucion_especial_ordenes_aceptadas_acreditadas = 23
751
- devolucion_extemporanea_especial_ordenes_acreditadas = 24
@@ -2,7 +2,6 @@ import json
2
2
  from dataclasses import dataclass
3
3
  from typing import Annotated, Any, Optional
4
4
 
5
- from clabe import BANK_NAMES
6
5
  from pydantic import (
7
6
  AfterValidator,
8
7
  AnyUrl,
@@ -42,19 +41,6 @@ NormalizedName = Annotated[
42
41
  ]
43
42
 
44
43
 
45
- def validate_bank_code(bank_code: str) -> str:
46
- if bank_code not in BANK_NAMES:
47
- raise ValueError('Not a valid bank code')
48
- return bank_code
49
-
50
-
51
- BankCode = Annotated[
52
- str,
53
- StringConstraints(strip_whitespace=True),
54
- AfterValidator(validate_bank_code),
55
- ]
56
-
57
-
58
44
  class SantizedDict(dict):
59
45
  def __init__(self, *args, **kwargs):
60
46
  super().__init__(*args, **kwargs)
@@ -15,6 +15,7 @@ from pydantic import (
15
15
  from ..typing import DictStrAny
16
16
  from ..validators import sanitize_dict
17
17
  from .enums import (
18
+ AgentStatus,
18
19
  BankAccountStatus,
19
20
  CardFundingType,
20
21
  CardIssuer,
@@ -193,6 +194,10 @@ class SessionQuery(QueryParams):
193
194
  type: SessionType
194
195
 
195
196
 
197
+ class AgentQuery(QueryParams):
198
+ status: Optional[AgentStatus] = None
199
+
200
+
196
201
  class FileQuery(QueryParams):
197
202
  type: Optional[KYCFileType] = None
198
203
  id: Optional[str] = None
@@ -1,7 +1,7 @@
1
1
  import datetime as dt
2
2
  from typing import Annotated, Any, Optional, Union
3
3
 
4
- from clabe import Clabe
4
+ from clabe import BANK_NAMES, Clabe
5
5
  from pydantic import (
6
6
  BaseModel,
7
7
  ConfigDict,
@@ -18,6 +18,7 @@ from pydantic_extra_types.coordinate import Coordinate
18
18
 
19
19
  from ..types.enums import (
20
20
  AccountUseType,
21
+ AgentStatus,
21
22
  AuthorizerTransaction,
22
23
  CardDesign,
23
24
  CardFundingType,
@@ -29,7 +30,6 @@ from ..types.enums import (
29
30
  Country,
30
31
  EcommerceIndicator,
31
32
  FileExtension,
32
- FraudFundsTransferTipoPago,
33
33
  Gender,
34
34
  IncomeType,
35
35
  IssuerNetwork,
@@ -67,7 +67,6 @@ from .card import (
67
67
  StrictPaymentCardNumber,
68
68
  )
69
69
  from .general import (
70
- BankCode,
71
70
  LogConfig,
72
71
  NonEmptyStr,
73
72
  SerializableAnyUrl,
@@ -329,17 +328,21 @@ class WalletTransactionRequest(BaseRequest):
329
328
  class FraudFundsTransferRequest(BaseRequest):
330
329
  user_id: NonEmptyStr
331
330
  clabe: Optional[Clabe] = None
332
- bank_code: Optional[BankCode] = None
333
- tipo_pago: Optional[FraudFundsTransferTipoPago] = None
331
+ bank_code: Optional[str] = None
334
332
  amount: Optional[StrictPositiveInt] = None
335
333
  concepto: Optional[NonEmptyStr] = None
336
334
 
335
+ @field_validator('bank_code')
336
+ @classmethod
337
+ def validate_bank_code(cls, bank_code: Optional[str]) -> Optional[str]:
338
+ if bank_code is not None and bank_code not in BANK_NAMES:
339
+ raise ValueError('Not a valid bank code')
340
+ return bank_code
341
+
337
342
  @model_validator(mode='after')
338
343
  def validate_destination(self) -> 'FraudFundsTransferRequest':
339
344
  if self.clabe is None and self.bank_code is None:
340
345
  raise ValueError('clabe or bank_code required')
341
- if self.bank_code is not None and self.tipo_pago is None:
342
- raise ValueError('tipo_pago required when using bank_code')
343
346
  return self
344
347
 
345
348
 
@@ -643,6 +646,45 @@ class SessionRequest(BaseRequest):
643
646
  )
644
647
 
645
648
 
649
+ class AgentRequest(BaseRequest):
650
+ phone_number: PhoneNumber
651
+ device_info: DictStrAny = Field(default_factory=dict)
652
+ model_config = ConfigDict(
653
+ json_schema_extra={
654
+ 'example': {
655
+ 'phone_number': '+525512345678',
656
+ 'device_info': {'client': 'cursor', 'os': 'macOS'},
657
+ }
658
+ }
659
+ )
660
+
661
+ @field_validator('phone_number', mode='before')
662
+ @classmethod
663
+ def normalize_phone(cls, v: PhoneNumber) -> str:
664
+ return normalize_phone_number(str(v))
665
+
666
+
667
+ class AgentUpdateRequest(BaseRequest):
668
+ pairing_code: Optional[str] = None
669
+ status: AgentStatus
670
+ model_config = ConfigDict(
671
+ json_schema_extra={
672
+ 'example': {
673
+ 'pairing_code': 'ABC-123',
674
+ 'status': 'succeeded',
675
+ }
676
+ }
677
+ )
678
+
679
+ @model_validator(mode='after')
680
+ def validate_update(self) -> 'AgentUpdateRequest':
681
+ if self.status == AgentStatus.created:
682
+ raise ValueError('Invalid status')
683
+ if self.status == AgentStatus.succeeded and not self.pairing_code:
684
+ raise ValueError('pairing_code is required')
685
+ return self
686
+
687
+
646
688
  class EndpointRequest(BaseRequest):
647
689
  url: SerializableHttpUrl
648
690
  events: Optional[list[WebhookEvent]] = None
@@ -0,0 +1 @@
1
+ __version__ = '2.1.39.dev1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuenca_validations
3
- Version: 2.1.38.dev2
3
+ Version: 2.1.39.dev1
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -2,6 +2,7 @@ import pytest
2
2
  from pydantic import ValidationError
3
3
  from pydantic_extra_types.phone_numbers import PhoneNumber
4
4
 
5
+ from cuenca_validations.types import AgentStatus, AgentUpdateRequest
5
6
  from cuenca_validations.types.enums import VerificationType
6
7
  from cuenca_validations.types.requests import (
7
8
  PasswordResetRequest,
@@ -123,3 +124,18 @@ def test_update_transfer_request_forbids_extra() -> None:
123
124
  {'status': 'succeeded', 'foo': 'bar'}
124
125
  )
125
126
  assert 'Extra inputs are not permitted' in str(ex.value)
127
+
128
+
129
+ def test_agent_update_request_rejects_created_status() -> None:
130
+ with pytest.raises(ValidationError) as exc:
131
+ AgentUpdateRequest(
132
+ pairing_code='ABC-123',
133
+ status=AgentStatus.created,
134
+ )
135
+ assert 'Invalid status' in str(exc.value)
136
+
137
+
138
+ def test_agent_update_request_succeeded_requires_pairing_code() -> None:
139
+ with pytest.raises(ValidationError) as exc:
140
+ AgentUpdateRequest(status=AgentStatus.succeeded)
141
+ assert 'pairing_code is required' in str(exc.value)
@@ -675,73 +675,19 @@ def test_bank_account_validation_clabe_request():
675
675
  assert BankAccountValidationRequest(account_number='646180157098510917')
676
676
 
677
677
 
678
- @pytest.mark.parametrize(
679
- 'data, expected_dump',
680
- [
681
- (
682
- dict(
683
- user_id='US123',
684
- clabe='646180157098510917',
685
- amount=10000,
686
- concepto=' Devolución fraude ',
687
- ),
688
- dict(
689
- user_id='US123',
690
- clabe='646180157098510917',
691
- amount=10000,
692
- concepto='Devolución fraude',
693
- ),
694
- ),
695
- (
696
- dict(user_id='US123', clabe='646180157098510917'),
697
- dict(user_id='US123', clabe='646180157098510917'),
698
- ),
699
- *[
700
- (
701
- dict(
702
- user_id='US123',
703
- bank_code='40012',
704
- tipo_pago=tipo_pago,
705
- amount=5000,
706
- ),
707
- dict(
708
- user_id='US123',
709
- bank_code='40012',
710
- tipo_pago=tipo_pago,
711
- amount=5000,
712
- ),
713
- )
714
- for tipo_pago in (7, 23, 24)
715
- ],
716
- ],
717
- )
718
- def test_fraud_funds_transfer_request(data, expected_dump):
719
- request = FraudFundsTransferRequest(**data)
720
- assert request.model_dump() == expected_dump
678
+ def test_fraud_funds_transfer_request():
679
+ assert FraudFundsTransferRequest(
680
+ user_id='US123',
681
+ bank_code='40012',
682
+ ).model_dump() == {'user_id': 'US123', 'bank_code': '40012'}
721
683
 
684
+ with pytest.raises(ValidationError) as exc:
685
+ FraudFundsTransferRequest(user_id='US123')
686
+ assert 'clabe or bank_code required' in str(exc.value)
722
687
 
723
- @pytest.mark.parametrize(
724
- 'data, expected_error',
725
- [
726
- (dict(user_id='US123'), 'clabe or bank_code required'),
727
- (
728
- dict(user_id='US123', bank_code='40012'),
729
- 'tipo_pago required when using bank_code',
730
- ),
731
- (
732
- dict(user_id='US123', bank_code='40012', tipo_pago=1),
733
- 'Input should be 7, 23 or 24',
734
- ),
735
- (
736
- dict(user_id='US123', bank_code='99999', tipo_pago=7),
737
- 'Not a valid bank code',
738
- ),
739
- ],
740
- )
741
- def test_fraud_funds_transfer_request_invalid(data, expected_error):
742
688
  with pytest.raises(ValidationError) as exc:
743
- FraudFundsTransferRequest(**data)
744
- assert expected_error in str(exc.value)
689
+ FraudFundsTransferRequest(user_id='US123', bank_code='99999')
690
+ assert 'Not a valid bank code' in str(exc.value)
745
691
 
746
692
 
747
693
  @pytest.mark.parametrize(
@@ -1 +0,0 @@
1
- __version__ = '2.1.38.dev2'