From 836dd1d27aa8d389ce852610d8bcd7ffd15d0b38 Mon Sep 17 00:00:00 2001 From: osbm Date: Thu, 1 May 2025 01:22:39 +0300 Subject: [PATCH] initial app --- main.py | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 40fafa2..bc11783 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,121 @@ -from typing import Union - from fastapi import FastAPI +from pydantic import BaseModel, Field, EmailStr +from sqlalchemy import ( + Column, Integer, String, DateTime, Enum, ForeignKey, Text, Float, Boolean, create_engine +) +from sqlalchemy.orm import declarative_base, relationship, sessionmaker +from sqlalchemy.dialects.postgresql import JSONB +from enum import Enum as PyEnum +import datetime app = FastAPI() +Base = declarative_base() +# Enums +class Role(str, PyEnum): + admin = "admin" + user = "user" + mod = "mod" -@app.get("/") -def read_root(): - return {"Hello": "World"} +class Status(str, PyEnum): + active = "active" + banned = "banned" + suspended = "suspended" + +class ItemType(str, PyEnum): + text = "text" + image = "image" + +class VoteType(str, PyEnum): + up = "up" + down = "down" + +# SQLAlchemy Models +class User(Base): + __tablename__ = "users" + + user_id = Column(Integer, primary_key=True, index=True) + username = Column(String, unique=True, nullable=False) + name = Column(String) + surname = Column(String) + email = Column(String, unique=True, nullable=False) + role = Column(Enum(Role), default=Role.user) + status = Column(Enum(Status), default=Status.active) + bio = Column(String(144)) + created_date = Column(DateTime, default=datetime.datetime.utcnow) + + collections = relationship("Collection", back_populates="user") + items = relationship("Item", back_populates="user") + +class Collection(Base): + __tablename__ = "collections" + + collection_id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey("users.user_id")) + visibility = Column(Boolean, default=True) # True = public, False = private + collection_name = Column(String, nullable=False) + collection_bio = Column(String) + + user = relationship("User", back_populates="collections") + items = relationship("Item", back_populates="collection") + +class Item(Base): + __tablename__ = "items" + + item_id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey("users.user_id")) + date = Column(DateTime, default=datetime.datetime.utcnow) + location_x = Column(Float) + location_y = Column(Float) + item_type = Column(Enum(ItemType)) + content_text = Column(Text, nullable=True) + content_image_path = Column(String, nullable=True) + collection_id = Column(Integer, ForeignKey("collections.collection_id")) + score = Column(Integer, default=0) + + user = relationship("User", back_populates="items") + collection = relationship("Collection", back_populates="items") + votes = relationship("Vote", back_populates="item") + +class Vote(Base): + __tablename__ = "votes" + + vote_id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey("users.user_id")) + item_id = Column(Integer, ForeignKey("items.item_id")) + vote_type = Column(Enum(VoteType)) + date = Column(DateTime, default=datetime.datetime.utcnow) + + item = relationship("Item", back_populates="votes") + +# Pydantic Schemas +class UserCreate(BaseModel): + username: str + name: str + surname: str + email: EmailStr + bio: str = Field(max_length=144) + +class ItemCreate(BaseModel): + location_x: float + location_y: float + item_type: ItemType + content_text: str | None = None + content_image_path: str | None = None + collection_id: int + +class CollectionCreate(BaseModel): + collection_name: str + collection_bio: str + visibility: bool = True + +class VoteCreate(BaseModel): + item_id: int + vote_type: VoteType + +# DB Setup (edit with your DB credentials) +DATABASE_URL = "postgresql://username:password@localhost:5432/mydatabase" +engine = create_engine(DATABASE_URL) +SessionLocal = sessionmaker(bind=engine) +Base.metadata.create_all(bind=engine)