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
6 changes: 3 additions & 3 deletions .github/workflows/Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ jobs:

services:
api:
image: ghcr.io/better-hpc/keystone-api
image: docker.cloudsmith.io/better-hpc/keystone/keystone-api
ports:
- 8000:8000

strategy:
fail-fast: false
matrix:
python-version: [ "3.9", "3.10", "3.11", "3.12" , "3.13" ]
python-version: ${{ fromJson(vars.PYTHON_VERSIONS) }}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [ "3.9", "3.10", "3.11", "3.12" , "3.13" ]
python-version: ${{ fromJson(vars.PYTHON_VERSIONS) }}

steps:
- name: Checkout repository
Expand Down
44 changes: 22 additions & 22 deletions keystone_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

import abc
from typing import Any, Callable, Dict, Optional, Union
from typing import Any, Callable

import httpx
from httpx import HTTPStatusError
Expand Down Expand Up @@ -74,10 +74,10 @@ def _delete_factory(self, endpoint: Endpoint) -> Callable:

@staticmethod
def _preprocess_filters(
filters: Optional[Dict[str, Any]],
search: Optional[str],
order: Optional[str]
) -> Optional[Dict[str, Any]]:
filters: dict[str, Any] | None,
search: str | None,
order: str | None
) -> dict[str, Any] | None:
"""Inject _search and _order into query parameters."""

if search is None and order is None:
Expand Down Expand Up @@ -110,7 +110,7 @@ def _handle_identity_response(response: httpx.Response) -> dict:
return response.json()

@staticmethod
def _handle_retrieve_response(response: httpx.Response) -> Optional[dict]:
def _handle_retrieve_response(response: httpx.Response) -> dict | None:
"""Handle the HTTP response for a record retrieval request.

Args:
Expand Down Expand Up @@ -218,7 +218,7 @@ def is_authenticated(self, timeout: int = httpx.USE_CLIENT_DEFAULT) -> dict:
def _create_factory(self, endpoint: Endpoint) -> Callable:
"""Factory function for data creation methods."""

def create_record(data: Optional[RequestData] = None, files: Optional[RequestFiles] = None) -> dict:
def create_record(data: RequestData | None = None, files: RequestFiles | None = None) -> dict:
"""Create a new API record.

Args:
Expand All @@ -239,12 +239,12 @@ def _retrieve_factory(self, endpoint: Endpoint) -> Callable:
"""Factory function for data retrieval methods."""

def retrieve_record(
pk: Optional[int] = None,
filters: Optional[Dict[str, Any]] = None,
search: Optional[str] = None,
order: Optional[str] = None,
pk: int | None = None,
filters: dict[str, Any] | None = None,
search: str | None = None,
order: str | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT
) -> Union[None, dict, list[dict]]:
) -> list[dict] | dict | None:
"""Retrieve one or more API records.

A single record is returned when specifying a primary key, otherwise the returned
Expand Down Expand Up @@ -274,8 +274,8 @@ def _update_factory(self, endpoint: Endpoint) -> Callable:

def update_record(
pk: int,
data: Optional[RequestData] = None,
files: Optional[RequestFiles] = None
data: RequestData | None = None,
files: RequestFiles | None = None
) -> dict:
"""Update partial values for an existing API record.

Expand Down Expand Up @@ -369,7 +369,7 @@ async def is_authenticated(self, timeout: int = httpx.USE_CLIENT_DEFAULT) -> dic
def _create_factory(self, endpoint: Endpoint) -> Callable:
"""Factory function for data creation methods."""

async def create_record(data: Optional[RequestData] = None, files: Optional[RequestFiles] = None) -> dict:
async def create_record(data: RequestData | None = None, files: RequestFiles | None = None) -> dict:
"""Create a new API record.

Args:
Expand All @@ -390,12 +390,12 @@ def _retrieve_factory(self, endpoint: Endpoint) -> Callable:
"""Factory function for data retrieval methods."""

async def retrieve_record(
pk: Optional[int] = None,
filters: Optional[Dict[str, Any]] = None,
search: Optional[str] = None,
order: Optional[str] = None,
pk: int | None = None,
filters: dict[str, Any] | None = None,
search: str | None = None,
order: str | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT
) -> Union[None, dict, list[dict]]:
) -> list[dict] | dict | None:
"""Retrieve one or more API records.

A single record is returned when specifying a primary key, otherwise the returned
Expand Down Expand Up @@ -425,8 +425,8 @@ def _update_factory(self, endpoint: Endpoint) -> Callable:

