Skip to content

Commit

Permalink
Errors (#102)
Browse files Browse the repository at this point in the history
* adding errors from docuemnts

* rename errors

* non optional

* update codecov action

* uses

* errors tested

* lint

* verification steps

* version

* v1
  • Loading branch information
alexviquez authored Oct 14, 2022
1 parent d5c6df3 commit 9a4d829
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 1 deletion.
16 changes: 16 additions & 0 deletions mati/resources/verifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from ..types.enums import (
DocumentScore,
Errors,
Liveness,
UserValidationFile,
VerificationDocument,
Expand Down Expand Up @@ -83,6 +84,21 @@ def proof_of_life_document(self) -> Optional[Liveness]:
pol = [pol for pol in self.steps if pol.id == 'liveness']
return pol[-1] if pol else None

@property
def proof_of_life_errors(self) -> List[Errors]:
return [
Errors(
identifier=pol.id,
type=pol.error['type'] if 'type' in pol.error else None,
code=pol.error['code'] if 'code' in pol.error else None,
message=pol.error['message']
if 'message' in pol.error
else None,
)
for pol in self.steps # type: ignore
if pol.id == 'liveness' and pol.error
]

@property
def govt_id_document(self) -> Optional[VerificationDocument]:
govs = [
Expand Down
2 changes: 2 additions & 0 deletions mati/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
__all__ = [
'Errors',
'SerializableEnum',
'PageType',
'ValidationInputType',
Expand All @@ -13,6 +14,7 @@

from .enums import (
DocumentScore,
Errors,
Liveness,
LivenessMedia,
PageType,
Expand Down
48 changes: 48 additions & 0 deletions mati/types/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ class VerificationDocumentStep:
data: Optional[Dict] = field(default_factory=dict)


@dataclass
class Errors:
identifier: str
type: str
code: str
message: str


@dataclass
class VerificationDocument:
country: str
Expand All @@ -44,6 +52,46 @@ class VerificationDocument:
type: str
fields: Optional[dict] = None

@property
def errors(self) -> List[Errors]:
if not self.steps:
return []
errors = [
Errors(
identifier=step.id,
type=step.error['type'] if 'type' in step.error else None,
code=step.error['code'] if 'code' in step.error else None,
message=step.error['message']
if 'message' in step.error
else None,
)
for step in self.steps
if step.error
]
if self.type == 'proof-of-residency' and self.steps:
step = self.steps[0]
keys = step.data.keys() # type: ignore
required_fileds = []
for key in keys:
data = step.data[key] # type: ignore
if (
'required' in data
and data['required']
and not data['value']
):
required_fileds.append(data['label'])
if required_fileds:
errors.append(
Errors(
identifier=step.id,
type='StepError',
code='document.extractRequiredFields',
message=f"We can't extract the following "
f"fields in the document: {required_fileds}",
)
)
return errors

@property
def document_type(self) -> str:
if self.type in ['national-id', 'passport']:
Expand Down
2 changes: 1 addition & 1 deletion mati/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.0.0' # pragma: no cover
__version__ = '2.0.1' # pragma: no cover
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ def verification(client: Client) -> Generator:
)


@pytest.fixture
def verification_without_pol(client: Client):
verification = client.verifications.retrieve('634870763768f1001cac7591')
verification.steps = []
yield verification


@pytest.fixture
def verification_document_national_id() -> VerificationDocument:
return VerificationDocument(
Expand Down
161 changes: 161 additions & 0 deletions tests/resources/cassettes/test_retrieve_dni_verification.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
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/2.0.1.dev1
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:
- Fri, 14 Oct 2022 19:18:06 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:
- 56dafc49-6548-4cb2-8be3-497d15d36645
X-Xss-Protection:
- '1'
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- mati-python/2.0.1.dev1
method: GET
uri: https://api.getmati.com/v2/verifications/634870763768f1001cac7591
response:
body:
string: '{"expired": false, "identity": {"status": "verified"}, "flow": {"id":
"some_flow", "name": "Default flow"}, "documents": [{"country": "MX", "region":
"", "type": "national-id", "photos": ["https://media.getmati.com/media/xxx",
"https://media.getmati.com/media/yyy"], "steps": [{"error": null, "status":
200, "id": "template-matching"}, {"error": null, "status": 200, "id": "mexican-curp-validation",
"data": {"curp": "CURP", "fullName": "LAST FIRST", "birthDate": "01/01/1980",
"gender": "HOMBRE", "nationality": "MEXICO", "surname": "LAST", "secondSurname":
"", "name": "FIRST"}}, {"error": null, "status": 200, "id": "document-reading",
"data": {"fullName": {"value": "FIRST LAST", "label": "Name", "sensitive":
true}, "documentNumber": {"value": "111", "label": "Document Number"}, "dateOfBirth":
{"value": "1980-01-01", "label": "Day of Birth", "format": "date"}, "expirationDate":
{"value": "2030-12-31", "label": "Date of Expiration", "format": "date"},
"curp": {"value": "CURP", "label": "CURP"}, "address": {"value": "Varsovia
36, 06600 CDMX", "label": "Address"}, "emissionDate": {"value": "2010-01-01",
"label": "Emission Date", "format": "date"}}}, {"error": null, "status": 200,
"id": "alteration-detection"}, {"error": null, "status": 200, "id": "watchlists"}],
"fields": {"fullName": {"value": "FIRST LAST", "label": "Name", "sensitive":
true}, "documentNumber": {"value": "111", "label": "Document Number"}, "dateOfBirth":
{"value": "1980-01-01", "label": "Day of Birth", "format": "date"}, "expirationDate":
{"value": "2030-12-31", "label": "Date of Expiration", "format": "date"},
"curp": {"value": "CURP", "label": "CURP"}, "address": {"value": "Varsovia
36, 06600 CDMX", "label": "Address"}, "emissionDate": {"value": "2010-01-01",
"label": "Emission Date", "format": "date"}}}, {"country": "MX", "region":
null, "type": "proof-of-residency", "steps": [{"status": 200, "id": "document-reading",
"data": {"fullName": {"required": true, "label": "Name", "value": "FIRST NAME"},
"address": {"label": "Address", "value": "Varsovia 36, 06600 CDMX"}, "emissionDate":
{"format": "date", "label": "Emission Date", "value": "1880-01-01"}}, "error":
null}, {"status": 200, "id": "watchlists", "error": null}], "fields": {"address":
{"value": "Varsovia 36, 06600 CDMX"}, "emissionDate": {"value": "1880-01-01"},
"fullName": {"value": "FIRST LASTNAME"}}, "photos": ["https://media.getmati.com/file?location=xyc"]}],
"steps": [{"status": 200, "id": "liveness", "data": {"videoUrl": "https://media.getmati.com/file?location=abc",
"spriteUrl": "https://media.getmati.com/file?location=def", "selfieUrl": "https://media.getmati.com/file?location=hij"},
"error": null}], "hasProblem": false, "computed": {"age": {"data": 100}, "isDocumentExpired":
{"data": {"national-id": false, "proof-of-residency": false}}}, "id": "5d9fb1f5bfbfac001a349bfb",
"metadata": {"name": "First Last", "dob": "1980-01-01"}}'
headers:
Cache-Control:
- no-store, no-cache, must-revalidate, proxy-revalidate
Connection:
- keep-alive
Content-Length:
- '4288'
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:
- Fri, 14 Oct 2022 19:18:06 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:
- 2a5d765d-f1f6-42b8-8de9-0343691d4a4f
X-Xss-Protection:
- '1'
status:
code: 200
message: OK
version: 1
10 changes: 10 additions & 0 deletions tests/resources/test_verifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ def test_retrieve_full_verification(client: Client):
assert verification.govt_id_validation.is_valid
assert verification.proof_of_life_validation.is_valid
assert verification.proof_of_residency_validation.is_valid
assert not verification.govt_id_document.errors
assert not verification.proof_of_residency_document.errors
assert not verification.proof_of_life_errors
assert (
verification.proof_of_residency_document.address
== 'Varsovia 36, 06600 CDMX'
Expand Down Expand Up @@ -67,3 +70,10 @@ def test_create_verification(client: Client):
assert verification.flow['id'] == FAKE_FLOW_ID
assert verification.metadata['user'] == 'some_id'
assert verification.identity


@pytest.mark.vcr
def test_retrieve_dni_verification(verification_without_pol):
verification = verification_without_pol
assert not verification.proof_of_life_errors
assert not verification.proof_of_life_document

0 comments on commit 9a4d829

Please sign in to comment.