Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Licensed under the MIT License.
# See License in the project root for license information.
# ------------------------------------
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import Generic, Optional, TypeVar
from warnings import warn

Expand All @@ -19,7 +19,7 @@ class RequestConfiguration(Generic[QueryParameters]):
Configuration for the request such as headers, query parameters, and middleware options.
"""
# Request headers
headers: HeadersCollection = HeadersCollection()
headers: HeadersCollection = field(default_factory=HeadersCollection)
# Request options
options: Optional[list[RequestOption]] = None
# Request query parameters
Expand Down
25 changes: 22 additions & 3 deletions packages/abstractions/tests/test_base_request_configuration.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import importlib
import warnings

import pytest

from kiota_abstractions.base_request_configuration import BaseRequestConfiguration
from kiota_abstractions import base_request_configuration
from kiota_abstractions.base_request_configuration import (
BaseRequestConfiguration,
RequestConfiguration,
)


def test_base_request_configuration_deprecation_warning():
Expand All @@ -9,5 +16,17 @@ def test_base_request_configuration_deprecation_warning():


def test_import_base_request_configuration_no_warning():
from kiota_abstractions.base_request_configuration import BaseRequestConfiguration, RequestConfiguration
assert len(pytest.warns()) == 0
with warnings.catch_warnings():
warnings.simplefilter("error")
importlib.reload(base_request_configuration)


def test_request_configurations_do_not_share_a_headers_collection():
first = RequestConfiguration()
second = RequestConfiguration()

first.headers.add("Prefer", "outlook.body-content-type=text")

assert first.headers is not second.headers
assert second.headers.try_get("Prefer") is False
assert RequestConfiguration().headers.count() == 0
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# See License in the project root for license information.
# ------------------------------------

from typing import Optional

from kiota_abstractions.request_option import RequestOption

import httpx
Expand All @@ -21,16 +23,16 @@ class HeadersInspectionHandler(BaseMiddleware):

def __init__(
self,
options: HeadersInspectionHandlerOption = HeadersInspectionHandlerOption(),
options: Optional[HeadersInspectionHandlerOption] = None,
Comment thread
baywet marked this conversation as resolved.
):
"""Create an instance of HeadersInspectionHandler

Args:
options (HeadersInspectionHandlerOption, optional): Default options to apply to the
handler. Defaults to HeadersInspectionHandlerOption().
handler. A new HeadersInspectionHandlerOption per handler when not provided.
"""
super().__init__()
self.options = options
self.options = options if options is not None else HeadersInspectionHandlerOption()

async def send(
self, request: httpx.Request, transport: httpx.AsyncBaseTransport
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,34 @@
# Licensed under the MIT License.
# See License in the project root for license information.
# ------------------------------------
from dataclasses import dataclass, field
from typing import ClassVar

from kiota_abstractions.headers_collection import HeadersCollection
from kiota_abstractions.request_option import RequestOption


@dataclass(eq=False)
class HeadersInspectionHandlerOption(RequestOption):
"""Config options for the HeaderInspectionHandler"""

HEADERS_INSPECTION_HANDLER_OPTION_KEY = "HeadersInspectionHandlerOption"

def __init__(
self,
inspect_request_headers: bool = True,
inspect_response_headers: bool = True,
request_headers: HeadersCollection = HeadersCollection(),
response_headers: HeadersCollection = HeadersCollection(),
) -> None:
"""Creates an instance of headers inspection handler option.

Args:
inspect_request_headers (bool, optional): whether the request headers
should be inspected. Defaults to True.
inspect_response_headers (bool, optional): whether the response headers
should be inspected. Defaults to True.
"""
self._inspect_request_headers = inspect_request_headers
self._inspect_response_headers = inspect_response_headers
self._request_headers = request_headers if request_headers else HeadersCollection()
self._response_headers = response_headers if response_headers else HeadersCollection()

@property
def inspect_request_headers(self):
"""Whether the request headers should be inspected."""
return self._inspect_request_headers

@inspect_request_headers.setter
def inspect_request_headers(self, value: bool):
self._inspect_request_headers = value

@property
def inspect_response_headers(self):
"""Whether the response headers should be inspected."""
return self._inspect_response_headers

@inspect_response_headers.setter
def inspect_response_headers(self, value: bool):
self._inspect_response_headers = value

@property
def request_headers(self):
"""Gets the request headers to for the current request."""
return self._request_headers

@request_headers.setter
def request_headers(self, value: HeadersCollection):
self._request_headers = value

@property
def response_headers(self):
"""Gets the response headers to for the current request."""
return self._response_headers

@response_headers.setter
def response_headers(self, value: HeadersCollection):
self._response_headers = value
Comment thread
baywet marked this conversation as resolved.
"""Config options for the HeadersInspectionHandler.

Args:
inspect_request_headers (bool, optional): whether the request headers
should be inspected. Defaults to True.
inspect_response_headers (bool, optional): whether the response headers
should be inspected. Defaults to True.
request_headers (HeadersCollection, optional): collection that receives the
request headers. A new one per option when not provided.
response_headers (HeadersCollection, optional): collection that receives the
response headers. A new one per option when not provided.
"""

HEADERS_INSPECTION_HANDLER_OPTION_KEY: ClassVar[str] = "HeadersInspectionHandlerOption"

inspect_request_headers: bool = True
inspect_response_headers: bool = True
request_headers: HeadersCollection = field(default_factory=HeadersCollection)
response_headers: HeadersCollection = field(default_factory=HeadersCollection)

@staticmethod
def get_key() -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,36 @@ def test_no_config():
assert isinstance(options.request_headers, HeadersCollection)


def test_options_do_not_share_header_collections():
"""
Two options built without explicit collections must not see each other's headers.
"""
first = HeadersInspectionHandlerOption()
second = HeadersInspectionHandlerOption()

first.request_headers.add('test_request', 'test_request_header')
first.response_headers.add('test_response', 'test_response_header')

assert first.request_headers is not second.request_headers
assert first.response_headers is not second.response_headers
assert second.request_headers.try_get('test_request') is False
assert second.response_headers.try_get('test_response') is False


def test_handlers_do_not_share_options():
"""
Two handlers built without explicit options must not share one option object,
or the headers one client inspects show up on, and get cleared by, another.
"""
first = HeadersInspectionHandler()
second = HeadersInspectionHandler()

first.options.request_headers.add('test_request', 'test_request_header')

assert first.options is not second.options
assert second.options.request_headers.try_get('test_request') is False


def test_custom_config():
"""
Ensures that setting is_enabled to False.
Expand Down
Loading