hesabixArc/hesabixAPI/app/main.py

319 lines
12 KiB
Python
Raw Normal View History

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
2025-09-15 13:53:54 +03:30
from app.core.settings import get_settings
from app.core.logging import configure_logging
from adapters.api.v1.health import router as health_router
from adapters.api.v1.auth import router as auth_router
from adapters.api.v1.users import router as users_router
2025-09-20 01:17:27 +03:30
from adapters.api.v1.businesses import router as businesses_router
from app.core.i18n import negotiate_locale, Translator
from app.core.error_handlers import register_error_handlers
2025-09-18 10:44:23 +03:30
from app.core.smart_normalizer import smart_normalize_json, SmartNormalizerConfig
from app.core.calendar_middleware import add_calendar_type
2025-09-15 13:53:54 +03:30
def create_app() -> FastAPI:
settings = get_settings()
configure_logging(settings)
application = FastAPI(
title=settings.app_name,
version=settings.app_version,
debug=settings.debug,
2025-09-20 01:17:27 +03:30
description="""
# Hesabix API
API جامع برای مدیریت کاربران، احراز هویت و سیستم معرفی
## ویژگی‌های اصلی:
- **احراز هویت**: ثبتنام، ورود، فراموشی رمز عبور
- **مدیریت کاربران**: لیست، جستجو، فیلتر و آمار کاربران
- **سیستم معرفی**: آمار و مدیریت معرفیها
- **خروجی**: PDF و Excel برای گزارشها
- **امنیت**: کپچا، کلیدهای API، رمزگذاری
## 🔐 احراز هویت (Authentication)
### کلیدهای API
تمام endpoint های محافظت شده نیاز به کلید API دارند که در header `Authorization` ارسال میشود:
```
Authorization: Bearer sk_your_api_key_here
```
### نحوه دریافت کلید API:
1. **ثبتنام**: با ثبتنام، یک کلید session دریافت میکنید
2. **ورود**: با ورود موفق، کلید session دریافت میکنید
3. **کلیدهای شخصی**: از endpoint `/api/v1/auth/api-keys` میتوانید کلیدهای شخصی ایجاد کنید
### انواع کلیدهای API:
- **Session Keys**: کلیدهای موقت که با ورود ایجاد میشوند
- **Personal Keys**: کلیدهای دائمی که خودتان ایجاد میکنید
### مثال درخواست با احراز هویت:
```bash
curl -X GET "http://localhost:8000/api/v1/auth/me" \\
-H "Authorization: Bearer sk_1234567890abcdef" \\
-H "Accept: application/json"
```
## 🛡️ مجوزهای دسترسی (Permissions)
برخی endpoint ها نیاز به مجوزهای خاص دارند:
### مجوزهای اپلیکیشن (App-Level Permissions):
- `user_management`: دسترسی به مدیریت کاربران
- `superadmin`: دسترسی کامل به سیستم
- `business_management`: مدیریت کسب و کارها
- `system_settings`: دسترسی به تنظیمات سیستم
### مثال مجوزها در JSON:
```json
{
"user_management": true,
"superadmin": false,
"business_management": true,
"system_settings": false
}
```
### endpoint های محافظت شده:
- تمام endpoint های `/api/v1/users/*` نیاز به مجوز `user_management` دارند
- endpoint های `/api/v1/auth/me` و `/api/v1/auth/api-keys/*` نیاز به احراز هویت دارند
## 🌍 چندزبانه (Internationalization)
API از چندزبانه پشتیبانی میکند:
### هدر زبان:
```
Accept-Language: fa
Accept-Language: en
Accept-Language: fa-IR
Accept-Language: en-US
```
### زبان‌های پشتیبانی شده:
- **فارسی (fa)**: پیشفرض
- **انگلیسی (en)**
### مثال درخواست با زبان فارسی:
```bash
curl -X GET "http://localhost:8000/api/v1/auth/me" \\
-H "Authorization: Bearer sk_1234567890abcdef" \\
-H "Accept-Language: fa" \\
-H "Accept: application/json"
```
## 📅 تقویم (Calendar)
API از تقویم شمسی (جلالی) پشتیبانی میکند:
### هدر تقویم:
```
X-Calendar-Type: jalali
X-Calendar-Type: gregorian
```
### انواع تقویم:
- **جلالی (jalali)**: تقویم شمسی - پیشفرض
- **میلادی (gregorian)**: تقویم میلادی
### مثال درخواست با تقویم شمسی:
```bash
curl -X GET "http://localhost:8000/api/v1/users" \\
-H "Authorization: Bearer sk_1234567890abcdef" \\
-H "X-Calendar-Type: jalali" \\
-H "Accept: application/json"
```
## 📊 فرمت پاسخ‌ها (Response Format)
تمام پاسخها در فرمت زیر هستند:
```json
{
"success": true,
"message": "پیام توضیحی",
"data": {
// دادههای اصلی
}
}
```
### کدهای خطا:
- **200**: موفقیت
- **400**: خطا در اعتبارسنجی دادهها
- **401**: احراز هویت نشده
- **403**: دسترسی غیرمجاز
- **404**: منبع یافت نشد
- **422**: خطا در اعتبارسنجی
- **500**: خطای سرور
## 🔒 امنیت (Security)
### کپچا:
برای عملیات حساس از کپچا استفاده میشود:
- دریافت کپچا: `POST /api/v1/auth/captcha`
- استفاده در ثبتنام، ورود، فراموشی رمز عبور
### رمزگذاری:
- رمزهای عبور با bcrypt رمزگذاری میشوند
- کلیدهای API با SHA-256 هش میشوند
## 📝 مثال کامل درخواست:
```bash
# 1. دریافت کپچا
curl -X POST "http://localhost:8000/api/v1/auth/captcha"
# 2. ورود
curl -X POST "http://localhost:8000/api/v1/auth/login" \\
-H "Content-Type: application/json" \\
-H "Accept-Language: fa" \\
-H "X-Calendar-Type: jalali" \\
-d '{
"identifier": "user@example.com",
"password": "password123",
"captcha_id": "captcha_id_from_step_1",
"captcha_code": "12345"
}'
# 3. استفاده از API با کلید دریافتی
curl -X GET "http://localhost:8000/api/v1/users" \\
-H "Authorization: Bearer sk_1234567890abcdef" \\
-H "Accept-Language: fa" \\
-H "X-Calendar-Type: jalali" \\
-H "Accept: application/json"
```
## 🚀 شروع سریع:
1. **ثبتنام**: `POST /api/v1/auth/register`
2. **ورود**: `POST /api/v1/auth/login`
3. **دریافت اطلاعات کاربر**: `GET /api/v1/auth/me`
4. **مدیریت کاربران**: `GET /api/v1/users` (نیاز به مجوز usermanager)
## 📞 پشتیبانی:
- **ایمیل**: support@hesabix.ir
- **مستندات**: `/docs` (Swagger UI)
- **ReDoc**: `/redoc`
""",
contact={
"name": "Hesabix Team",
"email": "support@hesabix.ir",
"url": "https://hesabix.ir",
},
license_info={
"name": "GNU GPLv3 License",
"url": "https://opensource.org/licenses/GPL-3.0",
},
servers=[
{
"url": "http://localhost:8000",
"description": "Development server"
},
{
"url": "https://agent.hesabix.ir",
"description": "Production server"
}
],
2025-09-15 13:53:54 +03:30
)
application.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_allowed_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
2025-09-18 10:44:23 +03:30
@application.middleware("http")
async def smart_number_normalizer(request: Request, call_next):
"""Middleware هوشمند برای تبدیل اعداد فارسی/عربی به انگلیسی"""
if SmartNormalizerConfig.ENABLED and request.method in ["POST", "PUT", "PATCH"]:
# خواندن body درخواست
body = await request.body()
if body:
# تبدیل اعداد در JSON
normalized_body = smart_normalize_json(body)
if normalized_body != body:
# ایجاد request جدید با body تبدیل شده
request._body = normalized_body
response = await call_next(request)
return response
@application.middleware("http")
async def add_locale(request: Request, call_next):
lang = negotiate_locale(request.headers.get("Accept-Language"))
request.state.locale = lang
request.state.translator = Translator(lang)
response = await call_next(request)
return response
2025-09-18 10:44:23 +03:30
@application.middleware("http")
async def add_calendar_middleware(request: Request, call_next):
return await add_calendar_type(request, call_next)
2025-09-15 13:53:54 +03:30
application.include_router(health_router, prefix=settings.api_v1_prefix)
application.include_router(auth_router, prefix=settings.api_v1_prefix)
application.include_router(users_router, prefix=settings.api_v1_prefix)
2025-09-20 01:17:27 +03:30
application.include_router(businesses_router, prefix=settings.api_v1_prefix)
register_error_handlers(application)
2025-09-15 13:53:54 +03:30
2025-09-20 01:17:27 +03:30
@application.get("/",
summary="اطلاعات سرویس",
description="دریافت اطلاعات کلی سرویس و نسخه",
tags=["general"]
)
2025-09-15 13:53:54 +03:30
def read_root() -> dict[str, str]:
return {"service": settings.app_name, "version": settings.app_version}
2025-09-20 01:17:27 +03:30
# اضافه کردن security schemes
from fastapi.openapi.utils import get_openapi
def custom_openapi():
if application.openapi_schema:
return application.openapi_schema
openapi_schema = get_openapi(
title=application.title,
version=application.version,
description=application.description,
routes=application.routes,
)
# اضافه کردن security schemes
openapi_schema["components"]["securitySchemes"] = {
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "API Key",
"description": "کلید API برای احراز هویت. فرمت: Bearer sk_your_api_key_here"
}
}
# اضافه کردن security به endpoint های محافظت شده
for path, methods in openapi_schema["paths"].items():
for method, details in methods.items():
if method in ["get", "post", "put", "delete", "patch"]:
# تمام endpoint های auth و users نیاز به احراز هویت دارند
if "/auth/" in path or "/users" in path:
details["security"] = [{"BearerAuth": []}]
application.openapi_schema = openapi_schema
return application.openapi_schema
application.openapi = custom_openapi
2025-09-15 13:53:54 +03:30
return application
app = create_app()