FastAPI¶
FastAPI is a Python API framework based on type hints, with data validation and OpenAPI schema generation. Use imgproxykit’s dependency integration to inject a client into route handlers and return image URLs and named variants in typed response models.
Explore the FastAPI tutorial and the project on GitHub.
Installation¶
In your FastAPI project, install imgproxykit with FastAPI support:
uv add 'imgproxykit[fastapi]'
poetry add 'imgproxykit[fastapi]'
pip install 'imgproxykit[fastapi]'
Register a client¶
Call add_imgproxy() while creating
the application. Keep the returned dependency for use in your routes:
from typing import Annotated, Final
from fastapi import Depends, FastAPI
from pydantic import BaseModel
from imgproxykit import Client, Transform
from imgproxykit.integrations.fastapi import add_imgproxy
_SOURCE_URL: Final = 'https://originals.example.com/photo.jpg'
_THUMBNAIL: Final = Transform(width=300, format='webp')
app = FastAPI()
get_imgproxy = add_imgproxy(app, Client('https://imgproxy.example.com')) # (1)!
class ImageResponse(BaseModel):
"""Generated image URL."""
image: str
@app.get('/image')
async def get_image(
imgproxy: Annotated[Client, Depends(get_imgproxy)], # (2)!
) -> ImageResponse:
"""Return a transformed image URL."""
image = imgproxy.url(_SOURCE_URL, transform=_THUMBNAIL)
return ImageResponse(image=image)
Register the client once and keep the returned dependency. The client is stored on
app.state.imgproxykit_client.Inject the registered client into the route handler. The same client is reused across requests.
URL generation makes no network requests. See Client to configure signing credentials.
Return variants¶
Declare image variants as a dataclass and use it as a field in a Pydantic response model:
from dataclasses import dataclass
from typing import Annotated, Final
from fastapi import Depends, FastAPI
from pydantic import BaseModel
from imgproxykit import Client, Transform
from imgproxykit.integrations.fastapi import add_imgproxy
_SOURCE_URL: Final = 'https://originals.example.com/photo.jpg'
_BASE: Final = Transform(format='webp')
app = FastAPI()
get_imgproxy = add_imgproxy(app, Client('https://imgproxy.example.com'))
@dataclass(frozen=True, slots=True)
class ProductImages:
"""Declare the image response fields and their transformations."""
thumbnail: Annotated[str, _BASE.extend(width=320)] # (1)!
preview: Annotated[str, _BASE.extend(width=1280)]
class ImageResponse(BaseModel):
"""Named image variants."""
images: ProductImages # (2)!
@app.get('/image')
async def get_image(
imgproxy: Annotated[Client, Depends(get_imgproxy)],
) -> ImageResponse:
"""Return named image variants."""
images = imgproxy.variants(_SOURCE_URL, variants=ProductImages) # (3)!
return ImageResponse(images=images)
Associate each URL field with a transformation using
Annotated.Include the dataclass in the response model. FastAPI documents its string fields in the OpenAPI schema.
Generate a dataclass instance containing the URLs. Pydantic serializes it as a nested object.
See Return a dataclass for declaration requirements.
Multiple clients¶
Register each client separately and use its returned dependency in
Depends. This example injects both a signed and an unsigned client:
from typing import Annotated, Final
from fastapi import Depends, FastAPI
from pydantic import BaseModel
from imgproxykit import Client
from imgproxykit.integrations.fastapi import add_imgproxy
_SOURCE_URL: Final = 'https://originals.example.com/photo.jpg'
app = FastAPI()
get_signed_imgproxy = add_imgproxy( # (1)!
app,
Client(
'https://imgproxy.example.com',
key='736563726574',
salt='73616c74',
),
)
get_unsigned_imgproxy = add_imgproxy(
app,
Client('https://imgproxy.example.com'),
name='unsigned_imgproxy', # (2)!
)
class ImageUrls(BaseModel):
"""Signed and unsigned image URLs."""
signed: str
unsigned: str
@app.get('/images')
async def get_images(
signed: Annotated[Client, Depends(get_signed_imgproxy)], # (3)!
unsigned: Annotated[Client, Depends(get_unsigned_imgproxy)],
) -> ImageUrls:
"""Build image URLs with each client's signing configuration."""
return ImageUrls(
signed=signed.url(_SOURCE_URL),
unsigned=unsigned.url(_SOURCE_URL),
)
Register a signed client under the default name. Replace the example key and salt with your imgproxy credentials.
Give the unsigned client a separate name on
app.state.Use each registration’s returned dependency to inject its client.
Registering a name already present on app.state raises ValueError.
Unsigned URLs require an imgproxy server configured to accept them.
Next steps¶
FastAPI documentation covers route handlers, dependencies, validation, and API schemas.
FastAPI on GitHub provides the source code, issues, and contribution guide.
Variants shows how to generate several image URLs.
FastAPI documents the registration function.