Shared httpx client and BaseServiceClient for typed service-to-service HTTP calls
Project description
fastapi-service-client
Shared httpx client and BaseServiceClient for typed service-to-service HTTP calls. Eliminates copy-pasting HTTP transport boilerplate across microservices: structured logging, typed responses via Pydantic, and a clean exception hierarchy for upstream failures.
Installation
pip install fastapi-service-client
Or with uv:
uv add fastapi-service-client
Quick start
1. Add settings to your app
from pydantic_settings import BaseSettings
from fastapi_service_client import HttpxSettings
class AppSettings(BaseSettings):
httpx: HttpxSettings = HttpxSettings()
2. Implement a service client
from fastapi_service_client import BaseServiceClient, HttpxSettings
class CryptoServiceClient(BaseServiceClient):
service_name = "crypto-service"
def __init__(self, base_url: str, settings: HttpxSettings) -> None:
super().__init__(base_url=base_url, settings=settings)
async def get_key(self, key_id: str) -> dict:
return await self._request_json("GET", f"/keys/{key_id}")
3. Use in your endpoint / use case
client = CryptoServiceClient(
base_url=settings.crypto_service_url,
settings=settings.httpx,
)
result = await client.get_key("abc123")
API
HttpxSettings
Pydantic model to include in your app settings.
| Field | Type | Default | Description |
|---|---|---|---|
ssl_verify |
bool |
True |
Verify SSL certificates. Set to False only for trusted internal services with self-signed certificates. |
BaseServiceClient
Base class for outbound HTTP clients.
Constructor:
BaseServiceClient(*, base_url: str = "", settings: HttpxSettings | None = None)
Methods (all protected, call from subclass):
| Method | Returns | Description |
|---|---|---|
_request_raw(method, url, ...) |
httpx.Response |
Raw response |
_request_json(method, url, ...) |
Any |
Parsed JSON |
_request_bytes(method, url, ...) |
bytes |
Response body as bytes |
_request_typed(adapter, method, url, ...) |
T |
Validated via TypeAdapter[T] |
_request_model(model, method, url, ...) |
TModel |
Validated Pydantic model |
All methods accept:
| Parameter | Type | Default | Description |
|---|---|---|---|
headers |
dict[str, str] | None |
None |
Extra request headers |
cookies |
dict[str, str] | None |
None |
Request cookies |
expected_status |
int |
200 |
Raises UpstreamResponseError on mismatch |
detail_on_bad_status |
str |
"Upstream request failed" |
Error message on bad status |
**kwargs |
Passed through to httpx.AsyncClient.request |
Class attribute:
class MyClient(BaseServiceClient):
service_name = "my-service" # used in exception messages and logs
Exceptions
from fastapi_service_client import (
UpstreamError, # base
UpstreamUnavailableError, # network error / timeout
UpstreamResponseError, # unexpected HTTP status
UpstreamInvalidResponseError # unparseable response body
)
All inherit from UpstreamError. Catch the base to handle any upstream failure:
try:
result = await client.get_key("abc")
except UpstreamUnavailableError:
raise HTTPException(status_code=503)
except UpstreamResponseError as exc:
raise HTTPException(status_code=exc.status_code, detail=exc.detail)
Logging
The library logs via standard Python logging. Each outbound request and response is logged at INFO level under the fastapi_service_client namespace:
{"event": "http_out_request", "method": "GET", "url": "http://..."}
{"event": "http_out_response", "status": 200, "url": "http://...", "duration_ms": 42.1}
Configure in your app's logging setup as usual.
Versioning
Releases are automated via python-semantic-release on every push to main. Version bumps follow Conventional Commits:
| Commit prefix | Version bump |
|---|---|
fix: |
patch (1.0.0 → 1.0.1) |
feat: |
minor (1.0.0 → 1.1.0) |
feat!: / BREAKING CHANGE: |
major (1.0.0 → 2.0.0) |
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_service_client-1.0.0.tar.gz.
File metadata
- Download URL: fastapi_service_client-1.0.0.tar.gz
- Upload date:
- Size: 5.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5aa23c8a8cea4115550429992640dc069bd7c3c1f53a63ef57881aa77d57c325
|
|
| MD5 |
4aa0af109dd5cd5fb66f2de09d6170ff
|
|
| BLAKE2b-256 |
00b89d7d214a25da66d330e2d58d973dc97c1c436d1be3cf30bafe9554e3354c
|
File details
Details for the file fastapi_service_client-1.0.0-py3-none-any.whl.
File metadata
- Download URL: fastapi_service_client-1.0.0-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
180717050211af03edbb7ec5b1f1a223ae53c6578c64531bc43050857e008444
|
|
| MD5 |
c56d4a007d2738396de73f10089b7c9c
|
|
| BLAKE2b-256 |
fc8e7fe07773c99c2190d04eaf02f6675d915cf41239357adf6f1de7df4fcb34
|