diff --git a/onfido/__init__.py b/onfido/__init__.py index edd1d35..e075c2e 100644 --- a/onfido/__init__.py +++ b/onfido/__init__.py @@ -51,7 +51,7 @@ from onfido.models.check_shared import CheckShared from onfido.models.checks_list import ChecksList from onfido.models.complete_task_builder import CompleteTaskBuilder -from onfido.models.complete_task_builder_data import CompleteTaskBuilderData +from onfido.models.complete_task_data_builder import CompleteTaskDataBuilder from onfido.models.consent_item import ConsentItem from onfido.models.consents_builder import ConsentsBuilder from onfido.models.country_codes import CountryCodes @@ -245,6 +245,7 @@ from onfido.models.sdk_token_request import SdkTokenRequest from onfido.models.sdk_token_response import SdkTokenResponse from onfido.models.task import Task +from onfido.models.task_item import TaskItem from onfido.models.us_driving_licence_breakdown import UsDrivingLicenceBreakdown from onfido.models.us_driving_licence_breakdown_address import UsDrivingLicenceBreakdownAddress from onfido.models.us_driving_licence_breakdown_address_breakdown import UsDrivingLicenceBreakdownAddressBreakdown diff --git a/onfido/api/default_api.py b/onfido/api/default_api.py index 19dec78..474045e 100644 --- a/onfido/api/default_api.py +++ b/onfido/api/default_api.py @@ -49,6 +49,7 @@ from onfido.models.sdk_token import SdkToken from onfido.models.sdk_token_builder import SdkTokenBuilder from onfido.models.task import Task +from onfido.models.task_item import TaskItem from onfido.models.watchlist_monitor import WatchlistMonitor from onfido.models.watchlist_monitor_builder import WatchlistMonitorBuilder from onfido.models.watchlist_monitor_matches_list import WatchlistMonitorMatchesList @@ -11917,7 +11918,7 @@ def list_tasks( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> List[Task]: + ) -> List[TaskItem]: """List Tasks The tasks of a Workflow can be retrieved by calling this endpoint with the unique identifier of the Workflow Run. @@ -11955,7 +11956,7 @@ def list_tasks( ) _response_types_map: Dict[str, Optional[str]] = { - '200': "List[Task]", + '200': "List[TaskItem]", } response_data = self.api_client.call_api( *_param, @@ -11984,7 +11985,7 @@ def list_tasks_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[List[Task]]: + ) -> ApiResponse[List[TaskItem]]: """List Tasks The tasks of a Workflow can be retrieved by calling this endpoint with the unique identifier of the Workflow Run. @@ -12022,7 +12023,7 @@ def list_tasks_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': "List[Task]", + '200': "List[TaskItem]", } response_data = self.api_client.call_api( *_param, @@ -12089,7 +12090,7 @@ def list_tasks_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': "List[Task]", + '200': "List[TaskItem]", } response_data = self.api_client.call_api( *_param, diff --git a/onfido/models/__init__.py b/onfido/models/__init__.py index de08469..68d55a0 100644 --- a/onfido/models/__init__.py +++ b/onfido/models/__init__.py @@ -34,7 +34,7 @@ from onfido.models.check_shared import CheckShared from onfido.models.checks_list import ChecksList from onfido.models.complete_task_builder import CompleteTaskBuilder -from onfido.models.complete_task_builder_data import CompleteTaskBuilderData +from onfido.models.complete_task_data_builder import CompleteTaskDataBuilder from onfido.models.consent_item import ConsentItem from onfido.models.consents_builder import ConsentsBuilder from onfido.models.country_codes import CountryCodes @@ -228,6 +228,7 @@ from onfido.models.sdk_token_request import SdkTokenRequest from onfido.models.sdk_token_response import SdkTokenResponse from onfido.models.task import Task +from onfido.models.task_item import TaskItem from onfido.models.us_driving_licence_breakdown import UsDrivingLicenceBreakdown from onfido.models.us_driving_licence_breakdown_address import UsDrivingLicenceBreakdownAddress from onfido.models.us_driving_licence_breakdown_address_breakdown import UsDrivingLicenceBreakdownAddressBreakdown diff --git a/onfido/models/complete_task_builder.py b/onfido/models/complete_task_builder.py index f74e5f1..692df68 100644 --- a/onfido/models/complete_task_builder.py +++ b/onfido/models/complete_task_builder.py @@ -19,7 +19,7 @@ from pydantic import BaseModel, ConfigDict from typing import Any, ClassVar, Dict, List -from onfido.models.complete_task_builder_data import CompleteTaskBuilderData +from onfido.models.complete_task_data_builder import CompleteTaskDataBuilder from typing import Optional, Set from typing_extensions import Self @@ -27,7 +27,7 @@ class CompleteTaskBuilder(BaseModel): """ CompleteTaskBuilder """ # noqa: E501 - data: CompleteTaskBuilderData + data: CompleteTaskDataBuilder additional_properties: Dict[str, Any] = {} __properties: ClassVar[List[str]] = ["data"] @@ -92,7 +92,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: return cls.model_validate(obj) _obj = cls.model_validate({ - "data": CompleteTaskBuilderData.from_dict(obj["data"]) if obj.get("data") is not None else None + "data": CompleteTaskDataBuilder.from_dict(obj["data"]) if obj.get("data") is not None else None }) # store additional fields in additional_properties for _key in obj.keys(): diff --git a/onfido/models/complete_task_builder_data.py b/onfido/models/complete_task_data_builder.py similarity index 89% rename from onfido/models/complete_task_builder_data.py rename to onfido/models/complete_task_data_builder.py index 381f3d8..418085b 100644 --- a/onfido/models/complete_task_builder_data.py +++ b/onfido/models/complete_task_data_builder.py @@ -21,16 +21,16 @@ from typing import Union, List, Set, Optional, Dict from typing_extensions import Literal, Self -COMPLETETASKBUILDERDATA_ONE_OF_SCHEMAS = ["List[object]", "object"] +COMPLETETASKDATABUILDER_ONE_OF_SCHEMAS = ["List[object]", "object"] -class CompleteTaskBuilderData(BaseModel): +class CompleteTaskDataBuilder(BaseModel): """ The Task completion payload. """ - # data type: object - oneof_schema_1_validator: Optional[Dict[str, Any]] = None # data type: List[object] - oneof_schema_2_validator: Optional[List[Dict[str, Any]]] = None + oneof_schema_1_validator: Optional[List[Dict[str, Any]]] = None + # data type: object + oneof_schema_2_validator: Optional[Dict[str, Any]] = None actual_instance: Optional[Union[List[object], object]] = None one_of_schemas: Set[str] = { "List[object]", "object" } @@ -52,16 +52,16 @@ def __init__(self, *args, **kwargs) -> None: @field_validator('actual_instance') def actual_instance_must_validate_oneof(cls, v): - instance = CompleteTaskBuilderData.model_construct() + instance = CompleteTaskDataBuilder.model_construct() error_messages = [] match = 0 - # validate data type: object + # validate data type: List[object] try: instance.oneof_schema_1_validator = v match += 1 except (ValidationError, ValueError) as e: error_messages.append(str(e)) - # validate data type: List[object] + # validate data type: object try: instance.oneof_schema_2_validator = v match += 1 @@ -69,10 +69,10 @@ def actual_instance_must_validate_oneof(cls, v): error_messages.append(str(e)) if match > 1: # more than 1 match - raise ValueError("Multiple matches found when setting `actual_instance` in CompleteTaskBuilderData with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) + raise ValueError("Multiple matches found when setting `actual_instance` in CompleteTaskDataBuilder with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) elif match == 0: # no match - raise ValueError("No match found when setting `actual_instance` in CompleteTaskBuilderData with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) + raise ValueError("No match found when setting `actual_instance` in CompleteTaskDataBuilder with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) else: return v @@ -87,7 +87,7 @@ def from_json(cls, json_str: str) -> Self: error_messages = [] match = 0 - # deserialize data into object + # deserialize data into List[object] try: # validation instance.oneof_schema_1_validator = json.loads(json_str) @@ -96,7 +96,7 @@ def from_json(cls, json_str: str) -> Self: match += 1 except (ValidationError, ValueError) as e: error_messages.append(str(e)) - # deserialize data into List[object] + # deserialize data into object try: # validation instance.oneof_schema_2_validator = json.loads(json_str) @@ -108,10 +108,10 @@ def from_json(cls, json_str: str) -> Self: if match > 1: # more than 1 match - raise ValueError("Multiple matches found when deserializing the JSON string into CompleteTaskBuilderData with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) + raise ValueError("Multiple matches found when deserializing the JSON string into CompleteTaskDataBuilder with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) elif match == 0: # no match - raise ValueError("No match found when deserializing the JSON string into CompleteTaskBuilderData with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) + raise ValueError("No match found when deserializing the JSON string into CompleteTaskDataBuilder with oneOf schemas: List[object], object. Details: " + ", ".join(error_messages)) else: return instance diff --git a/onfido/models/task.py b/onfido/models/task.py index b5f108e..24fc3e4 100644 --- a/onfido/models/task.py +++ b/onfido/models/task.py @@ -18,7 +18,7 @@ import json from datetime import datetime -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional from typing_extensions import Annotated from typing import Optional, Set @@ -29,11 +29,15 @@ class Task(BaseModel): Task """ # noqa: E501 id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="The identifier for the Task.") + workflow_run_id: Optional[StrictStr] = Field(default=None, description="The workflow run id the task belongs to.") task_def_id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="The identifier for the Task Definition.") + task_def_version: Optional[StrictStr] = Field(default=None, description="The task definition version.") + input: Optional[Dict[str, Any]] = Field(default=None, description="Input object with the fields used by the Task to execute.") + output: Optional[Dict[str, Any]] = Field(default=None, description="Output object with the fields produced by the Task execution.") created_at: Optional[datetime] = Field(default=None, description="The date and time when the Task was created.") updated_at: Optional[datetime] = Field(default=None, description="The date and time when the Task was last updated.") additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["id", "task_def_id", "created_at", "updated_at"] + __properties: ClassVar[List[str]] = ["id", "workflow_run_id", "task_def_id", "task_def_version", "input", "output", "created_at", "updated_at"] @field_validator('id') def id_validate_regular_expression(cls, value): @@ -101,6 +105,16 @@ def to_dict(self) -> Dict[str, Any]: for _key, _value in self.additional_properties.items(): _dict[_key] = _value + # set to None if task_def_version (nullable) is None + # and model_fields_set contains the field + if self.task_def_version is None and "task_def_version" in self.model_fields_set: + _dict['task_def_version'] = None + + # set to None if output (nullable) is None + # and model_fields_set contains the field + if self.output is None and "output" in self.model_fields_set: + _dict['output'] = None + return _dict @classmethod @@ -114,7 +128,11 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "id": obj.get("id"), + "workflow_run_id": obj.get("workflow_run_id"), "task_def_id": obj.get("task_def_id"), + "task_def_version": obj.get("task_def_version"), + "input": obj.get("input"), + "output": obj.get("output"), "created_at": obj.get("created_at"), "updated_at": obj.get("updated_at") }) diff --git a/onfido/models/task_item.py b/onfido/models/task_item.py new file mode 100644 index 0000000..5d4cf87 --- /dev/null +++ b/onfido/models/task_item.py @@ -0,0 +1,128 @@ +# coding: utf-8 + +""" + Onfido API v3.6 + + The Onfido API (v3.6) + + The version of the OpenAPI document: v3.6 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, field_validator +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class TaskItem(BaseModel): + """ + TaskItem + """ # noqa: E501 + id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="The identifier for the Task.") + task_def_id: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="The identifier for the Task Definition.") + created_at: Optional[datetime] = Field(default=None, description="The date and time when the Task was created.") + updated_at: Optional[datetime] = Field(default=None, description="The date and time when the Task was last updated.") + additional_properties: Dict[str, Any] = {} + __properties: ClassVar[List[str]] = ["id", "task_def_id", "created_at", "updated_at"] + + @field_validator('id') + def id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if value is None: + return value + + if not re.match(r"^[0-9a-z-_]+$", value): + raise ValueError(r"must validate the regular expression /^[0-9a-z-_]+$/") + return value + + @field_validator('task_def_id') + def task_def_id_validate_regular_expression(cls, value): + """Validates the regular expression""" + if value is None: + return value + + if not re.match(r"^[0-9a-z-_]+$", value): + raise ValueError(r"must validate the regular expression /^[0-9a-z-_]+$/") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of TaskItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + * Fields in `self.additional_properties` are added to the output dict. + """ + excluded_fields: Set[str] = set([ + "additional_properties", + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # puts key-value pairs in additional_properties in the top level + if self.additional_properties is not None: + for _key, _value in self.additional_properties.items(): + _dict[_key] = _value + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of TaskItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "task_def_id": obj.get("task_def_id"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at") + }) + # store additional fields in additional_properties + for _key in obj.keys(): + if _key not in cls.__properties: + _obj.additional_properties[_key] = obj.get(_key) + + return _obj + + diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 188f848..04741d1 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -1,6 +1,6 @@ import pytest -from onfido import Task, CompleteTaskBuilder, CompleteTaskBuilderData +from onfido import Task, TaskItem, CompleteTaskBuilder, CompleteTaskDataBuilder from tests.conftest import create_applicant, create_workflow_run @@ -25,7 +25,7 @@ def test_list_tasks(onfido_api, workflow_run_id): tasks = onfido_api.list_tasks(workflow_run_id) assert tasks is not None - assert isinstance(tasks[0], Task) + assert isinstance(tasks[0], TaskItem) assert len(tasks) == 2 @@ -44,7 +44,7 @@ def test_complete_task(onfido_api, workflow_run_id): profile_data_task_id = list(filter(lambda task: "profile" in task.id, tasks))[0].id complete_task_builder = CompleteTaskBuilder( - data=CompleteTaskBuilderData({"first_name": "Jane", "last_name": "Doe"}) + data=CompleteTaskDataBuilder({"first_name": "Jane", "last_name": "Doe"}) ) onfido_api.complete_task( @@ -55,7 +55,7 @@ def test_complete_task(onfido_api, workflow_run_id): task_outputs = onfido_api.find_task( workflow_run_id, profile_data_task_id - ).additional_properties.get("output") + ).output assert task_outputs["first_name"] == "Jane" assert task_outputs["last_name"] == "Doe" diff --git a/tests/test_workflow_run_outputs.py b/tests/test_workflow_run_outputs.py index e78a45d..3df13f4 100644 --- a/tests/test_workflow_run_outputs.py +++ b/tests/test_workflow_run_outputs.py @@ -3,7 +3,7 @@ from onfido import ( ApplicantBuilder, CompleteTaskBuilder, - CompleteTaskBuilderData, + CompleteTaskDataBuilder, CountryCodes, LocationBuilder, WorkflowRunBuilder, @@ -74,7 +74,7 @@ def test_profile_data_as_output(onfido_api, applicant_id, profile_data): profile_data_task_id = list(filter(lambda task: "profile" in task.id, tasks))[0].id complete_task_builder = CompleteTaskBuilder( - data=CompleteTaskBuilderData(profile_data) + data=CompleteTaskDataBuilder(profile_data) ) onfido_api.complete_task( @@ -104,7 +104,7 @@ def test_document_and_facial_similarity_report_as_output( profile_data_task_id = list(filter(lambda task: "profile" in task.id, tasks))[0].id complete_task_builder = CompleteTaskBuilder( - data=CompleteTaskBuilderData({"first_name": "Jane", "last_name": "Doe"}) + data=CompleteTaskDataBuilder({"first_name": "Jane", "last_name": "Doe"}) ) onfido_api.complete_task( workflow_run_id=workflow_run_id, @@ -118,7 +118,7 @@ def test_document_and_facial_similarity_report_as_output( )[0].id complete_document_capture_task_builder = CompleteTaskBuilder( - data=CompleteTaskBuilderData([{"id": document_id}]) + data=CompleteTaskDataBuilder([{"id": document_id}]) ) onfido_api.complete_task( workflow_run_id=workflow_run_id, @@ -131,7 +131,7 @@ def test_document_and_facial_similarity_report_as_output( filter(lambda task: "face_photo" in task.id, tasks) )[0].id complete_live_photo_capture_task_request = CompleteTaskBuilder( - data=CompleteTaskBuilderData([{"id": live_photo_id}]) + data=CompleteTaskDataBuilder([{"id": live_photo_id}]) ) onfido_api.complete_task( workflow_run_id=workflow_run_id,