From e1a4c8e329207e320528142622a49890603c4969 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:26:19 +0300 Subject: [PATCH 01/42] Add parsable factory type --- .../serialization/parsable_factory.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 abstractions/python/kiota/abstractions/serialization/parsable_factory.py diff --git a/abstractions/python/kiota/abstractions/serialization/parsable_factory.py b/abstractions/python/kiota/abstractions/serialization/parsable_factory.py new file mode 100644 index 0000000000..af26b91758 --- /dev/null +++ b/abstractions/python/kiota/abstractions/serialization/parsable_factory.py @@ -0,0 +1,21 @@ +from typing import Optional + +from .parsable import Parsable +from .parse_node import ParseNode, U + + +class ParsableFactory(Parsable): + """Defines the factory for creating parsable objects. + """ + @staticmethod + def create(parse_node: Optional[ParseNode]) -> U: + """Create a new parsable object from the given serialized data. + + Args: + parse_node (Optional[ParseNode]): The node to parse to get the discriminator value + from the payload. + + Returns: + U: The parsable object. + """ + pass From bccd985b43ef43a799892a89e19ff0440cb9a6dc Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:27:52 +0300 Subject: [PATCH 02/42] Update parse node object methods to take factory as parameter --- .../abstractions/serialization/parse_node.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index 3080c8a427..11768711c3 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -4,17 +4,20 @@ from datetime import date, datetime, time, timedelta from enum import Enum from io import BytesIO -from typing import Callable, List, Optional, TypeVar +from typing import TYPE_CHECKING, Callable, List, Optional, TypeVar from uuid import UUID from .parsable import Parsable + T = TypeVar("T") U = TypeVar("U", bound=Parsable) K = TypeVar("K", bound=Enum) +if TYPE_CHECKING: + from .parsable_factory import ParsableFactory class ParseNode(ABC): """ @@ -124,9 +127,10 @@ def get_collection_of_primitive_values(self) -> List[T]: pass @abstractmethod - def get_collection_of_object_values(self) -> List[U]: + def get_collection_of_object_values(self, factory: ParsableFactory) -> List[U]: """Gets the collection of model object values of the node - + Args: + factory (ParsableFactory): The factory to use to create the model object. Returns: List[U]: The collection of model object values of the node """ @@ -151,9 +155,10 @@ def get_enum_value(self) -> Enum: pass @abstractmethod - def get_object_value(self, class_type: Callable[[], U]) -> U: + def get_object_value(self, factory: ParsableFactory) -> U: """Gets the model object value of the node - + Args: + factory (ParsableFactory): The factory to use to create the model object. Returns: Parsable: The model object value of the node """ From ec672d9f79964f247a446c64bf3495376319c3f9 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:29:49 +0300 Subject: [PATCH 03/42] Add method to get additional data to parsable interface --- .../kiota/abstractions/serialization/parsable.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index 7769b44166..a80e3483c7 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Callable, Dict, TypeVar +from typing import TYPE_CHECKING, Any, Callable, Dict, TypeVar -T = TypeVar('T') +T = TypeVar("T") if TYPE_CHECKING: from .parse_node import ParseNode @@ -12,6 +12,15 @@ class Parsable(ABC): """ Defines a serializable model object. """ + @abstractmethod + def get_additional_data(self) -> Dict[str, Any]: + """Gets the additional data for this object that did not belong to the properties + + Returns: + Dict[str, Any]: The additional data for this object + """ + pass + @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. From 7c049bbf67ebe423e4415fcdf3f2d1d9e00e0fbe Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:30:17 +0300 Subject: [PATCH 04/42] Update module imports --- .../python/kiota/abstractions/serialization/__init__.py | 2 +- abstractions/python/kiota/abstractions/store/__init__.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/__init__.py b/abstractions/python/kiota/abstractions/serialization/__init__.py index 017f4476bd..0f6759b89f 100644 --- a/abstractions/python/kiota/abstractions/serialization/__init__.py +++ b/abstractions/python/kiota/abstractions/serialization/__init__.py @@ -1,5 +1,5 @@ -from .additional_data_holder import AdditionalDataHolder from .parsable import Parsable +from .parsable_factory import ParsableFactory from .parse_node import ParseNode from .parse_node_factory import ParseNodeFactory from .parse_node_factory_registry import ParseNodeFactoryRegistry diff --git a/abstractions/python/kiota/abstractions/store/__init__.py b/abstractions/python/kiota/abstractions/store/__init__.py index a82c7c15ed..2d4602719a 100644 --- a/abstractions/python/kiota/abstractions/store/__init__.py +++ b/abstractions/python/kiota/abstractions/store/__init__.py @@ -1,5 +1,3 @@ -import imp - from .backed_model import BackingStore from .backing_store import BackingStore from .backing_store_factory import BackingStoreFactory From 7bc9164290a730b211120051d5528afad0258517 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:30:59 +0300 Subject: [PATCH 05/42] Update error mapping type to use parsablefactory --- .../abstractions/native_response_handler.py | 6 +-- .../kiota/abstractions/request_adapter.py | 40 ++++++++++--------- .../kiota/abstractions/response_handler.py | 6 +-- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/abstractions/python/kiota/abstractions/native_response_handler.py b/abstractions/python/kiota/abstractions/native_response_handler.py index 1492796aeb..e00d4ff2a9 100644 --- a/abstractions/python/kiota/abstractions/native_response_handler.py +++ b/abstractions/python/kiota/abstractions/native_response_handler.py @@ -1,7 +1,7 @@ from typing import Any, Callable, Dict, Optional, TypeVar, cast from .response_handler import ResponseHandler -from .serialization import Parsable +from .serialization import Parsable, ParsableFactory NativeResponseType = TypeVar("NativeResponseType") ModelType = TypeVar("ModelType") @@ -16,10 +16,10 @@ class NativeResponseHandler(ResponseHandler): # The error mappings for the response to use when deserializing failed responses bodies. # Where an error code like 401 applies specifically to that status code, a class code like # 4XX applies to all status codes within the range if a specific error code is not present. - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]] async def handle_response_async( - self, response: NativeResponseType, error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, response: NativeResponseType, error_map: Dict[str, Optional[ParsableFactory]] ) -> ModelType: self.value = response self.error_map = error_map diff --git a/abstractions/python/kiota/abstractions/request_adapter.py b/abstractions/python/kiota/abstractions/request_adapter.py index ac0b5d161a..fcffe8d19c 100644 --- a/abstractions/python/kiota/abstractions/request_adapter.py +++ b/abstractions/python/kiota/abstractions/request_adapter.py @@ -5,7 +5,7 @@ from .request_information import RequestInformation from .response_handler import ResponseHandler -from .serialization import Parsable, SerializationWriterFactory +from .serialization import Parsable, ParsableFactory, SerializationWriterFactory from .store import BackingStoreFactory ResponseType = TypeVar("ResponseType", str, int, float, bool, datetime, BytesIO) @@ -30,19 +30,18 @@ def get_serialization_writer_factory(self) -> SerializationWriterFactory: @abstractmethod async def send_async( - self, request_info: RequestInformation, type: ModelType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, request_info: RequestInformation, type: ParsableFactory, + response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in case + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: @@ -52,19 +51,21 @@ async def send_async( @abstractmethod async def send_collection_async( - self, request_info: RequestInformation, type: ModelType, + self, + request_info: RequestInformation, + type: ParsableFactory, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]], ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: @@ -74,9 +75,11 @@ async def send_collection_async( @abstractmethod async def send_collection_of_primitive_async( - self, request_info: RequestInformation, response_type: ResponseType, + self, + request_info: RequestInformation, + response_type: ResponseType, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]], ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -87,19 +90,18 @@ async def send_collection_of_primitive_async( response into. response_handler (Optional[ResponseType]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: - Optional[List[ModelType]]: he deserialized response model collection. + Optional[List[ModelType]]: The deserialized response model collection. """ pass @abstractmethod async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -110,7 +112,7 @@ async def send_primitive_async( response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: @@ -121,7 +123,7 @@ async def send_primitive_async( @abstractmethod async def send_no_response_content_async( self, request_info: RequestInformation, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]] ) -> None: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -130,7 +132,7 @@ async def send_no_response_content_async( request_info (RequestInformation):the request info to execute. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[Optional[ParsableFactory]]): the error dict to use in case of a failed request. """ pass diff --git a/abstractions/python/kiota/abstractions/response_handler.py b/abstractions/python/kiota/abstractions/response_handler.py index 4933f71be2..cbcfd6e0fb 100644 --- a/abstractions/python/kiota/abstractions/response_handler.py +++ b/abstractions/python/kiota/abstractions/response_handler.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import Callable, Dict, Optional, TypeVar -from .serialization import Parsable +from .serialization import Parsable, ParsableFactory NativeResponseType = TypeVar("NativeResponseType") ModelType = TypeVar("ModelType") @@ -12,13 +12,13 @@ class ResponseHandler(ABC): """ @abstractmethod async def handle_response_async( - self, response: NativeResponseType, error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, response: NativeResponseType, error_map: Dict[str, Optional[ParsableFactory]] ) -> ModelType: """Callback method that is invoked when a response is received. Args: response (NativeResponseType): The type of the native response object. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: From 71655f9b6693aef47fbd0c6cb5da404fb1cea50b Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 17:55:10 +0300 Subject: [PATCH 06/42] Update json parse node to take factory as parameter --- .../python/json/serialization_json/json_parse_node.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/serialization/python/json/serialization_json/json_parse_node.py b/serialization/python/json/serialization_json/json_parse_node.py index 4ffe698263..632a8551e1 100644 --- a/serialization/python/json/serialization_json/json_parse_node.py +++ b/serialization/python/json/serialization_json/json_parse_node.py @@ -9,7 +9,8 @@ from uuid import UUID from dateutil import parser -from kiota.abstractions.serialization import AdditionalDataHolder, Parsable, ParseNode + +from kiota.abstractions.serialization import AdditionalDataHolder, Parsable, ParsableFactory, ParseNode T = TypeVar("T") @@ -165,14 +166,14 @@ def func(item): return list(map(func, json.loads(self._json_node))) return list(map(func, list(self._json_node))) - def get_collection_of_object_values(self, class_type: Type[U]) -> List[U]: + def get_collection_of_object_values(self, factory: ParsableFactory) -> List[U]: """Gets the collection of type U values from the json node Returns: List[U]: The collection of model object values of the node """ return list( map( - lambda x: JsonParseNode(json.dumps(x)).get_object_value(class_type), # type: ignore + lambda x: JsonParseNode(json.dumps(x)).get_object_value(factory), # type: ignore json.loads(self._json_node) ) ) @@ -203,12 +204,12 @@ def get_enum_value(self, enum_class: K) -> Optional[K]: raise Exception(f'Invalid key: {raw_key} for enum {enum_class._name_}.') return None - def get_object_value(self, class_type: Callable[[], U]) -> U: + def get_object_value(self, factory: ParsableFactory) -> U: """Gets the model object value of the node Returns: Parsable: The model object value of the node """ - result = class_type() + result = factory.create(self) if self.on_before_assign_field_values: self.on_before_assign_field_values(result) self._assign_field_values(result) From 8b944c0d199f5bade1d223706608a192ad9f1d1d Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:32:25 +0300 Subject: [PATCH 07/42] Add factory to request adapter implementation --- .../http_requests/requests_request_adapter.py | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index cba527fb1f..d17ef7c04f 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -12,6 +12,7 @@ from kiota.abstractions.response_handler import ResponseHandler from kiota.abstractions.serialization import ( Parsable, + ParsableFactory, ParseNode, ParseNodeFactory, ParseNodeFactoryRegistry, @@ -91,18 +92,18 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str return segments[0] async def send_async( - self, request_info: RequestInformation, model_type: ModelType, + self, request_info: RequestInformation, model_type: ParsableFactory, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -122,18 +123,18 @@ async def send_async( return result async def send_collection_async( - self, request_info: RequestInformation, model_type: ModelType, + self, request_info: RequestInformation, model_type: ParsableFactory, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -155,7 +156,7 @@ async def send_collection_async( async def send_collection_of_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -165,7 +166,7 @@ async def send_collection_of_primitive_async( response into. response_handler (Optional[ResponseType]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -186,7 +187,7 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -196,7 +197,7 @@ async def send_primitive_async( response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in case + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -228,7 +229,7 @@ async def send_primitive_async( async def send_no_response_content_async( self, request_info: RequestInformation, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> None: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -236,7 +237,7 @@ async def send_no_response_content_async( request_info (RequestInformation):the request info to execute. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in case + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. """ if not request_info: @@ -274,7 +275,7 @@ async def get_root_parse_node(self, response: requests.Response) -> ParseNode: return self._parse_node_factory.get_root_parse_node(response_content_type, payload) async def throw_failed_responses( - self, response: requests.Response, error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, response: requests.Response, error_map: Dict[str, ParsableFactory] ) -> None: if response.ok: return From 722c865820022c8e1896aa6194730d0f8d04ac64 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:34:15 +0300 Subject: [PATCH 08/42] Bump abstractions, http, and serialization package versions --- abstractions/python/kiota/abstractions/_version.py | 2 +- http/python/requests/http_requests/_version.py | 2 +- serialization/python/json/serialization_json/_version.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/abstractions/python/kiota/abstractions/_version.py b/abstractions/python/kiota/abstractions/_version.py index 6bf6b2c362..8dd7053bf0 100644 --- a/abstractions/python/kiota/abstractions/_version.py +++ b/abstractions/python/kiota/abstractions/_version.py @@ -1 +1 @@ -VERSION: str = '0.3.0' +VERSION: str = '0.4.0' diff --git a/http/python/requests/http_requests/_version.py b/http/python/requests/http_requests/_version.py index 6b47c142e5..8e3d668e72 100644 --- a/http/python/requests/http_requests/_version.py +++ b/http/python/requests/http_requests/_version.py @@ -1 +1 @@ -VERSION: str = '0.1.0' +VERSION: str = '0.2.0' diff --git a/serialization/python/json/serialization_json/_version.py b/serialization/python/json/serialization_json/_version.py index 6bf6b2c362..8dd7053bf0 100644 --- a/serialization/python/json/serialization_json/_version.py +++ b/serialization/python/json/serialization_json/_version.py @@ -1 +1 @@ -VERSION: str = '0.3.0' +VERSION: str = '0.4.0' From efe695afcd4290727566c1a79d703e3d335307c4 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:54:12 +0300 Subject: [PATCH 09/42] Fix linting and format issues --- .../kiota/abstractions/serialization/__init__.py | 1 + .../abstractions/serialization/parse_node.py | 2 +- .../http_requests/requests_request_adapter.py | 16 ++++++---------- .../json/serialization_json/json_parse_node.py | 9 ++++++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/__init__.py b/abstractions/python/kiota/abstractions/serialization/__init__.py index 0f6759b89f..9dfb2175d5 100644 --- a/abstractions/python/kiota/abstractions/serialization/__init__.py +++ b/abstractions/python/kiota/abstractions/serialization/__init__.py @@ -1,3 +1,4 @@ +from .additional_data_holder import AdditionalDataHolder from .parsable import Parsable from .parsable_factory import ParsableFactory from .parse_node import ParseNode diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index 11768711c3..f5d7eef4d1 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -9,7 +9,6 @@ from .parsable import Parsable - T = TypeVar("T") U = TypeVar("U", bound=Parsable) @@ -19,6 +18,7 @@ if TYPE_CHECKING: from .parsable_factory import ParsableFactory + class ParseNode(ABC): """ Interface for a deserialization node in a parse tree. This interace provides an abstraction diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index d17ef7c04f..eff4e388e9 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -93,14 +93,13 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str async def send_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -124,14 +123,13 @@ async def send_async( async def send_collection_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -155,8 +153,7 @@ async def send_collection_async( async def send_collection_of_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -186,8 +183,7 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. diff --git a/serialization/python/json/serialization_json/json_parse_node.py b/serialization/python/json/serialization_json/json_parse_node.py index 632a8551e1..b19d263d18 100644 --- a/serialization/python/json/serialization_json/json_parse_node.py +++ b/serialization/python/json/serialization_json/json_parse_node.py @@ -9,8 +9,12 @@ from uuid import UUID from dateutil import parser - -from kiota.abstractions.serialization import AdditionalDataHolder, Parsable, ParsableFactory, ParseNode +from kiota.abstractions.serialization import ( + AdditionalDataHolder, + Parsable, + ParsableFactory, + ParseNode, +) T = TypeVar("T") @@ -272,4 +276,3 @@ def _assign_field_values(self, item: U) -> None: else: if item_additional_data: item_additional_data[snake_case_key] = val - From 8fd37d410fe387155341719c994582920c4e1329 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 17:23:05 +0300 Subject: [PATCH 10/42] Add an entty to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6a7250d7a..686fb892ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a bug with special characters in query parameters names. [#1445](https://github.com/microsoft/kiota/issues/1445) - Fixed a bug where complex types path parameters would fail to generate. - Fixed a bug where Go serialization/deserialization method would generate invalid accessor names. +- Added discriminator support in the python abstractions serialization and http packages. [#1500](https://github.com/microsoft/kiota/issues/1256) ## [0.0.22] - 2022-04-08 From 0816afbb9a9013277550884c650ed60ed40f1a7a Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Tue, 24 May 2022 10:27:45 +0300 Subject: [PATCH 11/42] Remove unnecessary get additional data method from parsable inteface --- .../python/kiota/abstractions/serialization/parsable.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index a80e3483c7..bf06f9175f 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -12,15 +12,6 @@ class Parsable(ABC): """ Defines a serializable model object. """ - @abstractmethod - def get_additional_data(self) -> Dict[str, Any]: - """Gets the additional data for this object that did not belong to the properties - - Returns: - Dict[str, Any]: The additional data for this object - """ - pass - @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. From 02ff3e1ba6a1434c59f2e48b9cfe462ff32e9d84 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Tue, 24 May 2022 17:44:38 +0300 Subject: [PATCH 12/42] Add support for no content responses --- .../kiota/abstractions/request_adapter.py | 6 ++-- .../http_requests/requests_request_adapter.py | 17 ++++++++-- .../tests/test_requests_request_adapter.py | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/abstractions/python/kiota/abstractions/request_adapter.py b/abstractions/python/kiota/abstractions/request_adapter.py index fcffe8d19c..1c661a955e 100644 --- a/abstractions/python/kiota/abstractions/request_adapter.py +++ b/abstractions/python/kiota/abstractions/request_adapter.py @@ -32,7 +32,7 @@ def get_serialization_writer_factory(self) -> SerializationWriterFactory: async def send_async( self, request_info: RequestInformation, type: ParsableFactory, response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]] - ) -> ModelType: + ) -> Optional[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. @@ -56,7 +56,7 @@ async def send_collection_async( type: ParsableFactory, response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]], - ) -> List[ModelType]: + ) -> Optional[List[ModelType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -102,7 +102,7 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]] - ) -> ResponseType: + ) -> Optional[ResponseType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index eff4e388e9..f2b543c299 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -94,7 +94,7 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str async def send_async( self, request_info: RequestInformation, model_type: ParsableFactory, response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] - ) -> ModelType: + ) -> Optional[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: @@ -117,6 +117,8 @@ async def send_async( return await response_handler.handle_response_async(response, error_map) await self.throw_failed_responses(response, error_map) + if self._should_return_none(response): + return None root_node = await self.get_root_parse_node(response) result = root_node.get_object_value(model_type) return result @@ -124,7 +126,7 @@ async def send_async( async def send_collection_async( self, request_info: RequestInformation, model_type: ParsableFactory, response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] - ) -> List[ModelType]: + ) -> Optional[List[ModelType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: @@ -147,6 +149,8 @@ async def send_collection_async( return await response_handler.handle_response_async(response, error_map) await self.throw_failed_responses(response, error_map) + if self._should_return_none(response): + return None root_node = await self.get_root_parse_node(response) result = root_node.get_collection_of_object_values(model_type) return result @@ -178,13 +182,15 @@ async def send_collection_of_primitive_async( return await response_handler.handle_response_async(response, error_map) await self.throw_failed_responses(response, error_map) + if self._should_return_none(response): + return None root_node = await self.get_root_parse_node(response) return root_node.get_collection_of_primitive_values() async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] - ) -> ResponseType: + ) -> Optional[ResponseType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. Args: @@ -208,6 +214,8 @@ async def send_primitive_async( return await response_handler.handle_response_async(response, error_map) await self.throw_failed_responses(response, error_map) + if self._should_return_none(response): + return None root_node = await self.get_root_parse_node(response) if response_type == str: return root_node.get_string_value() @@ -270,6 +278,9 @@ async def get_root_parse_node(self, response: requests.Response) -> ParseNode: return self._parse_node_factory.get_root_parse_node(response_content_type, payload) + def _should_return_none(self, response: requests.Response) -> bool: + return response.status_code == 204 + async def throw_failed_responses( self, response: requests.Response, error_map: Dict[str, ParsableFactory] ) -> None: diff --git a/http/python/requests/tests/test_requests_request_adapter.py b/http/python/requests/tests/test_requests_request_adapter.py index bcb438438c..e3bc2ead8a 100644 --- a/http/python/requests/tests/test_requests_request_adapter.py +++ b/http/python/requests/tests/test_requests_request_adapter.py @@ -197,6 +197,30 @@ def mock_primitive_response(mocker): resp = session.send(prepped) return resp +@pytest.fixture +@responses.activate +def mock_no_content_response(mocker): + responses.add( + responses.GET, + url=BASE_URL, + status=204, + match=[ + matchers.header_matcher({"Content-Type": "application/json"}, strict_match=True) + ] + ) + + session = requests.Session() + prepped = session.prepare_request( + requests.Request( + method="GET", + url=BASE_URL, + ) + ) + prepped.headers = {"Content-Type": "application/json"} + + resp = session.send(prepped) + return resp + def test_create_requests_request_adapter(auth_provider, parse_node_factory, serialization_writer_factory): request_adapter = RequestsRequestAdapter(auth_provider, parse_node_factory, serialization_writer_factory) assert request_adapter._authentication_provider is auth_provider @@ -293,3 +317,12 @@ async def test_send_primitive_async(request_adapter, request_info, mock_primitiv assert resp.headers.get("content-type") == 'application/json' final_result = await request_adapter.send_primitive_async(request_info, float, None, {}) assert final_result == 22.3 + +@pytest.mark.asyncio +@responses.activate +async def test_send_primitive_async(request_adapter, request_info, mock_no_content_response): + request_adapter.get_http_response_message = AsyncMock(return_value = mock_no_content_response) + resp = await request_adapter.get_http_response_message(request_info) + assert resp.headers.get("content-type") == 'application/json' + final_result = await request_adapter.send_primitive_async(request_info, float, None, {}) + assert final_result is None From 05e6e8bb7633359b4951245431a29d22892f2d27 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Wed, 25 May 2022 15:40:08 +0300 Subject: [PATCH 13/42] Add support for vendor specific content types --- .../serialization/parse_node_factory_registry.py | 14 +++++++++++--- .../serialization_writer_factory_registry.py | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node_factory_registry.py b/abstractions/python/kiota/abstractions/serialization/parse_node_factory_registry.py index 1bebb0a7df..f626dbe28e 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node_factory_registry.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node_factory_registry.py @@ -1,5 +1,6 @@ from __future__ import annotations +import re from io import BytesIO from typing import Dict @@ -36,9 +37,16 @@ def get_root_parse_node(self, content_type: str, content: BytesIO) -> ParseNode: if not content: raise Exception("Content cannot be null") - factory = self.CONTENT_TYPE_ASSOCIATED_FACTORIES.get(content_type) + vendor_specific_content_type = content_type.split(';')[0] + factory = self.CONTENT_TYPE_ASSOCIATED_FACTORIES.get(vendor_specific_content_type) if factory: - return factory.get_root_parse_node(content_type, content) + return factory.get_root_parse_node(vendor_specific_content_type, content) + + cleaned_content_type = re.sub(r'[^/]+\+', '', vendor_specific_content_type) + factory = self.CONTENT_TYPE_ASSOCIATED_FACTORIES.get(cleaned_content_type) + if factory: + return factory.get_root_parse_node(cleaned_content_type, content) + raise Exception( - f"Content type {content_type} does not have a factory registered to be parsed" + f"Content type {cleaned_content_type} does not have a factory registered to be parsed" ) diff --git a/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory_registry.py b/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory_registry.py index 2fd5c2e848..f2fa4e4a12 100644 --- a/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory_registry.py +++ b/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory_registry.py @@ -1,3 +1,4 @@ +import re from typing import Dict from .serialization_writer import SerializationWriter @@ -32,9 +33,16 @@ def get_serialization_writer(self, content_type: str) -> SerializationWriter: if not content_type: raise Exception("Content type cannot be null") - factory = self.CONTENT_TYPE_ASSOCIATED_FACTORIES.get(content_type) + vendor_specific_content_type = content_type.split(';')[0] + factory = self.CONTENT_TYPE_ASSOCIATED_FACTORIES.get(vendor_specific_content_type) if factory: - return factory.get_serialization_writer(content_type) + return factory.get_serialization_writer(vendor_specific_content_type) + cleaned_content_type = re.sub(r'[^/]+\+', '', vendor_specific_content_type) + + factory = self.CONTENT_TYPE_ASSOCIATED_FACTORIES.get(cleaned_content_type) + if factory: + return factory.get_serialization_writer(cleaned_content_type) raise Exception( - f"Content type {content_type} does not have a factory registered to be serialized" + f"Content type {cleaned_content_type} does not have a factory registered" + "to be serialized" ) From 42750cf8865ae13f84c406f2b888340da1ac5c79 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Wed, 25 May 2022 18:40:24 +0300 Subject: [PATCH 14/42] Simplify field deserializers --- .../python/kiota/abstractions/serialization/parsable.py | 4 ++-- .../python/json/serialization_json/json_parse_node.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index bf06f9175f..cc3a01a14a 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -13,11 +13,11 @@ class Parsable(ABC): Defines a serializable model object. """ @abstractmethod - def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: + def get_field_deserializers(self) -> Dict[str, Callable[['ParseNode'], None]]: """Gets the deserialization information for this object. Returns: - Dict[str, Callable[[T, ParseNode], None]]: The deserialization information for this + Dict[str, Callable[[ParseNode], None]]: The deserialization information for this object where each entry is a property key with its deserialization callback. """ pass diff --git a/serialization/python/json/serialization_json/json_parse_node.py b/serialization/python/json/serialization_json/json_parse_node.py index b19d263d18..1516de078a 100644 --- a/serialization/python/json/serialization_json/json_parse_node.py +++ b/serialization/python/json/serialization_json/json_parse_node.py @@ -272,7 +272,7 @@ def _assign_field_values(self, item: U) -> None: snake_case_key = re.sub(r'(? Date: Wed, 25 May 2022 18:40:52 +0300 Subject: [PATCH 15/42] Update test fixtures --- .../python/json/tests/helpers/user.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/serialization/python/json/tests/helpers/user.py b/serialization/python/json/tests/helpers/user.py index 0fc8d4b22a..3f48cb0a67 100644 --- a/serialization/python/json/tests/helpers/user.py +++ b/serialization/python/json/tests/helpers/user.py @@ -87,34 +87,34 @@ def get_additional_data(self) -> Dict[str, Any]: def set_additional_data(self, data: Dict[str, Any]) -> None: self._additional_data = data - def get_field_deserializers(self) -> Dict[str, Callable[[T, ParseNode], None]]: + def get_field_deserializers(self) -> Dict[str, Callable[[ParseNode], None]]: """Gets the deserialization information for this object. Returns: - Dict[str, Callable[[T, ParseNode], None]]: The deserialization information for this + Dict[str, Callable[[ParseNode], None]]: The deserialization information for this object where each entry is a property key with its deserialization callback. """ return { "id": - lambda o, n: o.set_id(n.get_uuid_value()), + lambda n: self.set_id(n.get_uuid_value()), "display_name": - lambda o, n: o.set_display_name(n.get_string_value()), + lambda n: self.set_display_name(n.get_string_value()), "office_location": - lambda o, n: o.set_office_location(n.get_enum_value(OfficeLocation)), + lambda n: self.set_office_location(n.get_enum_value(OfficeLocation)), "updated_at": - lambda o, n: o.set_updated_at(n.get_datetime_offset_value()), + lambda n: self.set_updated_at(n.get_datetime_offset_value()), "birthday": - lambda o, n: o.set_birthday(n.get_date_value()), + lambda n: self.set_birthday(n.get_date_value()), "business_phones": - lambda o, n: o.set_business_phones(n.get_collection_of_primitive_values()), + lambda n: self.set_business_phones(n.get_collection_of_primitive_values()), "mobile_phone": - lambda o, n: o.set_mobile_phone(n.get_string_value()), + lambda n: self.set_mobile_phone(n.get_string_value()), "is_active": - lambda o, n: o.set_is_active(n.get_boolean_value()), + lambda n: self.set_is_active(n.get_boolean_value()), "age": - lambda o, n: o.set_age(n.get_int_value()), + lambda n: self.set_age(n.get_int_value()), "gpa": - lambda o, n: o.set_gpa(n.get_float_value()) + lambda n: self.set_gpa(n.get_float_value()) } def serialize(self, writer: SerializationWriter) -> None: From 9da3dce66e2c7cc9a02e97e01bb9c4cd2edbc1f0 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Tue, 21 Jun 2022 11:06:28 +0300 Subject: [PATCH 16/42] Add support for encoding and decoding special characters in query parameters --- .../kiota/abstractions/request_information.py | 11 +++++ .../http_requests/kiota_client_factory.py | 4 +- .../http_requests/middleware/__init__.py | 1 + .../middleware/options/__init__.py | 1 + .../parameters_name_decoding_options.py | 22 +++++++++ .../parameters_name_decoding_handler.py | 45 +++++++++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 http/python/requests/http_requests/middleware/options/parameters_name_decoding_options.py create mode 100644 http/python/requests/http_requests/middleware/parameters_name_decoding_handler.py diff --git a/abstractions/python/kiota/abstractions/request_information.py b/abstractions/python/kiota/abstractions/request_information.py index 48b277e6e8..1a14bf5ef5 100644 --- a/abstractions/python/kiota/abstractions/request_information.py +++ b/abstractions/python/kiota/abstractions/request_information.py @@ -1,4 +1,5 @@ from io import BytesIO +from dataclasses import fields from typing import TYPE_CHECKING, Any, Dict, Generic, List, Optional, Tuple, TypeVar from uritemplate import URITemplate @@ -133,3 +134,13 @@ def set_stream_content(self, value: BytesIO) -> None: """ self.headers[self.CONTENT_TYPE_HEADER] = self.BINARY_CONTENT_TYPE self.content = value + + def set_query_string_parameters_from_raw_object(self, q: object) -> None: + for field in fields(q): + key = field + if hasattr(q, 'get_query_parameter'): + serialization_key = q.get_query_parameter(key) + if serialization_key: + key = serialization_key + self.query_parameters[key] = getattr(q, field.name) + \ No newline at end of file diff --git a/http/python/requests/http_requests/kiota_client_factory.py b/http/python/requests/http_requests/kiota_client_factory.py index 6ae3f520b7..67a2a4c853 100644 --- a/http/python/requests/http_requests/kiota_client_factory.py +++ b/http/python/requests/http_requests/kiota_client_factory.py @@ -2,8 +2,7 @@ import requests -from .middleware import MiddlewarePipeline, RetryHandler - +from .middleware import MiddlewarePipeline, ParametersNameDecodingHandler, RetryHandler class KiotaClientFactory: DEFAULT_CONNECTION_TIMEOUT: int = 30 @@ -35,6 +34,7 @@ def _register_default_middleware(self, session: requests.Session) -> requests.Se """ middleware_pipeline = MiddlewarePipeline() middlewares = [ + ParametersNameDecodingHandler(), RetryHandler(), ] diff --git a/http/python/requests/http_requests/middleware/__init__.py b/http/python/requests/http_requests/middleware/__init__.py index 2ca89dee50..536b81f283 100644 --- a/http/python/requests/http_requests/middleware/__init__.py +++ b/http/python/requests/http_requests/middleware/__init__.py @@ -1,2 +1,3 @@ from .middleware import MiddlewarePipeline +from .parameters_name_decoding_handler import ParametersNameDecodingHandler from .retry_handler import RetryHandler diff --git a/http/python/requests/http_requests/middleware/options/__init__.py b/http/python/requests/http_requests/middleware/options/__init__.py index d71b2d1d27..16b887d9d5 100644 --- a/http/python/requests/http_requests/middleware/options/__init__.py +++ b/http/python/requests/http_requests/middleware/options/__init__.py @@ -1 +1,2 @@ +from .parameters_name_decoding_options import ParametersNameDecodingHandlerOption from .retry_handler_option import RetryHandlerOptions diff --git a/http/python/requests/http_requests/middleware/options/parameters_name_decoding_options.py b/http/python/requests/http_requests/middleware/options/parameters_name_decoding_options.py new file mode 100644 index 0000000000..db2d17325d --- /dev/null +++ b/http/python/requests/http_requests/middleware/options/parameters_name_decoding_options.py @@ -0,0 +1,22 @@ +from typing import List +from kiota.abstractions.request_option import RequestOption + +class ParametersNameDecodingHandlerOption(RequestOption): + """The ParametersNameDecodingOptions request class + """ + + parameters_name_decoding_handler_options_key = "ParametersNameDecodingOptionKey" + + def __init__(self, enable: bool = True, characters_to_decode: List[str] = [".", "-", "~", "$"]) -> None: + """To create an instance of ParametersNameDecodingHandlerOptions + + Args: + enable (bool, optional): - Whether to decode the specified characters in the request query parameters names. + Defaults to True. + characters_to_decode (List[str], optional):- The characters to decode. Defaults to [".", "-", "~", "$"]. + """ + self.enable = enable + self.characters_to_decode = characters_to_decode + + def get_key(self) -> str: + return self.parameters_name_decoding_handler_options_key \ No newline at end of file diff --git a/http/python/requests/http_requests/middleware/parameters_name_decoding_handler.py b/http/python/requests/http_requests/middleware/parameters_name_decoding_handler.py new file mode 100644 index 0000000000..858f324cae --- /dev/null +++ b/http/python/requests/http_requests/middleware/parameters_name_decoding_handler.py @@ -0,0 +1,45 @@ +from typing import Dict +from kiota.abstractions.request_option import RequestOption +from requests import PreparedRequest, Response + +from .middleware import BaseMiddleware +from .options import ParametersNameDecodingHandlerOption + +class ParametersNameDecodingHandler(BaseMiddleware): + + def __init__(self, options: ParametersNameDecodingHandlerOption = ParametersNameDecodingHandlerOption(), **kwargs): + """Create an instance of ParametersNameDecodingHandler + + Args: + options (ParametersNameDecodingHandlerOption, optional): The parameters name decoding handler options value. + Defaults to ParametersNameDecodingHandlerOption + """ + if not options: + raise Exception("The options parameter is required.") + + self.options = options + + def send(self, request: PreparedRequest, request_options: Dict[str, RequestOption], **kwargs) -> Response: + """To execute the current middleware + + Args: + request (PreparedRequest): The prepared request object + request_options (Dict[str, RequestOption]): The request options + + Returns: + Response: The response object. + """ + current_options = self.options + options_key = ParametersNameDecodingHandlerOption.parameters_name_decoding_handler_options_key + if request_options and options_key in request_options.keys(): + current_options = request_options[options_key] + + updated_url = request.url + if current_options and current_options.enable and '%' in updated_url and current_options.characters_to_decode: + for char in current_options.characters_to_decode: + encoding = f"{ord(f'{char}:X')}" + updated_url = updated_url.replace(f'%{encoding}', char) + + request.url = updated_url + response = super().send(request, **kwargs) + return response \ No newline at end of file From ba65992b569122cc2db4502e7a06f1f7adea2c1f Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Tue, 21 Jun 2022 14:10:59 +0300 Subject: [PATCH 17/42] Request configuration revamp --- ...se_bearer_token_authentication_provider.py | 4 +- .../kiota/abstractions/request_information.py | 69 ++++++++++++------- .../http_requests/requests_request_adapter.py | 2 +- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/abstractions/python/kiota/abstractions/authentication/base_bearer_token_authentication_provider.py b/abstractions/python/kiota/abstractions/authentication/base_bearer_token_authentication_provider.py index d0bbf22754..6525f81123 100644 --- a/abstractions/python/kiota/abstractions/authentication/base_bearer_token_authentication_provider.py +++ b/abstractions/python/kiota/abstractions/authentication/base_bearer_token_authentication_provider.py @@ -20,10 +20,10 @@ async def authenticate_request(self, request: RequestInformation) -> None: """ if not request: raise Exception("Request cannot be null") - if not request.headers: + if not request.get_request_headers(): request.headers = {} if not self.AUTHORIZATION_HEADER in request.headers: token = await self.access_token_provider.get_authorization_token(request.get_url()) if token: - request.headers.update({f'{self.AUTHORIZATION_HEADER}': f'Bearer {token}'}) + request.add_request_headers({f'{self.AUTHORIZATION_HEADER}': f'Bearer {token}'}) diff --git a/abstractions/python/kiota/abstractions/request_information.py b/abstractions/python/kiota/abstractions/request_information.py index 1a14bf5ef5..ee81cccb0f 100644 --- a/abstractions/python/kiota/abstractions/request_information.py +++ b/abstractions/python/kiota/abstractions/request_information.py @@ -22,29 +22,31 @@ class RequestInformation(Generic[QueryParams]): RAW_URL_KEY = 'request-raw-url' BINARY_CONTENT_TYPE = 'application/octet-stream' CONTENT_TYPE_HEADER = 'Content-Type' + + def __init__(self) -> None: - # The uri of the request - __uri: Optional[Url] + # The uri of the request + self.__uri: Optional[Url] = None - __request_options: Dict[str, RequestOption] = {} + self.__request_options: Dict[str, RequestOption] = {} - # The path parameters for the current request - path_parameters: Dict[str, Any] = {} + # The path parameters for the current request + self.path_parameters: Dict[str, Any] = {} - # The URL template for the request - url_template: Optional[str] + # The URL template for the request + self.url_template: Optional[str] - # The HTTP Method for the request - http_method: Method + # The HTTP Method for the request + self.http_method: Method - # The query parameters for the request - query_parameters: Dict[str, QueryParams] = {} + # The query parameters for the request + self.query_parameters: Dict[str, QueryParams] = {} - # The Request Headers - headers: Dict[str, str] = {} + # The Request Headers + self.headers: Dict[str, str] = {} - # The Request Body - content: BytesIO + # The Request Body + self.content: BytesIO def get_url(self) -> Url: """ Gets the URL of the request @@ -80,6 +82,25 @@ def set_url(self, url: Url) -> None: self.query_parameters.clear() self.path_parameters.clear() + def get_request_headers(self) -> Optional[Dict]: + return self.headers + + def add_request_headers(self, headers_to_add: Optional[Dict[str, str]]) -> None: + """Adds headers to the request + """ + if headers_to_add: + for key in headers_to_add: + self.headers[key.lower()] = headers_to_add[key] + + def remove_request_headers(self, key: str) -> None: + """Removes a request header from the current request + + Args: + key (str): The key of the header to remove + """ + if key and key.lower in self.headers.keys(): + del self.headers[key.lower()] + def get_request_options(self) -> List[Tuple[str, RequestOption]]: """Gets the request options for the request. """ @@ -135,12 +156,12 @@ def set_stream_content(self, value: BytesIO) -> None: self.headers[self.CONTENT_TYPE_HEADER] = self.BINARY_CONTENT_TYPE self.content = value - def set_query_string_parameters_from_raw_object(self, q: object) -> None: - for field in fields(q): - key = field - if hasattr(q, 'get_query_parameter'): - serialization_key = q.get_query_parameter(key) - if serialization_key: - key = serialization_key - self.query_parameters[key] = getattr(q, field.name) - \ No newline at end of file + def set_query_string_parameters_from_raw_object(self, q: Optional[object]) -> None: + if q: + for field in fields(q): + key = field + if hasattr(q, 'get_query_parameter'): + serialization_key = q.get_query_parameter(key) + if serialization_key: + key = serialization_key + self.query_parameters[key] = getattr(q, field.name) diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index f2b543c299..7699106b2c 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -333,7 +333,7 @@ def get_request_from_request_information( req = requests.Request( method=str(request_info.http_method), url=request_info.get_url(), - headers=request_info.headers, + headers=request_info.get_request_headers(), data=request_info.content, params=request_info.query_parameters, ) From 601af5ac05f85b1545b37590aeb85ed137c5d43a Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:26:19 +0300 Subject: [PATCH 18/42] Add parsable factory type --- .../serialization/parsable_factory.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 abstractions/python/kiota/abstractions/serialization/parsable_factory.py diff --git a/abstractions/python/kiota/abstractions/serialization/parsable_factory.py b/abstractions/python/kiota/abstractions/serialization/parsable_factory.py new file mode 100644 index 0000000000..af26b91758 --- /dev/null +++ b/abstractions/python/kiota/abstractions/serialization/parsable_factory.py @@ -0,0 +1,21 @@ +from typing import Optional + +from .parsable import Parsable +from .parse_node import ParseNode, U + + +class ParsableFactory(Parsable): + """Defines the factory for creating parsable objects. + """ + @staticmethod + def create(parse_node: Optional[ParseNode]) -> U: + """Create a new parsable object from the given serialized data. + + Args: + parse_node (Optional[ParseNode]): The node to parse to get the discriminator value + from the payload. + + Returns: + U: The parsable object. + """ + pass From 760dbc763fadb368fa086081084752781ef5cf47 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:27:52 +0300 Subject: [PATCH 19/42] Update parse node object methods to take factory as parameter --- .../abstractions/serialization/parse_node.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index 3080c8a427..11768711c3 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -4,17 +4,20 @@ from datetime import date, datetime, time, timedelta from enum import Enum from io import BytesIO -from typing import Callable, List, Optional, TypeVar +from typing import TYPE_CHECKING, Callable, List, Optional, TypeVar from uuid import UUID from .parsable import Parsable + T = TypeVar("T") U = TypeVar("U", bound=Parsable) K = TypeVar("K", bound=Enum) +if TYPE_CHECKING: + from .parsable_factory import ParsableFactory class ParseNode(ABC): """ @@ -124,9 +127,10 @@ def get_collection_of_primitive_values(self) -> List[T]: pass @abstractmethod - def get_collection_of_object_values(self) -> List[U]: + def get_collection_of_object_values(self, factory: ParsableFactory) -> List[U]: """Gets the collection of model object values of the node - + Args: + factory (ParsableFactory): The factory to use to create the model object. Returns: List[U]: The collection of model object values of the node """ @@ -151,9 +155,10 @@ def get_enum_value(self) -> Enum: pass @abstractmethod - def get_object_value(self, class_type: Callable[[], U]) -> U: + def get_object_value(self, factory: ParsableFactory) -> U: """Gets the model object value of the node - + Args: + factory (ParsableFactory): The factory to use to create the model object. Returns: Parsable: The model object value of the node """ From 6679636260bfa55050975bff6cad7494cd579100 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:29:49 +0300 Subject: [PATCH 20/42] Add method to get additional data to parsable interface --- .../kiota/abstractions/serialization/parsable.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index 7769b44166..a80e3483c7 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Callable, Dict, TypeVar +from typing import TYPE_CHECKING, Any, Callable, Dict, TypeVar -T = TypeVar('T') +T = TypeVar("T") if TYPE_CHECKING: from .parse_node import ParseNode @@ -12,6 +12,15 @@ class Parsable(ABC): """ Defines a serializable model object. """ + @abstractmethod + def get_additional_data(self) -> Dict[str, Any]: + """Gets the additional data for this object that did not belong to the properties + + Returns: + Dict[str, Any]: The additional data for this object + """ + pass + @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. From e6ed7c09e3026266a53f04019bc527fe8473c2f1 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:30:17 +0300 Subject: [PATCH 21/42] Update module imports --- .../python/kiota/abstractions/serialization/__init__.py | 2 +- abstractions/python/kiota/abstractions/store/__init__.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/__init__.py b/abstractions/python/kiota/abstractions/serialization/__init__.py index 017f4476bd..0f6759b89f 100644 --- a/abstractions/python/kiota/abstractions/serialization/__init__.py +++ b/abstractions/python/kiota/abstractions/serialization/__init__.py @@ -1,5 +1,5 @@ -from .additional_data_holder import AdditionalDataHolder from .parsable import Parsable +from .parsable_factory import ParsableFactory from .parse_node import ParseNode from .parse_node_factory import ParseNodeFactory from .parse_node_factory_registry import ParseNodeFactoryRegistry diff --git a/abstractions/python/kiota/abstractions/store/__init__.py b/abstractions/python/kiota/abstractions/store/__init__.py index a82c7c15ed..2d4602719a 100644 --- a/abstractions/python/kiota/abstractions/store/__init__.py +++ b/abstractions/python/kiota/abstractions/store/__init__.py @@ -1,5 +1,3 @@ -import imp - from .backed_model import BackingStore from .backing_store import BackingStore from .backing_store_factory import BackingStoreFactory From 06bec695d7a87b438e2ae3e363093d9a1a0e1490 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:30:59 +0300 Subject: [PATCH 22/42] Update error mapping type to use parsablefactory --- .../abstractions/native_response_handler.py | 6 +-- .../kiota/abstractions/request_adapter.py | 40 ++++++++++--------- .../kiota/abstractions/response_handler.py | 6 +-- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/abstractions/python/kiota/abstractions/native_response_handler.py b/abstractions/python/kiota/abstractions/native_response_handler.py index 1492796aeb..e00d4ff2a9 100644 --- a/abstractions/python/kiota/abstractions/native_response_handler.py +++ b/abstractions/python/kiota/abstractions/native_response_handler.py @@ -1,7 +1,7 @@ from typing import Any, Callable, Dict, Optional, TypeVar, cast from .response_handler import ResponseHandler -from .serialization import Parsable +from .serialization import Parsable, ParsableFactory NativeResponseType = TypeVar("NativeResponseType") ModelType = TypeVar("ModelType") @@ -16,10 +16,10 @@ class NativeResponseHandler(ResponseHandler): # The error mappings for the response to use when deserializing failed responses bodies. # Where an error code like 401 applies specifically to that status code, a class code like # 4XX applies to all status codes within the range if a specific error code is not present. - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]] async def handle_response_async( - self, response: NativeResponseType, error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, response: NativeResponseType, error_map: Dict[str, Optional[ParsableFactory]] ) -> ModelType: self.value = response self.error_map = error_map diff --git a/abstractions/python/kiota/abstractions/request_adapter.py b/abstractions/python/kiota/abstractions/request_adapter.py index ac0b5d161a..fcffe8d19c 100644 --- a/abstractions/python/kiota/abstractions/request_adapter.py +++ b/abstractions/python/kiota/abstractions/request_adapter.py @@ -5,7 +5,7 @@ from .request_information import RequestInformation from .response_handler import ResponseHandler -from .serialization import Parsable, SerializationWriterFactory +from .serialization import Parsable, ParsableFactory, SerializationWriterFactory from .store import BackingStoreFactory ResponseType = TypeVar("ResponseType", str, int, float, bool, datetime, BytesIO) @@ -30,19 +30,18 @@ def get_serialization_writer_factory(self) -> SerializationWriterFactory: @abstractmethod async def send_async( - self, request_info: RequestInformation, type: ModelType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, request_info: RequestInformation, type: ParsableFactory, + response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in case + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: @@ -52,19 +51,21 @@ async def send_async( @abstractmethod async def send_collection_async( - self, request_info: RequestInformation, type: ModelType, + self, + request_info: RequestInformation, + type: ParsableFactory, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]], ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: @@ -74,9 +75,11 @@ async def send_collection_async( @abstractmethod async def send_collection_of_primitive_async( - self, request_info: RequestInformation, response_type: ResponseType, + self, + request_info: RequestInformation, + response_type: ResponseType, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]], ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -87,19 +90,18 @@ async def send_collection_of_primitive_async( response into. response_handler (Optional[ResponseType]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: - Optional[List[ModelType]]: he deserialized response model collection. + Optional[List[ModelType]]: The deserialized response model collection. """ pass @abstractmethod async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + response_handler: Optional[ResponseHandler], error_map: Dict[str, Optional[ParsableFactory]] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -110,7 +112,7 @@ async def send_primitive_async( response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: @@ -121,7 +123,7 @@ async def send_primitive_async( @abstractmethod async def send_no_response_content_async( self, request_info: RequestInformation, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, Optional[ParsableFactory]] ) -> None: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -130,7 +132,7 @@ async def send_no_response_content_async( request_info (RequestInformation):the request info to execute. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, Optional[Optional[ParsableFactory]]): the error dict to use in case of a failed request. """ pass diff --git a/abstractions/python/kiota/abstractions/response_handler.py b/abstractions/python/kiota/abstractions/response_handler.py index 4933f71be2..cbcfd6e0fb 100644 --- a/abstractions/python/kiota/abstractions/response_handler.py +++ b/abstractions/python/kiota/abstractions/response_handler.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import Callable, Dict, Optional, TypeVar -from .serialization import Parsable +from .serialization import Parsable, ParsableFactory NativeResponseType = TypeVar("NativeResponseType") ModelType = TypeVar("ModelType") @@ -12,13 +12,13 @@ class ResponseHandler(ABC): """ @abstractmethod async def handle_response_async( - self, response: NativeResponseType, error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, response: NativeResponseType, error_map: Dict[str, Optional[ParsableFactory]] ) -> ModelType: """Callback method that is invoked when a response is received. Args: response (NativeResponseType): The type of the native response object. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use + error_map (Dict[str, Optional[ParsableFactory]]): the error dict to use in case of a failed request. Returns: From 38d98644e06c2a793752556ae32ac2cecfe5ed53 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 17:55:10 +0300 Subject: [PATCH 23/42] Update json parse node to take factory as parameter --- .../python/json/serialization_json/json_parse_node.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/serialization/python/json/serialization_json/json_parse_node.py b/serialization/python/json/serialization_json/json_parse_node.py index 4ffe698263..632a8551e1 100644 --- a/serialization/python/json/serialization_json/json_parse_node.py +++ b/serialization/python/json/serialization_json/json_parse_node.py @@ -9,7 +9,8 @@ from uuid import UUID from dateutil import parser -from kiota.abstractions.serialization import AdditionalDataHolder, Parsable, ParseNode + +from kiota.abstractions.serialization import AdditionalDataHolder, Parsable, ParsableFactory, ParseNode T = TypeVar("T") @@ -165,14 +166,14 @@ def func(item): return list(map(func, json.loads(self._json_node))) return list(map(func, list(self._json_node))) - def get_collection_of_object_values(self, class_type: Type[U]) -> List[U]: + def get_collection_of_object_values(self, factory: ParsableFactory) -> List[U]: """Gets the collection of type U values from the json node Returns: List[U]: The collection of model object values of the node """ return list( map( - lambda x: JsonParseNode(json.dumps(x)).get_object_value(class_type), # type: ignore + lambda x: JsonParseNode(json.dumps(x)).get_object_value(factory), # type: ignore json.loads(self._json_node) ) ) @@ -203,12 +204,12 @@ def get_enum_value(self, enum_class: K) -> Optional[K]: raise Exception(f'Invalid key: {raw_key} for enum {enum_class._name_}.') return None - def get_object_value(self, class_type: Callable[[], U]) -> U: + def get_object_value(self, factory: ParsableFactory) -> U: """Gets the model object value of the node Returns: Parsable: The model object value of the node """ - result = class_type() + result = factory.create(self) if self.on_before_assign_field_values: self.on_before_assign_field_values(result) self._assign_field_values(result) From 074e7543a5a1a27c1a28c1ac63c1d5171aab2293 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:32:25 +0300 Subject: [PATCH 24/42] Add factory to request adapter implementation --- .../http_requests/requests_request_adapter.py | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index cba527fb1f..d17ef7c04f 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -12,6 +12,7 @@ from kiota.abstractions.response_handler import ResponseHandler from kiota.abstractions.serialization import ( Parsable, + ParsableFactory, ParseNode, ParseNodeFactory, ParseNodeFactoryRegistry, @@ -91,18 +92,18 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str return segments[0] async def send_async( - self, request_info: RequestInformation, model_type: ModelType, + self, request_info: RequestInformation, model_type: ParsableFactory, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -122,18 +123,18 @@ async def send_async( return result async def send_collection_async( - self, request_info: RequestInformation, model_type: ModelType, + self, request_info: RequestInformation, model_type: ParsableFactory, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ModelType): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -155,7 +156,7 @@ async def send_collection_async( async def send_collection_of_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -165,7 +166,7 @@ async def send_collection_of_primitive_async( response into. response_handler (Optional[ResponseType]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -186,7 +187,7 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -196,7 +197,7 @@ async def send_primitive_async( response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in case + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. Returns: @@ -228,7 +229,7 @@ async def send_primitive_async( async def send_no_response_content_async( self, request_info: RequestInformation, response_handler: Optional[ResponseHandler], - error_map: Dict[str, Optional[Callable[[], Parsable]]] + error_map: Dict[str, ParsableFactory] ) -> None: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. @@ -236,7 +237,7 @@ async def send_no_response_content_async( request_info (RequestInformation):the request info to execute. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. - error_map (Dict[str, Optional[Callable[[], Parsable]]]): the error dict to use in case + error_map (Dict[str, ParsableFactory]): the error dict to use in case of a failed request. """ if not request_info: @@ -274,7 +275,7 @@ async def get_root_parse_node(self, response: requests.Response) -> ParseNode: return self._parse_node_factory.get_root_parse_node(response_content_type, payload) async def throw_failed_responses( - self, response: requests.Response, error_map: Dict[str, Optional[Callable[[], Parsable]]] + self, response: requests.Response, error_map: Dict[str, ParsableFactory] ) -> None: if response.ok: return From e18dd3c39967b515642d3679433cce6fb7f5661b Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:34:15 +0300 Subject: [PATCH 25/42] Bump abstractions, http, and serialization package versions --- abstractions/python/kiota/abstractions/_version.py | 2 +- http/python/requests/http_requests/_version.py | 2 +- serialization/python/json/serialization_json/_version.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/abstractions/python/kiota/abstractions/_version.py b/abstractions/python/kiota/abstractions/_version.py index 6bf6b2c362..8dd7053bf0 100644 --- a/abstractions/python/kiota/abstractions/_version.py +++ b/abstractions/python/kiota/abstractions/_version.py @@ -1 +1 @@ -VERSION: str = '0.3.0' +VERSION: str = '0.4.0' diff --git a/http/python/requests/http_requests/_version.py b/http/python/requests/http_requests/_version.py index 6b47c142e5..8e3d668e72 100644 --- a/http/python/requests/http_requests/_version.py +++ b/http/python/requests/http_requests/_version.py @@ -1 +1 @@ -VERSION: str = '0.1.0' +VERSION: str = '0.2.0' diff --git a/serialization/python/json/serialization_json/_version.py b/serialization/python/json/serialization_json/_version.py index 6bf6b2c362..8dd7053bf0 100644 --- a/serialization/python/json/serialization_json/_version.py +++ b/serialization/python/json/serialization_json/_version.py @@ -1 +1 @@ -VERSION: str = '0.3.0' +VERSION: str = '0.4.0' From a7b90c83d0dfdc5ae5d062ea7f143f7277fe3313 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:54:12 +0300 Subject: [PATCH 26/42] Fix linting and format issues --- .../kiota/abstractions/serialization/__init__.py | 1 + .../abstractions/serialization/parse_node.py | 2 +- .../http_requests/requests_request_adapter.py | 16 ++++++---------- .../json/serialization_json/json_parse_node.py | 9 ++++++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/__init__.py b/abstractions/python/kiota/abstractions/serialization/__init__.py index 0f6759b89f..9dfb2175d5 100644 --- a/abstractions/python/kiota/abstractions/serialization/__init__.py +++ b/abstractions/python/kiota/abstractions/serialization/__init__.py @@ -1,3 +1,4 @@ +from .additional_data_holder import AdditionalDataHolder from .parsable import Parsable from .parsable_factory import ParsableFactory from .parse_node import ParseNode diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index 11768711c3..f5d7eef4d1 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -9,7 +9,6 @@ from .parsable import Parsable - T = TypeVar("T") U = TypeVar("U", bound=Parsable) @@ -19,6 +18,7 @@ if TYPE_CHECKING: from .parsable_factory import ParsableFactory + class ParseNode(ABC): """ Interface for a deserialization node in a parse tree. This interace provides an abstraction diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index d17ef7c04f..eff4e388e9 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -93,14 +93,13 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str async def send_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -124,14 +123,13 @@ async def send_async( async def send_collection_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -155,8 +153,7 @@ async def send_collection_async( async def send_collection_of_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -186,8 +183,7 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. diff --git a/serialization/python/json/serialization_json/json_parse_node.py b/serialization/python/json/serialization_json/json_parse_node.py index 632a8551e1..b19d263d18 100644 --- a/serialization/python/json/serialization_json/json_parse_node.py +++ b/serialization/python/json/serialization_json/json_parse_node.py @@ -9,8 +9,12 @@ from uuid import UUID from dateutil import parser - -from kiota.abstractions.serialization import AdditionalDataHolder, Parsable, ParsableFactory, ParseNode +from kiota.abstractions.serialization import ( + AdditionalDataHolder, + Parsable, + ParsableFactory, + ParseNode, +) T = TypeVar("T") @@ -272,4 +276,3 @@ def _assign_field_values(self, item: U) -> None: else: if item_additional_data: item_additional_data[snake_case_key] = val - From 231e6631b74311c5e1450e57445c18731b5d3a6a Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 17:23:05 +0300 Subject: [PATCH 27/42] Add an entty to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b64b1bbaf8..64a6529c29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -141,6 +141,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a bug with special characters in query parameters names. [#1445](https://github.com/microsoft/kiota/issues/1445) - Fixed a bug where complex types path parameters would fail to generate. - Fixed a bug where Go serialization/deserialization method would generate invalid accessor names. +- Added discriminator support in the python abstractions serialization and http packages. [#1500](https://github.com/microsoft/kiota/issues/1256) ## [0.0.22] - 2022-04-08 From 22ec2302adc39855722032f3db6e9d057d897fdc Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Tue, 24 May 2022 10:27:45 +0300 Subject: [PATCH 28/42] Remove unnecessary get additional data method from parsable inteface --- .../python/kiota/abstractions/serialization/parsable.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index a80e3483c7..bf06f9175f 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -12,15 +12,6 @@ class Parsable(ABC): """ Defines a serializable model object. """ - @abstractmethod - def get_additional_data(self) -> Dict[str, Any]: - """Gets the additional data for this object that did not belong to the properties - - Returns: - Dict[str, Any]: The additional data for this object - """ - pass - @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. From 70e0eb7a2146c5fa2d122e2ed5dc1e10cacfb80d Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Jul 2022 18:12:10 +0300 Subject: [PATCH 29/42] Update parse node object methods to take factory as parameter --- .../python/kiota/abstractions/serialization/parse_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index f5d7eef4d1..11768711c3 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -9,6 +9,7 @@ from .parsable import Parsable + T = TypeVar("T") U = TypeVar("U", bound=Parsable) @@ -18,7 +19,6 @@ if TYPE_CHECKING: from .parsable_factory import ParsableFactory - class ParseNode(ABC): """ Interface for a deserialization node in a parse tree. This interace provides an abstraction From f442b64b2e69f86d26305dfed9cf269cf37959ca Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:29:49 +0300 Subject: [PATCH 30/42] Add method to get additional data to parsable interface --- .../python/kiota/abstractions/serialization/parsable.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index bf06f9175f..a80e3483c7 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -12,6 +12,15 @@ class Parsable(ABC): """ Defines a serializable model object. """ + @abstractmethod + def get_additional_data(self) -> Dict[str, Any]: + """Gets the additional data for this object that did not belong to the properties + + Returns: + Dict[str, Any]: The additional data for this object + """ + pass + @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. From ca96fe5a53d3cb53562447e5caa9824914f5b158 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 7 Apr 2022 16:30:17 +0300 Subject: [PATCH 31/42] Update module imports --- abstractions/python/kiota/abstractions/serialization/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/abstractions/python/kiota/abstractions/serialization/__init__.py b/abstractions/python/kiota/abstractions/serialization/__init__.py index 9dfb2175d5..0f6759b89f 100644 --- a/abstractions/python/kiota/abstractions/serialization/__init__.py +++ b/abstractions/python/kiota/abstractions/serialization/__init__.py @@ -1,4 +1,3 @@ -from .additional_data_holder import AdditionalDataHolder from .parsable import Parsable from .parsable_factory import ParsableFactory from .parse_node import ParseNode From 04524eb4757c8c825cfb91507b16573cc3088206 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Jul 2022 18:18:05 +0300 Subject: [PATCH 32/42] Add factory to request adapter implementation --- .../http_requests/requests_request_adapter.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index eff4e388e9..d17ef7c04f 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -93,13 +93,14 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str async def send_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], + error_map: Dict[str, ParsableFactory] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into + type (ParsableFactory): the class of the response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -123,13 +124,14 @@ async def send_async( async def send_collection_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], + error_map: Dict[str, ParsableFactory] ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into + type (ParsableFactory): the class of the response model to deserialize the response into. response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -153,7 +155,8 @@ async def send_collection_async( async def send_collection_of_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], + error_map: Dict[str, ParsableFactory] ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -183,7 +186,8 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], + error_map: Dict[str, ParsableFactory] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. From 1cb7bb89f37ef9dd2808814297d231a6b9affacd Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Apr 2022 15:54:12 +0300 Subject: [PATCH 33/42] Fix linting and format issues --- .../kiota/abstractions/serialization/__init__.py | 1 + .../abstractions/serialization/parse_node.py | 2 +- .../http_requests/requests_request_adapter.py | 16 ++++++---------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/__init__.py b/abstractions/python/kiota/abstractions/serialization/__init__.py index 0f6759b89f..9dfb2175d5 100644 --- a/abstractions/python/kiota/abstractions/serialization/__init__.py +++ b/abstractions/python/kiota/abstractions/serialization/__init__.py @@ -1,3 +1,4 @@ +from .additional_data_holder import AdditionalDataHolder from .parsable import Parsable from .parsable_factory import ParsableFactory from .parse_node import ParseNode diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index 11768711c3..f5d7eef4d1 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -9,7 +9,6 @@ from .parsable import Parsable - T = TypeVar("T") U = TypeVar("U", bound=Parsable) @@ -19,6 +18,7 @@ if TYPE_CHECKING: from .parsable_factory import ParsableFactory + class ParseNode(ABC): """ Interface for a deserialization node in a parse tree. This interace provides an abstraction diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index d17ef7c04f..eff4e388e9 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -93,14 +93,13 @@ def get_response_content_type(self, response: requests.Response) -> Optional[str async def send_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> ModelType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -124,14 +123,13 @@ async def send_async( async def send_collection_async( self, request_info: RequestInformation, model_type: ParsableFactory, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> List[ModelType]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. Args: request_info (RequestInformation): the request info to execute. - type (ParsableFactory): the class of the response model to deserialize the response into. + type (ParsableFactory): the class of the response model to deserialize the response into response_handler (Optional[ResponseHandler]): The response handler to use for the HTTP request instead of the default handler. error_map (Dict[str, ParsableFactory]): the error dict to use in @@ -155,8 +153,7 @@ async def send_collection_async( async def send_collection_of_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> Optional[List[ResponseType]]: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized response model collection. @@ -186,8 +183,7 @@ async def send_collection_of_primitive_async( async def send_primitive_async( self, request_info: RequestInformation, response_type: ResponseType, - response_handler: Optional[ResponseHandler], - error_map: Dict[str, ParsableFactory] + response_handler: Optional[ResponseHandler], error_map: Dict[str, ParsableFactory] ) -> ResponseType: """Excutes the HTTP request specified by the given RequestInformation and returns the deserialized primitive response model. From bf4b73c5ab532b7abaa88fc5dc783f2c45d9e2d1 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Tue, 24 May 2022 10:27:45 +0300 Subject: [PATCH 34/42] Remove unnecessary get additional data method from parsable inteface --- .../python/kiota/abstractions/serialization/parsable.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index a80e3483c7..bf06f9175f 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -12,15 +12,6 @@ class Parsable(ABC): """ Defines a serializable model object. """ - @abstractmethod - def get_additional_data(self) -> Dict[str, Any]: - """Gets the additional data for this object that did not belong to the properties - - Returns: - Dict[str, Any]: The additional data for this object - """ - pass - @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. From 73cbcf26b6968dbf53b986363d90536d53aaf82e Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Jul 2022 19:25:12 +0300 Subject: [PATCH 35/42] Add required dev dependency to fix failing checks --- abstractions/python/Pipfile | 1 + 1 file changed, 1 insertion(+) diff --git a/abstractions/python/Pipfile b/abstractions/python/Pipfile index 5c79830e4f..2ac76c2b07 100644 --- a/abstractions/python/Pipfile +++ b/abstractions/python/Pipfile @@ -12,4 +12,5 @@ pylint = "==2.14.4" mypy = "==0.961" yapf = "==0.32.0" isort = "==5.10.1" +toml = "==0.10.2" From e1cc2b54f29a628d627d4654c4a78bfcb3d0fa5e Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Jul 2022 19:55:34 +0300 Subject: [PATCH 36/42] Fix lint and formatting issues --- serialization/python/json/.pylintrc | 79 +-------- serialization/python/json/Pipfile | 3 +- serialization/python/json/Pipfile.lock | 155 ++++++++++-------- .../serialization_json/json_parse_node.py | 2 +- .../json_serialization_writer.py | 2 +- 5 files changed, 90 insertions(+), 151 deletions(-) diff --git a/serialization/python/json/.pylintrc b/serialization/python/json/.pylintrc index f0fbe81f44..eace9500b6 100644 --- a/serialization/python/json/.pylintrc +++ b/serialization/python/json/.pylintrc @@ -60,15 +60,9 @@ confidence= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". -disable=print-statement, - parameter-unpacking, - unpacking-in-except, - old-raise-syntax, - backtick, - long-suffix, +disable=long-suffix, old-ne-operator, old-octal-literal, - import-star-module-level, non-ascii-bytes-literal, raw-checker-failed, bad-inline-option, @@ -78,78 +72,14 @@ disable=print-statement, useless-suppression, deprecated-pragma, use-symbolic-message-instead, - apply-builtin, - basestring-builtin, - buffer-builtin, - cmp-builtin, - coerce-builtin, - execfile-builtin, - file-builtin, - long-builtin, - raw_input-builtin, - reduce-builtin, - standarderror-builtin, - unicode-builtin, - xrange-builtin, - coerce-method, - delslice-method, - getslice-method, - setslice-method, - no-absolute-import, - old-division, - dict-iter-method, - dict-view-method, - next-method-called, - metaclass-assignment, - indexing-exception, - raising-string, - reload-builtin, - oct-method, - hex-method, - nonzero-method, - cmp-method, - input-builtin, - round-builtin, - intern-builtin, - unichr-builtin, - map-builtin-not-iterating, - zip-builtin-not-iterating, - range-builtin-not-iterating, - filter-builtin-not-iterating, - using-cmp-argument, eq-without-hash, - div-method, - idiv-method, - rdiv-method, - exception-message-attribute, - invalid-str-codec, - sys-max-int, - bad-python3-import, - deprecated-string-function, - deprecated-str-translate-call, - deprecated-itertools-function, - deprecated-types-field, - next-method-defined, - dict-items-not-iterating, - dict-keys-not-iterating, - dict-values-not-iterating, - deprecated-operator-function, - deprecated-urllib-function, - xreadlines-attribute, - deprecated-sys-function, - exception-escape, - comprehension-escape, too-few-public-methods, - no-self-use, missing-module-docstring, missing-class-docstring, missing-function-docstring, C0103, - C0330, R0801, R0904, - R0911, - R0912, # Enable the message, report, category or checker with the given id(s). You can @@ -326,13 +256,6 @@ max-line-length=100 # Maximum number of lines in a module. max-module-lines=1000 -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no diff --git a/serialization/python/json/Pipfile b/serialization/python/json/Pipfile index 1c0b304b18..1f15b80567 100644 --- a/serialization/python/json/Pipfile +++ b/serialization/python/json/Pipfile @@ -20,4 +20,5 @@ yapf = {version="0.31.0", index="pypi"} isort = {version="5.10.1", index="pypi"} pytest = {version="7.1.2", index="pypi"} pytest-cov = {version="3.0.0", index="pypi"} -types-python-dateutil = {version="*", index="pypi"} \ No newline at end of file +types-python-dateutil = {version="*", index="pypi"} +toml = "==0.10.2" \ No newline at end of file diff --git a/serialization/python/json/Pipfile.lock b/serialization/python/json/Pipfile.lock index 54b563c7bd..67f1941302 100644 --- a/serialization/python/json/Pipfile.lock +++ b/serialization/python/json/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "99dae0890bc8fe34167af3db1db4faa52b04c267c90af3463bb5618bdb5fc8e4" + "sha256": "34b964d6845f07905feaa867da35d7d6ee9f6f24cf2eb1071817d1525d44ff6e" }, "pipfile-spec": 6, "requires": {}, @@ -49,11 +49,18 @@ "develop": { "astroid": { "hashes": [ - "sha256:4f933d0bf5e408b03a6feb5d23793740c27e07340605f236496cd6ce552043d6", - "sha256:ba33a82a9a9c06a5ceed98180c5aab16e29c285b828d94696bf32d6015ea82a9" + "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b", + "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946" ], "markers": "python_full_version >= '3.6.2'", - "version": "==2.11.6" + "version": "==2.11.7" + }, + "atomicwrites": { + "hashes": [ + "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11" + ], + "markers": "sys_platform == 'win32'", + "version": "==1.4.1" }, "attrs": { "hashes": [ @@ -79,55 +86,63 @@ "markers": "python_version >= '3.6'", "version": "==2.1.0" }, + "colorama": { + "hashes": [ + "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", + "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" + ], + "markers": "sys_platform == 'win32' and sys_platform == 'win32'", + "version": "==0.4.5" + }, "coverage": { "extras": [ "toml" ], "hashes": [ - "sha256:01c5615d13f3dd3aa8543afc069e5319cfa0c7d712f6e04b920431e5c564a749", - "sha256:106c16dfe494de3193ec55cac9640dd039b66e196e4641fa8ac396181578b982", - "sha256:129cd05ba6f0d08a766d942a9ed4b29283aff7b2cccf5b7ce279d50796860bb3", - "sha256:145f296d00441ca703a659e8f3eb48ae39fb083baba2d7ce4482fb2723e050d9", - "sha256:1480ff858b4113db2718848d7b2d1b75bc79895a9c22e76a221b9d8d62496428", - "sha256:269eaa2c20a13a5bf17558d4dc91a8d078c4fa1872f25303dddcbba3a813085e", - "sha256:26dff09fb0d82693ba9e6231248641d60ba606150d02ed45110f9ec26404ed1c", - "sha256:2bd9a6fc18aab8d2e18f89b7ff91c0f34ff4d5e0ba0b33e989b3cd4194c81fd9", - "sha256:309ce4a522ed5fca432af4ebe0f32b21d6d7ccbb0f5fcc99290e71feba67c264", - "sha256:3384f2a3652cef289e38100f2d037956194a837221edd520a7ee5b42d00cc605", - "sha256:342d4aefd1c3e7f620a13f4fe563154d808b69cccef415415aece4c786665397", - "sha256:39ee53946bf009788108b4dd2894bf1349b4e0ca18c2016ffa7d26ce46b8f10d", - "sha256:4321f075095a096e70aff1d002030ee612b65a205a0a0f5b815280d5dc58100c", - "sha256:4803e7ccf93230accb928f3a68f00ffa80a88213af98ed338a57ad021ef06815", - "sha256:4ce1b258493cbf8aec43e9b50d89982346b98e9ffdfaae8ae5793bc112fb0068", - "sha256:664a47ce62fe4bef9e2d2c430306e1428ecea207ffd68649e3b942fa8ea83b0b", - "sha256:75ab269400706fab15981fd4bd5080c56bd5cc07c3bccb86aab5e1d5a88dc8f4", - "sha256:83c4e737f60c6936460c5be330d296dd5b48b3963f48634c53b3f7deb0f34ec4", - "sha256:84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3", - "sha256:84e65ef149028516c6d64461b95a8dbcfce95cfd5b9eb634320596173332ea84", - "sha256:865d69ae811a392f4d06bde506d531f6a28a00af36f5c8649684a9e5e4a85c83", - "sha256:87f4f3df85aa39da00fd3ec4b5abeb7407e82b68c7c5ad181308b0e2526da5d4", - "sha256:8c08da0bd238f2970230c2a0d28ff0e99961598cb2e810245d7fc5afcf1254e8", - "sha256:961e2fb0680b4f5ad63234e0bf55dfb90d302740ae9c7ed0120677a94a1590cb", - "sha256:9b3e07152b4563722be523e8cd0b209e0d1a373022cfbde395ebb6575bf6790d", - "sha256:a7f3049243783df2e6cc6deafc49ea123522b59f464831476d3d1448e30d72df", - "sha256:bf5601c33213d3cb19d17a796f8a14a9eaa5e87629a53979a5981e3e3ae166f6", - "sha256:cec3a0f75c8f1031825e19cd86ee787e87cf03e4fd2865c79c057092e69e3a3b", - "sha256:d42c549a8f41dc103a8004b9f0c433e2086add8a719da00e246e17cbe4056f72", - "sha256:d67d44996140af8b84284e5e7d398e589574b376fb4de8ccd28d82ad8e3bea13", - "sha256:d9c80df769f5ec05ad21ea34be7458d1dc51ff1fb4b2219e77fe24edf462d6df", - "sha256:e57816f8ffe46b1df8f12e1b348f06d164fd5219beba7d9433ba79608ef011cc", - "sha256:ee2ddcac99b2d2aec413e36d7a429ae9ebcadf912946b13ffa88e7d4c9b712d6", - "sha256:f02cbbf8119db68455b9d763f2f8737bb7db7e43720afa07d8eb1604e5c5ae28", - "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b", - "sha256:f5b66caa62922531059bc5ac04f836860412f7f88d38a476eda0a6f11d4724f4", - "sha256:f69718750eaae75efe506406c490d6fc5a6161d047206cc63ce25527e8a3adad", - "sha256:fb73e0011b8793c053bfa85e53129ba5f0250fdc0392c1591fd35d915ec75c46", - "sha256:fd180ed867e289964404051a958f7cccabdeed423f91a899829264bb7974d3d3", - "sha256:fdb6f7bd51c2d1714cea40718f6149ad9be6a2ee7d93b19e9f00934c0f2a74d9", - "sha256:ffa9297c3a453fba4717d06df579af42ab9a28022444cae7fa605af4df612d54" + "sha256:0895ea6e6f7f9939166cc835df8fa4599e2d9b759b02d1521b574e13b859ac32", + "sha256:0f211df2cba951ffcae210ee00e54921ab42e2b64e0bf2c0befc977377fb09b7", + "sha256:147605e1702d996279bb3cc3b164f408698850011210d133a2cb96a73a2f7996", + "sha256:24b04d305ea172ccb21bee5bacd559383cba2c6fcdef85b7701cf2de4188aa55", + "sha256:25b7ec944f114f70803d6529394b64f8749e93cbfac0fe6c5ea1b7e6c14e8a46", + "sha256:2b20286c2b726f94e766e86a3fddb7b7e37af5d0c635bdfa7e4399bc523563de", + "sha256:2dff52b3e7f76ada36f82124703f4953186d9029d00d6287f17c68a75e2e6039", + "sha256:2f8553878a24b00d5ab04b7a92a2af50409247ca5c4b7a2bf4eabe94ed20d3ee", + "sha256:3def6791adf580d66f025223078dc84c64696a26f174131059ce8e91452584e1", + "sha256:422fa44070b42fef9fb8dabd5af03861708cdd6deb69463adc2130b7bf81332f", + "sha256:4f89d8e03c8a3757aae65570d14033e8edf192ee9298303db15955cadcff0c63", + "sha256:5336e0352c0b12c7e72727d50ff02557005f79a0b8dcad9219c7c4940a930083", + "sha256:54d8d0e073a7f238f0666d3c7c0d37469b2aa43311e4024c925ee14f5d5a1cbe", + "sha256:5ef42e1db047ca42827a85e34abe973971c635f83aed49611b7f3ab49d0130f0", + "sha256:5f65e5d3ff2d895dab76b1faca4586b970a99b5d4b24e9aafffc0ce94a6022d6", + "sha256:6c3ccfe89c36f3e5b9837b9ee507472310164f352c9fe332120b764c9d60adbe", + "sha256:6d0b48aff8e9720bdec315d67723f0babd936a7211dc5df453ddf76f89c59933", + "sha256:6fe75dcfcb889b6800f072f2af5a331342d63d0c1b3d2bf0f7b4f6c353e8c9c0", + "sha256:79419370d6a637cb18553ecb25228893966bd7935a9120fa454e7076f13b627c", + "sha256:7bb00521ab4f99fdce2d5c05a91bddc0280f0afaee0e0a00425e28e209d4af07", + "sha256:80db4a47a199c4563d4a25919ff29c97c87569130375beca3483b41ad5f698e8", + "sha256:866ebf42b4c5dbafd64455b0a1cd5aa7b4837a894809413b930026c91e18090b", + "sha256:8af6c26ba8df6338e57bedbf916d76bdae6308e57fc8f14397f03b5da8622b4e", + "sha256:a13772c19619118903d65a91f1d5fea84be494d12fd406d06c849b00d31bf120", + "sha256:a697977157adc052284a7160569b36a8bbec09db3c3220642e6323b47cec090f", + "sha256:a9032f9b7d38bdf882ac9f66ebde3afb8145f0d4c24b2e600bc4c6304aafb87e", + "sha256:b5e28db9199dd3833cc8a07fa6cf429a01227b5d429facb56eccd765050c26cd", + "sha256:c77943ef768276b61c96a3eb854eba55633c7a3fddf0a79f82805f232326d33f", + "sha256:d230d333b0be8042ac34808ad722eabba30036232e7a6fb3e317c49f61c93386", + "sha256:d4548be38a1c810d79e097a38107b6bf2ff42151900e47d49635be69943763d8", + "sha256:d4e7ced84a11c10160c0697a6cc0b214a5d7ab21dfec1cd46e89fbf77cc66fae", + "sha256:d56f105592188ce7a797b2bd94b4a8cb2e36d5d9b0d8a1d2060ff2a71e6b9bbc", + "sha256:d714af0bdba67739598849c9f18efdcc5a0412f4993914a0ec5ce0f1e864d783", + "sha256:d774d9e97007b018a651eadc1b3970ed20237395527e22cbeb743d8e73e0563d", + "sha256:e0524adb49c716ca763dbc1d27bedce36b14f33e6b8af6dba56886476b42957c", + "sha256:e2618cb2cf5a7cc8d698306e42ebcacd02fb7ef8cfc18485c59394152c70be97", + "sha256:e36750fbbc422c1c46c9d13b937ab437138b998fe74a635ec88989afb57a3978", + "sha256:edfdabe7aa4f97ed2b9dd5dde52d2bb29cb466993bb9d612ddd10d0085a683cf", + "sha256:f22325010d8824594820d6ce84fa830838f581a7fd86a9235f0d2ed6deb61e29", + "sha256:f23876b018dfa5d3e98e96f5644b109090f16a4acb22064e0f06933663005d39", + "sha256:f7bd0ffbcd03dc39490a1f40b2669cc414fae0c4e16b77bb26806a4d0b7d1452" ], "markers": "python_version >= '3.7'", - "version": "==6.4.1" + "version": "==6.4.2" }, "dill": { "hashes": [ @@ -139,13 +154,13 @@ }, "docutils": { "hashes": [ - "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c", - "sha256:2d58a992bfba95218c0bda128b127da1dfc6c3a1bffc1ce5e309fcc2c6652745", - "sha256:318e45b581ff01158741a399fbd75cd96cf20dffd7e67f73a7d70ace2c2b6bc1", - "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06" + "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", + "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc", + "sha256:5e493091c81994fdf8b1efd177b193ad5961c1c79ba70c49ddcb7f1bff5f2d0b", + "sha256:63f739bab1f40eec651870cc81e34a1b9406d5f80797e67dd2850b2fdd00847b" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.18.1" + "markers": "python_version >= '3.7'", + "version": "==0.19" }, "flit": { "hashes": [ @@ -344,16 +359,16 @@ "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], - "markers": "python_version >= '3.7' and python_version < '4'", + "markers": "python_version >= '3.7' and python_version < '4.0'", "version": "==2.28.1" }, - "setuptools": { + "toml": { "hashes": [ - "sha256:990a4f7861b31532871ab72331e755b5f14efbe52d336ea7f6118144dd478741", - "sha256:c1848f654aea2e3526d17fc3ce6aeaa5e7e24e66e645b5be2171f3f6b4e5a178" + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '3.7'", - "version": "==62.6.0" + "index": "pypi", + "version": "==0.10.2" }, "tomli": { "hashes": [ @@ -373,11 +388,11 @@ }, "tomlkit": { "hashes": [ - "sha256:0f4050db66fd445b885778900ce4dd9aea8c90c4721141fde0d6ade893820ef1", - "sha256:71ceb10c0eefd8b8f11fe34e8a51ad07812cb1dc3de23247425fbc9ddc47b9dd" + "sha256:1c5bebdf19d5051e2e1de6cf70adfc5948d47221f097fcff7a3ffc91e953eaf5", + "sha256:61901f81ff4017951119cd0d1ed9b7af31c821d6845c8c477587bbdcd5e5854e" ], - "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==0.11.0" + "markers": "python_version >= '3.6' and python_version < '4.0'", + "version": "==0.11.1" }, "types-python-dateutil": { "hashes": [ @@ -389,19 +404,19 @@ }, "typing-extensions": { "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", + "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" ], - "markers": "python_version >= '3.7'", - "version": "==4.2.0" + "markers": "python_version < '3.10'", + "version": "==4.3.0" }, "urllib3": { "hashes": [ - "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", - "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" + "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec", + "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.9" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4.0'", + "version": "==1.26.10" }, "wrapt": { "hashes": [ diff --git a/serialization/python/json/serialization_json/json_parse_node.py b/serialization/python/json/serialization_json/json_parse_node.py index b19d263d18..c1e43f9326 100644 --- a/serialization/python/json/serialization_json/json_parse_node.py +++ b/serialization/python/json/serialization_json/json_parse_node.py @@ -143,7 +143,7 @@ def get_collection_of_primitive_values(self) -> Optional[List[T]]: List[T]: The collection of primitive values """ - def func(item): + def func(item): # pylint: disable=too-many-return-statements generic_type = type(item) current_parse_node = JsonParseNode(item) if generic_type == bool: diff --git a/serialization/python/json/serialization_json/json_serialization_writer.py b/serialization/python/json/serialization_json/json_serialization_writer.py index 7b2685dcb3..8b9a9d6235 100644 --- a/serialization/python/json/serialization_json/json_serialization_writer.py +++ b/serialization/python/json/serialization_json/json_serialization_writer.py @@ -367,7 +367,7 @@ def write_non_parsable_object_value(self, key: Optional[str], value: T) -> Optio return value.__dict__ return None - def write_any_value(self, key: Optional[str], value: Any) -> Any: + def write_any_value(self, key: Optional[str], value: Any) -> Any: # pylint: disable=too-many-return-statements,too-many-branches """Writes the specified value to the stream with an optional given key. Args: key (Optional[str]): The key to be used for the written value. May be null. From 0fc57a89fd9af0f5cace770f6db4cf4047dd8d36 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Thu, 14 Jul 2022 20:03:21 +0300 Subject: [PATCH 37/42] Fix failing abstractions checks --- abstractions/python/.pylintrc | 77 +------------------ abstractions/python/Pipfile.lock | 70 +++++++++-------- .../python/kiota/abstractions/api_error.py | 1 + .../authentication/access_token_provider.py | 1 + .../authentication/allowed_hosts_validator.py | 1 + .../anonymous_authentication_provider.py | 1 + .../authentication/authentication_provider.py | 1 + .../abstractions/native_response_wrapper.py | 1 + .../kiota/abstractions/request_option.py | 1 + .../kiota/abstractions/response_handler.py | 1 + .../serialization/additional_data_holder.py | 1 + .../abstractions/serialization/parsable.py | 1 + .../serialization/parsable_factory.py | 1 + .../abstractions/serialization/parse_node.py | 1 + .../serialization/parse_node_factory.py | 1 + .../serialization/parse_node_proxy_factory.py | 1 + .../serialization/serialization_writer.py | 1 + .../serialization_writer_factory.py | 1 + .../serialization_writer_proxy_factory.py | 1 + .../kiota/abstractions/store/backed_model.py | 1 + .../kiota/abstractions/store/backing_store.py | 1 + .../store/backing_store_factory.py | 1 + .../store/backing_store_parse_node_factory.py | 2 + ...tore_serialization_writer_proxy_factory.py | 2 + .../store/in_memory_backing_store_factory.py | 1 + 25 files changed, 65 insertions(+), 107 deletions(-) diff --git a/abstractions/python/.pylintrc b/abstractions/python/.pylintrc index d051dfd4ab..eace9500b6 100644 --- a/abstractions/python/.pylintrc +++ b/abstractions/python/.pylintrc @@ -60,15 +60,9 @@ confidence= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". -disable=print-statement, - parameter-unpacking, - unpacking-in-except, - old-raise-syntax, - backtick, - long-suffix, +disable=long-suffix, old-ne-operator, old-octal-literal, - import-star-module-level, non-ascii-bytes-literal, raw-checker-failed, bad-inline-option, @@ -78,74 +72,12 @@ disable=print-statement, useless-suppression, deprecated-pragma, use-symbolic-message-instead, - apply-builtin, - basestring-builtin, - buffer-builtin, - cmp-builtin, - coerce-builtin, - execfile-builtin, - file-builtin, - long-builtin, - raw_input-builtin, - reduce-builtin, - standarderror-builtin, - unicode-builtin, - xrange-builtin, - coerce-method, - delslice-method, - getslice-method, - setslice-method, - no-absolute-import, - old-division, - dict-iter-method, - dict-view-method, - next-method-called, - metaclass-assignment, - indexing-exception, - raising-string, - reload-builtin, - oct-method, - hex-method, - nonzero-method, - cmp-method, - input-builtin, - round-builtin, - intern-builtin, - unichr-builtin, - map-builtin-not-iterating, - zip-builtin-not-iterating, - range-builtin-not-iterating, - filter-builtin-not-iterating, - using-cmp-argument, eq-without-hash, - div-method, - idiv-method, - rdiv-method, - exception-message-attribute, - invalid-str-codec, - sys-max-int, - bad-python3-import, - deprecated-string-function, - deprecated-str-translate-call, - deprecated-itertools-function, - deprecated-types-field, - next-method-defined, - dict-items-not-iterating, - dict-keys-not-iterating, - dict-values-not-iterating, - deprecated-operator-function, - deprecated-urllib-function, - xreadlines-attribute, - deprecated-sys-function, - exception-escape, - comprehension-escape, too-few-public-methods, - no-self-use, missing-module-docstring, missing-class-docstring, missing-function-docstring, C0103, - C0330, R0801, R0904, @@ -324,13 +256,6 @@ max-line-length=100 # Maximum number of lines in a module. max-module-lines=1000 -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no diff --git a/abstractions/python/Pipfile.lock b/abstractions/python/Pipfile.lock index bfa3baf0ab..3c11fb7e6a 100644 --- a/abstractions/python/Pipfile.lock +++ b/abstractions/python/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "cd4f99429037643b5f6b04782c12a98136b746cbf528c0f48e413841f80ae2f1" + "sha256": "ed0d2cfa923bdc14822d172e925a69379cbe7d94aef3bd95f9371a5b78800952" }, "pipfile-spec": 6, "requires": {}, @@ -26,18 +26,18 @@ "develop": { "astroid": { "hashes": [ - "sha256:4f933d0bf5e408b03a6feb5d23793740c27e07340605f236496cd6ce552043d6", - "sha256:ba33a82a9a9c06a5ceed98180c5aab16e29c285b828d94696bf32d6015ea82a9" + "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b", + "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946" ], "markers": "python_full_version >= '3.6.2'", - "version": "==2.11.6" + "version": "==2.11.7" }, "certifi": { "hashes": [ "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==2022.6.15" }, "charset-normalizer": { @@ -45,9 +45,17 @@ "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==2.1.0" }, + "colorama": { + "hashes": [ + "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", + "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.5" + }, "dill": { "hashes": [ "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302", @@ -58,11 +66,11 @@ }, "docutils": { "hashes": [ - "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c", - "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06" + "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", + "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.18.1" + "markers": "python_version >= '3.7'", + "version": "==0.19" }, "flit": { "hashes": [ @@ -77,7 +85,7 @@ "sha256:14955af340c43035dbfa96b5ee47407e377ee337f69e70f73064940d27d0a44f", "sha256:e454fdbf68c7036e1c7435ec7479383f9d9a1650ca5b304feb184eba1efcdcef" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==3.7.1" }, "idna": { @@ -136,7 +144,7 @@ "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b", "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==1.7.1" }, "mccabe": { @@ -144,7 +152,7 @@ "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==0.7.0" }, "mypy": { @@ -204,16 +212,16 @@ "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], - "markers": "python_version >= '3.7' and python_version < '4'", + "markers": "python_version >= '3.7' and python_version < '4.0'", "version": "==2.28.1" }, - "setuptools": { + "toml": { "hashes": [ - "sha256:990a4f7861b31532871ab72331e755b5f14efbe52d336ea7f6118144dd478741", - "sha256:c1848f654aea2e3526d17fc3ce6aeaa5e7e24e66e645b5be2171f3f6b4e5a178" + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '3.7'", - "version": "==62.6.0" + "index": "pypi", + "version": "==0.10.2" }, "tomli": { "hashes": [ @@ -233,27 +241,27 @@ }, "tomlkit": { "hashes": [ - "sha256:0f4050db66fd445b885778900ce4dd9aea8c90c4721141fde0d6ade893820ef1", - "sha256:71ceb10c0eefd8b8f11fe34e8a51ad07812cb1dc3de23247425fbc9ddc47b9dd" + "sha256:1c5bebdf19d5051e2e1de6cf70adfc5948d47221f097fcff7a3ffc91e953eaf5", + "sha256:61901f81ff4017951119cd0d1ed9b7af31c821d6845c8c477587bbdcd5e5854e" ], - "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==0.11.0" + "markers": "python_version < '4.0' and python_full_version >= '3.6.0'", + "version": "==0.11.1" }, "typing-extensions": { "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", + "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" ], - "markers": "python_version >= '3.7'", - "version": "==4.2.0" + "markers": "python_version < '3.10'", + "version": "==4.3.0" }, "urllib3": { "hashes": [ - "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", - "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" + "sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec", + "sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.9" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4.0'", + "version": "==1.26.10" }, "wrapt": { "hashes": [ diff --git a/abstractions/python/kiota/abstractions/api_error.py b/abstractions/python/kiota/abstractions/api_error.py index cbefc53fa8..9237a5441d 100644 --- a/abstractions/python/kiota/abstractions/api_error.py +++ b/abstractions/python/kiota/abstractions/api_error.py @@ -1,3 +1,4 @@ class APIError(Exception): + def __init__(self, message: str) -> None: super().__init__(message) diff --git a/abstractions/python/kiota/abstractions/authentication/access_token_provider.py b/abstractions/python/kiota/abstractions/authentication/access_token_provider.py index 19de2d456f..16f2826882 100644 --- a/abstractions/python/kiota/abstractions/authentication/access_token_provider.py +++ b/abstractions/python/kiota/abstractions/authentication/access_token_provider.py @@ -6,6 +6,7 @@ class AccessTokenProvider(ABC): """Defines a contract for obtaining access tokens for a given url. """ + @abstractmethod async def get_authorization_token(self, uri: str) -> str: """This method is called by the BaseBearerTokenAuthenticationProvider class to get the diff --git a/abstractions/python/kiota/abstractions/authentication/allowed_hosts_validator.py b/abstractions/python/kiota/abstractions/authentication/allowed_hosts_validator.py index 0223909809..7d72fbeda0 100644 --- a/abstractions/python/kiota/abstractions/authentication/allowed_hosts_validator.py +++ b/abstractions/python/kiota/abstractions/authentication/allowed_hosts_validator.py @@ -6,6 +6,7 @@ class AllowedHostsValidator: """Maintains a list of valid hosts and allows authentication providers to check whether a host is valid before authenticating a request """ + def __init__(self, allowed_hosts: List[str]) -> None: """Creates a new AllowedHostsValidator object with provided values. diff --git a/abstractions/python/kiota/abstractions/authentication/anonymous_authentication_provider.py b/abstractions/python/kiota/abstractions/authentication/anonymous_authentication_provider.py index d63e8d9642..554cf3ebfc 100644 --- a/abstractions/python/kiota/abstractions/authentication/anonymous_authentication_provider.py +++ b/abstractions/python/kiota/abstractions/authentication/anonymous_authentication_provider.py @@ -8,6 +8,7 @@ class AnonymousAuthenticationProvider(AuthenticationProvider): Args: AuthenticationProvider (ABC): The abstract base class that this class implements """ + async def authenticate_request(self, request: RequestInformation) -> None: """Authenticates the provided request information diff --git a/abstractions/python/kiota/abstractions/authentication/authentication_provider.py b/abstractions/python/kiota/abstractions/authentication/authentication_provider.py index 86724da4a4..ee386251aa 100644 --- a/abstractions/python/kiota/abstractions/authentication/authentication_provider.py +++ b/abstractions/python/kiota/abstractions/authentication/authentication_provider.py @@ -7,6 +7,7 @@ class AuthenticationProvider(ABC): """ Base class for providing authentication information for a request. """ + @abstractmethod async def authenticate_request(self, request: RequestInformation) -> None: """Authenticates the application request diff --git a/abstractions/python/kiota/abstractions/native_response_wrapper.py b/abstractions/python/kiota/abstractions/native_response_wrapper.py index 2dd981e7aa..cca88d26e6 100644 --- a/abstractions/python/kiota/abstractions/native_response_wrapper.py +++ b/abstractions/python/kiota/abstractions/native_response_wrapper.py @@ -25,6 +25,7 @@ class NativeResponseWrapper: """This class can be used to wrap a request using the fluent API and get the native response object in return. """ + async def call_and_get_native( self, original_call: OriginalCallType, q: Optional[QueryParametersType], h: Optional[HeadersType], o: Optional[RequestOption] diff --git a/abstractions/python/kiota/abstractions/request_option.py b/abstractions/python/kiota/abstractions/request_option.py index adfc042b0e..a9e974d42b 100644 --- a/abstractions/python/kiota/abstractions/request_option.py +++ b/abstractions/python/kiota/abstractions/request_option.py @@ -4,6 +4,7 @@ class RequestOption(ABC): """Represents a request option """ + @abstractmethod def get_key(self) -> str: """Gets the option key for when adding it to a request. Must be unique diff --git a/abstractions/python/kiota/abstractions/response_handler.py b/abstractions/python/kiota/abstractions/response_handler.py index cbcfd6e0fb..c8563cb3db 100644 --- a/abstractions/python/kiota/abstractions/response_handler.py +++ b/abstractions/python/kiota/abstractions/response_handler.py @@ -10,6 +10,7 @@ class ResponseHandler(ABC): """Abstract class that defines the contract for a response handler """ + @abstractmethod async def handle_response_async( self, response: NativeResponseType, error_map: Dict[str, Optional[ParsableFactory]] diff --git a/abstractions/python/kiota/abstractions/serialization/additional_data_holder.py b/abstractions/python/kiota/abstractions/serialization/additional_data_holder.py index 27cf3eea7e..362de7eab1 100644 --- a/abstractions/python/kiota/abstractions/serialization/additional_data_holder.py +++ b/abstractions/python/kiota/abstractions/serialization/additional_data_holder.py @@ -5,6 +5,7 @@ class AdditionalDataHolder(ABC): """Defines a contract for models that can hold additional data besides the described properties. """ + @abstractmethod def get_additional_data(self) -> Dict[str, Any]: """Stores the additional data for this object that did not belong to the properties. diff --git a/abstractions/python/kiota/abstractions/serialization/parsable.py b/abstractions/python/kiota/abstractions/serialization/parsable.py index bf06f9175f..c01a03a2be 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable.py @@ -12,6 +12,7 @@ class Parsable(ABC): """ Defines a serializable model object. """ + @abstractmethod def get_field_deserializers(self) -> Dict[str, Callable[[T, 'ParseNode'], None]]: """Gets the deserialization information for this object. diff --git a/abstractions/python/kiota/abstractions/serialization/parsable_factory.py b/abstractions/python/kiota/abstractions/serialization/parsable_factory.py index af26b91758..d06a311683 100644 --- a/abstractions/python/kiota/abstractions/serialization/parsable_factory.py +++ b/abstractions/python/kiota/abstractions/serialization/parsable_factory.py @@ -7,6 +7,7 @@ class ParsableFactory(Parsable): """Defines the factory for creating parsable objects. """ + @staticmethod def create(parse_node: Optional[ParseNode]) -> U: """Create a new parsable object from the given serialized data. diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node.py b/abstractions/python/kiota/abstractions/serialization/parse_node.py index f5d7eef4d1..bd39acb3d3 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node.py @@ -24,6 +24,7 @@ class ParseNode(ABC): Interface for a deserialization node in a parse tree. This interace provides an abstraction layer over serialization formats, libraries and implementations. """ + @abstractmethod def get_string_value(self) -> str: """Gets the string value of the node diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node_factory.py b/abstractions/python/kiota/abstractions/serialization/parse_node_factory.py index 95d584d111..5f24060cab 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node_factory.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node_factory.py @@ -7,6 +7,7 @@ class ParseNodeFactory(ABC): """Defines the protocol for a factory that is used to create ParseNodes. """ + @abstractmethod def get_valid_content_type(self) -> str: """Returns the content type this factory's parse nodes can deserialize diff --git a/abstractions/python/kiota/abstractions/serialization/parse_node_proxy_factory.py b/abstractions/python/kiota/abstractions/serialization/parse_node_proxy_factory.py index 5c7ff19bec..1f34662b01 100644 --- a/abstractions/python/kiota/abstractions/serialization/parse_node_proxy_factory.py +++ b/abstractions/python/kiota/abstractions/serialization/parse_node_proxy_factory.py @@ -9,6 +9,7 @@ class ParseNodeProxyFactory(ParseNodeFactory): """Proxy factory that allows the composition of before and after callbacks on existing factories """ + def __init__( self, concrete: ParseNodeFactory, on_before: Callable[[Parsable], None], on_after: Callable[[Parsable], None] diff --git a/abstractions/python/kiota/abstractions/serialization/serialization_writer.py b/abstractions/python/kiota/abstractions/serialization/serialization_writer.py index 6e6693bca1..835da53d9e 100644 --- a/abstractions/python/kiota/abstractions/serialization/serialization_writer.py +++ b/abstractions/python/kiota/abstractions/serialization/serialization_writer.py @@ -16,6 +16,7 @@ class SerializationWriter(ABC): """Defines an interface for serialization of objects to a stream """ + @abstractmethod def write_string_value(self, key: Optional[str], value: Optional[str]) -> None: """Writes the specified string value to the stream with an optional given key. diff --git a/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory.py b/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory.py index e9e24e70b3..1b16a5aab2 100644 --- a/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory.py +++ b/abstractions/python/kiota/abstractions/serialization/serialization_writer_factory.py @@ -6,6 +6,7 @@ class SerializationWriterFactory(ABC): """Defines the contract for a factory that creates SerializationWriter instances. """ + @abstractmethod def get_valid_content_type(self) -> str: """Gets the content type this factory creates serialization writers for. diff --git a/abstractions/python/kiota/abstractions/serialization/serialization_writer_proxy_factory.py b/abstractions/python/kiota/abstractions/serialization/serialization_writer_proxy_factory.py index d60e080689..b9ee0b3f5e 100644 --- a/abstractions/python/kiota/abstractions/serialization/serialization_writer_proxy_factory.py +++ b/abstractions/python/kiota/abstractions/serialization/serialization_writer_proxy_factory.py @@ -8,6 +8,7 @@ class SerializationWriterProxyFactory(SerializationWriterFactory): """Proxy factory that allows the composition of before and after callbacks on existing factories """ + def __init__( self, concrete: SerializationWriterFactory, on_before: Optional[Callable[[Parsable], None]], on_after: Optional[Callable[[Parsable], None]], diff --git a/abstractions/python/kiota/abstractions/store/backed_model.py b/abstractions/python/kiota/abstractions/store/backed_model.py index 1afe81ecbf..68aaaa1745 100644 --- a/abstractions/python/kiota/abstractions/store/backed_model.py +++ b/abstractions/python/kiota/abstractions/store/backed_model.py @@ -6,6 +6,7 @@ class BackedModel(ABC): """Defines the contracts for a model that is backed by a store. """ + @abstractmethod def get_backing_store(self) -> BackingStore: """Gets the store that is backing the model diff --git a/abstractions/python/kiota/abstractions/store/backing_store.py b/abstractions/python/kiota/abstractions/store/backing_store.py index a1c1e8f642..f08b5983e1 100644 --- a/abstractions/python/kiota/abstractions/store/backing_store.py +++ b/abstractions/python/kiota/abstractions/store/backing_store.py @@ -9,6 +9,7 @@ class BackingStore(ABC): Implementations can provide dirty tracking capabilities, caching capabilities or integration with 3rd party stores """ + @abstractmethod def get(self, key: str) -> Optional[T]: """Gets a value from the backing store based on its key. Returns null if the value hasn't diff --git a/abstractions/python/kiota/abstractions/store/backing_store_factory.py b/abstractions/python/kiota/abstractions/store/backing_store_factory.py index 2a1e11bb1c..b23e588b3f 100644 --- a/abstractions/python/kiota/abstractions/store/backing_store_factory.py +++ b/abstractions/python/kiota/abstractions/store/backing_store_factory.py @@ -6,6 +6,7 @@ class BackingStoreFactory(ABC): """Defines the contract for a factory that creates backing stores. """ + def create_backing_store(self) -> BackingStore: """Creates a new instance of the backing store. diff --git a/abstractions/python/kiota/abstractions/store/backing_store_parse_node_factory.py b/abstractions/python/kiota/abstractions/store/backing_store_parse_node_factory.py index 27b7bc9677..3e42ae045c 100644 --- a/abstractions/python/kiota/abstractions/store/backing_store_parse_node_factory.py +++ b/abstractions/python/kiota/abstractions/store/backing_store_parse_node_factory.py @@ -8,10 +8,12 @@ class BackingStoreParseNodeFactory(ParseNodeProxyFactory): """Proxy implementation of ParseNodeFactory for the backing store that automatically sets the state of the backing store when deserializing. """ + def __init__(self, concrete: ParseNodeFactory) -> None: """ Initializes a new instance of the BackingStoreParseNodeFactory class given a concrete implementation ParseNodeFactory. """ + def func1(x): if isinstance(x, BackedModel): backed_model = x diff --git a/abstractions/python/kiota/abstractions/store/backing_store_serialization_writer_proxy_factory.py b/abstractions/python/kiota/abstractions/store/backing_store_serialization_writer_proxy_factory.py index e8e2b1e93e..57e81d7116 100644 --- a/abstractions/python/kiota/abstractions/store/backing_store_serialization_writer_proxy_factory.py +++ b/abstractions/python/kiota/abstractions/store/backing_store_serialization_writer_proxy_factory.py @@ -6,6 +6,7 @@ class BackingStoreSerializationWriterProxyFactory(SerializationWriterProxyFactor """Proxy implementation of SerializationWriterFactory for the backing store that automatically sets the state of the backing store when serializing. """ + def __init__(self, concrete: SerializationWriterFactory) -> None: """Initializes a new instance of the BackingStoreSerializationWriterProxyFactory class given a concrete implementation of SerializationWriterFactory. @@ -14,6 +15,7 @@ def __init__(self, concrete: SerializationWriterFactory) -> None: concrete (SerializationWriterFactory): a concrete implementation of SerializationWriterFactory to wrap. """ + def func1(x): if isinstance(x, BackedModel): backed_model = x diff --git a/abstractions/python/kiota/abstractions/store/in_memory_backing_store_factory.py b/abstractions/python/kiota/abstractions/store/in_memory_backing_store_factory.py index 09b1578382..b31652bd5e 100644 --- a/abstractions/python/kiota/abstractions/store/in_memory_backing_store_factory.py +++ b/abstractions/python/kiota/abstractions/store/in_memory_backing_store_factory.py @@ -6,5 +6,6 @@ class InMemoryBackingStoreFactory(BackingStoreFactory): """This class is used to create instances of InMemoryBackingStore """ + def create_backing_store(self) -> BackingStore: return InMemoryBackingStore() From 0a624d829a1b75c12d7a5c844fdbe8429c6fe9f5 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Fri, 15 Jul 2022 05:21:00 +0300 Subject: [PATCH 38/42] Remove unnecessary print statement --- http/python/requests/http_requests/requests_request_adapter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http/python/requests/http_requests/requests_request_adapter.py b/http/python/requests/http_requests/requests_request_adapter.py index f2b543c299..5e492b0a53 100644 --- a/http/python/requests/http_requests/requests_request_adapter.py +++ b/http/python/requests/http_requests/requests_request_adapter.py @@ -271,8 +271,8 @@ def enable_backing_store(self, backing_store_factory: Optional[BackingStoreFacto async def get_root_parse_node(self, response: requests.Response) -> ParseNode: payload = response.content - print(payload) response_content_type = self.get_response_content_type(response) + if not response_content_type: raise Exception("No response content type found for deserialization") From 597c137879d9995a165634a595bacc32d4c8a122 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Fri, 15 Jul 2022 05:29:49 +0300 Subject: [PATCH 39/42] Add an entry into changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64a6529c29..dfed787042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Added support for no-content responses in python abstractions and http packages. [#1630](https://github.com/microsoft/kiota/issues/1459) ### Changed From f30e874637511ba6f079473ced2a65cbfcaae755 Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Fri, 15 Jul 2022 05:46:00 +0300 Subject: [PATCH 40/42] Add an entry into changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfed787042..582646fa19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for no-content responses in python abstractions and http packages. [#1630](https://github.com/microsoft/kiota/issues/1459) +- Added support for vendor-specific content types in python. [#1631](https://github.com/microsoft/kiota/issues/1463) ### Changed From ded67d920eb9c740ad1c8fc2169b15ce269324be Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Fri, 15 Jul 2022 06:11:57 +0300 Subject: [PATCH 41/42] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 582646fa19..fe3b933635 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for no-content responses in python abstractions and http packages. [#1630](https://github.com/microsoft/kiota/issues/1459) - Added support for vendor-specific content types in python. [#1631](https://github.com/microsoft/kiota/issues/1463) +- Simplified field deserializers for json in Python. [#1632](https://github.com/microsoft/kiota/issues/1492) ### Changed From a490962228915c4640a46a731d4bb3ef8bdd0b1f Mon Sep 17 00:00:00 2001 From: samwelkanda Date: Fri, 15 Jul 2022 07:38:51 +0300 Subject: [PATCH 42/42] Fix failing checks --- .../kiota/abstractions/request_information.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/abstractions/python/kiota/abstractions/request_information.py b/abstractions/python/kiota/abstractions/request_information.py index ee81cccb0f..94b4ed4c8b 100644 --- a/abstractions/python/kiota/abstractions/request_information.py +++ b/abstractions/python/kiota/abstractions/request_information.py @@ -1,5 +1,5 @@ -from io import BytesIO from dataclasses import fields +from io import BytesIO from typing import TYPE_CHECKING, Any, Dict, Generic, List, Optional, Tuple, TypeVar from uritemplate import URITemplate @@ -13,7 +13,7 @@ Url = str T = TypeVar("T", bound=Parsable) -QueryParams = TypeVar('QueryParams', int, float, str, bool, None) +QueryParams = TypeVar('QueryParams') class RequestInformation(Generic[QueryParams]): @@ -22,7 +22,7 @@ class RequestInformation(Generic[QueryParams]): RAW_URL_KEY = 'request-raw-url' BINARY_CONTENT_TYPE = 'application/octet-stream' CONTENT_TYPE_HEADER = 'Content-Type' - + def __init__(self) -> None: # The uri of the request @@ -84,23 +84,23 @@ def set_url(self, url: Url) -> None: def get_request_headers(self) -> Optional[Dict]: return self.headers - + def add_request_headers(self, headers_to_add: Optional[Dict[str, str]]) -> None: """Adds headers to the request """ if headers_to_add: for key in headers_to_add: self.headers[key.lower()] = headers_to_add[key] - + def remove_request_headers(self, key: str) -> None: """Removes a request header from the current request Args: key (str): The key of the header to remove """ - if key and key.lower in self.headers.keys(): + if key and key.lower() in self.headers: del self.headers[key.lower()] - + def get_request_options(self) -> List[Tuple[str, RequestOption]]: """Gets the request options for the request. """ @@ -155,13 +155,13 @@ def set_stream_content(self, value: BytesIO) -> None: """ self.headers[self.CONTENT_TYPE_HEADER] = self.BINARY_CONTENT_TYPE self.content = value - - def set_query_string_parameters_from_raw_object(self, q: Optional[object]) -> None: + + def set_query_string_parameters_from_raw_object(self, q: Optional[QueryParams]) -> None: if q: for field in fields(q): - key = field + key = field.name if hasattr(q, 'get_query_parameter'): - serialization_key = q.get_query_parameter(key) + serialization_key = q.get_query_parameter(key) #type: ignore if serialization_key: key = serialization_key self.query_parameters[key] = getattr(q, field.name)