async def update_record(
pk: int,
data: Optional[RequestData] = None,
files: Optional[RequestFiles] = None
data: RequestData | None = None,
files: RequestFiles | None = None
) -> dict:
"""Update partial values for an existing API record.

Expand Down
72 changes: 36 additions & 36 deletions keystone_client/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import logging
import re
import uuid
from typing import Literal, Optional, Union
from typing import Literal
from urllib.parse import urljoin, urlparse

import httpx
Expand All @@ -38,9 +38,9 @@ def __init__(
verify_ssl: bool = True,
follow_redirects: bool = False,
max_redirects: int = 10,
timeout: Optional[int] = 15,
timeout: int | None = 15,
limits: httpx.Limits = httpx.Limits(max_connections=100, max_keepalive_connections=20),
transport: Optional[httpx.BaseTransport] = None,
transport: httpx.BaseTransport | None = None,
) -> None:
"""Initialize a new HTTP session.

Expand Down Expand Up @@ -97,7 +97,7 @@ def normalize_url(url: str) -> str:
path = re.sub(r"/{2,}", "/", parts.path).rstrip("/") + "/"
return parts._replace(path=path).geturl()

def get_application_headers(self, overrides: Union[dict, None] = None) -> dict[str, str]:
def get_application_headers(self, overrides: dict | None = None) -> dict[str, str]:
"""Return application-specific headers for the current session."""

headers = {self.CID_HEADER: self._cid}
Expand All @@ -110,7 +110,7 @@ def get_application_headers(self, overrides: Union[dict, None] = None) -> dict[s
return headers

@abc.abstractmethod
def _client_factory(self, **kwargs) -> Union[httpx.Client, httpx.AsyncClient]:
def _client_factory(self, **kwargs) -> httpx.Client | httpx.AsyncClient:
"""Create a new HTTP client instance with the provided settings."""

@abc.abstractmethod
Expand All @@ -123,10 +123,10 @@ def send_request(
method: HttpMethod,
endpoint: str,
*,
headers: Optional[dict] = None,
json: Optional[RequestContent] = None,
files: Optional[RequestFiles] = None,
params: Optional[QueryParamTypes] = None,
headers: dict | None = None,
json: RequestContent | None = None,
files: RequestFiles | None = None,
params: QueryParamTypes | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an HTTP request (sync or async depending on the implementation)."""
Expand All @@ -135,7 +135,7 @@ def send_request(
def http_get(
self,
endpoint: str,
params: Optional[QueryParamTypes] = None,
params: QueryParamTypes | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a GET request."""
Expand All @@ -144,8 +144,8 @@ def http_get(
def http_post(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a POST request."""
Expand All @@ -154,8 +154,8 @@ def http_post(
def http_patch(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a PATCH request."""
Expand All @@ -164,8 +164,8 @@ def http_patch(
def http_put(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a PUT request."""
Expand Down Expand Up @@ -206,9 +206,9 @@ def send_request(
endpoint: str,
*,
headers: dict = None,
json: Optional[RequestContent] = None,
files: Optional[RequestFiles] = None,
params: Optional[QueryParamTypes] = None,
json: RequestContent | None = None,
files: RequestFiles | None = None,
params: QueryParamTypes | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an HTTP request.
Expand Down Expand Up @@ -243,7 +243,7 @@ def send_request(
def http_get(
self,
endpoint: str,
params: Optional[QueryParamTypes] = None,
params: QueryParamTypes | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a GET request to an API endpoint.
Expand All @@ -262,8 +262,8 @@ def http_get(
def http_post(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a POST request to an API endpoint.
Expand All @@ -283,8 +283,8 @@ def http_post(
def http_patch(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a PATCH request to an API endpoint.
Expand All @@ -304,8 +304,8 @@ def http_patch(
def http_put(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send a PUT request to an API endpoint.
Expand Down Expand Up @@ -363,9 +363,9 @@ async def send_request(
endpoint: str,
*,
headers: dict = None,
json: Optional[dict] = None,
files: Optional[RequestFiles] = None,
params: Optional[QueryParamTypes] = None,
json: dict | None = None,
files: RequestFiles | None = None,
params: QueryParamTypes | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an HTTP request.
Expand Down Expand Up @@ -400,7 +400,7 @@ async def send_request(
async def http_get(
self,
endpoint: str,
params: Optional[QueryParamTypes] = None,
params: QueryParamTypes | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an asynchronous GET request to an API endpoint.
Expand All @@ -419,8 +419,8 @@ async def http_get(
async def http_post(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an asynchronous POST request to an API endpoint.
Expand All @@ -440,8 +440,8 @@ async def http_post(
async def http_patch(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an asynchronous PATCH request to an API endpoint.
Expand All @@ -461,8 +461,8 @@ async def http_patch(
async def http_put(
self,
endpoint: str,
json: Optional[RequestData] = None,
files: Optional[RequestFiles] = None,
json: RequestData | None = None,
files: RequestFiles | None = None,
timeout: int = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
"""Send an asynchronous PUT request to an API endpoint.
Expand Down
10 changes: 5 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ classifiers = [
]

[tool.poetry.dependencies]
python = "^3.9"
python = "^3.10"
httpx = "^0.28.1"

[tool.poetry.group.tests]
Expand Down
File renamed without changes.
Loading
Loading