Automated Action a9210ca8ed Create manga inventory API with FastAPI and SQLite
- Implemented CRUD operations for manga, authors, publishers, and genres
- Added search and filtering functionality
- Set up SQLAlchemy ORM with SQLite database
- Configured Alembic for database migrations
- Implemented logging with Loguru
- Added comprehensive API documentation
- Set up error handling and validation
- Added ruff for linting and formatting
2025-05-30 12:29:35 +00:00

81 lines
3.1 KiB
Python

from datetime import datetime
from pydantic import BaseModel, Field, validator
from app.schemas.author import Author
from app.schemas.genre import Genre
from app.schemas.publisher import Publisher
# Shared properties
class MangaBase(BaseModel):
title: str = Field(..., min_length=1, max_length=255, description="Title of the manga")
original_title: str | None = Field(
None, max_length=255, description="Original title in Japanese or other language"
)
isbn: str | None = Field(None, max_length=20, description="ISBN of the manga volume")
description: str | None = Field(None, description="Description of the manga")
volume_number: int | None = Field(None, ge=1, description="Volume number in the series")
total_volumes: int | None = Field(
None, ge=1, description="Total number of volumes in the series"
)
publication_date: datetime | None = Field(None, description="Publication date of the manga")
page_count: int | None = Field(None, ge=1, description="Number of pages")
price: float | None = Field(None, ge=0, description="Price of the manga")
quantity: int = Field(0, ge=0, description="Quantity in inventory")
in_stock: bool = Field(True, description="Whether the manga is in stock")
rating: float | None = Field(None, ge=0, le=10, description="Rating of the manga (0-10)")
language: str | None = Field(None, max_length=50, description="Language of the manga")
cover_image_url: str | None = Field(None, max_length=255, description="URL to the cover image")
@validator("total_volumes")
def validate_total_volumes(self, v, values):
if v is not None and "volume_number" in values and values["volume_number"] is not None:
if v < values["volume_number"]:
raise ValueError("Total volumes must be greater than or equal to volume number")
return v
# Properties to receive on manga creation
class MangaCreate(MangaBase):
author_id: int | None = Field(None, description="ID of the author")
publisher_id: int | None = Field(None, description="ID of the publisher")
genre_ids: list[int] | None = Field(None, description="IDs of the genres")
# Properties to receive on manga update
class MangaUpdate(MangaBase):
title: str | None = Field(None, min_length=1, max_length=255, description="Title of the manga")
author_id: int | None = Field(None, description="ID of the author")
publisher_id: int | None = Field(None, description="ID of the publisher")
genre_ids: list[int] | None = Field(None, description="IDs of the genres")
# Properties shared by models stored in DB
class MangaInDBBase(MangaBase):
id: int
author_id: int | None
publisher_id: int | None
created_at: datetime
updated_at: datetime
class Config:
orm_mode = True
# Properties to return to client
class Manga(MangaInDBBase):
pass
# Properties properties stored in DB
class MangaInDB(MangaInDBBase):
pass
# Additional properties for response with relationships
class MangaWithRelations(Manga):
author: Author | None = None
publisher: Publisher | None = None
genres: list[Genre] = []