cuenca-validations 2.1.17.dev3__tar.gz → 2.1.18__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.17.dev3 → cuenca_validations-2.1.18}/PKG-INFO +1 -1
  2. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/__init__.py +2 -0
  3. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/enums.py +1 -1
  4. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/identities.py +7 -3
  5. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/requests.py +16 -26
  6. cuenca_validations-2.1.18/cuenca_validations/version.py +1 -0
  7. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations.egg-info/PKG-INFO +1 -1
  8. cuenca_validations-2.1.18/tests/test_requests.py +31 -0
  9. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/tests/test_types.py +3 -26
  10. cuenca_validations-2.1.17.dev3/cuenca_validations/version.py +0 -1
  11. cuenca_validations-2.1.17.dev3/tests/test_requests.py +0 -70
  12. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/LICENSE +0 -0
  13. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/README.md +0 -0
  14. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/__init__.py +0 -0
  15. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/card_bins.py +0 -0
  16. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/errors.py +0 -0
  17. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/py.typed +0 -0
  18. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/card.py +0 -0
  19. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/files.py +0 -0
  20. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/general.py +0 -0
  21. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/helpers.py +0 -0
  22. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/morals.py +0 -0
  23. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/types/queries.py +0 -0
  24. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/typing.py +0 -0
  25. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations/validators.py +0 -0
  26. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations.egg-info/SOURCES.txt +0 -0
  27. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations.egg-info/dependency_links.txt +0 -0
  28. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations.egg-info/requires.txt +0 -0
  29. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/cuenca_validations.egg-info/top_level.txt +0 -0
  30. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/setup.cfg +0 -0
  31. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/setup.py +0 -0
  32. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/tests/__init__.py +0 -0
  33. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/tests/test_card.py +0 -0
  34. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/tests/test_errors.py +0 -0
  35. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/tests/test_helpers.py +0 -0
  36. {cuenca_validations-2.1.17.dev3 → cuenca_validations-2.1.18}/tests/test_statement.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuenca_validations
