From 99e6494fe2f12070f775162ce1c8e60537584056 Mon Sep 17 00:00:00 2001 From: dvacca-onfido <134616519+dvacca-onfido@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:32:05 +0000 Subject: [PATCH 1/2] Upgrade after onfido-openapi-spec change 01ed1b5 --- .release.json | 8 +-- README.md | 3 + onfido/__init__.py | 2 +- onfido/api_client.py | 2 +- onfido/configuration.py | 2 +- onfido/models/document_properties.py | 66 ++++++++++++++++++- ...r_verification_report_all_of_properties.py | 66 ++++++++++++++++++- onfido/webhook_event_verifier.py | 11 ++-- pyproject.toml | 2 +- setup.py | 2 +- 10 files changed, 147 insertions(+), 17 deletions(-) diff --git a/.release.json b/.release.json index c464f9d..ec00d96 100644 --- a/.release.json +++ b/.release.json @@ -1,9 +1,9 @@ { "source": { "repo_url": "https://github.com/onfido/onfido-openapi-spec", - "short_sha": "a34b6d8", - "long_sha": "a34b6d86714f7f74da2d60a33a76ec3a693d264a", - "version": "v3.0.0" + "short_sha": "01ed1b5", + "long_sha": "01ed1b5fe0f7490bfce54816504a9fec13b33862", + "version": "v3.1.0" }, - "release": "v3.1.0" + "release": "v3.2.0" } diff --git a/README.md b/README.md index 5d3ce61..f17a66c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ Documentation can be found at . This version uses Onfido API v3.6. Refer to our [API versioning guide](https://developers.onfido.com/guide/api-versioning-policy#client-libraries) for details of which client library versions use which versions of the API. +[![PyPI version](https://badge.fury.io/py/onfido-python.svg)](https://badge.fury.io/py/onfido-python) +![Build Status](https://github.com/onfido/onfido-python/actions/workflows/python.yml/badge.svg) + ## Installation & Usage ### Requirements diff --git a/onfido/__init__.py b/onfido/__init__.py index 57891ea..24c393d 100644 --- a/onfido/__init__.py +++ b/onfido/__init__.py @@ -14,7 +14,7 @@ """ # noqa: E501 -__version__ = "3.1.0" +__version__ = "3.2.0" # import apis into sdk package from onfido.api.default_api import DefaultApi diff --git a/onfido/api_client.py b/onfido/api_client.py index 7209a2f..02bd247 100644 --- a/onfido/api_client.py +++ b/onfido/api_client.py @@ -88,7 +88,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'onfido-python/3.1.0' + self.user_agent = 'onfido-python/3.2.0' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/onfido/configuration.py b/onfido/configuration.py index 35ab5c3..69aa407 100644 --- a/onfido/configuration.py +++ b/onfido/configuration.py @@ -383,7 +383,7 @@ def to_debug_report(self): "OS: {env}\n"\ "Python Version: {pyversion}\n"\ "Version of the API: v3.6\n"\ - "SDK Package Version: 3.1.0".\ + "SDK Package Version: 3.2.0".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self): diff --git a/onfido/models/document_properties.py b/onfido/models/document_properties.py index 49456a6..063531d 100644 --- a/onfido/models/document_properties.py +++ b/onfido/models/document_properties.py @@ -18,7 +18,7 @@ import json from datetime import date -from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional from onfido.models.document_properties_address_lines import DocumentPropertiesAddressLines from onfido.models.document_properties_barcode_inner import DocumentPropertiesBarcodeInner @@ -36,6 +36,7 @@ class DocumentProperties(BaseModel): """ # noqa: E501 date_of_birth: Optional[date] = None date_of_expiry: Optional[date] = None + personal_number: Optional[StrictStr] = None document_numbers: Optional[List[DocumentPropertiesDocumentNumbersInner]] = None document_type: Optional[StrictStr] = None first_name: Optional[StrictStr] = None @@ -55,7 +56,22 @@ class DocumentProperties(BaseModel): widow_name: Optional[StrictStr] = None alias_name: Optional[StrictStr] = None issuing_authority: Optional[StrictStr] = None + remarks: Optional[StrictStr] = None + civil_state: Optional[StrictStr] = None + expatriation: Optional[StrictStr] = None + father_name: Optional[StrictStr] = None + mother_name: Optional[StrictStr] = None + religion: Optional[StrictStr] = None + type_of_permit: Optional[StrictStr] = None + version_number: Optional[StrictStr] = None + document_subtype: Optional[StrictStr] = None + profession: Optional[StrictStr] = None + security_document_number: Optional[StrictStr] = None + tax_number: Optional[StrictStr] = None + nist_identity_evidence_strength: Optional[StrictStr] = None + has_issuance_confirmation: Optional[StrictStr] = None real_id_compliance: Optional[StrictBool] = None + security_tier: Optional[StrictStr] = None address_lines: Optional[DocumentPropertiesAddressLines] = None barcode: Optional[List[DocumentPropertiesBarcodeInner]] = None nfc: Optional[DocumentPropertiesNfc] = None @@ -63,7 +79,37 @@ class DocumentProperties(BaseModel): document_classification: Optional[DocumentPropertiesDocumentClassification] = None extracted_data: Optional[DocumentPropertiesExtractedData] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["date_of_birth", "date_of_expiry", "document_numbers", "document_type", "first_name", "gender", "issuing_country", "last_name", "nationality", "issuing_state", "issuing_date", "categorisation", "mrz_line1", "mrz_line2", "mrz_line3", "address", "place_of_birth", "spouse_name", "widow_name", "alias_name", "issuing_authority", "real_id_compliance", "address_lines", "barcode", "nfc", "driving_licence_information", "document_classification", "extracted_data"] + __properties: ClassVar[List[str]] = ["date_of_birth", "date_of_expiry", "personal_number", "document_numbers", "document_type", "first_name", "gender", "issuing_country", "last_name", "nationality", "issuing_state", "issuing_date", "categorisation", "mrz_line1", "mrz_line2", "mrz_line3", "address", "place_of_birth", "spouse_name", "widow_name", "alias_name", "issuing_authority", "remarks", "civil_state", "expatriation", "father_name", "mother_name", "religion", "type_of_permit", "version_number", "document_subtype", "profession", "security_document_number", "tax_number", "nist_identity_evidence_strength", "has_issuance_confirmation", "real_id_compliance", "security_tier", "address_lines", "barcode", "nfc", "driving_licence_information", "document_classification", "extracted_data"] + + @field_validator('nist_identity_evidence_strength') + def nist_identity_evidence_strength_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['superior', 'strong', 'fair', 'weak', 'unacceptable', 'unspecified_identity_evidence_strength']): + raise ValueError("must be one of enum values ('superior', 'strong', 'fair', 'weak', 'unacceptable', 'unspecified_identity_evidence_strength')") + return value + + @field_validator('has_issuance_confirmation') + def has_issuance_confirmation_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['true', 'false', 'unspecified']): + raise ValueError("must be one of enum values ('true', 'false', 'unspecified')") + return value + + @field_validator('security_tier') + def security_tier_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['tier_1', 'tier_2', 'tier_3', 'tier_4', 'tier_5', 'unspecified_security_tier']): + raise ValueError("must be one of enum values ('tier_1', 'tier_2', 'tier_3', 'tier_4', 'tier_5', 'unspecified_security_tier')") + return value model_config = ConfigDict( populate_by_name=True, @@ -154,6 +200,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "date_of_birth": obj.get("date_of_birth"), "date_of_expiry": obj.get("date_of_expiry"), + "personal_number": obj.get("personal_number"), "document_numbers": [DocumentPropertiesDocumentNumbersInner.from_dict(_item) for _item in obj["document_numbers"]] if obj.get("document_numbers") is not None else None, "document_type": obj.get("document_type"), "first_name": obj.get("first_name"), @@ -173,7 +220,22 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "widow_name": obj.get("widow_name"), "alias_name": obj.get("alias_name"), "issuing_authority": obj.get("issuing_authority"), + "remarks": obj.get("remarks"), + "civil_state": obj.get("civil_state"), + "expatriation": obj.get("expatriation"), + "father_name": obj.get("father_name"), + "mother_name": obj.get("mother_name"), + "religion": obj.get("religion"), + "type_of_permit": obj.get("type_of_permit"), + "version_number": obj.get("version_number"), + "document_subtype": obj.get("document_subtype"), + "profession": obj.get("profession"), + "security_document_number": obj.get("security_document_number"), + "tax_number": obj.get("tax_number"), + "nist_identity_evidence_strength": obj.get("nist_identity_evidence_strength"), + "has_issuance_confirmation": obj.get("has_issuance_confirmation"), "real_id_compliance": obj.get("real_id_compliance"), + "security_tier": obj.get("security_tier"), "address_lines": DocumentPropertiesAddressLines.from_dict(obj["address_lines"]) if obj.get("address_lines") is not None else None, "barcode": [DocumentPropertiesBarcodeInner.from_dict(_item) for _item in obj["barcode"]] if obj.get("barcode") is not None else None, "nfc": DocumentPropertiesNfc.from_dict(obj["nfc"]) if obj.get("nfc") is not None else None, diff --git a/onfido/models/document_with_driver_verification_report_all_of_properties.py b/onfido/models/document_with_driver_verification_report_all_of_properties.py index 23be345..a40a369 100644 --- a/onfido/models/document_with_driver_verification_report_all_of_properties.py +++ b/onfido/models/document_with_driver_verification_report_all_of_properties.py @@ -18,7 +18,7 @@ import json from datetime import date -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional from onfido.models.document_properties_address_lines import DocumentPropertiesAddressLines from onfido.models.document_properties_barcode_inner import DocumentPropertiesBarcodeInner @@ -38,6 +38,7 @@ class DocumentWithDriverVerificationReportAllOfProperties(BaseModel): """ # noqa: E501 date_of_birth: Optional[date] = None date_of_expiry: Optional[date] = None + personal_number: Optional[StrictStr] = None document_numbers: Optional[List[DocumentPropertiesDocumentNumbersInner]] = None document_type: Optional[StrictStr] = None first_name: Optional[StrictStr] = None @@ -57,7 +58,22 @@ class DocumentWithDriverVerificationReportAllOfProperties(BaseModel): widow_name: Optional[StrictStr] = None alias_name: Optional[StrictStr] = None issuing_authority: Optional[StrictStr] = None + remarks: Optional[StrictStr] = None + civil_state: Optional[StrictStr] = None + expatriation: Optional[StrictStr] = None + father_name: Optional[StrictStr] = None + mother_name: Optional[StrictStr] = None + religion: Optional[StrictStr] = None + type_of_permit: Optional[StrictStr] = None + version_number: Optional[StrictStr] = None + document_subtype: Optional[StrictStr] = None + profession: Optional[StrictStr] = None + security_document_number: Optional[StrictStr] = None + tax_number: Optional[StrictStr] = None + nist_identity_evidence_strength: Optional[StrictStr] = None + has_issuance_confirmation: Optional[StrictStr] = None real_id_compliance: Optional[StrictBool] = None + security_tier: Optional[StrictStr] = None address_lines: Optional[DocumentPropertiesAddressLines] = None barcode: Optional[List[DocumentPropertiesBarcodeInner]] = None nfc: Optional[DocumentPropertiesNfc] = None @@ -71,7 +87,37 @@ class DocumentWithDriverVerificationReportAllOfProperties(BaseModel): vehicle_class_details: Optional[List[DocumentWithDriverVerificationReportAllOfPropertiesAllOfVehicleClassDetailsInner]] = Field(default=None, description="Detailed classes/categories information") passenger_vehicle: Optional[DocumentWithDriverVerificationReportAllOfPropertiesAllOfPassengerVehicle] = None additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["date_of_birth", "date_of_expiry", "document_numbers", "document_type", "first_name", "gender", "issuing_country", "last_name", "nationality", "issuing_state", "issuing_date", "categorisation", "mrz_line1", "mrz_line2", "mrz_line3", "address", "place_of_birth", "spouse_name", "widow_name", "alias_name", "issuing_authority", "real_id_compliance", "address_lines", "barcode", "nfc", "driving_licence_information", "document_classification", "extracted_data", "drivers_licence", "restricted_licence", "raw_licence_category", "raw_vehicle_classes", "vehicle_class_details", "passenger_vehicle"] + __properties: ClassVar[List[str]] = ["date_of_birth", "date_of_expiry", "personal_number", "document_numbers", "document_type", "first_name", "gender", "issuing_country", "last_name", "nationality", "issuing_state", "issuing_date", "categorisation", "mrz_line1", "mrz_line2", "mrz_line3", "address", "place_of_birth", "spouse_name", "widow_name", "alias_name", "issuing_authority", "remarks", "civil_state", "expatriation", "father_name", "mother_name", "religion", "type_of_permit", "version_number", "document_subtype", "profession", "security_document_number", "tax_number", "nist_identity_evidence_strength", "has_issuance_confirmation", "real_id_compliance", "security_tier", "address_lines", "barcode", "nfc", "driving_licence_information", "document_classification", "extracted_data", "drivers_licence", "restricted_licence", "raw_licence_category", "raw_vehicle_classes", "vehicle_class_details", "passenger_vehicle"] + + @field_validator('nist_identity_evidence_strength') + def nist_identity_evidence_strength_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['superior', 'strong', 'fair', 'weak', 'unacceptable', 'unspecified_identity_evidence_strength']): + raise ValueError("must be one of enum values ('superior', 'strong', 'fair', 'weak', 'unacceptable', 'unspecified_identity_evidence_strength')") + return value + + @field_validator('has_issuance_confirmation') + def has_issuance_confirmation_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['true', 'false', 'unspecified']): + raise ValueError("must be one of enum values ('true', 'false', 'unspecified')") + return value + + @field_validator('security_tier') + def security_tier_validate_enum(cls, value): + """Validates the enum""" + if value is None: + return value + + if value not in set(['tier_1', 'tier_2', 'tier_3', 'tier_4', 'tier_5', 'unspecified_security_tier']): + raise ValueError("must be one of enum values ('tier_1', 'tier_2', 'tier_3', 'tier_4', 'tier_5', 'unspecified_security_tier')") + return value model_config = ConfigDict( populate_by_name=True, @@ -172,6 +218,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "date_of_birth": obj.get("date_of_birth"), "date_of_expiry": obj.get("date_of_expiry"), + "personal_number": obj.get("personal_number"), "document_numbers": [DocumentPropertiesDocumentNumbersInner.from_dict(_item) for _item in obj["document_numbers"]] if obj.get("document_numbers") is not None else None, "document_type": obj.get("document_type"), "first_name": obj.get("first_name"), @@ -191,7 +238,22 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "widow_name": obj.get("widow_name"), "alias_name": obj.get("alias_name"), "issuing_authority": obj.get("issuing_authority"), + "remarks": obj.get("remarks"), + "civil_state": obj.get("civil_state"), + "expatriation": obj.get("expatriation"), + "father_name": obj.get("father_name"), + "mother_name": obj.get("mother_name"), + "religion": obj.get("religion"), + "type_of_permit": obj.get("type_of_permit"), + "version_number": obj.get("version_number"), + "document_subtype": obj.get("document_subtype"), + "profession": obj.get("profession"), + "security_document_number": obj.get("security_document_number"), + "tax_number": obj.get("tax_number"), + "nist_identity_evidence_strength": obj.get("nist_identity_evidence_strength"), + "has_issuance_confirmation": obj.get("has_issuance_confirmation"), "real_id_compliance": obj.get("real_id_compliance"), + "security_tier": obj.get("security_tier"), "address_lines": DocumentPropertiesAddressLines.from_dict(obj["address_lines"]) if obj.get("address_lines") is not None else None, "barcode": [DocumentPropertiesBarcodeInner.from_dict(_item) for _item in obj["barcode"]] if obj.get("barcode") is not None else None, "nfc": DocumentPropertiesNfc.from_dict(obj["nfc"]) if obj.get("nfc") is not None else None, diff --git a/onfido/webhook_event_verifier.py b/onfido/webhook_event_verifier.py index 272032f..d69e670 100644 --- a/onfido/webhook_event_verifier.py +++ b/onfido/webhook_event_verifier.py @@ -1,21 +1,24 @@ import hmac import hashlib -import json from .models import WebhookEvent + class OnfidoInvalidSignatureError(Exception): pass + class WebhookEventVerifier: def __init__(self, webhook_token): self.webhook_token = webhook_token def read_payload(self, raw_event, signature): # Compute the the actual HMAC signature from the raw request body. - event_signature = hmac.new(key=self.webhook_token.encode("utf-8"), - msg=raw_event.encode("utf-8"), - digestmod=hashlib.sha256).hexdigest() + event_signature = hmac.new( + key=self.webhook_token.encode("utf-8"), + msg=raw_event.encode("utf-8"), + digestmod=hashlib.sha256, + ).hexdigest() # Compare the signatures (prevent against timing attacks). if not hmac.compare_digest(signature, event_signature): diff --git a/pyproject.toml b/pyproject.toml index 36b060e..41e3b73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "onfido-python" -version = "3.1.0" +version = "3.2.0" description = "Python library for the Onfido API" authors = ["OpenAPI Generator Community "] license = "MIT" diff --git a/setup.py b/setup.py index 616d472..06dbf57 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ # prerequisite: setuptools # http://pypi.python.org/pypi/setuptools NAME = "onfido-python" -VERSION = "3.1.0" +VERSION = "3.2.0" PYTHON_REQUIRES = ">=3.7" REQUIRES = [ "urllib3 >= 1.25.3, < 2.1.0", From 28b160d89bb33cab9029daf24fb0af238c91cb65 Mon Sep 17 00:00:00 2001 From: Davide Vacca Date: Tue, 2 Jul 2024 18:04:20 +0200 Subject: [PATCH 2/2] Validate release and update CHANGELOG in CI --- .github/workflows/python.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 12eca37..de9f24a 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -68,13 +68,19 @@ jobs: publish: runs-on: ubuntu-latest needs: integration-tests + environment: delivery if: github.event_name == 'release' steps: - uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_ACTION_ACCESS_TOKEN }} + ref: ${{ github.event.release.tag_name }} - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.x" + - name: Validate release + uses: onfido/onfido-actions/release-check@main - name: Install dependencies run: | python -m pip install --upgrade pip @@ -86,3 +92,5 @@ jobs: with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} + - name: Update and commit CHANGELOG.md + uses: onfido/onfido-actions/update-changelog@main \ No newline at end of file