Spaces:
Sleeping
Sleeping
Commit Β·
ca677e2
1
Parent(s): 9547157
add bcrypt requirement
Browse files- app/main.py +18 -15
- app/seeder.py +22 -26
- requirements.txt +1 -0
app/main.py
CHANGED
|
@@ -9,7 +9,8 @@ from app.core.database import engine, Base
|
|
| 9 |
from app.seeder import seed_admins
|
| 10 |
from app.api.v1.endpoints import (
|
| 11 |
auth, conversation, phoneme, dashboard, material,
|
| 12 |
-
talents, history, exam, transcribe, interview_flow,
|
|
|
|
| 13 |
)
|
| 14 |
|
| 15 |
@asynccontextmanager
|
|
@@ -17,10 +18,9 @@ async def lifespan(app: FastAPI):
|
|
| 17 |
async with engine.begin() as conn:
|
| 18 |
await conn.run_sync(Base.metadata.create_all)
|
| 19 |
try:
|
| 20 |
-
print("π± Running Auto-Seeder...")
|
| 21 |
await seed_admins()
|
| 22 |
except Exception as e:
|
| 23 |
-
print(f"
|
| 24 |
|
| 25 |
yield
|
| 26 |
|
|
@@ -41,23 +41,26 @@ async def app_exception_handler(request: Request, exc: AppError):
|
|
| 41 |
content={"success": False, "message": str(exc.detail), "data": None},
|
| 42 |
)
|
| 43 |
|
| 44 |
-
|
|
|
|
|
|
|
| 45 |
app.include_router(auth.router, prefix="/web/admin", tags=["Auth Admin"])
|
| 46 |
app.include_router(dashboard.router, prefix="/web/admin", tags=["Dashboard"])
|
| 47 |
app.include_router(material.router, prefix="/web/admin", tags=["Material"])
|
| 48 |
app.include_router(talents.router, prefix="/web/admin/talents", tags=["Talent Management"])
|
| 49 |
|
| 50 |
-
#
|
| 51 |
-
app.include_router(auth.router, prefix="/
|
| 52 |
-
app.include_router(
|
| 53 |
-
app.include_router(
|
| 54 |
-
app.include_router(
|
| 55 |
-
app.include_router(
|
| 56 |
-
app.include_router(
|
| 57 |
-
app.include_router(
|
| 58 |
-
app.include_router(
|
| 59 |
-
app.include_router(
|
|
|
|
| 60 |
|
| 61 |
@app.get("/")
|
| 62 |
def root():
|
| 63 |
-
return {"message": "TalentaTalk API v1.
|
|
|
|
| 9 |
from app.seeder import seed_admins
|
| 10 |
from app.api.v1.endpoints import (
|
| 11 |
auth, conversation, phoneme, dashboard, material,
|
| 12 |
+
talents, history, exam, transcribe, interview_flow,
|
| 13 |
+
mobile_profile, pretest, home
|
| 14 |
)
|
| 15 |
|
| 16 |
@asynccontextmanager
|
|
|
|
| 18 |
async with engine.begin() as conn:
|
| 19 |
await conn.run_sync(Base.metadata.create_all)
|
| 20 |
try:
|
|
|
|
| 21 |
await seed_admins()
|
| 22 |
except Exception as e:
|
| 23 |
+
print(f"Startup Seeder Error: {e}")
|
| 24 |
|
| 25 |
yield
|
| 26 |
|
|
|
|
| 41 |
content={"success": False, "message": str(exc.detail), "data": None},
|
| 42 |
)
|
| 43 |
|
| 44 |
+
api_v1 = settings.API_V1_STR
|
| 45 |
+
|
| 46 |
+
# Admin Routes
|
| 47 |
app.include_router(auth.router, prefix="/web/admin", tags=["Auth Admin"])
|
| 48 |
app.include_router(dashboard.router, prefix="/web/admin", tags=["Dashboard"])
|
| 49 |
app.include_router(material.router, prefix="/web/admin", tags=["Material"])
|
| 50 |
app.include_router(talents.router, prefix="/web/admin/talents", tags=["Talent Management"])
|
| 51 |
|
| 52 |
+
# Mobile Routes
|
| 53 |
+
app.include_router(auth.router, prefix=f"{api_v1}/auth", tags=["Auth Mobile"])
|
| 54 |
+
app.include_router(home.router, prefix=f"{api_v1}/home", tags=["Home"])
|
| 55 |
+
app.include_router(conversation.router, prefix=f"{api_v1}/conversation", tags=["Conversation"])
|
| 56 |
+
app.include_router(interview_flow.router, prefix=f"{api_v1}/interview", tags=["Interview"])
|
| 57 |
+
app.include_router(phoneme.router, prefix=f"{api_v1}/phoneme", tags=["Phoneme"])
|
| 58 |
+
app.include_router(history.router, prefix=f"{api_v1}/history", tags=["History"])
|
| 59 |
+
app.include_router(exam.router, prefix=f"{api_v1}/exam", tags=["Exam"])
|
| 60 |
+
app.include_router(transcribe.router, prefix=api_v1, tags=["Transcribe"])
|
| 61 |
+
app.include_router(mobile_profile.router, prefix=f"{api_v1}/profile", tags=["Profile Mobile"])
|
| 62 |
+
app.include_router(pretest.router, prefix=f"{api_v1}/pretest", tags=["Pretest"])
|
| 63 |
|
| 64 |
@app.get("/")
|
| 65 |
def root():
|
| 66 |
+
return {"message": "TalentaTalk API v1.9 (Bcrypt Fix) Running"}
|
app/seeder.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
import asyncio
|
| 2 |
import logging
|
| 3 |
from passlib.context import CryptContext
|
| 4 |
-
from sqlalchemy import delete
|
| 5 |
from app.core.database import AsyncSessionLocal, engine, Base
|
| 6 |
from app.models.models import Manajemen
|
| 7 |
|
| 8 |
-
# Logging
|
| 9 |
logging.basicConfig(level=logging.INFO)
|
| 10 |
logger = logging.getLogger(__name__)
|
| 11 |
|
|
@@ -15,7 +15,7 @@ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
| 15 |
def get_password_hash(password: str) -> str:
|
| 16 |
return pwd_context.hash(password)
|
| 17 |
|
| 18 |
-
# Data Admin
|
| 19 |
ADMIN_DATA = [
|
| 20 |
{
|
| 21 |
"namamanajemen": "Admin",
|
|
@@ -24,38 +24,34 @@ ADMIN_DATA = [
|
|
| 24 |
}
|
| 25 |
]
|
| 26 |
|
| 27 |
-
async def
|
| 28 |
-
logger.info("π οΈ Memeriksa dan membuat tabel database...")
|
| 29 |
async with engine.begin() as conn:
|
| 30 |
await conn.run_sync(Base.metadata.create_all)
|
| 31 |
-
logger.info("β
Tabel siap.")
|
| 32 |
-
|
| 33 |
-
async def seed_admins():
|
| 34 |
-
await init_tables()
|
| 35 |
-
logger.info("π± Memulai clean seeding data Admin...")
|
| 36 |
|
| 37 |
async with AsyncSessionLocal() as session:
|
| 38 |
try:
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
email=data["email"],
|
| 49 |
-
password=get_password_hash(data["password"])
|
| 50 |
)
|
| 51 |
-
session.add(
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
except Exception as e:
|
| 57 |
await session.rollback()
|
| 58 |
-
logger.error(f"β Seeder
|
| 59 |
finally:
|
| 60 |
await session.close()
|
| 61 |
|
|
|
|
| 1 |
import asyncio
|
| 2 |
import logging
|
| 3 |
from passlib.context import CryptContext
|
| 4 |
+
from sqlalchemy import select, delete
|
| 5 |
from app.core.database import AsyncSessionLocal, engine, Base
|
| 6 |
from app.models.models import Manajemen
|
| 7 |
|
| 8 |
+
# Logging config
|
| 9 |
logging.basicConfig(level=logging.INFO)
|
| 10 |
logger = logging.getLogger(__name__)
|
| 11 |
|
|
|
|
| 15 |
def get_password_hash(password: str) -> str:
|
| 16 |
return pwd_context.hash(password)
|
| 17 |
|
| 18 |
+
# Data Admin Default
|
| 19 |
ADMIN_DATA = [
|
| 20 |
{
|
| 21 |
"namamanajemen": "Admin",
|
|
|
|
| 24 |
}
|
| 25 |
]
|
| 26 |
|
| 27 |
+
async def seed_admins():
|
|
|
|
| 28 |
async with engine.begin() as conn:
|
| 29 |
await conn.run_sync(Base.metadata.create_all)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
async with AsyncSessionLocal() as session:
|
| 32 |
try:
|
| 33 |
+
result = await session.execute(select(Manajemen).where(Manajemen.email == ADMIN_DATA[0]["email"]))
|
| 34 |
+
existing_admin = result.scalar_one_or_none()
|
| 35 |
+
|
| 36 |
+
if not existing_admin:
|
| 37 |
+
logger.info("π± Seeding Admin Baru...")
|
| 38 |
+
new_admin = Manajemen(
|
| 39 |
+
namamanajemen=ADMIN_DATA[0]["namamanajemen"],
|
| 40 |
+
email=ADMIN_DATA[0]["email"],
|
| 41 |
+
password=get_password_hash(ADMIN_DATA[0]["password"])
|
|
|
|
|
|
|
| 42 |
)
|
| 43 |
+
session.add(new_admin)
|
| 44 |
+
await session.commit()
|
| 45 |
+
logger.info("β
Admin berhasil dibuat: admin@gmail.com / admin123")
|
| 46 |
+
else:
|
| 47 |
+
logger.info("π Admin ditemukan, mereset password ke default...")
|
| 48 |
+
existing_admin.password = get_password_hash(ADMIN_DATA[0]["password"])
|
| 49 |
+
await session.commit()
|
| 50 |
+
logger.info("β
Password Admin di-reset: admin123")
|
| 51 |
|
| 52 |
except Exception as e:
|
| 53 |
await session.rollback()
|
| 54 |
+
logger.error(f"β Seeder Error: {e}")
|
| 55 |
finally:
|
| 56 |
await session.close()
|
| 57 |
|
requirements.txt
CHANGED
|
@@ -8,6 +8,7 @@ pydantic-settings>=2.1.0
|
|
| 8 |
email-validator>=2.1.0
|
| 9 |
python-jose[cryptography]
|
| 10 |
passlib[bcrypt]
|
|
|
|
| 11 |
python-multipart
|
| 12 |
python-dotenv
|
| 13 |
aiohttp
|
|
|
|
| 8 |
email-validator>=2.1.0
|
| 9 |
python-jose[cryptography]
|
| 10 |
passlib[bcrypt]
|
| 11 |
+
bcrypt==4.0.1
|
| 12 |
python-multipart
|
| 13 |
python-dotenv
|
| 14 |
aiohttp
|