Skip to content

Instantly share code, notes, and snippets.

@nyck33
Created June 2, 2024 12:22
Show Gist options
  • Select an option

  • Save nyck33/74a1d20254a1d369aabbc3147ce63661 to your computer and use it in GitHub Desktop.

Select an option

Save nyck33/74a1d20254a1d369aabbc3147ce63661 to your computer and use it in GitHub Desktop.

Revisions

  1. nyck33 created this gist Jun 2, 2024.
    171 changes: 171 additions & 0 deletions main.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,171 @@
    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()