Ctrl K
ComunidadGuías…

scripts/generate_schema.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import json
import os
import sys
from unittest.mock import MagicMock

# -------------------------------------------------------------------------
# 1. SETUP DUMMY ENVIRONMENT
#    We set these before importing the app to prevent config validation errors.
# -------------------------------------------------------------------------
os.environ["DATABASE_URL"] = "sqlite:///:memory:"
os.environ["REDIS_URL"] = "redis://localhost:6379/0"
os.environ["ENTITIES_API_KEY"] = "dummy_key"
os.environ["SIGNED_URL_SECRET"] = "dummy_secret"
os.environ["DOWNLOAD_BASE_URL"] = "http://localhost:9000"
os.environ["HYPERBOLIC_API_KEY"] = "dummy"
os.environ["TOGETHER_API_KEY"] = "dummy"

# -------------------------------------------------------------------------
# 2. MOCK BLOCKING MODULES
#    Your main.py calls `wait_for_databases()` on import.
#    We must mock the database module BEFORE importing main to skip that check.
# -------------------------------------------------------------------------
mock_db_module = MagicMock()
mock_db_module.wait_for_databases = lambda: print(
    ">> [MOCK] Skipping DB Connection Check"
)
mock_db_module.engine = MagicMock()
mock_db_module.SessionLocal = MagicMock()

# Inject the mock into sys.modules so Python uses it instead of the real file
sys.modules["src.api.entities_api.db.database"] = mock_db_module

# -------------------------------------------------------------------------
# 3. IMPORT APP AND GENERATE SPEC
# -------------------------------------------------------------------------
try:
    from fastapi.openapi.utils import get_openapi

    from src.api.entities_api.app import create_app

    print(">> Initializing FastAPI App (Schema Mode)...")
    app = create_app(init_db=False)  # We pass False so it doesn't try to create tables

    print(">> Generating OpenAPI JSON...")

    # Generate the raw schema
    openapi_schema = get_openapi(
        title=app.title,
        version=app.version,
        openapi_version=app.openapi_version,
        description=app.description,
        routes=app.routes,
    )

    # ---------------------------------------------------------------------
    # 4. STAINLESS OPTIMIZATION (OPTIONAL BUT RECOMMENDED)
    #    Stainless uses 'operationId' to name SDK methods.
    #    FastAPI defaults to function names (e.g., 'create_run').
    #    This logic ensures method names are clean.
    # ---------------------------------------------------------------------
    for path, methods in openapi_schema["paths"].items():
        for method, details in methods.items():
            # If function is named 'create_run', operationId becomes 'create_run'
            # This results in SDK usage: client.runs.create_run()
            # You can manually rename these here if you prefer client.runs.create()
            if "operationId" not in details:
                # Fallback if FastAPI didn't set it (rare)
                details["operationId"] = (
                    details.get("summary", "").replace(" ", "_").lower()
                )

    # ---------------------------------------------------------------------
    # 5. WRITE TO FILE
    # ---------------------------------------------------------------------
    output_filename = "../openapi.json"
    with open(output_filename, "w") as f:
        json.dump(openapi_schema, f, indent=2)

    print(f"\n✅ SUCCESS! Schema saved to: {os.path.abspath(output_filename)}")
    print("   Upload this file to the Stainless dashboard.")

except ImportError as e:
    print(f"\n❌ IMPORT ERROR: {e}")
    print(
        "   Make sure you are running this from the project root and your virtualenv is active."
    )
except Exception as e:
    print(f"\n❌ ERROR: {e}")
    import traceback

    traceback.print_exc()