Skip to content
Snippets Groups Projects
Commit 0085f10b authored by Antoine Gaudron-Desjardins's avatar Antoine Gaudron-Desjardins
Browse files

restructure backend

parent 63fa4023
No related branches found
No related tags found
1 merge request!24restructure backend
Pipeline #43860 passed with warnings
...@@ -2,27 +2,14 @@ ...@@ -2,27 +2,14 @@
Module to interact with the database Module to interact with the database
""" """
from datetime import date, datetime, time, timedelta from datetime import date, datetime, time, timedelta
from numpy import average
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.sql import func from sqlalchemy.sql import func
import pytz
from db import models, schemas from db import models, schemas
def get_records(place: str, db: Session): ## Define CRUD operation to collect the statistics
""" Get all the records for the given place """
records = db.query(models.Records).filter(models.Records.place == place).order_by(models.Records.date.desc()).all()
return records
def create_record(new_record: schemas.RecordBase, db: Session):
""" Add a new record to the database """
db_record = models.Records(**new_record.dict())
db.add(db_record)
db.commit()
db.refresh(db_record)
return db_record
def get_waiting_time(place: str, db: Session): def get_waiting_time(place: str, db: Session):
""" Get the last estimated waiting time for the given place """ """ Get the last estimated waiting time for the given place """
...@@ -72,3 +59,60 @@ def get_stats(place: str, weekday: int, min_time_hour: int, min_time_mn: int, ma ...@@ -72,3 +59,60 @@ def get_stats(place: str, weekday: int, min_time_hour: int, min_time_mn: int, ma
start_time, end_time = end_time, shift_time(end_time, interval) start_time, end_time = end_time, shift_time(end_time, interval)
return stats return stats
## Define CRUD operation for the comments
def get_comments(place: str, page: int, db: Session):
""" Get the 10 last comments for the given place """
if page == 0:
comments = db.query(models.Comments).order_by(models.Comments.date.desc(), models.Comments.id.desc()).all()
else:
comments = db.query(models.Comments).filter(models.Comments.place == place).order_by(models.Comments.date.desc(), models.Comments.id.desc()).slice((page-1)*10, page*10).all()
return comments
def create_comment(place: str, new_comments: schemas.CommentBase, db: Session):
""" Add a new comment to the database """
date = datetime.now(tz=pytz.timezone("Europe/Paris"))
db_comment = models.Comments(**new_comments.dict(), date=date, place=place)
db.add(db_comment)
db.commit()
db.refresh(db_comment)
return db_comment
def delete_comment(id: int, db: Session):
""" Delete the comment with the matching id """
if id == 0:
db.query(models.Comments).delete()
else:
db.query(models.Comments).filter(models.Comments.id == id).delete()
db.commit()
## Define CRUD operation for the news
def get_news(place: str, db: Session):
""" Get the news for the given place """
news = db.query(models.News).filter(models.News.place == place).order_by(models.News.date.desc()).all()
return news
def create_news(new_news: schemas.NewsBase, db: Session):
""" Add a news to the database """
date = datetime.now(tz=pytz.timezone("Europe/Paris"))
db_news = models.News(**new_news.dict(), published_at=date)
db.add(db_news)
db.commit()
db.refresh(db_news)
return db_news
def delete_news(id: int, db: Session):
""" Delete the news with the matching id """
if id == 0:
db.query(models.News).delete()
else:
db.query(models.News).filter(models.News.id == id).delete()
db.commit()
\ No newline at end of file
...@@ -21,3 +21,11 @@ engine = create_engine(SQLALCHEMY_DATABASE_URL) ...@@ -21,3 +21,11 @@ engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base() Base = declarative_base()
def get_db():
"""Create a database session."""
db = SessionLocal()
try:
yield db
finally:
db.close()
\ No newline at end of file
""" """
Models of the database for magasin app Models of the database for magasin app
""" """
from sqlalchemy import Column, Integer, DateTime, Float, Interval, String from sqlalchemy import Column, Integer, DateTime, Float, Interval, String, Text
from db.database import Base from db.database import Base
...@@ -15,3 +15,25 @@ class Records(Base): ...@@ -15,3 +15,25 @@ class Records(Base):
date = Column(DateTime) date = Column(DateTime)
density = Column(Float) density = Column(Float)
waiting_time = Column(Interval) waiting_time = Column(Interval)
class Comments(Base):
"""Comments sql table model"""
__tablename__ = "comments"
id = Column(Integer, primary_key=True, index=True)
comment = Column(Text)
date = Column(DateTime)
place = Column(String(10))
class News(Base):
"""Records sql table model"""
__tablename__ = "News sql table model"
id = Column(Integer, primary_key=True, index=True)
title = Column(String(50))
content = Column(Text)
published_at = Column(DateTime)
end_date = Column(DateTime)
place = Column(String(10))
...@@ -8,17 +8,47 @@ from pydantic import BaseModel, Field ...@@ -8,17 +8,47 @@ from pydantic import BaseModel, Field
class RecordBase(BaseModel): class RecordBase(BaseModel):
"""Records base schema""" """Records base schema"""
place: str = Field(..., place: str = Field(..., title="Name of the RU corresponding the given record")
title="Name of the RU corresponding the given record")
date: datetime = Field(..., title="Date of the record") date: datetime = Field(..., title="Date of the record")
density: float = Field(..., title="Estimated density of people") density: float = Field(..., title="Estimated density of people")
waiting_time: Optional[timedelta] = Field( waiting_time: Optional[timedelta] = Field(title="Estimated waiting time for people coming at this date")
title="Estimated waiting time for people coming at this date")
class Record(RecordBase): class Record(RecordBase):
"""Database records schema""" """Database records base schema"""
id: int id: int
class Config: class Config:
orm_mode = True orm_mode = True
class CommentBase(BaseModel):
"""Comments base schema"""
comment: str = Field(..., title="Content of the comment posted")
class Comment(CommentBase):
"""Database comments base schema"""
id: int
date: datetime = Field(..., title="Publication date of the comment")
place: str = Field(..., title="Name of the RU corresponding the comment")
class Config:
orm_mode = True
class NewsBase(BaseModel):
"""News sql table model"""
title: str = Field(..., title="Title of the news")
content: str = Field(..., title="Content of the news")
end_date: datetime = Field(..., title="End date to display the news")
place: str = Field(..., title="Name of the RU corresponding the news")
class News(NewsBase):
"""Database news base schema"""
id: int
published_at: datetime = Field(..., title="Publication date of the news")
class Config:
orm_mode = True
\ No newline at end of file
from datetime import datetime, time, timedelta from fastapi import FastAPI
from typing import List
from fastapi import Body, Depends, FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from dotenv import load_dotenv from dotenv import load_dotenv
import os import os
from db import crud, schemas, database, models from db import database, models
from routers import stats, comments, news
app = FastAPI(docs_url="/api/docs", openapi_url="/api/openapi.json")
# load environment variables # load environment variables
load_dotenv() load_dotenv()
app = FastAPI(docs_url="/api/docs", openapi_url="/api/openapi.json")
origins = [ origins = [
os.getenv('WEB_ROOT'), os.getenv('WEB_ROOT'),
] ]
...@@ -27,40 +24,19 @@ app.add_middleware( ...@@ -27,40 +24,19 @@ app.add_middleware(
) )
def get_db():
"""Create a database session."""
db = database.SessionLocal()
try:
yield db
finally:
db.close()
@app.on_event("startup") @app.on_event("startup")
def on_startup(): def on_startup():
# Database creation # Database creation
models.Base.metadata.create_all(bind=database.engine) models.Base.metadata.create_all(bind=database.engine)
@app.get('/api/{place}', response_model=List[schemas.Record]) # Integration of routers
async def eatfast(place: str, db: Session = Depends(get_db)): app.include_router(stats.router)
return crud.get_records(place, db) app.include_router(comments.router)
app.include_router(news.router)
@app.post('/api/create', response_model=schemas.Record)
async def post(record: schemas.RecordBase = Body(...), db: Session = Depends(get_db)):
return crud.create_record(record, db)
@app.get('/api/{place}/waiting_time', response_model=timedelta)
async def waiting_time(place: str, db: Session = Depends(get_db)):
return crud.get_waiting_time(place, db)
@app.get('/api/{place}/stats/{day}/{min_time_hour}/{min_time_mn}/{max_time_hour}/{max_time_mn}/{interval}', response_model=list)
async def stats(place: str, day: int, min_time_hour: int, min_time_mn: int,
max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session = Depends(get_db)):
return crud.get_stats(place, day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval, db)
""" """
......
...@@ -15,3 +15,4 @@ uvicorn==0.17.6 ...@@ -15,3 +15,4 @@ uvicorn==0.17.6
SQLAlchemy==1.4.19 SQLAlchemy==1.4.19
python-dotenv==0.18.0 python-dotenv==0.18.0
PyMySQL==1.0.2 PyMySQL==1.0.2
pytz==2022.1
\ No newline at end of file
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from typing import List
from db import schemas, crud
from db.database import get_db
router = APIRouter(prefix="/api/comments", tags=["comments"])
@router.get('/{place}', response_model=List[schemas.Comment])
async def get_comments(place: str, page: int=1, db: Session = Depends(get_db)):
return crud.get_comments(place, page, db)
@router.post('/{place}', response_model=schemas.Comment)
async def create_comment(place: str, comment: schemas.CommentBase, db: Session = Depends(get_db)):
return crud.create_comment(place, comment, db)
@router.delete('/{id}', response_model=None)
async def delete_comment(id: int, db: Session = Depends(get_db)):
return crud.delete_comment(id, db)
\ No newline at end of file
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from typing import List
from db import schemas, crud
from db.database import get_db
router = APIRouter(prefix="/api/news", tags=["news"])
@router.get('/{place}', response_model=List[schemas.News])
async def get_news(place: str, db: Session = Depends(get_db)):
return crud.get_news(place, db)
@router.post('/{place}', response_model=schemas.News)
async def create_news(place: str, news: schemas.NewsBase, db: Session = Depends(get_db)):
return crud.create_news(place, news, db)
@router.delete('/{id}', response_model=None)
async def delete_news(id: int, db: Session = Depends(get_db)):
return crud.delete_news(id, db)
\ No newline at end of file
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from datetime import timedelta
from typing import List
from db import crud
from db.database import get_db
router = APIRouter(prefix="/api", tags=["stats"])
@router.get('/{place}/waiting_time', response_model=timedelta)
async def waiting_time(place: str, db: Session = Depends(get_db)):
return crud.get_waiting_time(place, db)
@router.get('/{place}/stats/{day}/{min_time_hour}/{min_time_mn}/{max_time_hour}/{max_time_mn}/{interval}', response_model=list)
async def stats(place: str, day: int, min_time_hour: int, min_time_mn: int,
max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session = Depends(get_db)):
return crud.get_stats(place, day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval, db)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment