Skip to content

Instantly share code, notes, and snippets.

@nyck33
Created June 2, 2024 12:22
Show Gist options
  • Save nyck33/74a1d20254a1d369aabbc3147ce63661 to your computer and use it in GitHub Desktop.
Save nyck33/74a1d20254a1d369aabbc3147ce63661 to your computer and use it in GitHub Desktop.
FastAPI server zitified
from fastapi import FastAPI, HTTPException, Response, UploadFile, Form, Depends, Request
from fastapi.responses import JSONResponse
import json
import zipfile
import io
from dotenv import load_dotenv
import os
from supabase import create_client
from schemas import AuthDetails, DebugQuery, DebugResponse
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
import logging
from pathlib import Path
import sys
import uvicorn
import openziti
logger = logging.getLogger(__name__)
# Set the logging level to ERROR
logger.setLevel(logging.ERROR)
# Create a console handler and set its level to ERROR
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.ERROR)
# Create a formatter and attach it to the handler
c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
c_handler.setFormatter(c_format)
# Add the handler to the logger
logger.addHandler(c_handler)
# Load environment variables
load_dotenv()
# Supabase configuration
url: str = os.getenv("SUPABASE_URL")
key: str = os.getenv("SUPABASE_ANON_KEY")
# Initialize FastAPI app and Supabase client
app = FastAPI(debug=True)
static_files = StaticFiles(directory="frontend")#content_type='application/javascript')
frontend_dir = Path(__file__).parent.parent / "frontend"
app.mount("/frontend", StaticFiles(directory=frontend_dir), name="frontend")
@app.middleware("http")
async def log_requests(request: Request, call_next):
logger.info(f"Request: {request.method} {request.url}")
response = await call_next(request)
return response
origins = [
"http://localhost",
"http://localhost:8601/signup",
"http://localhost:8601/login",
"http://localhost:8601/logout",
'http://localhost:8601',
"http://localhost:8601/",
"http://localhost:5000",
"http://localhost:8000",
"https://localhost",
"https://localhost:3000",
"https://localhost:5000",
"https://localhost:8601",
"https://localhost:8601/signup",
"https://localhost:8601/login",
"https://localhost:8601/logout",
"https://localhost:8601",
"https://localhost:8601/",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["GET","POST","OPTIONS"],
allow_headers=["*"],
)
supabase = create_client(url, key)
# Setup basic configuration for logging
logging.basicConfig(level=logging.INFO)
@app.post("/api/signup")
async def signup(auth_details: AuthDetails):
try:
result = supabase.auth.sign_up({
"email": auth_details.email,
"password": auth_details.password
})
if result.user:
return JSONResponse(status_code=201, content={"message": "User created successfully"})
else:
# Log the error if result.error is present
if result.error:
logging.error(f"Signup error: {result.error.message}")
raise HTTPException(status_code=500, detail=result.error.message)
raise HTTPException(status_code=500, detail="Unexpected error during signup")
except Exception as e:
error_message = getattr(e, 'message', str(e))
logging.error(f"Exception during signup: {error_message}") # Log the error
status_code = 400 if isinstance(e, HTTPException) else 500
return JSONResponse(status_code=status_code, content={"message": error_message})
@app.post("/api/login")
async def login(request: Request, auth_details: AuthDetails, response: Response):
try:
result = supabase.auth.sign_in_with_password({
"email": auth_details.email,
"password": auth_details.password
})
if result.session:
response.set_cookie(key="jwt", value=result.session.access_token, httponly=True)
return JSONResponse(status_code=200, content={"message": "Login successful"})
else:
# Log the error if result.error is present
if result.error:
logging.error(f"Login error: {result.error.message}")
raise HTTPException(status_code=401, detail=result.error.message)
raise HTTPException(status_code=401, detail="Invalid email or password")
except Exception as e:
error_message = getattr(e, 'message', str(e))
logging.error(f"Exception during login: {error_message}") # Log the error
status_code = 400 if isinstance(e, HTTPException) else 500
return JSONResponse(status_code=status_code, content={"message": error_message})
@app.post("/api/logout")
async def logout(response: Response):
# This endpoint does not interact with Supabase directly, so no changes needed here
response.delete_cookie(key="jwt")
return JSONResponse(status_code=200, content={"message": "Logout successful"})
# Debug Endpoint
@app.post("/debug", response_model=DebugResponse)
async def debug(file: UploadFile, query: DebugQuery = Depends()):
# Handle file upload and process as needed
# [Remaining implementation of /debug endpoint]
pass
# need catch all route for frontend so React Router can handle routing
@app.get("/{catchall:path}")
async def read_index(catchall: str):
if (frontend_dir / catchall).exists():
return FileResponse(frontend_dir / catchall)
return FileResponse(frontend_dir / "index.html")
def process_project_json_to_graph(project_data):
# [Insert your logic here]
pass
def interact_with_cloud_llm(graph, query):
# [Insert your LLM interaction logic here]
return "Processed response based on the graph and query"
bind_opts = {}
@openziti.zitify(bindings={':8000': bind_opts})
def runApp():
print("Starting server on OpenZiti overlay")
# FastAPI uses Uvicorn as the ASGI server, so we start it with Uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
if __name__ == '__main__':
# python app/main.py ./python-flazk-server-id.json Python-Flazk-Service
# Assuming the Ziti context and service name are passed as command-line arguments
bind_opts['ztx'] = sys.argv[1]
bind_opts['service'] = sys.argv[2]
runApp()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment