77 lines
3.4 KiB
Python
77 lines
3.4 KiB
Python
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.middleware.gzip import GZipMiddleware
|
|
|
|
from . import models # noqa: F401 — ثبت مدلها پیش از ساخت جداول
|
|
from .api import admin, forms, public
|
|
from .config import settings
|
|
from .database import Base, engine
|
|
from .seo_pages import router as seo_router
|
|
|
|
# ساخت جداول پایه — تغییرات بعدی اسکیما فقط با revisionهای Alembic اعمال میشوند
|
|
# (مigrations/versions). اجرای اینجا برای اجرای مستقیم uvicorn در محیط توسعه است؛
|
|
# در کانتینر، CMD همین کار را قبل از alembic upgrade head انجام میدهد.
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
app = FastAPI(
|
|
title="Aramesh Building Group API",
|
|
description=(
|
|
"بکاند سایت گروه ساختمانی آرامش — API محتوای سایت، فرم تماس و خبرنامه، "
|
|
"و پنل مدیریت با احراز هویت JWT."
|
|
),
|
|
version="1.0.0",
|
|
docs_url="/docs",
|
|
redoc_url="/redoc",
|
|
)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.cors_origins,
|
|
allow_credentials=False,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
# پاسخهای JSON /api — فشردهسازی وقتی بدنه قابلتوجه است
|
|
app.add_middleware(GZipMiddleware, minimum_size=1024)
|
|
|
|
|
|
# پیشنمایش خصوصی — لایه دوم جلوگیری از ایندکس (لایه اول، گیت ورود Traefik است).
|
|
# روی همه پاسخها هدر noindex مینشیند تا حتی در صورت حذف گیت، گوگل چیزی ذخیره نکند.
|
|
# همیشه ثبت میشود و پرچم در زمان هر درخواست خوانده میشود (خاموشکردن انتشار = فقط تغییر .env).
|
|
@app.middleware("http")
|
|
async def _preview_noindex(request, call_next):
|
|
response = await call_next(request)
|
|
if settings.preview_mode:
|
|
response.headers["X-Robots-Tag"] = "noindex, nofollow, noarchive"
|
|
return response
|
|
|
|
# پاسخهای API هرگز کش مرورگر/CDN نشوند — دادهٔ پنل بعد از هر ذخیره فوراً fresh بماند
|
|
@app.middleware("http")
|
|
async def _api_no_store(request, call_next):
|
|
response = await call_next(request)
|
|
if request.url.path.startswith("/api"):
|
|
response.headers["Cache-Control"] = "no-store"
|
|
return response
|
|
|
|
app.include_router(public.router, prefix="/api", tags=["عمومی"])
|
|
app.include_router(forms.router, prefix="/api", tags=["فرمها"])
|
|
app.include_router(admin.auth_router, prefix="/api", tags=["احراز هویت"])
|
|
app.include_router(admin.router, prefix="/api/admin", tags=["پنل مدیریت"])
|
|
# robots.txt، sitemap.xml و HTML صفحات وبلاگ/پروژه با متای سئو — در ریشه دامنه
|
|
app.include_router(seo_router, tags=["سئو"])
|
|
|
|
# متریکهای Prometheus — فقط Prometheus در شبکه داخلی اسکرپ میکند
|
|
# (Traefik مسیر /metrics را نمیشناسد، پس از بیرون در دسترس نیست)
|
|
from prometheus_fastapi_instrumentator import Instrumentator # noqa: E402
|
|
|
|
Instrumentator().instrument(app).expose(app, endpoint="/metrics", include_in_schema=False)
|
|
|
|
|
|
@app.get("/")
|
|
def root():
|
|
return {
|
|
"app": "Aramesh Building Group API",
|
|
"docs": "/docs",
|
|
"health": "/api/health",
|
|
}
|