Skip to content

Commit

Permalink
refactor: configurable httpclient
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurD1 committed Jun 6, 2024
1 parent b2d6a3e commit d73c579
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 22 deletions.
7 changes: 5 additions & 2 deletions docs/apps/http_client/examples/http_client_settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ http_client:
timeout: 10.0
cache:
disabled: false
cacheable_methods: [GET]
cacheable_status_codes: [200, 300, 3001]
controller:
allow_stale: true
allow_heuristics: true
cacheable_methods: [GET]
cacheable_status_codes: [200, 301, 308]
17 changes: 15 additions & 2 deletions docs/apps/http_client/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,28 @@ Below is an example configuration for the HTTP client:


- **timeout:** Specifies the request timeout duration in seconds (default: 30 seconds).

- **cache:** Configuration for caching behavior.

- **disabled:** Boolean flag to enable or disable caching.
- **cacheable_methods:** List of HTTP methods that can be cached (e.g., GET).
- **cacheable_status_codes:** List of HTTP status codes that can be cached (e.g., 200, 300).

- **controller:** Configuration for controller settings.

- **allow_stale:** Boolean flag to allow serving stale cache data when the cache is expired (default: True).

- **allow_heuristics:** Boolean flag to allow heuristic caching (default: True).

- **cacheable_methods:** List of HTTP methods that can be cached (e.g., GET).

- **cacheable_status_codes:** List of HTTP status codes that can be cached (e.g., 200, 300).

Internal Implementation
-----------------------

The internal implementation leverages the following classes:

- :class:`ControllerSettings <harp_apps.http_client.settings.ControllerSettings>`

- :class:`CacheSettings <harp_apps.http_client.settings.CacheSettings>`

- :class:`HttpClientSettings <harp_apps.http_client.settings.HttpClientSettings>`
22 changes: 9 additions & 13 deletions harp_apps/http_client/__app__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from hishel import HEURISTICALLY_CACHEABLE_STATUS_CODES, AsyncCacheTransport, Controller
from hishel import AsyncCacheTransport, Controller
from httpx import AsyncClient, AsyncHTTPTransport

from harp import get_logger
from harp.config import Application
from harp.config.events import FactoryBindEvent
from harp.settings import DEFAULT_TIMEOUT

from .settings import HttpClientSettings

Expand All @@ -16,18 +15,16 @@ class AsyncHttpClient(AsyncClient):

def __init__(self, settings: HttpClientSettings):
transport = AsyncHTTPTransport()
if not (settings.cache and settings.cache.disabled):
controller = Controller(
allow_heuristics=True,
cacheable_methods=settings.cache.cacheable_methods if settings.cache else None,
cacheable_status_codes=(
settings.cache.cacheable_status_codes
if settings.cache
else list(HEURISTICALLY_CACHEABLE_STATUS_CODES)
if settings.cache.enabled:
transport = AsyncCacheTransport(
transport=transport,
controller=Controller(
allow_heuristics=settings.cache.controller.allow_heuristics,
allow_stale=settings.cache.controller.allow_stale,
cacheable_methods=settings.cache.controller.cacheable_methods,
cacheable_status_codes=settings.cache.controller.cacheable_status_codes,
),
allow_stale=True,
)
transport = AsyncCacheTransport(transport=transport, controller=controller)

super().__init__(transport=transport, timeout=settings.timeout)

Expand All @@ -39,7 +36,6 @@ class HttpClientApplication(Application):
@classmethod
def defaults(cls, settings=None) -> dict:
settings = settings if settings is not None else {}
settings.setdefault("timeout", DEFAULT_TIMEOUT)
return settings

async def on_bind(self, event: FactoryBindEvent):
Expand Down
32 changes: 27 additions & 5 deletions harp_apps/http_client/settings.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
from typing import Optional
from dataclasses import field
from typing import List, Optional

from hishel import HEURISTICALLY_CACHEABLE_STATUS_CODES

from harp.config.settings.base import BaseSetting, settings_dataclass
from harp.settings import DEFAULT_TIMEOUT


def default_status_codes() -> List[int]:
return list(HEURISTICALLY_CACHEABLE_STATUS_CODES)


@settings_dataclass
class ControllerSettings:
allow_heuristics: bool = True
allow_stale: bool = True
cacheable_methods: Optional[List[str]] = field(default_factory=lambda: ["GET"])
cacheable_status_codes: List[int] = field(default_factory=default_status_codes)


@settings_dataclass
class CacheSettings:
cacheable_methods: Optional[list[str]] = None
cacheable_status_codes: Optional[list[int]] = None
disabled: Optional[bool] = False
enabled: Optional[bool] = True
controller: ControllerSettings = field(default_factory=ControllerSettings)

def __post_init__(self):
if self.controller:
self.controller = (
self.controller
if isinstance(self.controller, ControllerSettings)
else ControllerSettings(**self.controller)
)


@settings_dataclass
class HttpClientSettings(BaseSetting):
cache: Optional[CacheSettings] = None
timeout: Optional[float] = DEFAULT_TIMEOUT
cache: CacheSettings = field(default_factory=CacheSettings)

def __post_init__(self):
if self.cache:
Expand Down

0 comments on commit d73c579

Please sign in to comment.