3v324v23 commited on
Commit
3b7d047
·
2 Parent(s): 65a6d79 227477c

merge: Merge feat/database into dev

Browse files
DB_SCHEMA.md ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Database Schema Documentation
2
+
3
+ The application uses a single table `prediction_logs` to store all prediction requests and results.
4
+
5
+ ## Table: `prediction_logs`
6
+
7
+ | Column Name | Type | Description |
8
+ | :--- | :--- | :--- |
9
+ | `id` | Integer | Primary Key, Auto-increment |
10
+ | `timestamp` | DateTime | Timestamp of the prediction (UTC) |
11
+ | `prediction` | Integer | Predicted class (0 or 1) |
12
+ | `probability` | Float | Probability of the positive class (optional) |
13
+ | `age` | Integer | Age of the employee |
14
+ | `genre` | String | Gender (M/F) |
15
+ | `revenu_mensuel` | Integer | Monthly income |
16
+ | `statut_marital` | String | Marital status |
17
+ | `departement` | String | Department |
18
+ | `poste` | String | Job title |
19
+ | `nombre_experiences_precedentes` | Integer | Number of previous companies |
20
+ | `nombre_heures_travailless` | Integer | Hours worked |
21
+ | `annee_experience_totale` | Integer | Total working years |
22
+ | `annees_dans_l_entreprise` | Integer | Years at current company |
23
+ | `annees_dans_le_poste_actuel` | Integer | Years in current role |
24
+ | `satisfaction_employee_environnement` | Integer | Environment satisfaction (1-4) |
25
+ | `note_evaluation_precedente` | Integer | Previous performance rating |
26
+ | `niveau_hierarchique_poste` | Integer | Job level |
27
+ | `satisfaction_employee_nature_travail` | Integer | Job involvement (1-4) |
28
+ | `satisfaction_employee_equipe` | Integer | Relationship satisfaction (1-4) |
29
+ | `satisfaction_employee_equilibre_pro_perso` | Integer | Work-life balance (1-4) |
30
+ | `note_evaluation_actuelle` | Integer | Current performance rating |
31
+ | `heure_supplementaires` | String | Overtime (Yes/No) |
32
+ | `augementation_salaire_precedente` | String | Percent salary hike |
33
+ | `nombre_participation_pee` | Integer | Stock option level |
34
+ | `nb_formations_suivies` | Integer | Training times last year |
35
+ | `nombre_employee_sous_responsabilite` | Integer | Number of subordinates |
36
+ | `distance_domicile_travail` | Integer | Distance from home |
37
+ | `niveau_education` | Integer | Education level (1-5) |
38
+ | `domaine_etude` | String | Education field |
39
+ | `ayant_enfants` | String | Has children (Yes/No) |
40
+ | `frequence_deplacement` | String | Business travel frequency |
41
+ | `annees_depuis_la_derniere_promotion` | Integer | Years since last promotion |
42
+ | `annes_sous_responsable_actuel` | Integer | Years with current manager |
43
+
44
+ ## Relationships
45
+ No relationships as this is a single-table logging schema for this POC.
app/core/config.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ class Settings:
4
+ PROJECT_NAME: str = "ML Prediction API"
5
+ PROJECT_VERSION: str = "1.0.0"
6
+
7
+ # Database
8
+ DATABASE_URL: str = os.getenv("DATABASE_URL", "postgresql://postgres:pwd@localhost:5432/prediction_db")
9
+
10
+ # Security
11
+ API_KEY: str = os.getenv("API_KEY", "default_insecure_key")
12
+
13
+ # Model
14
+ MODEL_PATH: str = os.getenv("MODEL_PATH", "02_xgb_model_tuned.pkl")
15
+
16
+ settings = Settings()
app/core/database.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import create_engine
2
+ from sqlalchemy.ext.declarative import declarative_base
3
+ from sqlalchemy.orm import sessionmaker
4
+ from app.core.config import settings
5
+
6
+ # Handle cases where DATABASE_URL might start with postgres:// (Heroku style) instead of postgresql://
7
+ SQLALCHEMY_DATABASE_URL = settings.DATABASE_URL
8
+ if SQLALCHEMY_DATABASE_URL and SQLALCHEMY_DATABASE_URL.startswith("postgres://"):
9
+ SQLALCHEMY_DATABASE_URL = SQLALCHEMY_DATABASE_URL.replace("postgres://", "postgresql://", 1)
10
+
11
+ engine = create_engine(SQLALCHEMY_DATABASE_URL)
12
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
13
+
14
+ Base = declarative_base()
15
+
16
+ def get_db():
17
+ db = SessionLocal()
18
+ try:
19
+ yield db
20
+ finally:
21
+ db.close()
app/models/models.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Column, Integer, String, Float, DateTime
2
+ from sqlalchemy.sql import func
3
+ from app.core.database import Base
4
+
5
+ class PredictionLog(Base):
6
+ __tablename__ = "prediction_logs"
7
+
8
+ id = Column(Integer, primary_key=True, index=True)
9
+ timestamp = Column(DateTime(timezone=True), server_default=func.now())
10
+
11
+ # Input features
12
+ age = Column(Integer)
13
+ genre = Column(String)
14
+ revenu_mensuel = Column(Integer)
15
+ statut_marital = Column(String)
16
+ departement = Column(String)
17
+ poste = Column(String)
18
+ nombre_experiences_precedentes = Column(Integer)
19
+ nombre_heures_travailless = Column(Integer)
20
+ annee_experience_totale = Column(Integer)
21
+ annees_dans_l_entreprise = Column(Integer)
22
+ annees_dans_le_poste_actuel = Column(Integer)
23
+ satisfaction_employee_environnement = Column(Integer)
24
+ note_evaluation_precedente = Column(Integer)
25
+ niveau_hierarchique_poste = Column(Integer)
26
+ satisfaction_employee_nature_travail = Column(Integer)
27
+ satisfaction_employee_equipe = Column(Integer)
28
+ satisfaction_employee_equilibre_pro_perso = Column(Integer)
29
+ note_evaluation_actuelle = Column(Integer)
30
+ heure_supplementaires = Column(String)
31
+ augementation_salaire_precedente = Column(String)
32
+ nombre_participation_pee = Column(Integer)
33
+ nb_formations_suivies = Column(Integer)
34
+ nombre_employee_sous_responsabilite = Column(Integer)
35
+ distance_domicile_travail = Column(Integer)
36
+ niveau_education = Column(Integer)
37
+ domaine_etude = Column(String)
38
+ ayant_enfants = Column(String)
39
+ frequence_deplacement = Column(String)
40
+ annees_depuis_la_derniere_promotion = Column(Integer)
41
+ annes_sous_responsable_actuel = Column(Integer)
42
+
43
+ # Output
44
+ prediction = Column(Integer)
45
+ probability = Column(Float, nullable=True)
app/models/schemas.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from typing import Optional
3
+
4
+ class InputSchema(BaseModel):
5
+ age: int
6
+ genre: str
7
+ revenu_mensuel: int
8
+ statut_marital: str
9
+ departement: str
10
+ poste: str
11
+ nombre_experiences_precedentes: int
12
+ nombre_heures_travailless: int
13
+ annee_experience_totale: int
14
+ annees_dans_l_entreprise: int
15
+ annees_dans_le_poste_actuel: int
16
+ satisfaction_employee_environnement: int
17
+ note_evaluation_precedente: int
18
+ niveau_hierarchique_poste: int
19
+ satisfaction_employee_nature_travail: int
20
+ satisfaction_employee_equipe: int
21
+ satisfaction_employee_equilibre_pro_perso: int
22
+ note_evaluation_actuelle: int
23
+ heure_supplementaires: str
24
+ augementation_salaire_precedente: str
25
+ nombre_participation_pee: int
26
+ nb_formations_suivies: int
27
+ nombre_employee_sous_responsabilite: int
28
+ distance_domicile_travail: int
29
+ niveau_education: int
30
+ domaine_etude: str
31
+ ayant_enfants: str
32
+ frequence_deplacement: str
33
+ annees_depuis_la_derniere_promotion: int
34
+ annes_sous_responsable_actuel: int
35
+
36
+ class PredictionOutput(BaseModel):
37
+ prediction: int
38
+ probability: Optional[float] = None
scripts/create_db.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from app.core.database import Base, engine
2
+ from app.models.models import PredictionLog
3
+
4
+ def create_tables():
5
+ print("Creating database")
6
+ Base.metadata.create_all(bind=engine)
7
+ print("Tables created")
8
+
9
+ if __name__ == "__main__":
10
+ create_tables()