
- Create project structure and dependencies - Set up SQLAlchemy models for anime, genres, and their relationships - Implement CRUD operations for all models - Set up FastAPI endpoints for managing anime and genres - Add health check endpoint - Configure Alembic for database migrations - Add data seeding capability - Update README with project information
110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
import logging
|
|
from datetime import date
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app import crud, schemas
|
|
from app.db.session import SessionLocal
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# Example genres
|
|
INITIAL_GENRES = [
|
|
{"name": "Action"},
|
|
{"name": "Adventure"},
|
|
{"name": "Comedy"},
|
|
{"name": "Drama"},
|
|
{"name": "Fantasy"},
|
|
{"name": "Horror"},
|
|
{"name": "Mystery"},
|
|
{"name": "Romance"},
|
|
{"name": "Sci-Fi"},
|
|
{"name": "Slice of Life"},
|
|
{"name": "Sports"},
|
|
{"name": "Supernatural"},
|
|
{"name": "Thriller"},
|
|
]
|
|
|
|
# Example anime
|
|
INITIAL_ANIME = [
|
|
{
|
|
"title": "Fullmetal Alchemist: Brotherhood",
|
|
"alternative_titles": "Hagane no Renkinjutsushi: Fullmetal Alchemist",
|
|
"synopsis": "After a horrific alchemy experiment goes wrong in the Elric household, brothers Edward and Alphonse are left in a catastrophic new reality.",
|
|
"episodes": 64,
|
|
"status": "Finished Airing",
|
|
"aired_from": date(2009, 4, 5),
|
|
"aired_to": date(2010, 7, 4),
|
|
"duration": "24 min per ep",
|
|
"rating": "R - 17+ (violence & profanity)",
|
|
"score": 9.15,
|
|
"ranked": 1,
|
|
"popularity": 3,
|
|
"studio": "Bones",
|
|
"source": "Manga",
|
|
"genre_ids": [1, 2, 4, 5], # Action, Adventure, Drama, Fantasy
|
|
},
|
|
{
|
|
"title": "Death Note",
|
|
"synopsis": "A high school student discovers a supernatural notebook that has deadly powers. When he discovers that he can kill anyone by writing their name in the notebook, he begins to create his perfect world.",
|
|
"episodes": 37,
|
|
"status": "Finished Airing",
|
|
"aired_from": date(2006, 10, 4),
|
|
"aired_to": date(2007, 6, 27),
|
|
"duration": "23 min per ep",
|
|
"rating": "R - 17+ (violence & profanity)",
|
|
"score": 8.63,
|
|
"ranked": 69,
|
|
"popularity": 1,
|
|
"studio": "Madhouse",
|
|
"source": "Manga",
|
|
"genre_ids": [7, 9, 13], # Mystery, Sci-Fi, Thriller
|
|
},
|
|
{
|
|
"title": "Attack on Titan",
|
|
"alternative_titles": "Shingeki no Kyojin",
|
|
"synopsis": "Centuries ago, mankind was slaughtered to near extinction by monstrous humanoid creatures called Titans, forcing humans to hide in fear behind enormous concentric walls.",
|
|
"episodes": 75,
|
|
"status": "Finished Airing",
|
|
"aired_from": date(2013, 4, 7),
|
|
"aired_to": date(2021, 3, 29),
|
|
"duration": "24 min per ep",
|
|
"rating": "R - 17+ (violence & profanity)",
|
|
"score": 8.51,
|
|
"ranked": 108,
|
|
"popularity": 2,
|
|
"studio": "Wit Studio",
|
|
"source": "Manga",
|
|
"genre_ids": [1, 4, 5], # Action, Drama, Fantasy
|
|
},
|
|
]
|
|
|
|
|
|
def init_db(db: Session) -> None:
|
|
# Create genres
|
|
for genre_data in INITIAL_GENRES:
|
|
genre = crud.genre.get_by_name(db, name=genre_data["name"])
|
|
if not genre:
|
|
genre_in = schemas.genre.GenreCreate(name=genre_data["name"])
|
|
crud.genre.create(db, obj_in=genre_in)
|
|
logger.info(f"Created genre: {genre_data['name']}")
|
|
|
|
# Create anime
|
|
for anime_data in INITIAL_ANIME:
|
|
anime = crud.anime.get_multi(db, limit=1, skip=0)
|
|
if not anime or all(a.title != anime_data["title"] for a in anime):
|
|
anime_in = schemas.anime.AnimeCreate(**anime_data)
|
|
crud.anime.create_with_genres(db, obj_in=anime_in)
|
|
logger.info(f"Created anime: {anime_data['title']}")
|
|
|
|
|
|
def seed_data() -> None:
|
|
"""Seed initial data to the database."""
|
|
logger.info("Seeding initial data to the database")
|
|
db = SessionLocal()
|
|
try:
|
|
init_db(db)
|
|
finally:
|
|
db.close()
|
|
logger.info("Initial data seeded successfully") |