Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -18,18 +18,18 @@ from jose import JWTError, jwt
|
|
| 18 |
from google import genai
|
| 19 |
import bcrypt
|
| 20 |
|
| 21 |
-
# ==========================================
|
| 22 |
-
# بخش
|
| 23 |
-
# ==========================================
|
| 24 |
logging.basicConfig(level=logging.INFO)
|
| 25 |
logger = logging.getLogger("production_backend")
|
| 26 |
|
| 27 |
# کلید پردازشهای ابری هوشمند (Secrets)
|
| 28 |
AI_CORE_KEY = os.getenv("GEMINI_API_KEY") or os.getenv("SECRET")
|
| 29 |
|
| 30 |
-
# ==========================================
|
| 31 |
-
# بخش
|
| 32 |
-
# ==========================================
|
| 33 |
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./test.db")
|
| 34 |
if DATABASE_URL.startswith("postgres://"):
|
| 35 |
DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1)
|
|
@@ -56,9 +56,9 @@ Base = declarative_base()
|
|
| 56 |
def get_now():
|
| 57 |
return datetime.now(timezone.utc).replace(tzinfo=None)
|
| 58 |
|
| 59 |
-
# ==========================================
|
| 60 |
-
# بخش
|
| 61 |
-
# ==========================================
|
| 62 |
|
| 63 |
class User(Base):
|
| 64 |
__tablename__ = "users"
|
|
@@ -211,9 +211,9 @@ class Review(Base):
|
|
| 211 |
rating = Column(Float, default=5.0)
|
| 212 |
comment = Column(Text, nullable=True)
|
| 213 |
|
| 214 |
-
# ==========================================
|
| 215 |
-
# بخش
|
| 216 |
-
# ==========================================
|
| 217 |
|
| 218 |
def get_password_hash(password: str) -> str:
|
| 219 |
salt = bcrypt.gensalt()
|
|
@@ -230,9 +230,9 @@ SECRET_KEY = os.getenv("JWT_SECRET", "8c12fa4870a23049102c89eeffb8a719280abdc029
|
|
| 230 |
ALGORITHM = "HS256"
|
| 231 |
security = HTTPBearer()
|
| 232 |
|
| 233 |
-
# ==========================================
|
| 234 |
-
# بخش
|
| 235 |
-
# ==========================================
|
| 236 |
|
| 237 |
def clean_expired_bookings(db: Session):
|
| 238 |
try:
|
|
@@ -283,9 +283,9 @@ def get_current_user(db: Session = Depends(get_db), credentials: HTTPAuthorizati
|
|
| 283 |
raise credentials_exception
|
| 284 |
return user
|
| 285 |
|
| 286 |
-
# ==========================================
|
| 287 |
-
# بخش
|
| 288 |
-
# ==========================================
|
| 289 |
|
| 290 |
def _execute_native_matrix_processing(prompt: str, model_type: str = "fast") -> str:
|
| 291 |
if not AI_CORE_KEY:
|
|
@@ -322,7 +322,7 @@ def core_selection_engine(rank: int, quota: str, favorite_cities: str) -> str:
|
|
| 322 |
پایگاه داده دانشگاهها:
|
| 323 |
{context_str}
|
| 324 |
|
| 325 |
-
یک سناریوی پیشنهادی شامل حداکثر 8 انتخاب خوشبینانه و منطقی به زبان کاملاً ساده
|
| 326 |
خروجی را صرفاً و بدون هیچگونه متن توضیحی اضافه در قالب یک آرایه معتبر JSON و فاقد کدهای مارکداون برگردانید:
|
| 327 |
[
|
| 328 |
{{
|
|
@@ -367,9 +367,9 @@ def core_bio_extraction(resume_text: str) -> str:
|
|
| 367 |
return "کارشناس تحصیلی با سابقه رتبهپروری در کنکور و برنامهریزی تخصصی داوطلبان گروه علوم تجربی و ریاضی."
|
| 368 |
return result
|
| 369 |
|
| 370 |
-
# ==========================================
|
| 371 |
-
# بخش
|
| 372 |
-
# ==========================================
|
| 373 |
|
| 374 |
class RegisterRequest(BaseModel):
|
| 375 |
email: EmailStr
|
|
@@ -467,40 +467,9 @@ class UpdateProfileRequest(BaseModel):
|
|
| 467 |
phone_number: Optional[str] = None
|
| 468 |
city: Optional[str] = None
|
| 469 |
|
| 470 |
-
# ==========================================
|
| 471 |
-
# بخش
|
| 472 |
-
# ==========================================
|
| 473 |
-
|
| 474 |
-
@asynccontextmanager
|
| 475 |
-
async def lifespan(app: FastAPI):
|
| 476 |
-
Base.metadata.create_all(bind=engine)
|
| 477 |
-
db = SessionLocal()
|
| 478 |
-
try:
|
| 479 |
-
seed_initial_data(db)
|
| 480 |
-
except Exception as seed_err:
|
| 481 |
-
logger.error(f"Error seeding database during startup: {seed_err}", exc_info=True)
|
| 482 |
-
finally:
|
| 483 |
-
db.close()
|
| 484 |
-
yield
|
| 485 |
-
|
| 486 |
-
app = FastAPI(
|
| 487 |
-
title="پلتفرم خدمات هوشمند تحصیلی تاپ دانش",
|
| 488 |
-
description="سیستم محاسباتی و ارزیابی تراز تحصیلی بومی",
|
| 489 |
-
version="1.3.0",
|
| 490 |
-
lifespan=lifespan
|
| 491 |
-
)
|
| 492 |
-
|
| 493 |
-
app.add_middleware(
|
| 494 |
-
CORSMiddleware,
|
| 495 |
-
allow_origins=["*"],
|
| 496 |
-
allow_credentials=True,
|
| 497 |
-
allow_methods=["*"],
|
| 498 |
-
allow_headers=["*"],
|
| 499 |
-
)
|
| 500 |
-
|
| 501 |
-
# ==========================================
|
| 502 |
-
# بخش نهم: همگامسازی اجباری کلمههای عبور (Forced Check-Seeding)
|
| 503 |
-
# ==========================================
|
| 504 |
|
| 505 |
def seed_initial_data(db: Session):
|
| 506 |
try:
|
|
@@ -604,9 +573,38 @@ def seed_initial_data(db: Session):
|
|
| 604 |
logger.error(f"Seeding process crashed: {e}", exc_info=True)
|
| 605 |
db.rollback()
|
| 606 |
|
| 607 |
-
# =======================================================
|
| 608 |
-
#
|
| 609 |
-
# =======================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 610 |
@app.exception_handler(Exception)
|
| 611 |
async def global_exception_handler(request: Request, exc: Exception):
|
| 612 |
logger.error(f"Internal Crash logged on {request.url.path}: {exc}", exc_info=True)
|
|
@@ -616,7 +614,7 @@ async def global_exception_handler(request: Request, exc: Exception):
|
|
| 616 |
)
|
| 617 |
|
| 618 |
# ==========================================
|
| 619 |
-
# بخش
|
| 620 |
# ==========================================
|
| 621 |
|
| 622 |
@app.post("/api/auth/register")
|
|
|
|
| 18 |
from google import genai
|
| 19 |
import bcrypt
|
| 20 |
|
| 21 |
+
# =========================================================================
|
| 22 |
+
# بخش ۱: لایه ثبت لاگ سیستم
|
| 23 |
+
# =========================================================================
|
| 24 |
logging.basicConfig(level=logging.INFO)
|
| 25 |
logger = logging.getLogger("production_backend")
|
| 26 |
|
| 27 |
# کلید پردازشهای ابری هوشمند (Secrets)
|
| 28 |
AI_CORE_KEY = os.getenv("GEMINI_API_KEY") or os.getenv("SECRET")
|
| 29 |
|
| 30 |
+
# =========================================================================
|
| 31 |
+
# بخش ۲: اتصال پایگاه داده Neon.tech و ساختار بومی دیتابیس
|
| 32 |
+
# =========================================================================
|
| 33 |
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./test.db")
|
| 34 |
if DATABASE_URL.startswith("postgres://"):
|
| 35 |
DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1)
|
|
|
|
| 56 |
def get_now():
|
| 57 |
return datetime.now(timezone.utc).replace(tzinfo=None)
|
| 58 |
|
| 59 |
+
# =========================================================================
|
| 60 |
+
# بخش ۳: مدلهای دیتابیس (SQLAlchemy Models)
|
| 61 |
+
# =========================================================================
|
| 62 |
|
| 63 |
class User(Base):
|
| 64 |
__tablename__ = "users"
|
|
|
|
| 211 |
rating = Column(Float, default=5.0)
|
| 212 |
comment = Column(Text, nullable=True)
|
| 213 |
|
| 214 |
+
# =========================================================================
|
| 215 |
+
# بخش ۴: توابع کمکی امنیتی و رمزنگاری
|
| 216 |
+
# =========================================================================
|
| 217 |
|
| 218 |
def get_password_hash(password: str) -> str:
|
| 219 |
salt = bcrypt.gensalt()
|
|
|
|
| 230 |
ALGORITHM = "HS256"
|
| 231 |
security = HTTPBearer()
|
| 232 |
|
| 233 |
+
# =========================================================================
|
| 234 |
+
# بخش ۵: توابع وابستگی تزریق پایگاه داده و احراز هویت
|
| 235 |
+
# =========================================================================
|
| 236 |
|
| 237 |
def clean_expired_bookings(db: Session):
|
| 238 |
try:
|
|
|
|
| 283 |
raise credentials_exception
|
| 284 |
return user
|
| 285 |
|
| 286 |
+
# =========================================================================
|
| 287 |
+
# بخش ۶: توابع پردازش ابری هوشمند بومی تاپ دانش
|
| 288 |
+
# =========================================================================
|
| 289 |
|
| 290 |
def _execute_native_matrix_processing(prompt: str, model_type: str = "fast") -> str:
|
| 291 |
if not AI_CORE_KEY:
|
|
|
|
| 322 |
پایگاه داده دانشگاهها:
|
| 323 |
{context_str}
|
| 324 |
|
| 325 |
+
یک سناریوی پیشنهادی شامل حداکثر 8 انتخاب خوشبینانه و منطقی به زبان کاملاً ساده, روان, صمیمی و دانشجویی تولید کنید.
|
| 326 |
خروجی را صرفاً و بدون هیچگونه متن توضیحی اضافه در قالب یک آرایه معتبر JSON و فاقد کدهای مارکداون برگردانید:
|
| 327 |
[
|
| 328 |
{{
|
|
|
|
| 367 |
return "کارشناس تحصیلی با سابقه رتبهپروری در کنکور و برنامهریزی تخصصی داوطلبان گروه علوم تجربی و ریاضی."
|
| 368 |
return result
|
| 369 |
|
| 370 |
+
# =========================================================================
|
| 371 |
+
# بخش ۷: کلاسهای ورودی Pydantic (صحتسنجی)
|
| 372 |
+
# =========================================================================
|
| 373 |
|
| 374 |
class RegisterRequest(BaseModel):
|
| 375 |
email: EmailStr
|
|
|
|
| 467 |
phone_number: Optional[str] = None
|
| 468 |
city: Optional[str] = None
|
| 469 |
|
| 470 |
+
# =========================================================================
|
| 471 |
+
# بخش ۸: لایه همگامسازی دادههای تستی و دمو (Check-Seeding)
|
| 472 |
+
# =========================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
|
| 474 |
def seed_initial_data(db: Session):
|
| 475 |
try:
|
|
|
|
| 573 |
logger.error(f"Seeding process crashed: {e}", exc_info=True)
|
| 574 |
db.rollback()
|
| 575 |
|
| 576 |
+
# =========================================================================
|
| 577 |
+
# بخش ۹: راهاندازی و اجرای وبسرور FastAPI
|
| 578 |
+
# =========================================================================
|
| 579 |
+
|
| 580 |
+
@asynccontextmanager
|
| 581 |
+
async def lifespan(app: FastAPI):
|
| 582 |
+
Base.metadata.create_all(bind=engine)
|
| 583 |
+
db = SessionLocal()
|
| 584 |
+
try:
|
| 585 |
+
seed_initial_data(db)
|
| 586 |
+
except Exception as seed_err:
|
| 587 |
+
logger.error(f"Error seeding database during startup: {seed_err}", exc_info=True)
|
| 588 |
+
finally:
|
| 589 |
+
db.close()
|
| 590 |
+
yield
|
| 591 |
+
|
| 592 |
+
app = FastAPI(
|
| 593 |
+
title="پلتفرم خدمات هوشمند تحصیلی تاپ دانش",
|
| 594 |
+
description="سیستم محاسباتی و ارزیابی تراز تحصیلی بومی",
|
| 595 |
+
version="1.3.0",
|
| 596 |
+
lifespan=lifespan
|
| 597 |
+
)
|
| 598 |
+
|
| 599 |
+
app.add_middleware(
|
| 600 |
+
CORSMiddleware,
|
| 601 |
+
allow_origins=["*"],
|
| 602 |
+
allow_credentials=True,
|
| 603 |
+
allow_methods=["*"],
|
| 604 |
+
allow_headers=["*"],
|
| 605 |
+
)
|
| 606 |
+
|
| 607 |
+
|
| 608 |
@app.exception_handler(Exception)
|
| 609 |
async def global_exception_handler(request: Request, exc: Exception):
|
| 610 |
logger.error(f"Internal Crash logged on {request.url.path}: {exc}", exc_info=True)
|
|
|
|
| 614 |
)
|
| 615 |
|
| 616 |
# ==========================================
|
| 617 |
+
# بخش ۱۰: کلیه آدرسهای APIها (مراحل ۱ تا ۴)
|
| 618 |
# ==========================================
|
| 619 |
|
| 620 |
@app.post("/api/auth/register")
|