From 13623120aad773dc69702bab749991aeca8ae079 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Wed, 17 Nov 2021 10:06:49 +0100 Subject: [PATCH] feat: allow union return types (#71) * feat: support union types Signed-off-by: Timo Glastra * chore: update version to 0.4.0 Signed-off-by: Timo Glastra * style: black formatting Signed-off-by: Timo Glastra --- .../api/credential_definition.py | 7 ++- aries_cloudcontroller/api/revocation.py | 12 +++-- aries_cloudcontroller/api/schema.py | 5 +- .../util/pydantic_converter.py | 24 ++++++++- generator/data/openapi.patch | 50 +++++++++++-------- generator/data/openapi.yml | 16 ++++-- setup.py | 2 +- 7 files changed, 81 insertions(+), 35 deletions(-) diff --git a/aries_cloudcontroller/api/credential_definition.py b/aries_cloudcontroller/api/credential_definition.py index 6dd22a7d..c9e3d1bb 100644 --- a/aries_cloudcontroller/api/credential_definition.py +++ b/aries_cloudcontroller/api/credential_definition.py @@ -29,6 +29,9 @@ from aries_cloudcontroller.model.credential_definitions_created_result import ( CredentialDefinitionsCreatedResult, ) +from aries_cloudcontroller.model.txn_or_credential_definition_send_result import ( + TxnOrCredentialDefinitionSendResult, +) class CredentialDefinitionApi(Consumer): @@ -72,7 +75,7 @@ async def publish_cred_def( conn_id: Optional[str] = None, create_transaction_for_endorser: Optional[bool] = None, body: Optional[CredentialDefinitionSendRequest] = None - ) -> CredentialDefinitionSendResult: + ) -> Union[CredentialDefinitionSendResult, TxnOrCredentialDefinitionSendResult]: """Sends a credential definition to the ledger""" return await self.__publish_cred_def( conn_id=conn_id, @@ -115,5 +118,5 @@ def __publish_cred_def( conn_id: Query = None, create_transaction_for_endorser: Query = None, body: Body(type=CredentialDefinitionSendRequest) = {} - ) -> CredentialDefinitionSendResult: + ) -> Union[CredentialDefinitionSendResult, TxnOrCredentialDefinitionSendResult]: """Internal uplink method for publish_cred_def""" diff --git a/aries_cloudcontroller/api/revocation.py b/aries_cloudcontroller/api/revocation.py index 2435f53e..bd75cf21 100644 --- a/aries_cloudcontroller/api/revocation.py +++ b/aries_cloudcontroller/api/revocation.py @@ -30,6 +30,10 @@ ) from aries_cloudcontroller.model.rev_regs_created import RevRegsCreated from aries_cloudcontroller.model.revoke_request import RevokeRequest +from aries_cloudcontroller.model.txn_or_publish_revocations_result import ( + TxnOrPublishRevocationsResult, +) +from aries_cloudcontroller.model.txn_or_rev_reg_result import TxnOrRevRegResult class RevocationApi(Consumer): @@ -106,7 +110,7 @@ async def publish_rev_reg_def( rev_reg_id: str, conn_id: Optional[str] = None, create_transaction_for_endorser: Optional[bool] = None - ) -> RevRegResult: + ) -> Union[RevRegResult, TxnOrRevRegResult]: """Send revocation registry definition to ledger""" return await self.__publish_rev_reg_def( rev_reg_id=rev_reg_id, @@ -134,7 +138,7 @@ async def publish_revocations( conn_id: Optional[str] = None, create_transaction_for_endorser: Optional[bool] = None, body: Optional[PublishRevocations] = None - ) -> PublishRevocations: + ) -> Union[PublishRevocations, TxnOrPublishRevocationsResult]: """Publish pending revocations to ledger""" return await self.__publish_revocations( conn_id=conn_id, @@ -233,7 +237,7 @@ def __publish_rev_reg_def( rev_reg_id: str, conn_id: Query = None, create_transaction_for_endorser: Query = None - ) -> RevRegResult: + ) -> Union[RevRegResult, TxnOrRevRegResult]: """Internal uplink method for publish_rev_reg_def""" @returns.json @@ -256,7 +260,7 @@ def __publish_revocations( conn_id: Query = None, create_transaction_for_endorser: Query = None, body: Body(type=PublishRevocations) = {} - ) -> PublishRevocations: + ) -> Union[PublishRevocations, TxnOrPublishRevocationsResult]: """Internal uplink method for publish_revocations""" @returns.json diff --git a/aries_cloudcontroller/api/schema.py b/aries_cloudcontroller/api/schema.py index f1081714..ccb3f32b 100644 --- a/aries_cloudcontroller/api/schema.py +++ b/aries_cloudcontroller/api/schema.py @@ -21,6 +21,7 @@ from aries_cloudcontroller.model.schema_send_request import SchemaSendRequest from aries_cloudcontroller.model.schema_send_result import SchemaSendResult from aries_cloudcontroller.model.schemas_created_result import SchemasCreatedResult +from aries_cloudcontroller.model.txn_or_schema_send_result import TxnOrSchemaSendResult class SchemaApi(Consumer): @@ -52,7 +53,7 @@ async def publish_schema( conn_id: Optional[str] = None, create_transaction_for_endorser: Optional[bool] = None, body: Optional[SchemaSendRequest] = None - ) -> SchemaSendResult: + ) -> Union[SchemaSendResult, TxnOrSchemaSendResult]: """Sends a schema to the ledger""" return await self.__publish_schema( conn_id=conn_id, @@ -92,7 +93,7 @@ def __publish_schema( conn_id: Query = None, create_transaction_for_endorser: Query = None, body: Body(type=SchemaSendRequest) = {} - ) -> SchemaSendResult: + ) -> Union[SchemaSendResult, TxnOrSchemaSendResult]: """Internal uplink method for publish_schema""" @returns.json diff --git a/aries_cloudcontroller/util/pydantic_converter.py b/aries_cloudcontroller/util/pydantic_converter.py index b9810f04..5f4d77d0 100644 --- a/aries_cloudcontroller/util/pydantic_converter.py +++ b/aries_cloudcontroller/util/pydantic_converter.py @@ -3,7 +3,8 @@ to deserialize and serialize values. """ -from typing import Any +from typing import Any, Union +import typing from pydantic.json import ENCODERS_BY_TYPE from uplink.converters.interfaces import Factory, Converter from uplink.utils import is_subclass @@ -66,6 +67,16 @@ def convert(self, response): except AttributeError: data = response + # workaround because uplink doesn't support Union types + # see https://github.com/prkumar/uplink/issues/233 + if typing.get_origin(self._model) is Union: + + class UnionContainer(BaseModel): + v: self._model + + data = {"v": data} + return UnionContainer.parse_obj(data).v + return self._model.parse_obj(data) @@ -97,6 +108,17 @@ def get_users(self, username) -> List[UserModel]: def _get_model(self, type_): if is_subclass(type_, BaseModel): return type_ + # workaround because uplink doesn't support Union types + # see https://github.com/prkumar/uplink/issues/233 + elif typing.get_origin(type_) is Union: + typing_args = typing.get_args(type_) + all_are_models = all( + [is_subclass(inner_type, BaseModel) for inner_type in typing_args] + ) + + if all_are_models: + return type_ + raise ValueError("Expected pydantic.BaseModel subclass or instance") def _make_converter(self, converter, type_): diff --git a/generator/data/openapi.patch b/generator/data/openapi.patch index 1b7b611b..bbf0d531 100644 --- a/generator/data/openapi.patch +++ b/generator/data/openapi.patch @@ -1,44 +1,52 @@ diff --git a/generator/data/openapi.yml b/generator/data/openapi.yml -index 81a975a..647ae7e 100644 +index 81a975a..ab4c13c 100644 --- a/generator/data/openapi.yml +++ b/generator/data/openapi.yml -@@ -705,7 +705,7 @@ paths: +@@ -705,7 +705,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/TxnOrCredentialDefinitionSendResult' -+ $ref: '#/components/schemas/CredentialDefinitionSendResult' ++ oneOf: ++ - $ref: '#/components/schemas/CredentialDefinitionSendResult' ++ - $ref: '#/components/schemas/TxnOrCredentialDefinitionSendResult' x-codegen-request-body-name: body operationId: publish_cred_def /credential-definitions/created: -@@ -3322,7 +3322,7 @@ paths: +@@ -3322,7 +3324,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/TxnOrPublishRevocationsResult' -+ $ref: '#/components/schemas/PublishRevocations' ++ oneOf: ++ - $ref: '#/components/schemas/PublishRevocations' ++ - $ref: '#/components/schemas/TxnOrPublishRevocationsResult' x-codegen-request-body-name: body operationId: publish_revocations /revocation/registries/created: -@@ -3433,7 +3433,7 @@ paths: +@@ -3433,7 +3437,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/TxnOrRevRegResult' -+ $ref: '#/components/schemas/RevRegResult' ++ oneOf: ++ - $ref: '#/components/schemas/RevRegResult' ++ - $ref: '#/components/schemas/TxnOrRevRegResult' operationId: publish_rev_reg_def /revocation/registry/{rev_reg_id}/entry: post: -@@ -3610,7 +3610,7 @@ paths: +@@ -3610,7 +3616,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/TxnOrSchemaSendResult' -+ $ref: '#/components/schemas/SchemaSendResult' ++ oneOf: ++ - $ref: '#/components/schemas/SchemaSendResult' ++ - $ref: '#/components/schemas/TxnOrSchemaSendResult' x-codegen-request-body-name: body operationId: publish_schema /schemas/created: -@@ -5045,7 +5045,8 @@ components: +@@ -5045,7 +5053,8 @@ components: description: Tag within credential definition identifier example: tag type: @@ -48,7 +56,7 @@ index 81a975a..647ae7e 100644 description: 'Signature type: CL for Camenisch-Lysyanskaya' example: CL value: -@@ -5087,6 +5088,8 @@ components: +@@ -5087,6 +5096,8 @@ components: example: default CredentialDefinitionSendResult: type: object @@ -57,7 +65,7 @@ index 81a975a..647ae7e 100644 properties: credential_definition_id: pattern: ^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$ -@@ -6111,18 +6114,14 @@ components: +@@ -6111,18 +6122,14 @@ components: type: object properties: from: @@ -76,7 +84,7 @@ index 81a975a..647ae7e 100644 example: 1640995199 IndyProofReqPredSpec: required: -@@ -6168,18 +6167,14 @@ components: +@@ -6168,18 +6175,14 @@ components: type: object properties: from: @@ -95,7 +103,7 @@ index 81a975a..647ae7e 100644 example: 1640995199 IndyProofRequest: type: object -@@ -6217,18 +6212,14 @@ components: +@@ -6217,18 +6220,14 @@ components: type: object properties: from: @@ -114,7 +122,7 @@ index 81a975a..647ae7e 100644 example: 1640995199 IndyProofRequestedProof: type: object -@@ -7394,6 +7385,8 @@ components: +@@ -7394,6 +7393,8 @@ components: example: 0 RevRegResult: type: object @@ -123,7 +131,7 @@ index 81a975a..647ae7e 100644 properties: result: $ref: '#/components/schemas/IssuerRevRegRecord' -@@ -7545,6 +7538,7 @@ components: +@@ -7545,6 +7546,7 @@ components: SchemaSendResult: required: - schema_id @@ -131,7 +139,7 @@ index 81a975a..647ae7e 100644 type: object properties: schema: -@@ -7683,10 +7677,7 @@ components: +@@ -7683,10 +7685,7 @@ components: mechanism: type: string time: @@ -142,7 +150,7 @@ index 81a975a..647ae7e 100644 example: 1640995199 TAAInfo: type: object -@@ -7831,6 +7822,7 @@ components: +@@ -7831,6 +7830,7 @@ components: example: 2021-12-31 23:59:59+00:00 TxnOrCredentialDefinitionSendResult: type: object @@ -150,7 +158,7 @@ index 81a975a..647ae7e 100644 properties: sent: $ref: '#/components/schemas/CredentialDefinitionSendResult' -@@ -7841,6 +7833,7 @@ components: +@@ -7841,6 +7841,7 @@ components: - $ref: '#/components/schemas/TransactionRecord' TxnOrPublishRevocationsResult: type: object @@ -158,7 +166,7 @@ index 81a975a..647ae7e 100644 properties: sent: $ref: '#/components/schemas/PublishRevocations' -@@ -7851,6 +7844,7 @@ components: +@@ -7851,6 +7852,7 @@ components: - $ref: '#/components/schemas/TransactionRecord' TxnOrRevRegResult: type: object @@ -166,7 +174,7 @@ index 81a975a..647ae7e 100644 properties: sent: $ref: '#/components/schemas/RevRegResult' -@@ -7861,6 +7855,7 @@ components: +@@ -7861,6 +7863,7 @@ components: - $ref: '#/components/schemas/TransactionRecord' TxnOrSchemaSendResult: type: object diff --git a/generator/data/openapi.yml b/generator/data/openapi.yml index 647ae7ea..ab4c13c8 100644 --- a/generator/data/openapi.yml +++ b/generator/data/openapi.yml @@ -705,7 +705,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/CredentialDefinitionSendResult' + oneOf: + - $ref: '#/components/schemas/CredentialDefinitionSendResult' + - $ref: '#/components/schemas/TxnOrCredentialDefinitionSendResult' x-codegen-request-body-name: body operationId: publish_cred_def /credential-definitions/created: @@ -3322,7 +3324,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/PublishRevocations' + oneOf: + - $ref: '#/components/schemas/PublishRevocations' + - $ref: '#/components/schemas/TxnOrPublishRevocationsResult' x-codegen-request-body-name: body operationId: publish_revocations /revocation/registries/created: @@ -3433,7 +3437,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/RevRegResult' + oneOf: + - $ref: '#/components/schemas/RevRegResult' + - $ref: '#/components/schemas/TxnOrRevRegResult' operationId: publish_rev_reg_def /revocation/registry/{rev_reg_id}/entry: post: @@ -3610,7 +3616,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/SchemaSendResult' + oneOf: + - $ref: '#/components/schemas/SchemaSendResult' + - $ref: '#/components/schemas/TxnOrSchemaSendResult' x-codegen-request-body-name: body operationId: publish_schema /schemas/created: diff --git a/setup.py b/setup.py index c048f08e..6056feba 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ def parse_requirements(filename: str): if __name__ == "__main__": setup( name=PACKAGE_NAME, - version="0.3.2", + version="0.4.0", description="A simple python package for controlling an aries agent through the admin-api interface", long_description=long_description, long_description_content_type="text/markdown",