h2oai / h2ogpt

Private chat with local GPT with document, images, video, etc. 100% private, Apache 2.0. Supports oLLaMa, Mixtral, llama.cpp, and more. Demo: https://gpt.h2o.ai/ https://codellama.h2o.ai/
http://h2o.ai
Apache License 2.0
11.05k stars 1.2k forks source link

cookie based auth to preserve access to original db/docs so not lost, e.g. on gpt.h2o.ai #400

Closed pseudotensor closed 11 months ago

pseudotensor commented 1 year ago

https://stackoverflow.com/questions/66836600/cookie-based-authentication-in-fastapi https://www.gradio.app/guides/sharing-your-app#mounting-within-another-fastapi-app https://github.com/gradio-app/gradio/issues/461

pseudotensor commented 1 year ago

Or google auth

https://github.com/gradio-app/gradio/issues/2790

import json
from authlib.integrations.base_client import OAuthError
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
from starlette.responses import HTMLResponse, RedirectResponse
from starlette.requests import Request
import gradio as gr
from authlib.integrations.starlette_client import OAuth
from starlette.config import Config

# CODE FOR NEW APP

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="!secret")

config = Config('.env')
oauth = OAuth(config)

CONF_URL = 'https://accounts.google.com/.well-known/openid-configuration'
oauth.register(
    name='google',
    server_metadata_url=CONF_URL,
    client_kwargs={
        'scope': 'openid email profile'
    }
)

@app.get('/')
async def homepage(request: Request):
    user = request.session.get('user')
    if user:
        data = json.dumps(user)
        html = (
            f'<pre>{data}</pre>'
            '<a href="/logout">logout</a>'
            '<br>'
            '<a href="/gradio">demo</a>'
        )
        return HTMLResponse(html)
    return HTMLResponse('<a href="/login">login</a>')

@app.get('/login')
async def login(request: Request):
    redirect_uri = request.url_for('auth')
    return await oauth.google.authorize_redirect(request, redirect_uri)

@app.get('/auth')
async def auth(request: Request):
    print(f"before request user {request.session.get('user')}")
    try:
        token = await oauth.google.authorize_access_token(request)
    except OAuthError as error:
        return HTMLResponse(f'<h1>{error.error}</h1>')
    user = token.get('userinfo')
    if user:
        request.session['user'] = dict(user)
    print(f"after request user {request.session.get('user')}")
    return RedirectResponse(url='/')

@app.get('/logout')
async def logout(request: Request):
    request.session.pop('user', None)
    return RedirectResponse(url='/')

# CODE FOR MOUNTED GRADIO APP

def update(name, request: gr.Request):
    return f"Welcome to Gradio, {name}!\n{request.request.session.get('user')}"

def make_demo_visible(request: gr.Request):
    if request.request.session.get('user'):
        return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=False)
    return gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(value="Looks like you are not logged in. Please login at the main app.")

with gr.Blocks() as demo:
    start_btn = gr.Button("Press Here to initialize the demo!")

    with gr.Row():
        inp = gr.Textbox(placeholder="What is your name?", visible=False)
        out = gr.Textbox(visible=False)

    btn = gr.Button("Run", visible=False)

    start_btn.click(make_demo_visible, outputs=[inp, out, btn, start_btn])
    btn.click(fn=update, inputs=inp, outputs=out)

gradio_app = gr.mount_gradio_app(app, demo, "/gradio")
fengke-j commented 11 months ago

Where should this source code file be placed?

pseudotensor commented 11 months ago

https://github.com/h2oai/h2ogpt/pull/618

tares003 commented 9 months ago

Where should this source code file be placed?

this is a separate file, just make main.py or something similar

pseudotensor commented 9 months ago

This issue was closed because we already support native gradio way with --auth related options. See gen.py.