From d5c6df3fd9fe96189a9e651ea46b94759cde5606 Mon Sep 17 00:00:00 2001 From: Alex Viquez Date: Mon, 26 Sep 2022 17:40:58 -0500 Subject: [PATCH] Verifications instead of Identities (old) (#98) * adding verification create * version * assert * format * bump * changes in verification upload documents * some fixes * version * BREAKING CHANGE, remove identities * fix lint * readme * group 1 --- README.md | 67 +++++++- mati/client.py | 9 +- mati/resources/__init__.py | 2 - mati/resources/identities.py | 60 -------- mati/resources/verifications.py | 22 +++ mati/types/enums.py | 5 +- mati/version.py | 2 +- tests/conftest.py | 10 +- .../cassettes/test_create_identity.yaml | 73 --------- .../cassettes/test_create_verification.yaml | 131 ++++++++++++++++ .../test_ine_and_liveness_upload.yaml | 143 ++++++++++++++---- .../cassettes/test_retrieve_identity.yaml | 135 ----------------- tests/resources/test_identities.py | 24 --- .../resources/test_user_verification_data.py | 16 +- tests/resources/test_verifications.py | 11 ++ tests/test_multiple_clients.py | 38 ----- 16 files changed, 356 insertions(+), 392 deletions(-) delete mode 100644 mati/resources/identities.py delete mode 100644 tests/resources/cassettes/test_create_identity.yaml create mode 100644 tests/resources/cassettes/test_create_verification.yaml delete mode 100644 tests/resources/cassettes/test_retrieve_identity.yaml delete mode 100644 tests/resources/test_identities.py delete mode 100644 tests/test_multiple_clients.py diff --git a/README.md b/README.md index 7f4568e..8e6b5b4 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,70 @@ source venv/bin/activate make test ``` -## Create Identity +## Create Verification ```python from mati import Client -client = Client() -georg = client.identities.create( - name='Georg Wilhelm Friedrich Hegel', - occupation='Philosopher', - dob='1770-08-27' +client = Client('api_key', 'secret_key') +verification = client.verifications.create( + 'some_flow_id', + company_id='some_id', ) ``` + +## Upload documents +```python +from mati.types import ( + PageType, + UserValidationFile, + ValidationInputType, + ValidationType, +) + +# Load documents +front = open('ine_front.jpg', 'rb') +back = open('ine_back.jpg', 'rb') +live = open('liveness.mp4', 'rb') + +# Create document with metadata +user_validation_file = UserValidationFile( + filename='ine_front.jpg', + content=front, + input_type=ValidationInputType.document_photo, + validation_type=ValidationType.national_id, + country='MX', + group=0, #The group is important when create your metamap +) +user_validation_file_back = UserValidationFile( + filename='ine_back.jpg', + content=back, + input_type=ValidationInputType.document_photo, + validation_type=ValidationType.national_id, + country='MX', + page=PageType.back, + group=0, +) +user_validation_live = UserValidationFile( + filename='liveness.MOV', + content=live, + input_type=ValidationInputType.selfie_video, + group=1, +) + +# Send documentation for validation +resp = client.verifications.upload_validation_data( + [ + user_validation_file, + user_validation_file_back, + user_validation_live, + ], + verification.identity, +) +``` + +## Verification status +Retrieve the verification when its complete +```python +verification = client.verifications.retrieve('verification_id') +``` \ No newline at end of file diff --git a/mati/client.py b/mati/client.py index 53daa1c..5c08dc4 100644 --- a/mati/client.py +++ b/mati/client.py @@ -3,13 +3,7 @@ from requests import Response, Session -from .resources import ( - AccessToken, - Identity, - Resource, - UserValidationData, - Verification, -) +from .resources import AccessToken, Resource, UserValidationData, Verification from .version import __version__ as client_version API_URL = 'https://api.getmati.com' @@ -25,7 +19,6 @@ class Client: # resources access_tokens: ClassVar = AccessToken - identities: ClassVar = Identity user_validation_data: ClassVar = UserValidationData verifications: ClassVar = Verification diff --git a/mati/resources/__init__.py b/mati/resources/__init__.py index eb90183..eef7dd4 100644 --- a/mati/resources/__init__.py +++ b/mati/resources/__init__.py @@ -1,6 +1,5 @@ __all__ = [ 'AccessToken', - 'Identity', 'Resource', 'UserValidationData', 'Verification', @@ -8,6 +7,5 @@ from .access_tokens import AccessToken from .base import Resource -from .identities import Identity from .user_verification_data import UserValidationData from .verifications import Verification diff --git a/mati/resources/identities.py b/mati/resources/identities.py deleted file mode 100644 index 27186c0..0000000 --- a/mati/resources/identities.py +++ /dev/null @@ -1,60 +0,0 @@ -import datetime as dt -from dataclasses import dataclass, field -from typing import ClassVar, List, Optional, Union, cast - -from ..types import UserValidationFile -from .base import Resource -from .user_verification_data import UserValidationData - - -@dataclass -class Identity(Resource): - """ - Based on: https://docs.getmati.com/#step-2-create-a-new-identity - """ - - _endpoint: ClassVar[str] = '/v2/identities' - - id: str - alive: Optional[bool] - status: str - date_created: Union[Optional[dt.datetime], None] = None - date_updated: Union[Optional[dt.datetime], None] = None - annotated_status: Optional[str] = None - user: Optional[str] = None - metadata: Union[dict, List[str]] = field(default_factory=dict) - full_name: Optional[str] = None - facematch_score: Optional[float] = None - photo: Optional[str] = None - video: Optional[str] = None - flow_id: Optional[str] = None - merchant_id: Optional[str] = None - - @classmethod - def create(cls, client=None, **metadata) -> 'Identity': - client = client or cls._client - resp = client.post(cls._endpoint, json=dict(metadata=metadata)) - resp['id'] = resp.pop('_id') - return cast('Identity', cls._from_dict(resp)) - - @classmethod - def retrieve(cls, identity_id: str, client=None) -> 'Identity': - client = client or cls._client - endpoint = f'{cls._endpoint}/{identity_id}' - resp = client.get(endpoint) - resp['id'] = resp.pop('_id') - return cast('Identity', cls._from_dict(resp)) - - def refresh(self, client=None) -> None: - client = client or self._client - identity = self.retrieve(self.id, client=client) - for k, v in identity.__dict__.items(): - setattr(self, k, v) - - def upload_validation_data( - self, user_validation_files: List[UserValidationFile], client=None - ) -> List[dict]: - client = client or self._client - return UserValidationData.upload( - self.id, user_validation_files, client=client - ) diff --git a/mati/resources/verifications.py b/mati/resources/verifications.py index 2280c77..41d11d6 100644 --- a/mati/resources/verifications.py +++ b/mati/resources/verifications.py @@ -5,10 +5,12 @@ from ..types.enums import ( DocumentScore, Liveness, + UserValidationFile, VerificationDocument, VerificationDocumentStep, ) from .base import Resource +from .user_verification_data import UserValidationData @dataclass @@ -36,6 +38,14 @@ def __post_init__(self): docs.append(VerificationDocument(**doc)) self.documents = docs + @classmethod + def create(cls, flow_id: str, client=None, **metadata): + client = client or cls._client + resp = client.post( + cls._endpoint, json=dict(flowId=flow_id, metadata=metadata) + ) + return cast('Verification', cls._from_dict(resp)) + @classmethod def retrieve(cls, verification_id: str, client=None) -> 'Verification': client = client or cls._client @@ -43,6 +53,18 @@ def retrieve(cls, verification_id: str, client=None) -> 'Verification': resp = client.get(endpoint) return cast('Verification', cls._from_dict(resp)) + @classmethod + def upload_validation_data( + cls, + user_validation_files: List[UserValidationFile], + identity_id: str, + client=None, + ) -> List[dict]: + client = client or cls._client + return UserValidationData.upload( + identity_id, user_validation_files, client=client + ) + @property def is_pending(self) -> bool: return self.identity['status'] in ['running', 'pending'] diff --git a/mati/types/enums.py b/mati/types/enums.py index b6ec4a0..3e95894 100644 --- a/mati/types/enums.py +++ b/mati/types/enums.py @@ -24,6 +24,7 @@ class ValidationType(SerializableEnum): national_id = 'national-id' passport = 'passport' proof_of_residency = 'proof-of-residency' + liveness = 'video/mp4' @dataclass @@ -109,8 +110,8 @@ class LivenessMedia: class Liveness: status: int id: str - data: LivenessMedia - error: Optional[Dict] + data: Optional[LivenessMedia] = None + error: Optional[Dict] = None @dataclass diff --git a/mati/version.py b/mati/version.py index 26b3eb4..3cb60e3 100644 --- a/mati/version.py +++ b/mati/version.py @@ -1 +1 @@ -__version__ = '0.3.4' # pragma: no cover +__version__ = '2.0.0' # pragma: no cover diff --git a/tests/conftest.py b/tests/conftest.py index 3564476..ae859aa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -213,13 +213,11 @@ def client() -> Generator: @pytest.fixture -def identity(client: Client) -> Generator: - yield client.identities.create( +def verification(client: Client) -> Generator: + yield client.verifications.create( + 'SOME_FLOW_ID', client=client, - nombres='Georg Wilhelm', - primer_apellido='Friedrich', - segundo_apellido='Hegel', - dob='1770-08-27', + user='some_id', ) diff --git a/tests/resources/cassettes/test_create_identity.yaml b/tests/resources/cassettes/test_create_identity.yaml deleted file mode 100644 index 54f9b4d..0000000 --- a/tests/resources/cassettes/test_create_identity.yaml +++ /dev/null @@ -1,73 +0,0 @@ -interactions: -- request: - body: grant_type=client_credentials - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '29' - Content-Type: - - application/x-www-form-urlencoded - User-Agent: - - python-requests/2.22.0 - method: POST - uri: https://api.getmati.com/oauth - response: - body: - string: '{"access_token": "ACCESS_TOKEN", "expiresIn": 3600, "payload": {"user": - {"_id": "ID", "firstName": "FIRST_NAME", "lastName": "LAST_NAME"}}}' - headers: - Connection: - - keep-alive - Content-Length: - - '504' - Content-Type: - - application/json; charset=utf-8 - Date: - - Tue, 08 Oct 2019 22:04:57 GMT - X-Request-Id: - - 0a46273c-86e6-42a9-9937-d8e56c4fceeb - status: - code: 200 - message: OK -- request: - body: '{"metadata": {"nombres": "Georg Wilhelm", "primer_apellido": "Friedrich", - "segundo_apellido": "Hegel", "dob": "1770-08-27"}}' - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '124' - Content-Type: - - application/json - User-Agent: - - python-requests/2.22.0 - method: POST - uri: https://api.getmati.com/v2/identities - response: - body: - string: '{"_id":"5d9d0809bfbfac001a348632","alive":null,"dateCreated":"2019-10-08T22:04:57.729Z","dateUpdated":"2019-10-08T22:04:57.729Z","flowId":"5e9576d9ac2c70001ca9f092","merchantId":"5cec5d4e69eb4d001b8544cf","metadata":{"nombres":"Georg - Wilhelm","primer_apellido":"Friedrich","segundo_apellido":"Hegel","dob":"1770-08-27"},"status":"pending","user":"5cec5d4e69eb4d001b8544ce","some":"field","summary":{"extra":"Fields"}}' - headers: - Connection: - - keep-alive - Content-Length: - - '297' - Content-Type: - - application/json; charset=utf-8 - Date: - - Tue, 08 Oct 2019 22:04:57 GMT - X-Request-Id: - - 25d83302-cb05-4d30-b0e6-ac792913899c - status: - code: 200 - message: OK -version: 1 diff --git a/tests/resources/cassettes/test_create_verification.yaml b/tests/resources/cassettes/test_create_verification.yaml new file mode 100644 index 0000000..235c1a2 --- /dev/null +++ b/tests/resources/cassettes/test_create_verification.yaml @@ -0,0 +1,131 @@ +interactions: +- request: + body: grant_type=client_credentials + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '29' + Content-Type: + - application/x-www-form-urlencoded + User-Agent: + - mati-python/0.3.4 + method: POST + uri: https://api.getmati.com/oauth + response: + body: + string: '{"access_token": "ACCESS_TOKEN", "expiresIn": 3600, "payload": {"user": + {"_id": "ID", "firstName": "FIRST_NAME", "lastName": "LAST_NAME"}}}' + headers: + Cache-Control: + - no-store, no-cache, must-revalidate, proxy-revalidate + Connection: + - keep-alive + Content-Length: + - '746' + Content-Security-Policy: + - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self'' + https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src + ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests' + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 12 Sep 2022 16:54:24 GMT + Expect-Ct: + - max-age=0 + Expires: + - '0' + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=15552000; includeSubDomains; preload + Surrogate-Control: + - no-store + X-Content-Type-Options: + - nosniff + X-Dns-Prefetch-Control: + - 'off' + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - 1824447c-4ad9-4468-b4de-8c0e448b54c4 + X-Xss-Protection: + - '1' + status: + code: 200 + message: OK +- request: + body: '{"flowId": "some_flow_id", "metadata": {"user": "some_id"}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '71' + Content-Type: + - application/json + User-Agent: + - mati-python/0.3.4 + method: POST + uri: https://api.getmati.com/v2/verifications + response: + body: + string: '{"documents":[],"expired":false,"flow":{"id":"some_flow_id","name":"FakeFlow"},"identity":"631f644019cdeb001d743839","inputs":[{"id":"connection-data","status":200,"optional":false},{"id":"selfie-video","status":0},{"id":"document-photo","status":0,"group":0},{"id":"document-photo","status":0,"group":1}],"metadata":{"user":"some_id"},"steps":[{"status":0,"id":"liveness"}],"masJobToBePostpone":false,"id":"631f644019cdeb001d74383b","deviceFingerprint":{"ua":"mati-python/0.3.4","ip":"187.189.101.53","vpnDetectionEnabled":false},"hasProblem":false}' + headers: + Cache-Control: + - no-store, no-cache, must-revalidate, proxy-revalidate + Connection: + - keep-alive + Content-Length: + - '568' + Content-Security-Policy: + - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self'' + https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src + ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests' + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 12 Sep 2022 16:54:24 GMT + Expect-Ct: + - max-age=0 + Expires: + - '0' + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=15552000; includeSubDomains; preload + Surrogate-Control: + - no-store + X-Content-Type-Options: + - nosniff + X-Dns-Prefetch-Control: + - 'off' + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - a2ae0e22-5f1f-40e6-97d9-6b4feed674de + X-Xss-Protection: + - '1' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/resources/cassettes/test_ine_and_liveness_upload.yaml b/tests/resources/cassettes/test_ine_and_liveness_upload.yaml index fc597b8..e1a149a 100644 --- a/tests/resources/cassettes/test_ine_and_liveness_upload.yaml +++ b/tests/resources/cassettes/test_ine_and_liveness_upload.yaml @@ -13,7 +13,7 @@ interactions: Content-Type: - application/x-www-form-urlencoded User-Agent: - - python-requests/2.22.0 + - mati-python/2.0.0 method: POST uri: https://api.getmati.com/oauth response: @@ -21,22 +21,51 @@ interactions: string: '{"access_token": "ACCESS_TOKEN", "expiresIn": 3600, "payload": {"user": {"_id": "ID", "firstName": "FIRST_NAME", "lastName": "LAST_NAME"}}}' headers: + Cache-Control: + - no-store, no-cache, must-revalidate, proxy-revalidate Connection: - keep-alive Content-Length: - - '504' + - '746' + Content-Security-Policy: + - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self'' + https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src + ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests' Content-Type: - application/json; charset=utf-8 Date: - - Wed, 16 Oct 2019 22:02:31 GMT + - Mon, 26 Sep 2022 21:45:23 GMT + Expect-Ct: + - max-age=0 + Expires: + - '0' + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=15552000; includeSubDomains; preload + Surrogate-Control: + - no-store + X-Content-Type-Options: + - nosniff + X-Dns-Prefetch-Control: + - 'off' + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none X-Request-Id: - - ae9e11cc-92c0-4f1c-8f3e-7cd88f98048c + - 1f75632d-78ad-48eb-a588-87f5817d6adf + X-Xss-Protection: + - '1' status: code: 200 message: OK - request: - body: '{"metadata": {"nombres": "Georg Wilhelm", "primer_apellido": "Friedrich", - "segundo_apellido": "Hegel", "dob": "1770-08-27"}}' + body: '{"flowId": "SOME_FLOW_ID", "metadata": {"user": "some_id"}}' headers: Accept: - '*/*' @@ -45,34 +74,64 @@ interactions: Connection: - keep-alive Content-Length: - - '124' + - '59' Content-Type: - application/json User-Agent: - - python-requests/2.22.0 + - mati-python/0.3.5 method: POST - uri: https://api.getmati.com/v2/identities + uri: https://api.getmati.com/v2/verifications response: body: - string: '{"_id":"5da793771b6d78001b4596b0","alive":null,"dateCreated":"2019-10-16T22:02:31.307Z","dateUpdated":"2019-10-16T22:02:31.307Z","metadata":{"nombres":"Georg - Wilhelm","primer_apellido":"Friedrich","segundo_apellido":"Hegel","dob":"1770-08-27"},"status":"pending","user":"5cec5d4e69eb4d001b8544ce"}' + string: '{"documents":[],"expired":false,"flow":{"id":"5e9576d9ac2c70001ca9f092","name":"Default + flow"},"identity":"63321d73fa4e97001c4fcca2","inputs":[{"id":"connection-data","status":200,"optional":false},{"id":"selfie-video","status":0},{"id":"document-photo","status":0,"group":0}],"metadata":{"user":"some_id"},"steps":[{"status":0,"id":"liveness"}],"masJobToBePostpone":false,"id":"63321d73fa4e97001c4fcca4","deviceFingerprint":{"ua":"mati-python/0.3.5","ip":"187.189.101.53","vpnDetectionEnabled":false},"hasProblem":false}' headers: + Cache-Control: + - no-store, no-cache, must-revalidate, proxy-revalidate Connection: - keep-alive Content-Length: - - '297' + - '521' + Content-Security-Policy: + - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self'' + https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src + ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests' Content-Type: - application/json; charset=utf-8 Date: - - Wed, 16 Oct 2019 22:02:31 GMT + - Mon, 26 Sep 2022 21:45:23 GMT + Expect-Ct: + - max-age=0 + Expires: + - '0' + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=15552000; includeSubDomains; preload + Surrogate-Control: + - no-store + X-Content-Type-Options: + - nosniff + X-Dns-Prefetch-Control: + - 'off' + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none X-Request-Id: - - 8b601be3-06b7-4088-b41b-34d1c45aff3b + - b5becaf0-1bbc-4fa5-8772-7c167c9d650d + X-Xss-Protection: + - '1' status: code: 200 message: OK - request: body: !!binary | - LS0xNWEwMDlmYzQ4ZjUxODI0NjIxM2M4MjZlODM1NDJlNQ0KQ29udGVudC1EaXNwb3NpdGlvbjog + LS1mNDI4NjAwNzBmMDYyMGFhOTRkMWQzY2YxOTkxY2I0Ng0KQ29udGVudC1EaXNwb3NpdGlvbjog Zm9ybS1kYXRhOyBuYW1lPSJpbnB1dHMiDQoNClt7ImlucHV0VHlwZSI6ICJkb2N1bWVudC1waG90 byIsICJncm91cCI6IDAsICJkYXRhIjogeyJ0eXBlIjogIm5hdGlvbmFsLWlkIiwgImNvdW50cnki OiAiTVgiLCAicGFnZSI6ICJmcm9udCIsICJmaWxlbmFtZSI6ICJpbmVfZnJvbnQuanBnIiwgInJl @@ -80,7 +139,7 @@ interactions: ImRhdGEiOiB7InR5cGUiOiAibmF0aW9uYWwtaWQiLCAiY291bnRyeSI6ICJNWCIsICJwYWdlIjog ImJhY2siLCAiZmlsZW5hbWUiOiAiaW5lX2JhY2suanBnIiwgInJlZ2lvbiI6ICIifX0sIHsiaW5w dXRUeXBlIjogInNlbGZpZS12aWRlbyIsICJkYXRhIjogeyJmaWxlbmFtZSI6ICJsaXZlbmVzcy5N - T1YifX1dDQotLTE1YTAwOWZjNDhmNTE4MjQ2MjEzYzgyNmU4MzU0MmU1DQpDb250ZW50LURpc3Bv + T1YifX1dDQotLWY0Mjg2MDA3MGYwNjIwYWE5NGQxZDNjZjE5OTFjYjQ2DQpDb250ZW50LURpc3Bv c2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImRvY3VtZW50IjsgZmlsZW5hbWU9ImluZV9mcm9udC5q cGciDQoNCv/Y/+AAEEpGSUYAAQEAAEgASAAA/+EAjEV4aWYAAE1NACoAAAAIAAUBEgADAAAAAQAB AAABGgAFAAAAAQAAAEoBGwAFAAAAAQAAAFIBKAADAAAAAQACAACHaQAEAAAAAQAAAFoAAAAAAAAA @@ -1951,8 +2010,8 @@ interactions: yJnX+6mGHy/3WJh+X+6+IJ7f7sDP8v8A3Vo3h9SeqSwkojTB5olwcjuxcurRGCOD91TlFnkoClgO WgQjhWfF0sITNdifI3uxSMvixpOcsQJ5bBmQhY8IYKJlouXCdWSTRb5Kel4fL/dQ91A0FLMAFtjo ZQ2QIiY5sjPmsQcpItPO6FDGj1QUq+d0fbShZlC8WDI4VjosFDJfrsmT0k0MiKnAv91qUGSqzMh2 - B/NLJBVlfHuq41hgf3NAxqBUKPmAms6o8ll/NIkDZoJATiyqCdoxcOCuZYkmqAPF/9kNCi0tMTVh - MDA5ZmM0OGY1MTgyNDYyMTNjODI2ZTgzNTQyZTUNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0t + B/NLJBVlfHuq41hgf3NAxqBUKPmAms6o8ll/NIkDZoJATiyqCdoxcOCuZYkmqAPF/9kNCi0tZjQy + ODYwMDcwZjA2MjBhYTk0ZDFkM2NmMTk5MWNiNDYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0t ZGF0YTsgbmFtZT0iZG9jdW1lbnQiOyBmaWxlbmFtZT0iaW5lX2JhY2suanBnIg0KDQr/2P/gABBK RklGAAEBAABIAEgAAP/hAIxFeGlmAABNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABK ARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAAEgAAAABAAAASAAAAAEA @@ -3823,8 +3882,8 @@ interactions: viCe3+7Az/L/AN1aN4fUnqksJKI0weaJcHI7sXLq0Rgjg/dU5RZ5KApYDloEI4VnxdLCEzXYnyN7 sUjL4saTnLECeWwZkIWPCGCiZaLlwnVkk0W+SnpeHy/3UPdQNBSzABbY6GUNkCImObIz5rEHKSLT zuhQxo9UFKvndH20oWZQvFgyOFY6LBQyX67Jk9JNDIipwL/dalBkqszIdgfzSyQVZXx7quNYYH9z - QMagVCj5gJrOqPJZfzSJA2aCQE4sqgnaMXDgrmWJJqgDxf/ZDQotLTE1YTAwOWZjNDhmNTE4MjQ2 - MjEzYzgyNmU4MzU0MmU1DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9InZp + QMagVCj5gJrOqPJZfzSJA2aCQE4sqgnaMXDgrmWJJqgDxf/ZDQotLWY0Mjg2MDA3MGYwNjIwYWE5 + NGQxZDNjZjE5OTFjYjQ2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9InZp ZGVvIjsgZmlsZW5hbWU9ImxpdmVuZXNzLk1PViINCg0KAAAAFGZ0eXBxdCAgAAAAAHF0ICAAAAAI d2lkZQAVtDBtZGF0ISADQGgcIU7vPYfi3CZQkIQIopDrecX4ENvi8qnt3SdtkqWY0ORwNuQNpbj4 t1HJHh1gZKviEiNiPZ57hd9lLs7WF2uyi4Z8hVHty6CYY6YfFbIzP6xsMjVkXWJz88ZCczgS+52e @@ -28919,7 +28978,7 @@ interactions: AAAAqGZyZWUAAAAgdHJleAAAAAAAAAABAAAAAQAAABQAAyOmAQEAAAAAACB0cmV4AAAAAAAAAAIA AAABAAAEAAAAAAYAAAAAAAAAIHRyZXgAAAAAAAAAAwAAAAEAAAK9AAAACAAAAAAAAAAgdHJleAAA AAAAAAAEAAAAAQAAAr0AAAAKAAAAAAAAACB0cmV4AAAAAAAAAAUAAAABAAAAFAAAAEgAAAAADQot - LTE1YTAwOWZjNDhmNTE4MjQ2MjEzYzgyNmU4MzU0MmU1LS0NCg== + LWY0Mjg2MDA3MGYwNjIwYWE5NGQxZDNjZjE5OTFjYjQ2LS0NCg== headers: Accept: - '*/*' @@ -28930,25 +28989,55 @@ interactions: Content-Length: - '1644316' Content-Type: - - multipart/form-data; boundary=15a009fc48f518246213c826e83542e5 + - multipart/form-data; boundary=f42860070f0620aa94d1d3cf1991cb46 User-Agent: - - python-requests/2.22.0 + - mati-python/0.3.5 method: POST - uri: https://api.getmati.com/v2/identities/5da793771b6d78001b4596b0/send-input + uri: https://api.getmati.com/v2/identities/63321d73fa4e97001c4fcca2/send-input response: body: string: '[{"result":true},{"result":true},{"result":true}]' headers: + Cache-Control: + - no-store, no-cache, must-revalidate, proxy-revalidate Connection: - keep-alive Content-Length: - - '49' + - '142' + Content-Security-Policy: + - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self'' + https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src + ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests' Content-Type: - application/json; charset=utf-8 Date: - - Wed, 16 Oct 2019 22:02:34 GMT + - Mon, 26 Sep 2022 21:45:34 GMT + Expect-Ct: + - max-age=0 + Expires: + - '0' + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=15552000; includeSubDomains; preload + Surrogate-Control: + - no-store + X-Content-Type-Options: + - nosniff + X-Dns-Prefetch-Control: + - 'off' + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none X-Request-Id: - - 2ccae222-da78-41e3-a582-f3d24682cc12 + - ccd527c1-fab1-4858-ac3d-734f4429d5b5 + X-Xss-Protection: + - '1' status: code: 201 message: Created diff --git a/tests/resources/cassettes/test_retrieve_identity.yaml b/tests/resources/cassettes/test_retrieve_identity.yaml deleted file mode 100644 index b5bcf85..0000000 --- a/tests/resources/cassettes/test_retrieve_identity.yaml +++ /dev/null @@ -1,135 +0,0 @@ -interactions: -- request: - body: grant_type=client_credentials - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '29' - Content-Type: - - application/x-www-form-urlencoded - User-Agent: - - python-requests/2.22.0 - method: POST - uri: https://api.getmati.com/oauth - response: - body: - string: '{"access_token": "ACCESS_TOKEN", "expiresIn": 3600, "payload": {"user": - {"_id": "ID", "firstName": "FIRST_NAME", "lastName": "LAST_NAME"}}}' - headers: - Connection: - - keep-alive - Content-Length: - - '504' - Content-Type: - - application/json; charset=utf-8 - Date: - - Wed, 09 Oct 2019 00:19:58 GMT - X-Request-Id: - - dbcab789-4627-455f-8aab-a4517a425a19 - status: - code: 200 - message: OK -- request: - body: '{"metadata": {"nombres": "Georg Wilhelm", "primer_apellido": "Friedrich", - "segundo_apellido": "Hegel", "dob": "1770-08-27"}}' - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '124' - Content-Type: - - application/json - User-Agent: - - python-requests/2.22.0 - method: POST - uri: https://api.getmati.com/v2/identities - response: - body: - string: '{"_id":"5d9d27aebfbfac001a348701","alive":null,"dateCreated":"2019-10-09T00:19:58.898Z","dateUpdated":"2019-10-09T00:19:58.898Z","metadata":{"nombres":"Georg - Wilhelm","primer_apellido":"Friedrich","segundo_apellido":"Hegel","dob":"1770-08-27"},"status":"pending","user":"5cec5d4e69eb4d001b8544ce"}' - headers: - Connection: - - keep-alive - Content-Length: - - '297' - Content-Type: - - application/json; charset=utf-8 - Date: - - Wed, 09 Oct 2019 00:19:58 GMT - X-Request-Id: - - 01e55ae3-cca8-4bdb-84cb-597ba02611f2 - status: - code: 200 - message: OK -- request: - body: null - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - User-Agent: - - python-requests/2.22.0 - method: GET - uri: https://api.getmati.com/v2/identities/5d9d27aebfbfac001a348701 - response: - body: - string: '{"_id":"5d9d27aebfbfac001a348701","alive":null,"dateCreated":"2019-10-09T00:19:58.898Z","dateUpdated":"2019-10-09T00:19:58.898Z","metadata":{"nombres":"Georg - Wilhelm","primer_apellido":"Friedrich","segundo_apellido":"Hegel","dob":"1770-08-27"},"status":"pending","user":"5cec5d4e69eb4d001b8544ce"}' - headers: - Connection: - - keep-alive - Content-Length: - - '297' - Content-Type: - - application/json; charset=utf-8 - Date: - - Wed, 09 Oct 2019 00:19:59 GMT - X-Request-Id: - - 5e7e2484-2574-4452-bd87-7cc745889790 - status: - code: 200 - message: OK -- request: - body: null - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - User-Agent: - - python-requests/2.22.0 - method: GET - uri: https://api.getmati.com/v2/identities/5d9d27aebfbfac001a348701 - response: - body: - string: '{"_id":"5d9d27aebfbfac001a348701","alive":null,"dateCreated":"2019-10-09T00:19:58.898Z","dateUpdated":"2019-10-09T00:19:58.898Z","metadata":{"nombres":"Georg - Wilhelm","primer_apellido":"Friedrich","segundo_apellido":"Hegel","dob":"1770-08-27"},"status":"pending","user":"5cec5d4e69eb4d001b8544ce"}' - headers: - Connection: - - keep-alive - Content-Length: - - '297' - Content-Type: - - application/json; charset=utf-8 - Date: - - Wed, 09 Oct 2019 00:19:59 GMT - X-Request-Id: - - b5380418-deb1-492a-950b-7083af1e4a03 - status: - code: 200 - message: OK -version: 1 diff --git a/tests/resources/test_identities.py b/tests/resources/test_identities.py deleted file mode 100644 index 23f4183..0000000 --- a/tests/resources/test_identities.py +++ /dev/null @@ -1,24 +0,0 @@ -import pytest - -from mati import Client -from mati.resources import Identity - - -@pytest.mark.vcr -def test_create_identity(client: Client): - metadata = dict( - nombres='Georg Wilhelm', - primer_apellido='Friedrich', - segundo_apellido='Hegel', - dob='1770-08-27', - ) - identity = client.identities.create(**metadata) - assert identity.metadata == metadata - - -@pytest.mark.vcr -def test_retrieve_identity(client: Client, identity: Identity): - new_identity = client.identities.retrieve(identity.id) - assert new_identity == identity - identity.refresh() - assert new_identity == identity diff --git a/tests/resources/test_user_verification_data.py b/tests/resources/test_user_verification_data.py index f986b8a..423a15a 100644 --- a/tests/resources/test_user_verification_data.py +++ b/tests/resources/test_user_verification_data.py @@ -3,7 +3,7 @@ import pytest -from mati.resources import Identity +from mati.resources.verifications import Verification from mati.types import ( PageType, UserValidationFile, @@ -17,7 +17,7 @@ @pytest.mark.vcr -def test_ine_and_liveness_upload(identity: Identity): +def test_ine_and_liveness_upload(verification: Verification): filepath_front = os.path.join(FIXTURE_DIR, 'ine_front.jpg') filepath_back = os.path.join(FIXTURE_DIR, 'ine_back.jpg') filepath_live = os.path.join(FIXTURE_DIR, 'liveness.MOV') @@ -45,17 +45,13 @@ def test_ine_and_liveness_upload(identity: Identity): content=live, input_type=ValidationInputType.selfie_video, ) - user_validation_photo = UserValidationFile( - filename='selfie.jpg', - content=front, - input_type=ValidationInputType.selfie_photo, - ) - resp = identity.upload_validation_data( + + resp = Verification.upload_validation_data( [ user_validation_file, user_validation_file_back, user_validation_live, - user_validation_photo, - ] + ], + verification.identity, ) assert all([resp[i]['result'] for i in range(3)]) is True diff --git a/tests/resources/test_verifications.py b/tests/resources/test_verifications.py index dd83466..60474ab 100644 --- a/tests/resources/test_verifications.py +++ b/tests/resources/test_verifications.py @@ -56,3 +56,14 @@ def test_verification_is_pending(client: Client): verification = client.verifications.retrieve('61c4181a668ff5001c017ff5') verification.identity['status'] = 'running' assert verification.is_pending + + +@pytest.mark.vcr +def test_create_verification(client: Client): + FAKE_FLOW_ID = 'some_flow_id' + verification = client.verifications.create( + FAKE_FLOW_ID, **dict(user='some_id') + ) + assert verification.flow['id'] == FAKE_FLOW_ID + assert verification.metadata['user'] == 'some_id' + assert verification.identity diff --git a/tests/test_multiple_clients.py b/tests/test_multiple_clients.py deleted file mode 100644 index 875c691..0000000 --- a/tests/test_multiple_clients.py +++ /dev/null @@ -1,38 +0,0 @@ -import pytest - -from mati import Client -from mati.resources import Resource - - -@pytest.mark.vcr() -def test_two_clients(): - secondary_client = Client('test', 'test') - main_client = Client('api_key', 'secret_key') - - # NOTE: Resource._client is the default client for requests and - # always has the reference to the last client initialized - assert Resource._client == main_client - - assert main_client.bearer_token is None - assert secondary_client.bearer_token is None - - metadata = dict( - nombres='Georg Wilhelm', - primer_apellido='Friedrich', - segundo_apellido='Hegel', - dob='1770-08-27', - ) - - main_identity = main_client.identities.create(**metadata) - secondary_identity = secondary_client.identities.create( - client=secondary_client, **metadata - ) - - main_retrieve = main_client.identities.retrieve(main_identity.id) - secondary_retrieve = secondary_client.identities.retrieve( - secondary_identity.id, client=secondary_client - ) - assert main_retrieve.id == main_identity.id - assert secondary_retrieve.id == secondary_identity.id - - assert main_client.bearer_token == main_client.get_valid_bearer_token()