Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/generator reduction #219

Merged
merged 17 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2024-01-31

### Added
- Added methods in request information to reduce the amount of code being generated.

## [1.1.0] - 2024-01-25

### Added
Expand Down
2 changes: 1 addition & 1 deletion kiota_abstractions/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION: str = "1.1.0"
VERSION: str = "1.2.0"
2 changes: 1 addition & 1 deletion kiota_abstractions/default_query_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


@dataclass
class GetQueryParameters:
class QueryParameters:
samwelkanda marked this conversation as resolved.
Show resolved Hide resolved
"""
Default placeholder class for query parameters.
"""
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
# See License in the project root for license information.
# ------------------------------------
from dataclasses import dataclass
from typing import Dict, List, Optional, Union
from typing import Dict, List, Optional

from .default_query_parameters import QueryParameters
from .headers_collection import HeadersCollection
from .request_option import RequestOption


@dataclass
class BaseRequestConfiguration:
class RequestConfiguration:
samwelkanda marked this conversation as resolved.
Show resolved Hide resolved
"""
Configuration for the request such as headers, query parameters, and middleware options.
"""
Expand All @@ -20,3 +21,5 @@ class BaseRequestConfiguration:

# Request options
options: Optional[List[RequestOption]] = None

query_parameters: Optional[QueryParameters] = None
44 changes: 32 additions & 12 deletions kiota_abstractions/request_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
from stduritemplate import StdUriTemplate

from ._version import VERSION
from .default_query_parameters import QueryParameters
from .headers_collection import HeadersCollection
from .method import Method
from .request_configuration import RequestConfiguration
from .request_option import RequestOption
from .serialization import Parsable, SerializationWriter

Expand All @@ -23,11 +25,6 @@
tracer = trace.get_tracer(OBSERVABILITY_TRACER_NAME, VERSION)


@dataclass
class QueryParams:
pass


class RequestInformation:
"""This class represents an abstract HTTP request"""

Expand All @@ -36,30 +33,53 @@ class RequestInformation:
CONTENT_TYPE_HEADER = "Content-Type"
REQUEST_TYPE_KEY = "com.microsoft.kiota.request.type"

def __init__(self) -> None:
def __init__(
self, method: Method, url_template: str, path_parameters: Dict[str, Any] = {}
) -> None:
"""Creates a new instance of the RequestInformation class.

Args:
method (Method): The request method.
url_template (str): The given url template.
path_parameters (Dict[str, Any], optional): Path parameters
for the request. Defaults to {}.
"""
# The uri of the request
self.__uri: Optional[Url] = None

self.__request_options: Dict[str, RequestOption] = {}

# The path parameters for the current request
self.path_parameters: Dict[str, Any] = {}
self.path_parameters: Dict[str, Any] = path_parameters

# The URL template for the request
self.url_template: Optional[str] = None
self.url_template: Optional[str] = url_template

# The HTTP Method for the request
self.http_method: Optional[Method] = None
self.http_method: Optional[Method] = method

# The query parameters for the request
self.query_parameters: Dict[str, QueryParams] = {}
self.query_parameters: Dict[str, Any] = {}

# The Request Headers
self.headers: HeadersCollection = HeadersCollection()

# The Request Body
self.content: Optional[BytesIO] = None

def configure(self, request_configuration: RequestConfiguration) -> None:
"""Configures the current request information headers, query parameters, and options
based on the request configuration provided

Args:
request_configuration (RequestConfiguration): Configuration instance to
configure the request information.
"""
if request_configuration:
self.headers.add_all(request_configuration.headers)
self.add_request_options(request_configuration.options)
self.set_query_string_parameters_from_raw_object(request_configuration.query_parameters)

@property
def url(self) -> Url:
"""Gets the URL of the request"""
Expand Down Expand Up @@ -105,7 +125,7 @@ def request_options(self) -> Dict[str, RequestOption]:
"""Gets the request options for the request."""
return self.__request_options

def add_request_options(self, options: List[RequestOption]) -> None:
def add_request_options(self, options: Optional[List[RequestOption]]) -> None:
if not options:
return
for option in options:
Expand Down Expand Up @@ -202,7 +222,7 @@ def set_stream_content(self, value: BytesIO, content_type: Optional[str] = None)
self.headers.try_add(self.CONTENT_TYPE_HEADER, content_type)
self.content = value

def set_query_string_parameters_from_raw_object(self, q: Optional[QueryParams]) -> None:
def set_query_string_parameters_from_raw_object(self, q: Optional[QueryParameters]) -> None:
if q:
for field in fields(q):
key = field.name
Expand Down
1 change: 1 addition & 0 deletions kiota_abstractions/serialization/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .additional_data_holder import AdditionalDataHolder
from .composed_type_wrapper import ComposedTypeWrapper
from .parsable import Parsable
from .parsable_factory import ParsableFactory
from .parse_node import ParseNode
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def mock_user():

@pytest.fixture
def mock_request_information():
request_info = RequestInformation()
request_info = RequestInformation(None, None)
samwelkanda marked this conversation as resolved.
Show resolved Hide resolved
request_info.url = "https://example.com"
return request_info

Expand Down
49 changes: 48 additions & 1 deletion tests/test_request_information.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import pytest
from dataclasses import dataclass
from typing import Optional

from kiota_abstractions.request_information import RequestInformation
from kiota_abstractions.headers_collection import HeadersCollection
from kiota_abstractions.request_configuration import RequestConfiguration
from kiota_abstractions.default_query_parameters import QueryParameters


def test_initialization():
"""Tests initialization of the RequestInformation objects
"""
request_info = RequestInformation()
request_info = RequestInformation(None, None)
assert request_info
assert not request_info.path_parameters
assert not request_info.query_parameters
Expand Down Expand Up @@ -83,3 +87,46 @@ def test_set_stream_content(mock_request_information):
mock_request_information.set_stream_content(b'stream')
assert mock_request_information.content == b'stream'
assert mock_request_information.headers.get("content-type") == {"application/octet-stream"}

def test_configure_empty_configuration(mock_request_information):
"""Tests configuring the request information
"""
request_config = RequestConfiguration()
mock_request_information.configure(request_config)
assert not mock_request_information.headers.get_all()
assert not mock_request_information.request_options
assert not mock_request_information.query_parameters

def test_configure_request_configuration(mock_request_information):
"""Tests configuring the request information
"""

@dataclass
class CustomParams(QueryParameters):
query1: Optional[str] = None

def get_query_parameter(self,original_name: Optional[str] = None) -> str:
"""
Maps the query parameters names to their encoded names for the URI template parsing.
param original_name: The original query parameter name in the class.
Returns: str
"""
if not original_name:
raise TypeError("original_name cannot be null.")
if original_name == "query1":
return "%24query1"

query_params = CustomParams(query1="value1")

headers = HeadersCollection()
headers.add("header1", "value1")
headers.add("header2", "value2")

request_config = RequestConfiguration(headers=headers, query_parameters=query_params)


mock_request_information.configure(request_config)
assert mock_request_information.headers.get("header1") == {"value1"}
assert mock_request_information.headers.get("header2") == {"value2"}
assert mock_request_information.query_parameters == {"%24query1": "value1"}
assert not mock_request_information.request_options
Loading