DTOs

Data Transfer Objects for serializing StoredFile objects in API responses.

DTO Classes

class litestar_storages.contrib.dto.StoredFileDTO[source]

DTO for StoredFile responses.

This DTO provides a standard way to serialize StoredFile objects in API responses. By default, it excludes the metadata field to keep responses clean.

Example

Basic usage:

from litestar import post
from litestar.datastructures import UploadFile
from litestar_storages import Storage, StoredFile
from litestar_storages.contrib.dto import StoredFileDTO


@post("/upload", return_dto=StoredFileDTO)
async def upload(
    data: UploadFile,
    storage: Storage,
) -> StoredFile:
    return await storage.put(
        key=f"uploads/{data.filename}",
        data=data.file,
        content_type=data.content_type,
    )

Response will be:

{
    "key": "uploads/example.jpg",
    "size": 12345,
    "content_type": "image/jpeg",
    "etag": "abc123",
    "last_modified": "2024-01-15T10:30:00Z",
}
Parameters:

asgi_connection (ASGIConnection)

Bases: DataclassDTO[StoredFile]

Excluded fields: metadata

Use this DTO for standard upload responses where internal metadata should not be exposed to clients.

config: ClassVar[DTOConfig] = DTOConfig(exclude={'metadata'}, include=set(), rename_fields={}, rename_strategy=None, max_nested_depth=1, partial=False, underscore_fields_private=True, experimental_codegen_backend=None, forbid_unknown_fields=False)

Config objects to define properties of the DTO.

asgi_connection
class litestar_storages.contrib.dto.StoredFileReadDTO[source]

DTO for read-only StoredFile responses.

This DTO is useful when you want to include all fields from StoredFile, including metadata, in read operations.

Example

Include metadata in response:

from litestar import get
from litestar_storages import Storage, StoredFile
from litestar_storages.contrib.dto import StoredFileReadDTO


@get("/files/{key:path}/info", return_dto=StoredFileReadDTO)
async def get_file_info(
    key: str,
    storage: Storage,
) -> StoredFile:
    return await storage.info(key)

Response will be:

{
    "key": "uploads/example.jpg",
    "size": 12345,
    "content_type": "image/jpeg",
    "etag": "abc123",
    "last_modified": "2024-01-15T10:30:00Z",
    "metadata": {"uploaded_by": "user123", "original_filename": "my_photo.jpg"},
}
Parameters:

asgi_connection (ASGIConnection)

Bases: DataclassDTO[StoredFile]

Included fields: All (including metadata)

Use this DTO when you need to expose all file information, including user-defined metadata.

config: ClassVar[DTOConfig] = DTOConfig(exclude=set(), include=set(), rename_fields={}, rename_strategy=None, max_nested_depth=1, partial=False, underscore_fields_private=True, experimental_codegen_backend=None, forbid_unknown_fields=False)

Config objects to define properties of the DTO.

asgi_connection

Usage Examples

Basic Upload Response

from litestar import post
from litestar.datastructures import UploadFile
from litestar_storages import Storage, StoredFile
from litestar_storages.contrib.dto import StoredFileDTO

@post("/upload", return_dto=StoredFileDTO)
async def upload(
    data: UploadFile,
    storage: Storage,
) -> StoredFile:
    content = await data.read()
    return await storage.put(
        key=f"uploads/{data.filename}",
        data=content,
        content_type=data.content_type,
    )

Response:

{
    "key": "uploads/document.pdf",
    "size": 102400,
    "content_type": "application/pdf",
    "etag": "d41d8cd98f00b204e9800998ecf8427e",
    "last_modified": "2024-01-15T10:30:00Z"
}

File Info with Metadata

from litestar import get
from litestar_storages import Storage, StoredFile
from litestar_storages.contrib.dto import StoredFileReadDTO

@get("/files/{key:path}/info", return_dto=StoredFileReadDTO)
async def get_file_info(
    key: str,
    storage: Storage,
) -> StoredFile:
    return await storage.info(key)

Response:

{
    "key": "uploads/document.pdf",
    "size": 102400,
    "content_type": "application/pdf",
    "etag": "d41d8cd98f00b204e9800998ecf8427e",
    "last_modified": "2024-01-15T10:30:00Z",
    "metadata": {
        "uploaded_by": "user123",
        "department": "engineering"
    }
}

Listing Files

from litestar import get
from litestar_storages import Storage, StoredFile
from litestar_storages.contrib.dto import StoredFileDTO

@get("/files", return_dto=StoredFileDTO)
async def list_files(
    storage: Storage,
    prefix: str = "",
) -> list[StoredFile]:
    return [file async for file in storage.list(prefix)]

Custom DTOs

Create custom DTOs for specific use cases:

from litestar.dto import DataclassDTO, DTOConfig
from litestar_storages.types import StoredFile

class MinimalFileDTO(DataclassDTO[StoredFile]):
    """Only return key and size."""
    config = DTOConfig(
        include={"key", "size"},
    )

class DetailedFileDTO(DataclassDTO[StoredFile]):
    """Return all fields with renamed output."""
    config = DTOConfig(
        rename_fields={"key": "path", "content_type": "mime_type"},
    )

Using DTOs with Upload Results

from dataclasses import dataclass
from litestar import post
from litestar.dto import DataclassDTO
from litestar_storages import Storage, StoredFile
from litestar_storages.contrib.dto import StoredFileDTO

@dataclass
class UploadResponse:
    file: StoredFile
    download_url: str

class UploadResponseDTO(DataclassDTO[UploadResponse]):
    pass

@post("/upload", return_dto=UploadResponseDTO)
async def upload(
    data: UploadFile,
    storage: Storage,
) -> UploadResponse:
    content = await data.read()
    file = await storage.put(
        key=f"uploads/{data.filename}",
        data=content,
    )
    url = await storage.url(file.key)
    return UploadResponse(file=file, download_url=url)