adding base project
This commit is contained in:
+156
@@ -0,0 +1,156 @@
|
||||
import os
|
||||
import importlib
|
||||
import pkgutil
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.database import Base, engine, SessionLocal
|
||||
from app.core.security import get_password_hash
|
||||
from app.auth.models import AppUser, Role
|
||||
from app.menu.models import GrpMenuAccess
|
||||
|
||||
from app.auth.router import router as auth_router
|
||||
from app.menu.router import router as menu_router
|
||||
|
||||
def init_db_and_seed():
|
||||
"""Creates database tables and seeds initial administrator & menu access."""
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
# Auto-migration safeguard for existing databases
|
||||
try:
|
||||
from sqlalchemy import text
|
||||
with engine.connect() as conn:
|
||||
conn.execute(text("ALTER TABLE app_users ADD COLUMN random_no VARCHAR(50);"))
|
||||
conn.commit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
db: Session = SessionLocal()
|
||||
try:
|
||||
# 1. Seed Roles
|
||||
admin_role = db.query(Role).filter(Role.name == "ROLE_ADMIN").first()
|
||||
if not admin_role:
|
||||
admin_role = Role(name="ROLE_ADMIN", description="Admin")
|
||||
db.add(admin_role)
|
||||
|
||||
user_role = db.query(Role).filter(Role.name == "ROLE_USER").first()
|
||||
if not user_role:
|
||||
user_role = Role(name="ROLE_USER", description="User")
|
||||
db.add(user_role)
|
||||
db.commit()
|
||||
|
||||
# 2. Seed Admin User
|
||||
admin_user = db.query(AppUser).filter(AppUser.email == "admin@cns.com").first()
|
||||
if not admin_user:
|
||||
admin_user = AppUser(
|
||||
email="admin@cns.com",
|
||||
username="admin",
|
||||
password=get_password_hash("admin123"),
|
||||
full_name="Admin User",
|
||||
first_name="Admin",
|
||||
last_name="User",
|
||||
status="ACTIVE",
|
||||
user_grp_id=1,
|
||||
is_active=True
|
||||
)
|
||||
admin_user.roles.append(admin_role)
|
||||
db.add(admin_user)
|
||||
db.commit()
|
||||
|
||||
# 3. Seed Default Menu Items
|
||||
root_menu = db.query(GrpMenuAccess).filter(GrpMenuAccess.menu_id == 0, GrpMenuAccess.menu_item_id == 1).first()
|
||||
if not root_menu:
|
||||
root_menu = GrpMenuAccess(
|
||||
menu_id=0,
|
||||
menu_item_id=1,
|
||||
menu_item_desc="Core Modules",
|
||||
module_name="Core",
|
||||
main_menu_action_name="/cns-portal",
|
||||
main_menu_icon_name="cog",
|
||||
item_seq=1,
|
||||
status="A",
|
||||
role="Admin",
|
||||
usr_grp=1
|
||||
)
|
||||
db.add(root_menu)
|
||||
db.commit()
|
||||
|
||||
# Submenu pointing to Azzu entity
|
||||
sub_menu = GrpMenuAccess(
|
||||
menu_id=1,
|
||||
menu_item_id=2,
|
||||
menu_item_desc="Azzu Management",
|
||||
module_name="Core",
|
||||
main_menu_action_name="/cns-portal/azzu",
|
||||
main_menu_icon_name="file",
|
||||
item_seq=1,
|
||||
status="A",
|
||||
role="Admin",
|
||||
usr_grp=1
|
||||
)
|
||||
db.add(sub_menu)
|
||||
db.commit()
|
||||
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def auto_discover_entity_routers(app: FastAPI):
|
||||
"""
|
||||
Automatically discovers and includes any entity controllers located under app/io8ref/*/controllers.py
|
||||
"""
|
||||
io8ref_dir = os.path.join(os.path.dirname(__file__), "io8ref")
|
||||
if not os.path.exists(io8ref_dir):
|
||||
return
|
||||
|
||||
for item in os.listdir(io8ref_dir):
|
||||
entity_dir = os.path.join(io8ref_dir, item)
|
||||
if os.path.isdir(entity_dir) and os.path.exists(os.path.join(entity_dir, "controllers.py")):
|
||||
try:
|
||||
module = importlib.import_module(f"app.io8ref.{item}.controllers")
|
||||
if hasattr(module, "router"):
|
||||
app.include_router(module.router)
|
||||
print(f"✓ Registered Entity Router: {item}")
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to load entity router {item}: {e}")
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
# Startup:
|
||||
init_db_and_seed()
|
||||
yield
|
||||
# Shutdown
|
||||
|
||||
app = FastAPI(
|
||||
title=settings.PROJECT_NAME,
|
||||
description="Drop-in Python FastAPI Base Project compatible with Angular Clarity, React, and Code Extractor V2",
|
||||
version="1.0.0",
|
||||
lifespan=lifespan
|
||||
)
|
||||
|
||||
# CORS Middleware
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Core Routers
|
||||
app.include_router(auth_router)
|
||||
app.include_router(menu_router)
|
||||
|
||||
# Dynamically Register Generated Entities
|
||||
auto_discover_entity_routers(app)
|
||||
|
||||
@app.get("/", tags=["Health"])
|
||||
@app.get("/health", tags=["Health"])
|
||||
def health_check():
|
||||
return {
|
||||
"status": "UP",
|
||||
"service": settings.PROJECT_NAME,
|
||||
"docs_url": "/docs"
|
||||
}
|
||||
Reference in New Issue
Block a user