[add]: refactor/clean up

This commit is contained in:
VivianDee
2025-09-09 10:57:47 +01:00
parent d9b6a7e92e
commit 4e22161088
10 changed files with 240 additions and 26 deletions
-26
View File
@@ -1,26 +0,0 @@
from flask import Flask
import os
from .extensions import db, migrate
"""
Salary Analytics Package
A package for analyzing and predicting salary patterns from transaction data.
"""
__version__ = "0.1.0"
def create_app():
app = Flask(__name__)
app.config.from_object('salary_analytics.config')
# Initialize extensions
db.init_app(app)
migrate.init_app(app, db)
# Register blueprints or CLI commands here if needed
from app.analytics.commands import commands
app.cli.add_command(commands.upload_xls_cli)
return app
+21
View File
@@ -0,0 +1,21 @@
from flask import Flask
import os
from app.extensions import db, migrate
def create_app():
app = Flask(__name__)
# Load configuration from config.py
app.config.from_object('app.config')
# Initialize extensions
db.init_app(app)
migrate.init_app(app, db)
# Register blueprints or CLI commands here if needed
from app.api.commands import commands
app.cli.add_command(commands.upload_xls_cli)
return app
+4
View File
@@ -0,0 +1,4 @@
from .raw_transaction import RawTransaction
__all__ = ['RawTransaction']
+40
View File
@@ -0,0 +1,40 @@
from fastapi import FastAPI
from app.salary_analytics.routes import analysis, reports, pipeline, load, base, train
from app.salary_analytics.middlewares.middleware import add_middlewares
from app.salary_analytics.events.lifecycle import register_events
from app.utils.logger import logger
import socket
"""
Salary Analytics Package
A package for analyzing and predicting salary patterns from transaction data.
"""
__version__ = "0.1.0"
def create_app() -> FastAPI:
app = FastAPI(
title="Salary Analytics API",
description="API for analyzing and predicting salary patterns from transaction data",
version="1.0.0"
)
# Middlewares
add_middlewares(app)
# Events
register_events(app)
# Routers
app.include_router(base.router, tags=["Base"])
app.include_router(analysis.router, prefix="/analyze", tags=["Analysis"])
app.include_router(reports.router, tags=["Reports"])
app.include_router(pipeline.router, tags=["Pipeline"])
app.include_router(load.router, tags=["Data"])
app.include_router(train.router, tags=["Model Training"])
return app
app = create_app()
+64
View File
@@ -0,0 +1,64 @@
from app.salary_analytics.services.main import SalaryAnalyticsPipeline
from app.salary_analytics.services.data_loader import DataLoader
class GlobalState:
def __init__(self):
self._pipeline = None
self._data_loader = None
self.df = None
self.salary_predictor = None
self.salary_earner_analyzer = None
# ---- Pipeline ----
@property
def pipeline(self):
if self._pipeline is None:
self._pipeline = SalaryAnalyticsPipeline()
return self._pipeline
@pipeline.setter
def pipeline(self, value):
self._pipeline = value
# ---- Data Loader ----
@property
def data_loader(self):
if self._data_loader is None:
self._data_loader = DataLoader()
return self._data_loader
@data_loader.setter
def data_loader(self, value):
self._data_loader = value
# ---- DataFrame ----
@property
def df(self):
return self._df
@df.setter
def df(self, value):
self._df = value
# ---- Salary Predictor ----
@property
def salary_predictor(self):
return self._salary_predictor
@salary_predictor.setter
def salary_predictor(self, value):
self._salary_predictor = value
# ---- Salary Earner Analyzer ----
@property
def salary_earner_analyzer(self):
return self._salary_earner_analyzer
@salary_earner_analyzer.setter
def salary_earner_analyzer(self, value):
self._salary_earner_analyzer = value
state = GlobalState()
+36
View File
@@ -0,0 +1,36 @@
import socket
from fastapi import FastAPI
from app.salary_analytics.integrations.salary_detect import SalaryDetect
from app.utils.logger import logger
salary_detect = SalaryDetect()
def register_events(app: FastAPI):
@app.on_event("startup")
async def startup_event():
"""Initialize the pipeline on startup."""
try:
logger.info("Initializing pipeline...")
# Start autonomous salary detection loop
salary_detect.start()
logger.info("Started autonomous salary detection loop.")
# Print network information
hostname = socket.gethostname()
ip_address = socket.gethostbyname(hostname)
logger.info(f"Server running on hostname: {hostname}")
logger.info(f"Server IP address: {ip_address}")
logger.info(f"Server is accessible at:")
logger.info(f"- http://localhost:8000")
logger.info(f"- http://127.0.0.1:8000")
logger.info(f"- http://{ip_address}:8000")
logger.info("Pipeline initialized successfully")
except Exception as e:
logger.error(f"Error during startup: {str(e)}")
raise
@app.on_event("shutdown")
async def shutdown_event():
logger.info("Shutting down Salary Analytics API...")
@@ -0,0 +1,12 @@
from fastapi import HTTPException
from app.salary_analytics.core.state import state
def check_data_loaded():
"""Raise HTTP 400 if no data is loaded into the pipeline."""
if state.pipeline.df is None:
raise HTTPException(
status_code=400,
detail="No data loaded. Please load data first using the /load-data endpoint."
)
return True
+28
View File
@@ -0,0 +1,28 @@
from fastapi import APIRouter
from app.utils.logger import logger
import time
router = APIRouter()
@router.get("/")
async def root():
"""Root endpoint."""
start_time = time.time()
logger.info("Root endpoint accessed")
response = {"message": "Welcome to Salary Analytics API"}
logger.info(f"Root endpoint completed in {time.time() - start_time:.2f} seconds")
return response
@router.get("/health")
async def health_check():
"""Health check endpoint."""
start_time = time.time()
logger.info("Health check endpoint accessed")
response = {"status": "healthy"}
logger.info(f"Health check completed in {time.time() - start_time:.2f} seconds")
return response
+33
View File
@@ -0,0 +1,33 @@
import time
import logging
from fastapi import APIRouter, HTTPException
from app.salary_analytics.services.main import SalaryAnalyticsPipeline
from app.salary_analytics.helpers.data_checks import check_data_loaded
from app.salary_analytics.helpers.response_helpers import AnalysisResponse
from app.salary_analytics.core.state import state
from app.utils.logger import logger
router = APIRouter()
@router.post("/train/models", response_model=AnalysisResponse)
async def train_models():
"""Train salary prediction models."""
start_time = time.time()
try:
check_data_loaded()
logger.info("Starting model training...")
state.pipeline.train_salary_prediction_models()
logger.info("Models trained successfully")
response = AnalysisResponse(
message="Models trained successfully"
)
logger.info(f"Model training endpoint completed in {time.time() - start_time:.2f} seconds")
return response
except Exception as e:
logger.error(f"Error in model training: {str(e)}")
logger.info(f"Model training endpoint failed after {time.time() - start_time:.2f} seconds")
raise HTTPException(status_code=500, detail=str(e))
+2
View File
@@ -1,6 +1,8 @@
services:
digifi-analytics:
build: .
env_file:
- .env
ports:
- "${APP_PORT:-4800}:8000"
environment: