Refactor: deplacer backend dans apps/backend
This commit is contained in:
1 parent
ca3de277b4
commit
357b47bd61
18 files changed
+3
-3
No files matched your search
@@ -0,0 +1,38 @@
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm import declarative_base
|
||||
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
|
||||
load_dotenv()
|
||||
|
||||
DATABASE_URL = (
|
||||
f"mysql+pymysql://"
|
||||
f"{os.getenv('DB_USER')}:"
|
||||
f"{os.getenv('DB_PASSWORD')}@"
|
||||
f"{os.getenv('DB_HOST')}:"
|
||||
f"{os.getenv('DB_PORT')}/"
|
||||
f"{os.getenv('DB_NAME')}"
|
||||
)
|
||||
|
||||
engine = create_engine(
|
||||
DATABASE_URL,
|
||||
pool_pre_ping=True
|
||||
)
|
||||
|
||||
SessionLocal = sessionmaker(
|
||||
autocommit=False,
|
||||
autoflush=False,
|
||||
bind=engine
|
||||
)
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
def get_db():
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
@@ -0,0 +1,9 @@
|
||||
from fastapi import FastAPI
|
||||
|
||||
from app.routers import projects, experiences, skills
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
app.include_router(projects.router, prefix="/api")
|
||||
app.include_router(experiences.router, prefix="/api")
|
||||
app.include_router(skills.router, prefix="/api")
|
||||
@@ -0,0 +1,47 @@
|
||||
from app.models.experience_task import ExperienceTask
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Integer,
|
||||
String
|
||||
)
|
||||
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class Experience(Base):
|
||||
__tablename__ = "experiences"
|
||||
|
||||
id = Column(
|
||||
Integer,
|
||||
primary_key=True,
|
||||
index=True
|
||||
)
|
||||
|
||||
company = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
location = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
duration = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
role = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
tasks = relationship(
|
||||
"ExperienceTask",
|
||||
back_populates="experience",
|
||||
cascade="all, delete-orphan"
|
||||
)
|
||||
@@ -0,0 +1,39 @@
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Integer,
|
||||
String,
|
||||
ForeignKey
|
||||
)
|
||||
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class ExperienceTask(Base):
|
||||
__tablename__ = "experience_tasks"
|
||||
|
||||
id = Column(
|
||||
Integer,
|
||||
primary_key=True,
|
||||
index=True
|
||||
)
|
||||
|
||||
description = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
experience_id = Column(
|
||||
Integer,
|
||||
ForeignKey(
|
||||
"experiences.id",
|
||||
ondelete="CASCADE"
|
||||
),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
experience = relationship(
|
||||
"Experience",
|
||||
back_populates="tasks"
|
||||
)
|
||||
@@ -0,0 +1,70 @@
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Integer,
|
||||
String,
|
||||
Text,
|
||||
Boolean
|
||||
)
|
||||
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from app.database import Base
|
||||
from app.models.project_skill import project_skills
|
||||
|
||||
|
||||
class Project(Base):
|
||||
__tablename__ = "projects"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
|
||||
title = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
nb_image = Column(
|
||||
Integer,
|
||||
default=1
|
||||
)
|
||||
|
||||
short_description = Column(
|
||||
Text,
|
||||
nullable=False
|
||||
)
|
||||
|
||||
image_name = Column(
|
||||
String(255),
|
||||
nullable=False,
|
||||
default="empty"
|
||||
)
|
||||
|
||||
school = Column(
|
||||
Boolean,
|
||||
nullable=False
|
||||
)
|
||||
|
||||
long_description = Column(
|
||||
Text,
|
||||
nullable=False
|
||||
)
|
||||
|
||||
repo_link = Column(
|
||||
String(255),
|
||||
nullable=True
|
||||
)
|
||||
|
||||
beginning_year = Column(
|
||||
Integer,
|
||||
nullable=False
|
||||
)
|
||||
|
||||
end_year = Column(
|
||||
Integer,
|
||||
nullable=True
|
||||
)
|
||||
|
||||
skills = relationship(
|
||||
"Skill",
|
||||
secondary=project_skills,
|
||||
back_populates="projects"
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
from sqlalchemy import Table, Column, Integer, ForeignKey
|
||||
|
||||
from app.database import Base
|
||||
|
||||
project_skills = Table(
|
||||
"project_skills",
|
||||
Base.metadata,
|
||||
|
||||
Column(
|
||||
"project_id",
|
||||
Integer,
|
||||
ForeignKey("projects.id", ondelete="CASCADE"),
|
||||
primary_key=True
|
||||
),
|
||||
|
||||
Column(
|
||||
"skill_id",
|
||||
Integer,
|
||||
ForeignKey("skills.id", ondelete="CASCADE"),
|
||||
primary_key=True
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
from sqlalchemy import Column, Integer, String
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from app.database import Base
|
||||
from app.models.project_skill import project_skills
|
||||
|
||||
|
||||
class Skill(Base):
|
||||
__tablename__ = "skills"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
|
||||
name = Column(
|
||||
String(255),
|
||||
nullable=False,
|
||||
unique=True
|
||||
)
|
||||
|
||||
type = Column(
|
||||
String(255),
|
||||
nullable=False
|
||||
)
|
||||
|
||||
projects = relationship(
|
||||
"Project",
|
||||
secondary=project_skills,
|
||||
back_populates="skills"
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from app.database import get_db
|
||||
from app.models.experience import Experience
|
||||
from app.schemas.experience import ExperienceResponse
|
||||
|
||||
router = APIRouter(prefix="/experiences", tags=["Experiences"])
|
||||
|
||||
|
||||
@router.get("/", response_model=list[ExperienceResponse])
|
||||
def get_experiences(db: Session = Depends(get_db)):
|
||||
return (
|
||||
db.query(Experience)
|
||||
.options(joinedload(Experience.tasks))
|
||||
.all()
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
|
||||
from app.database import get_db
|
||||
from app.models.project import Project
|
||||
from app.schemas.project import ProjectCard, ProjectPage
|
||||
|
||||
router = APIRouter(prefix="/projects", tags=["Projects"])
|
||||
|
||||
|
||||
@router.get("/", response_model=list[ProjectCard])
|
||||
def get_projects(db: Session = Depends(get_db)):
|
||||
return (
|
||||
db.query(Project)
|
||||
.options(joinedload(Project.skills))
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{project_id}", response_model=ProjectPage)
|
||||
def get_project(project_id: int, db: Session = Depends(get_db)):
|
||||
project = (
|
||||
db.query(Project)
|
||||
.options(joinedload(Project.skills))
|
||||
.filter(Project.id == project_id)
|
||||
.first()
|
||||
)
|
||||
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
|
||||
return project
|
||||
@@ -0,0 +1,13 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.database import get_db
|
||||
from app.models.skill import Skill
|
||||
from app.schemas.skill import SkillResponse
|
||||
|
||||
router = APIRouter(prefix="/skills", tags=["Skills"])
|
||||
|
||||
|
||||
@router.get("/", response_model=list[SkillResponse])
|
||||
def get_skills(db: Session = Depends(get_db)):
|
||||
return db.query(Skill).all()
|
||||
@@ -0,0 +1,20 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ExperienceTaskResponse(BaseModel):
|
||||
id: int
|
||||
description: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
class ExperienceResponse(BaseModel):
|
||||
id: int
|
||||
company: str
|
||||
location: str
|
||||
duration: str
|
||||
role: str
|
||||
tasks: list[ExperienceTaskResponse]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
from pydantic import BaseModel
|
||||
from app.schemas.skill import ProjectSkill
|
||||
|
||||
|
||||
class ProjectCard(BaseModel):
|
||||
id: int
|
||||
title: str
|
||||
short_description: str
|
||||
image_name: str
|
||||
school: bool
|
||||
beginning_year: int
|
||||
end_year: int | None
|
||||
skills: list[ProjectSkill]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ProjectPage(BaseModel):
|
||||
id: int
|
||||
title: str
|
||||
short_description: str
|
||||
long_description: str
|
||||
repo_link: str | None
|
||||
nb_image: int
|
||||
image_name: str
|
||||
school: bool
|
||||
beginning_year: int
|
||||
end_year: int | None
|
||||
skills: list[ProjectSkill]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@@ -0,0 +1,17 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
class SkillResponse(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
type: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ProjectSkill(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
Reference in new issue
Block a user