3
- Version: 2.1.17.dev3
3
+ Version: 2.1.18
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -14,6 +14,7 @@ __all__ = [
14
14
  'BankAccountStatus',
15
15
  'BatchFileMetadata',
16
16
  'Beneficiary',
17
+ 'BeneficiaryRequest',
17
18
  'BillPaymentQuery',
18
19
  'CardErrorType',
19
20
  'CardFundingType',
@@ -221,6 +222,7 @@ from .queries import (
221
222
  from .requests import (
222
223
  ApiKeyUpdateRequest,
223
224
  BankAccountValidationRequest,
225
+ BeneficiaryRequest,
224
226
  CurpValidationRequest,
225
227
  EndpointRequest,
226
228
  EndpointUpdateRequest,
@@ -259,6 +259,7 @@ class KYCValidationSource(str, Enum):
259
259
  class Gender(str, Enum):
260
260
  female = 'female'
261
261
  male = 'male'
262
+ non_binary = 'non_binary'
262
263
 
263
264
 
264
265
  class State(str, Enum):
@@ -588,7 +589,6 @@ class SessionType(str, Enum):
588
589
  account_entries = 'session.account_entries'
589
590
  download_file = 'session.download_file'
590
591
  upload_file = 'session.upload_file'
591
- metamap_verification = 'session.metamap_verification'
592
592
 
593
593
 
594
594
  class WebhookObject(str, Enum):
@@ -1,5 +1,5 @@
1
1
  import datetime as dt
2
- from typing import Annotated, Optional
2
+ from typing import Annotated, Optional, Union
3
3
 
4
4
  from pydantic import BaseModel, ConfigDict, Field, SecretStr, StringConstraints
5
5
  from pydantic_extra_types.phone_numbers import PhoneNumber
@@ -89,12 +89,12 @@ class AddressRequest(BaseModel):
89
89
  )
90
90
 
91
91
 
92
- class Beneficiary(BaseModel):
92
+ class BaseBeneficiary(BaseModel):
93
93
  name: str
94
94
  birth_date: dt.date
95
- phone_number: PhoneNumber
96
95
  user_relationship: str
97
96
  percentage: Annotated[int, Field(ge=1, le=100)]
97
+
98
98
  model_config = ConfigDict(
99
99
  json_schema_extra={
100
100
  "example": {
@@ -108,6 +108,10 @@ class Beneficiary(BaseModel):
108
108
  )
109
109
 
110
110
 
111
+ class Beneficiary(BaseBeneficiary):
112
+ phone_number: Union[PhoneNumber, str]
113
+
114
+
111
115
  class VerificationErrors(BaseModel):
112
116
  identifier: str = Field(
113
117
  description='Unique identifier for the step validation'
@@ -73,7 +73,7 @@ from .general import (
73
73
  from .helpers import validate_age_requirement
74
74
  from .identities import (
75
75
  AddressRequest,
76
- Beneficiary,
76
+ BaseBeneficiary,
77
77
  Curp,
78
78
  KYCFile,
79
79
  Password,
@@ -330,7 +330,7 @@ class UserPldRiskLevelRequest(BaseModel):
330
330
  level: float = Field(ge=0.0, le=1.0)
331
331
 
332
332
 
333
- class CurpValidationRequest(BaseModel):
333
+ class CurpValidationRequest(BaseRequest):
334
334
  names: Optional[str] = None
335
335
  first_surname: Optional[str] = None
336
336
  second_surname: Optional[str] = Field(
@@ -439,13 +439,13 @@ class FileCuencaUrl(str):
439
439
  )
440
440
 
441
441
 
442
- class UserTOSAgreementRequest(BaseModel):
442
+ class UserTOSAgreementRequest(BaseRequest):
443
443
  tos_id: str
444
444
  location: Coordinate
445
445
  signature_image_url: Optional[FileCuencaUrl] = None
446
446
 
447
447
 
448
- class UserRequest(BaseModel):
448
+ class UserRequest(BaseRequest):
449
449
  curp: Curp = Field(
450
450
  description=(
451
451
  'Mexican government ID (18 characters). ' 'Must be pre-validated.'
@@ -495,12 +495,16 @@ class UserRequest(BaseModel):
495
495
  return profession
496
496
 
497
497
 
498
- class UserUpdateRequest(BaseModel):
498
+ class BeneficiaryRequest(BaseBeneficiary, BaseRequest):
499
+ phone_number: PhoneNumber
500
+
501
+
502
+ class UserUpdateRequest(BaseRequest):
499
503
  profession: Optional[Profession] = None
500
504
  email_verification_id: Optional[str] = None
501
505
  phone_verification_id: Optional[str] = None
502
506
  address: Optional[AddressRequest] = None
503
- beneficiaries: Optional[list[Beneficiary]] = None
507
+ beneficiaries: Optional[list[BeneficiaryRequest]] = None
504
508
  govt_id: Optional[KYCFile] = None
505
509
  proof_of_address: Optional[KYCFile] = None
506
510
  proof_of_life: Optional[KYCFile] = None
@@ -518,7 +522,7 @@ class UserUpdateRequest(BaseModel):
518
522
  @field_validator('beneficiaries')
519
523
  @classmethod
520
524
  def beneficiary_percentage(
521
- cls, beneficiaries: Optional[list[Beneficiary]] = None
525
+ cls, beneficiaries: Optional[list[BeneficiaryRequest]] = None
522
526
  ):
523
527
  if beneficiaries and sum(b.percentage for b in beneficiaries) != 100:
524
528
  raise ValueError('The total percentage should be 100%')
@@ -547,19 +551,6 @@ class SessionRequest(BaseRequest):
547
551
  type: SessionType
548
552
  success_url: Optional[SerializableAnyUrl] = None
549
553
  failure_url: Optional[SerializableAnyUrl] = None
550
- resource_id: Optional[str] = None
551
-
552
- @model_validator(mode='before')
553
- @classmethod
554
- def validate_metadata(cls, values: dict) -> dict:
555
- if values[
556
- 'type'
557
- ] == SessionType.metamap_verification and not values.get(
558
- 'resource_id'
559
- ):
560
- raise ValueError('Resource id expected for this session')
561
- return values
562
-
563
554
  model_config = ConfigDict(
564
555
  json_schema_extra={
565
556
  'example': {
@@ -567,7 +558,6 @@ class SessionRequest(BaseRequest):
567
558
  'type': 'session.registration',
568
559
  'success_url': 'http://example_success.com',
569
560
  'failure_url': 'http://example_failure.com',
570
- 'resource_id': 'some_resource_id',
571
561
  }
572
562
  }
573
563
  )
@@ -604,7 +594,7 @@ class FileBatchUploadRequest(BaseModel):
604
594
  user_id: str
605
595
 
606
596
 
607
- class VerificationRequest(BaseModel):
597
+ class VerificationRequest(BaseRequest):
608
598
  type: VerificationType
609
599
  recipient: Union[EmailStr, PhoneNumber] = Field(
610
600
  description='Phone or email to validate'
@@ -628,7 +618,7 @@ class VerificationRequest(BaseModel):
628
618
  )
629
619
 
630
620
 
631
- class VerificationAttemptRequest(BaseModel):
621
+ class VerificationAttemptRequest(BaseRequest):
632
622
  code: Annotated[
633
623
  str,
634
624
  StringConstraints(strict=True, min_length=6, max_length=6),
@@ -669,11 +659,11 @@ class KYCValidationRequest(BaseRequest):
669
659
  force: bool = False
670
660
 
671
661
 
672
- class BankAccountValidationRequest(BaseModel):
662
+ class BankAccountValidationRequest(BaseRequest):
673
663
  account_number: Union[Clabe, PaymentCardNumber]
674
664
 
675
665
 
676
- class UserListsRequest(BaseModel):
666
+ class UserListsRequest(BaseRequest):
677
667
  curp: Optional[Curp] = Field(None, description='Curp to review on lists')
678
668
  rfc: Optional[Rfc] = Field(None, description='Rfc to review on lists')
679
669
  account_number: Optional[Union[Clabe, PaymentCardNumber]] = Field(
@@ -772,5 +762,5 @@ class PartnerUpdateRequest(BaseRequest):
772
762
  shareholders: Optional[list[Shareholder]] = None
773
763
 
774
764
 
775
- class PhoneVerificationAssociationRequest(BaseModel):
765
+ class PhoneVerificationAssociationRequest(BaseRequest):
776
766
  verification_id: str
@@ -0,0 +1 @@
1
+ __version__ = '2.1.18'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuenca_validations
3
- Version: 2.1.17.dev3
3
+ Version: 2.1.18
4
4
  Summary: Cuenca common validations
5
5
  Home-page: https://github.com/cuenca-mx/cuenca-validations
6
6
  Author: Cuenca
@@ -0,0 +1,31 @@
1
+ import pytest
2
+ from pydantic import ValidationError
3
+
4
+ from cuenca_validations.types.requests import UserTOSAgreementRequest
5
+ from cuenca_validations.typing import DictStrAny
6
+
7
+
8
+ @pytest.mark.parametrize('environment', ['stage', 'sandbox', 'api'])
9
+ def test_file_cuenca_url(environment: str) -> None:
10
+ request_data: DictStrAny = dict(
11
+ tos_id='TS67dcae8e74e81bba5a77bf47',
12
+ location=(19.432607, -99.133209),
13
+ signature_image_url=(
14
+ f'https://{environment}.cuenca.com/files/EFQL8_ohvoRp-PkOTYgvQYFA'
15
+ ),
16
+ )
17
+ utos = UserTOSAgreementRequest(**request_data)
18
+ assert utos.signature_image_url is not None
19
+ assert utos.signature_image_url.file_id == 'EFQL8_ohvoRp-PkOTYgvQYFA'
20
+
21
+
22
+ def test_file_cuenca_url_invalid() -> None:
23
+ request_data: DictStrAny = dict(
24
+ tos_id='TS67dcae8e74e81bba5a77bf47',
25
+ location=(19.432607, -99.133209),
26
+ signature_image_url=(
27
+ 'https://cuenca.com/files/EFQL87ohvoRp-PkOTYgvQYFA/invalid'
28
+ ),
29
+ )
30
+ with pytest.raises(ValidationError):
31
+ UserTOSAgreementRequest(**request_data)
@@ -394,7 +394,9 @@ def test_curp_validation_request():
394
394
  assert all(field in error_msg for field in required_fields)
395
395
 
396
396
  req_curp = CurpValidationRequest(**request)
397
- assert req_curp.model_dump() == request
397
+ # exclude_none=False to test that the request equals the original dict,
398
+ # since normally exclude_none defaults to True in BaseRequest.model_dump()
399
+ assert req_curp.model_dump(exclude_none=False) == request
398
400
 
399
401
  request['date_of_birth'] = dt.date(2006, 5, 17)
400
402
 
@@ -435,16 +437,11 @@ def test_user_update_request():
435
437
  percentage=50,
436
438
  ),
437
439
  ],
438
- curp_document_uri='https://sandbox.cuenca.com/files/EF123',
439
440
  profession=Profession.empleado,
440
441
  )
441
442
  update_req = UserUpdateRequest(**request)
442
443
  beneficiaries = [b.model_dump() for b in update_req.beneficiaries]
443
444
  assert beneficiaries == request['beneficiaries']
444
- assert (
445
- update_req.curp_document_uri.unicode_string()
446
- == request['curp_document_uri']
447
- )
448
445
  assert update_req.profession == Profession.empleado
449
446
 
450
447
  request['beneficiaries'] = [
@@ -480,26 +477,6 @@ def test_user_update_request():
480
477
  assert 'The total percentage should be 100%' in str(v)
481
478
  request.pop('beneficiaries')
482
479
 
483
- tos_request = dict(
484
- terms_of_service=dict(
485
- version='2022-01-01',
486
- ip='127.0.0.1',
487
- location='1111,1111',
488
- type='ifpe',
489
- )
490
- )
491
- UserUpdateRequest(**tos_request)
492
-
493
- tos_request = dict(
494
- terms_of_service=dict(
495
- version='2022-01-01',
496
- ip='2001:0db8:0000:0000:0000:ff00:0042:8329',
497
- location='1111,1111',
498
- type='ifpe',
499
- )
500
- )
501
- UserUpdateRequest(**tos_request)
502
-
503
480
  kyc_request = dict(
504
481
  govt_id=dict(
505
482
  type='ine',
@@ -1 +0,0 @@
1
- __version__ = '2.1.17.dev3'
@@ -1,70 +0,0 @@
1
- import pytest
2
- from pydantic import ValidationError
3
-
4
- from cuenca_validations.types.enums import SessionType
5
- from cuenca_validations.types.requests import (
6
- SessionRequest,
7
- UserTOSAgreementRequest,
8
- )
9
- from cuenca_validations.typing import DictStrAny
10
-
11
-
12
- @pytest.mark.parametrize('environment', ['stage', 'sandbox', 'api'])
13
- def test_file_cuenca_url(environment: str) -> None:
14
- request_data: DictStrAny = dict(
15
- tos_id='TS67dcae8e74e81bba5a77bf47',
16
- location=(19.432607, -99.133209),
17
- signature_image_url=(
18
- f'https://{environment}.cuenca.com/files/EFQL8_ohvoRp-PkOTYgvQYFA'
19
- ),
20
- )
21
- utos = UserTOSAgreementRequest(**request_data)
22
- assert utos.signature_image_url is not None
23
- assert utos.signature_image_url.file_id == 'EFQL8_ohvoRp-PkOTYgvQYFA'
24
-
25
-
26
- def test_file_cuenca_url_invalid() -> None:
27
- request_data: DictStrAny = dict(
28
- tos_id='TS67dcae8e74e81bba5a77bf47',
29
- location=(19.432607, -99.133209),
30
- signature_image_url=(
31
- 'https://cuenca.com/files/EFQL87ohvoRp-PkOTYgvQYFA/invalid'
32
- ),
33
- )
34
- with pytest.raises(ValidationError):
35
- UserTOSAgreementRequest(**request_data)
36
-
37
-
38
- def test_session_request_without_metadata():
39
- request_data = {
40
- 'user_id': 'USWqY5cvkISJOxHyEKjAKf8w',
41
- 'type': 'session.curp_validation',
42
- }
43
- request = SessionRequest(**request_data)
44
- assert request.type == SessionType.curp_validation
45
- assert request.user_id == 'USWqY5cvkISJOxHyEKjAKf8w'
46
-
47
-
48
- def test_session_request_with_resource_id():
49
- request_data = {
50
- 'user_id': 'USWqY5cvkISJOxHyEKjAKf8w',
51
- 'type': 'session.metamap_verification',
52
- 'resource_id': 'some_verification_id',
53
- }
54
- request = SessionRequest(**request_data)
55
- assert request.type == SessionType.metamap_verification
56
- assert request.user_id == 'USWqY5cvkISJOxHyEKjAKf8w'
57
- assert request.resource_id
58
- assert request.resource_id == 'some_verification_id'
59
-
60
-
61
- def test_metamap_session_request_without_metadata():
62
- request_data = {
63
- 'user_id': 'USWqY5cvkISJOxHyEKjAKf8w',
64
- 'type': 'session.metamap_verification',
65
- }
66
-
67
- with pytest.raises(ValidationError) as exception:
68
- SessionRequest(**request_data)
69
-
70
- assert 'Resource id expected for this session' in str(exception)