diff --git a/horde_sdk/generic_api/generic_clients.py b/horde_sdk/generic_api/generic_clients.py index 4a7a6d9..67b3ad5 100644 --- a/horde_sdk/generic_api/generic_clients.py +++ b/horde_sdk/generic_api/generic_clients.py @@ -4,10 +4,13 @@ import asyncio import os +import ssl from abc import ABC +from ssl import SSLContext from typing import Any, TypeVar import aiohttp +import certifi import requests from loguru import logger from pydantic import BaseModel, ValidationError @@ -32,6 +35,9 @@ GenericQueryFields, ) +_default_sslcontext = ssl.create_default_context(cafile=certifi.where()) +"""The default SSL context to use for aiohttp requests.""" + class ParsedRawRequest(BaseModel): """A helper class for passing around the data needed to make an actual web request.""" @@ -59,6 +65,7 @@ class BaseHordeAPIClient(ABC): # region Private Fields _aiohttp_session: aiohttp.ClientSession + _ssl_context: SSLContext _apikey: str | None @@ -82,6 +89,7 @@ def __init__( path_fields: type[GenericPathFields] = GenericPathFields, query_fields: type[GenericQueryFields] = GenericQueryFields, accept_types: type[GenericAcceptTypes] = GenericAcceptTypes, + ssl_context: SSLContext = _default_sslcontext, **kwargs: Any, # noqa: ANN401 ) -> None: """Initialize a new `GenericHordeAPIClient` instance. @@ -104,6 +112,11 @@ def __init__( """ self._apikey = apikey + if not isinstance(ssl_context, SSLContext): + raise TypeError("`ssl_context` must be of type `SSLContext`!") + + self._ssl_context = ssl_context + if not self._apikey: self._apikey = ANON_API_KEY @@ -445,6 +458,7 @@ async def submit_request( params=parsed_request.request_queries, json=parsed_request.request_body, allow_redirects=True, + ssl=self._ssl_context, ) as response, ): raw_response_json = await response.json() diff --git a/requirements.txt b/requirements.txt index 0cfbb28..34a5bbd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ pydantic==2.9.2 requests StrEnum loguru +certifi aiohttp aiofiles aiodns