[add]: refactor/clean up
This commit is contained in:
@@ -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
|
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
from .raw_transaction import RawTransaction
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['RawTransaction']
|
||||||
@@ -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()
|
||||||
@@ -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()
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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))
|
||||||
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
services:
|
services:
|
||||||
digifi-analytics:
|
digifi-analytics:
|
||||||
build: .
|
build: .
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT:-4800}:8000"
|
- "${APP_PORT:-4800}:8000"
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
Reference in New Issue
Block a user