| | |
| |
|
| | import io |
| | import os |
| | import warnings |
| | import jwt |
| | from fastapi import FastAPI, Form, File, UploadFile, HTTPException |
| | from fastapi.responses import StreamingResponse, FileResponse |
| | from huggingface_hub import InferenceClient |
| | from typing import Optional |
| | from urllib3.exceptions import InsecureRequestWarning |
| |
|
| | |
| | warnings.filterwarnings("ignore", category=InsecureRequestWarning) |
| | app = FastAPI( |
| | title="Sora-2 Video Generation API", |
| | description="Integrates Sora-2 model with a custom credit and payment system." |
| | ) |
| |
|
| | |
| | |
| | |
| | SECRET_KEY = os.getenv("INTERNAL_API_KEY", "301101005") |
| |
|
| | |
| | @app.get("/", response_class=FileResponse) |
| | async def read_root(): |
| | """ارائه فایل اصلی index.html""" |
| | return FileResponse('index.html') |
| |
|
| | async def generate_video_logic(prompt: str, token: str, image_bytes: Optional[bytes] = None): |
| | """ |
| | منطق اصلی ساخت ویدیو که از توکن JWT برای اعتبارسنجی و دریافت کلید API استفاده میکند. |
| | """ |
| | try: |
| | |
| | payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) |
| | api_token = payload.get("api_key") |
| | deduction_token = payload.get("deduction_token") |
| |
|
| | if not all([api_token, deduction_token]): |
| | raise ValueError("Token payload is invalid.") |
| |
|
| | except jwt.ExpiredSignatureError: |
| | raise HTTPException(status_code=403, detail="مجوز ساخت ویدیو منقضی شده است. لطفا دوباره تلاش کنید.") |
| | except jwt.InvalidTokenError: |
| | raise HTTPException(status_code=403, detail="مجوز ساخت ویدیو نامعتبر است.") |
| | except Exception as e: |
| | raise HTTPException(status_code=400, detail=f"خطا در پردازش مجوز: {e}") |
| |
|
| | |
| | try: |
| | client = InferenceClient(provider="fal-ai", api_key=api_token) |
| | |
| | if image_bytes: |
| | |
| | model_id = "akhaliq/sora-2-image-to-video" |
| | video_bytes = client.image_to_video( |
| | image_bytes, |
| | prompt=prompt, |
| | model=model_id, |
| | ) |
| | else: |
| | |
| | model_id = "akhaliq/sora-2" |
| | video_bytes = client.text_to_video( |
| | prompt, |
| | model=model_id |
| | ) |
| | |
| | |
| | response = StreamingResponse(io.BytesIO(video_bytes), media_type="video/mp4") |
| | response.headers["X-Deduction-Token"] = deduction_token |
| | return response |
| | |
| | except Exception as e: |
| | error_message = f"سرویس ساخت ویدیو با خطا مواجه شد ممکنه درخواست طبق قوانین نباشه درخواست تغییر بدید. و همچنین امکان ساخت ویدیو از قسمت تصویر به ویدیو با تصاویر کودکان وجود نداره تصویر کودکان رو آپلود نکنید. و یا افراد مشهور که باعث نقض قوانین میشه. (اعتباری کسر نشد) - جزئیات: {str(e)}" |
| | print(f"Hugging Face API Error: {e}") |
| | raise HTTPException(status_code=500, detail=error_message) |
| |
|
| | @app.post("/text-to-video/") |
| | async def api_text_to_video(prompt: str = Form(...), token: str = Form(...)): |
| | """Endpoint برای تبدیل متن به ویدیو""" |
| | return await generate_video_logic(prompt, token) |
| |
|
| | @app.post("/image-to-video/") |
| | async def api_image_to_video(prompt: str = Form(...), token: str = Form(...), image: UploadFile = File(...)): |
| | """Endpoint برای تبدیل تصویر به ویدیو""" |
| | if not image.content_type.startswith("image/"): |
| | raise HTTPException(status_code=400, detail="فایل نامعتبر است. لطفاً یک تصویر آپلود کنید.") |
| | image_bytes = await image.read() |
| | return await generate_video_logic(prompt, token, image_bytes=image_bytes) |