From c61abb1d18294e23c52f7a1d417b4cf0b24a7b03 Mon Sep 17 00:00:00 2001 From: Idris Abdurrahman Date: Fri, 21 Mar 2025 11:55:44 +0100 Subject: [PATCH] Update generated backend for blog_app with entities: posts, comments, tags, user --- app/api/core/dependencies/dependencies.py | 9 +++++++++ app/api/core/middleware/activity_tracker.py | 13 +++++++++++++ app/api/db/database.py | 7 +++++++ app/api/v1/models/comments.py | 21 +++++++++++++++++++++ app/api/v1/models/posts.py | 18 ++++++++++++++++++ app/api/v1/models/tags.py | 17 +++++++++++++++++ app/api/v1/models/user.py | 20 ++++++++++++++++++++ app/api/v1/routes/__init__.py | 3 +++ app/api/v1/routes/comments.py | 9 +++++++++ app/api/v1/routes/posts.py | 9 +++++++++ app/api/v1/routes/tags.py | 9 +++++++++ app/api/v1/routes/user.py | 9 +++++++++ app/api/v1/schemas/comments.py | 13 +++++++++++++ app/api/v1/schemas/posts.py | 12 ++++++++++++ app/api/v1/schemas/tags.py | 11 +++++++++++ app/api/v1/schemas/user.py | 11 +++++++++++ main.py | 13 +++++++++---- requirements.txt | 3 ++- 18 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 app/api/core/dependencies/dependencies.py create mode 100644 app/api/core/middleware/activity_tracker.py create mode 100644 app/api/db/database.py create mode 100644 app/api/v1/models/comments.py create mode 100644 app/api/v1/models/posts.py create mode 100644 app/api/v1/models/tags.py create mode 100644 app/api/v1/models/user.py create mode 100644 app/api/v1/routes/comments.py create mode 100644 app/api/v1/routes/posts.py create mode 100644 app/api/v1/routes/tags.py create mode 100644 app/api/v1/routes/user.py create mode 100644 app/api/v1/schemas/comments.py create mode 100644 app/api/v1/schemas/posts.py create mode 100644 app/api/v1/schemas/tags.py create mode 100644 app/api/v1/schemas/user.py diff --git a/app/api/core/dependencies/dependencies.py b/app/api/core/dependencies/dependencies.py new file mode 100644 index 0000000..965f5ff --- /dev/null +++ b/app/api/core/dependencies/dependencies.py @@ -0,0 +1,9 @@ +from sqlalchemy.orm import Session +from app.api.db.database import SessionLocal + +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() \ No newline at end of file diff --git a/app/api/core/middleware/activity_tracker.py b/app/api/core/middleware/activity_tracker.py new file mode 100644 index 0000000..2779748 --- /dev/null +++ b/app/api/core/middleware/activity_tracker.py @@ -0,0 +1,13 @@ +from time import time +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.requests import Request +from starlette.responses import Response +from loguru import logger + +class ActivityTrackerMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next): + start_time = time() + response = await call_next(request) + process_time = time() - start_time + logger.info(f"Request processed in {process_time:.4f} seconds") + return response \ No newline at end of file diff --git a/app/api/db/database.py b/app/api/db/database.py new file mode 100644 index 0000000..f327867 --- /dev/null +++ b/app/api/db/database.py @@ -0,0 +1,7 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +SQLALCHEMY_DATABASE_URL = 'sqlite:///./blog_app.db' +engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={'check_same_thread': False}) +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) +Base = declarative_base() diff --git a/app/api/v1/models/comments.py b/app/api/v1/models/comments.py new file mode 100644 index 0000000..07b33ec --- /dev/null +++ b/app/api/v1/models/comments.py @@ -0,0 +1,21 @@ +# app/api/v1/models/comments.py + +from sqlalchemy import Column, ForeignKey, Integer, String, Text +from sqlalchemy.orm import relationship +from app.api.db.database import Base + +class Comments(Base): + __tablename__ = 'comments' + + id = Column(Integer, primary_key=True, index=True) + post_id = Column(Integer, ForeignKey('posts.id')) + user_id = Column(Integer, ForeignKey('users.id')) + content = Column(Text) + created_at = Column(String) + updated_at = Column(String, nullable=True) + + post = relationship('Post', back_populates='comments') + user = relationship('User', back_populates='comments') + + def __repr__(self): + return f'Comment(id={self.id}, post_id={self.post_id}, user_id={self.user_id}, content="{self.content[:20]}...")' \ No newline at end of file diff --git a/app/api/v1/models/posts.py b/app/api/v1/models/posts.py new file mode 100644 index 0000000..6c5478e --- /dev/null +++ b/app/api/v1/models/posts.py @@ -0,0 +1,18 @@ +# app/api/v1/models/posts.py + +from sqlalchemy import Column, ForeignKey, Integer, String, Text +from sqlalchemy.orm import relationship +from app.api.db.database import Base + +class Posts(Base): + __tablename__ = 'posts' + + id = Column(Integer, primary_key=True, index=True) + user_id = Column(Integer, ForeignKey('users.id')) + title = Column(String) + content = Column(Text) + + user = relationship('User', back_populates='posts') + + def __repr__(self): + return f'Post(id={self.id}, title="{self.title}", content="{self.content[:20]}...")' \ No newline at end of file diff --git a/app/api/v1/models/tags.py b/app/api/v1/models/tags.py new file mode 100644 index 0000000..1d693f6 --- /dev/null +++ b/app/api/v1/models/tags.py @@ -0,0 +1,17 @@ +# app/api/v1/models/tags.py + +from sqlalchemy import Column, ForeignKey, Integer, String +from sqlalchemy.orm import relationship +from app.api.db.database import Base + +class Tags(Base): + __tablename__ = 'tags' + + id = Column(Integer, primary_key=True, index=True) + name = Column(String, nullable=False) + description = Column(Text) + + posts = relationship('Post', back_populates='tags', secondary='post_tags') + + def __repr__(self): + return f'Tag(id={self.id}, name={self.name})' \ No newline at end of file diff --git a/app/api/v1/models/user.py b/app/api/v1/models/user.py new file mode 100644 index 0000000..7b86a0c --- /dev/null +++ b/app/api/v1/models/user.py @@ -0,0 +1,20 @@ +# app/api/v1/models/user.py + +from sqlalchemy import Column, ForeignKey, Integer, String, Text +from sqlalchemy.orm import relationship +from app.api.db.database import Base + +class User(Base): + __tablename__ = 'user' + + id = Column(Integer, primary_key=True, index=True) + username = Column(String, unique=True, nullable=False) + email = Column(String, unique=True, nullable=False) + password = Column(String, nullable=False) + bio = Column(Text, nullable=True) + + # Define relationships here if needed + # posts = relationship("Post", back_populates="author") + + def __repr__(self): + return f"User(id={self.id}, username='{self.username}', email='{self.email}')" \ No newline at end of file diff --git a/app/api/v1/routes/__init__.py b/app/api/v1/routes/__init__.py index e69de29..4d5194a 100644 --- a/app/api/v1/routes/__init__.py +++ b/app/api/v1/routes/__init__.py @@ -0,0 +1,3 @@ +from fastapi import APIRouter + +router = APIRouter() \ No newline at end of file diff --git a/app/api/v1/routes/comments.py b/app/api/v1/routes/comments.py new file mode 100644 index 0000000..940e1eb --- /dev/null +++ b/app/api/v1/routes/comments.py @@ -0,0 +1,9 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from app.api.core.dependencies import get_db + +router = APIRouter() + +@router.get('/comments/') +def read_comments(db: Session = Depends(get_db)): + return {'message': 'Read comments'} diff --git a/app/api/v1/routes/posts.py b/app/api/v1/routes/posts.py new file mode 100644 index 0000000..717942a --- /dev/null +++ b/app/api/v1/routes/posts.py @@ -0,0 +1,9 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from app.api.core.dependencies import get_db + +router = APIRouter() + +@router.get('/posts/') +def read_posts(db: Session = Depends(get_db)): + return {'message': 'Read posts'} diff --git a/app/api/v1/routes/tags.py b/app/api/v1/routes/tags.py new file mode 100644 index 0000000..928683c --- /dev/null +++ b/app/api/v1/routes/tags.py @@ -0,0 +1,9 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from app.api.core.dependencies import get_db + +router = APIRouter() + +@router.get('/tags/') +def read_tags(db: Session = Depends(get_db)): + return {'message': 'Read tags'} diff --git a/app/api/v1/routes/user.py b/app/api/v1/routes/user.py new file mode 100644 index 0000000..818519d --- /dev/null +++ b/app/api/v1/routes/user.py @@ -0,0 +1,9 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from app.api.core.dependencies import get_db + +router = APIRouter() + +@router.get('/user/') +def read_user(db: Session = Depends(get_db)): + return {'message': 'Read user'} diff --git a/app/api/v1/schemas/comments.py b/app/api/v1/schemas/comments.py new file mode 100644 index 0000000..f23b92e --- /dev/null +++ b/app/api/v1/schemas/comments.py @@ -0,0 +1,13 @@ +app/api/v1/schemas/comments.py: + +from pydantic import BaseModel + +class CommentsBase(BaseModel): + text: str + +class Comments(CommentsBase): + id: int + post_id: int + + class Config: + orm_mode = True \ No newline at end of file diff --git a/app/api/v1/schemas/posts.py b/app/api/v1/schemas/posts.py new file mode 100644 index 0000000..5962b00 --- /dev/null +++ b/app/api/v1/schemas/posts.py @@ -0,0 +1,12 @@ +from pydantic import BaseModel + +class PostsBase(BaseModel): + title: str + content: str + +class Posts(PostsBase): + id: int + owner_id: int + + class Config: + orm_mode = True \ No newline at end of file diff --git a/app/api/v1/schemas/tags.py b/app/api/v1/schemas/tags.py new file mode 100644 index 0000000..92f9fd2 --- /dev/null +++ b/app/api/v1/schemas/tags.py @@ -0,0 +1,11 @@ +from pydantic import BaseModel + +class TagsBase(BaseModel): + name: str + +class Tags(TagsBase): + id: int + name: str + + class Config: + orm_mode = True \ No newline at end of file diff --git a/app/api/v1/schemas/user.py b/app/api/v1/schemas/user.py new file mode 100644 index 0000000..7ef2cc4 --- /dev/null +++ b/app/api/v1/schemas/user.py @@ -0,0 +1,11 @@ +from pydantic import BaseModel, EmailStr + +class UserBase(BaseModel): + email: EmailStr + username: str + +class User(UserBase): + id: int + + class Config: + orm_mode = True \ No newline at end of file diff --git a/main.py b/main.py index dca5c44..c59cecf 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,12 @@ from fastapi import FastAPI +from app.api.db.database import engine, Base +from app.api.v1.routes import router +from app.api.core.middleware.activity_tracker import ActivityTrackerMiddleware -app = FastAPI(title="Generated Backend") +app = FastAPI() +app.add_middleware(ActivityTrackerMiddleware) +app.include_router(router, prefix='/v1') -@app.get("/") -def read_root(): - return {"message": "Welcome to the generated backend"} \ No newline at end of file +@app.on_event("startup") +def startup_event(): + Base.metadata.create_all(bind=engine) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a70e8ac..1bbf170 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ fastapi uvicorn sqlalchemy -pydantic \ No newline at end of file +pydantic +loguru \ No newline at end of file