gcli2api / src /main.py
bibibi12345's picture
fixed login link not showing
4fe6125
import logging
import os
from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from .gemini_routes import router as gemini_router
from .openai_routes import router as openai_router
from .auth import get_credentials, get_user_project_id, onboard_user
# Load environment variables from .env file
try:
from dotenv import load_dotenv
load_dotenv()
logging.info("Environment variables loaded from .env file")
except ImportError:
logging.warning("python-dotenv not installed, .env file will not be loaded automatically")
except Exception as e:
logging.warning(f"Could not load .env file: {e}")
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
app = FastAPI()
# Add CORS middleware for preflight requests
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allow all origins
allow_credentials=True,
allow_methods=["*"], # Allow all methods
allow_headers=["*"], # Allow all headers
)
@app.on_event("startup")
async def startup_event():
try:
logging.info("Starting Gemini proxy server...")
# Check if credentials exist
import os
from .config import CREDENTIAL_FILE
env_creds_json = os.getenv("GEMINI_CREDENTIALS")
creds_file_exists = os.path.exists(CREDENTIAL_FILE)
if env_creds_json or creds_file_exists:
try:
# Try to load existing credentials without OAuth flow first
creds = get_credentials(allow_oauth_flow=False)
if creds:
try:
proj_id = get_user_project_id(creds)
if proj_id:
onboard_user(creds, proj_id)
logging.info(f"Successfully onboarded with project ID: {proj_id}")
logging.info("Gemini proxy server started successfully")
logging.info("Authentication required - Password: see .env file")
except Exception as e:
logging.error(f"Setup failed: {str(e)}")
logging.warning("Server started but may not function properly until setup issues are resolved.")
else:
logging.warning("Credentials file exists but could not be loaded. Server started - authentication will be required on first request.")
except Exception as e:
logging.error(f"Credential loading error: {str(e)}")
logging.warning("Server started but credentials need to be set up.")
else:
# No credentials found - prompt user to authenticate
logging.info("No credentials found. Starting OAuth authentication flow...")
try:
creds = get_credentials(allow_oauth_flow=True)
if creds:
try:
proj_id = get_user_project_id(creds)
if proj_id:
onboard_user(creds, proj_id)
logging.info(f"Successfully onboarded with project ID: {proj_id}")
logging.info("Gemini proxy server started successfully")
except Exception as e:
logging.error(f"Setup failed: {str(e)}")
logging.warning("Server started but may not function properly until setup issues are resolved.")
else:
logging.error("Authentication failed. Server started but will not function until credentials are provided.")
except Exception as e:
logging.error(f"Authentication error: {str(e)}")
logging.warning("Server started but authentication failed.")
logging.info("Authentication required - Password: see .env file")
except Exception as e:
logging.error(f"Startup error: {str(e)}")
logging.warning("Server may not function properly.")
@app.options("/{full_path:path}")
async def handle_preflight(request: Request, full_path: str):
"""Handle CORS preflight requests without authentication."""
return Response(
status_code=200,
headers={
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Credentials": "true",
}
)
# Root endpoint - no authentication required
@app.get("/")
async def root():
"""
Root endpoint providing project information.
No authentication required.
"""
return {
"name": "geminicli2api",
"description": "OpenAI-compatible API proxy for Google's Gemini models via gemini-cli",
"purpose": "Provides both OpenAI-compatible endpoints (/v1/chat/completions) and native Gemini API endpoints for accessing Google's Gemini models",
"version": "1.0.0",
"endpoints": {
"openai_compatible": {
"chat_completions": "/v1/chat/completions",
"models": "/v1/models"
},
"native_gemini": {
"models": "/v1beta/models",
"generate": "/v1beta/models/{model}/generateContent",
"stream": "/v1beta/models/{model}/streamGenerateContent"
},
"health": "/health"
},
"authentication": "Required for all endpoints except root and health",
"repository": "https://github.com/user/geminicli2api"
}
# Health check endpoint for Docker/Hugging Face
@app.get("/health")
async def health_check():
"""Health check endpoint for container orchestration."""
return {"status": "healthy", "service": "geminicli2api"}
app.include_router(openai_router)
app.include_router(gemini_router)