cleanup ui folder (#7363)
This commit is contained in:
parent
3671829e39
commit
d883241b36
@ -1,20 +0,0 @@
|
||||
# Use an official Node.js image as the base image
|
||||
FROM node:18-alpine
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package.json and package-lock.json to the working directory
|
||||
COPY ./litellm-dashboard/package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the application code to the working directory
|
||||
COPY ./litellm-dashboard .
|
||||
|
||||
# Expose the port that the Next.js app will run on
|
||||
EXPOSE 3000
|
||||
|
||||
# Start the Next.js app
|
||||
CMD ["npm", "run", "dev"]
|
||||
@ -1,7 +0,0 @@
|
||||
# proxy ui
|
||||
|
||||
Create Proxy Keys, Track Spend per key
|
||||
|
||||
👉 UI is available on `/ui` on your Proxy. [docs](https://docs.litellm.ai/docs/proxy/ui)
|
||||
|
||||

|
||||
522
ui/admin.py
522
ui/admin.py
@ -1,522 +0,0 @@
|
||||
"""
|
||||
Admin sets proxy url + allowed email subdomain
|
||||
"""
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
import streamlit as st
|
||||
import base64
|
||||
import os
|
||||
import json
|
||||
import uuid
|
||||
import requests
|
||||
import pandas as pd
|
||||
import plotly.express as px
|
||||
import click
|
||||
|
||||
# Replace your_base_url with the actual URL where the proxy auth app is hosted
|
||||
your_base_url = os.getenv("BASE_URL") # Example base URL
|
||||
|
||||
|
||||
# Function to encode the configuration
|
||||
def encode_config(proxy_url, allowed_email_subdomain, admin_emails):
|
||||
combined_string = f"proxy_url={proxy_url}&accepted_email_subdomain={allowed_email_subdomain}&admin_emails={admin_emails}"
|
||||
return base64.b64encode(combined_string.encode("utf-8")).decode("utf-8")
|
||||
|
||||
|
||||
# Simple function to update config values
|
||||
def update_config_values(proxy_url, allowed_email_subdomain, admin_emails):
|
||||
st.session_state["proxy_url"] = proxy_url
|
||||
st.session_state["allowed_email_subdomain"] = allowed_email_subdomain
|
||||
st.session_state["admin_emails"] = admin_emails
|
||||
if your_base_url.endswith("/"):
|
||||
st.session_state["user_auth_url"] = (
|
||||
f"{your_base_url}user?page={encode_config(proxy_url=proxy_url, allowed_email_subdomain=allowed_email_subdomain, admin_emails=admin_emails)}"
|
||||
)
|
||||
else:
|
||||
st.session_state["user_auth_url"] = (
|
||||
f"{your_base_url}/user?page={encode_config(proxy_url=proxy_url, allowed_email_subdomain=allowed_email_subdomain, admin_emails=admin_emails)}"
|
||||
)
|
||||
st.session_state["is_admin"] = True
|
||||
|
||||
|
||||
def proxy_setup():
|
||||
# Create a configuration placeholder
|
||||
st.session_state.setdefault("proxy_url", "http://example.com")
|
||||
st.session_state.setdefault("allowed_email_subdomain", "example.com")
|
||||
st.session_state.setdefault("admin_emails", "admin@example.com")
|
||||
st.session_state.setdefault("user_auth_url", "NOT_GIVEN")
|
||||
|
||||
with st.form("config_form", clear_on_submit=False):
|
||||
proxy_url = st.text_input("Set Proxy URL", st.session_state["proxy_url"])
|
||||
allowed_email_subdomain = st.text_input(
|
||||
"Set Allowed Email Subdomain", st.session_state["allowed_email_subdomain"]
|
||||
)
|
||||
admin_emails = st.text_input(
|
||||
"Allowed Admin Emails (add ',' to separate multiple emails)",
|
||||
st.session_state["admin_emails"],
|
||||
)
|
||||
submitted = st.form_submit_button("Save")
|
||||
|
||||
if submitted:
|
||||
update_config_values(
|
||||
proxy_url=proxy_url,
|
||||
allowed_email_subdomain=allowed_email_subdomain,
|
||||
admin_emails=admin_emails,
|
||||
)
|
||||
|
||||
# Display the current configuration
|
||||
st.write(f"Current Proxy URL: {st.session_state['proxy_url']}")
|
||||
st.write(
|
||||
f"Current Allowed Email Subdomain: {st.session_state['allowed_email_subdomain']}"
|
||||
)
|
||||
st.write(f"Current User Auth URL: {st.session_state['user_auth_url']}")
|
||||
|
||||
|
||||
def add_new_model():
|
||||
import streamlit as st
|
||||
import requests
|
||||
|
||||
if (
|
||||
st.session_state.get("api_url", None) is None
|
||||
and st.session_state.get("proxy_key", None) is None
|
||||
):
|
||||
st.warning(
|
||||
f"Please configure the Proxy Endpoint and Proxy Key on the Proxy Setup page. Currently set Proxy Endpoint: {st.session_state.get('api_url', None)} and Proxy Key: {st.session_state.get('proxy_key', None)}"
|
||||
)
|
||||
|
||||
model_name = st.text_input(
|
||||
"Model Name - user-facing model name", placeholder="gpt-3.5-turbo"
|
||||
)
|
||||
st.subheader("LiteLLM Params")
|
||||
litellm_model_name = st.text_input(
|
||||
"Model", placeholder="azure/gpt-35-turbo-us-east"
|
||||
)
|
||||
litellm_api_key = st.text_input("API Key")
|
||||
litellm_api_base = st.text_input(
|
||||
"API Base",
|
||||
placeholder="https://my-endpoint.openai.azure.com",
|
||||
)
|
||||
litellm_api_version = st.text_input("API Version", placeholder="2023-07-01-preview")
|
||||
litellm_params = json.loads(
|
||||
st.text_area(
|
||||
"Additional Litellm Params (JSON dictionary). [See all possible inputs](https://github.com/BerriAI/litellm/blob/3f15d7230fe8e7492c95a752963e7fbdcaf7bf98/litellm/main.py#L293)",
|
||||
value={},
|
||||
)
|
||||
)
|
||||
st.subheader("Model Info")
|
||||
mode_options = ("completion", "embedding", "image generation")
|
||||
mode_selected = st.selectbox("Mode", mode_options)
|
||||
model_info = json.loads(
|
||||
st.text_area(
|
||||
"Additional Model Info (JSON dictionary)",
|
||||
value={},
|
||||
)
|
||||
)
|
||||
|
||||
if st.button("Submit"):
|
||||
try:
|
||||
model_info = {
|
||||
"model_name": model_name,
|
||||
"litellm_params": {
|
||||
"model": litellm_model_name,
|
||||
"api_key": litellm_api_key,
|
||||
"api_base": litellm_api_base,
|
||||
"api_version": litellm_api_version,
|
||||
},
|
||||
"model_info": {
|
||||
"id": str(uuid.uuid4()),
|
||||
"mode": mode_selected,
|
||||
},
|
||||
}
|
||||
# Make the POST request to the specified URL
|
||||
complete_url = ""
|
||||
if st.session_state["api_url"].endswith("/"):
|
||||
complete_url = f"{st.session_state['api_url']}model/new"
|
||||
else:
|
||||
complete_url = f"{st.session_state['api_url']}/model/new"
|
||||
|
||||
headers = {"Authorization": f"Bearer {st.session_state['proxy_key']}"}
|
||||
response = requests.post(complete_url, json=model_info, headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
st.success("Model added successfully!")
|
||||
else:
|
||||
st.error(f"Failed to add model. Status code: {response.status_code}")
|
||||
|
||||
st.success("Form submitted successfully!")
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
def list_models():
|
||||
import streamlit as st
|
||||
import requests
|
||||
|
||||
# Check if the necessary configuration is available
|
||||
if (
|
||||
st.session_state.get("api_url", None) is not None
|
||||
and st.session_state.get("proxy_key", None) is not None
|
||||
):
|
||||
# Make the GET request
|
||||
try:
|
||||
complete_url = ""
|
||||
if isinstance(st.session_state["api_url"], str) and st.session_state[
|
||||
"api_url"
|
||||
].endswith("/"):
|
||||
complete_url = f"{st.session_state['api_url']}models"
|
||||
else:
|
||||
complete_url = f"{st.session_state['api_url']}/models"
|
||||
response = requests.get(
|
||||
complete_url,
|
||||
headers={"Authorization": f"Bearer {st.session_state['proxy_key']}"},
|
||||
)
|
||||
# Check if the request was successful
|
||||
if response.status_code == 200:
|
||||
models = response.json()
|
||||
st.write(models) # or st.json(models) to pretty print the JSON
|
||||
else:
|
||||
st.error(f"Failed to get models. Status code: {response.status_code}")
|
||||
except Exception as e:
|
||||
st.error(f"An error occurred while requesting models: {e}")
|
||||
else:
|
||||
st.warning(
|
||||
f"Please configure the Proxy Endpoint and Proxy Key on the Proxy Setup page. Currently set Proxy Endpoint: {st.session_state.get('api_url', None)} and Proxy Key: {st.session_state.get('proxy_key', None)}"
|
||||
)
|
||||
|
||||
|
||||
def spend_per_key():
|
||||
import streamlit as st
|
||||
import requests
|
||||
|
||||
# Check if the necessary configuration is available
|
||||
if (
|
||||
st.session_state.get("api_url", None) is not None
|
||||
and st.session_state.get("proxy_key", None) is not None
|
||||
):
|
||||
# Make the GET request
|
||||
try:
|
||||
complete_url = ""
|
||||
if isinstance(st.session_state["api_url"], str) and st.session_state[
|
||||
"api_url"
|
||||
].endswith("/"):
|
||||
complete_url = f"{st.session_state['api_url']}/spend/keys"
|
||||
else:
|
||||
complete_url = f"{st.session_state['api_url']}/spend/keys"
|
||||
response = requests.get(
|
||||
complete_url,
|
||||
headers={"Authorization": f"Bearer {st.session_state['proxy_key']}"},
|
||||
)
|
||||
# Check if the request was successful
|
||||
if response.status_code == 200:
|
||||
spend_per_key = response.json()
|
||||
# Create DataFrame
|
||||
spend_df = pd.DataFrame(spend_per_key)
|
||||
|
||||
# Display the spend per key as a graph
|
||||
st.header("Spend ($) per API Key:")
|
||||
top_10_df = spend_df.nlargest(10, "spend")
|
||||
fig = px.bar(
|
||||
top_10_df,
|
||||
x="token",
|
||||
y="spend",
|
||||
title="Top 10 Spend per Key",
|
||||
height=550, # Adjust the height
|
||||
width=1200, # Adjust the width)
|
||||
hover_data=["token", "spend", "user_id", "team_id"],
|
||||
)
|
||||
st.plotly_chart(fig)
|
||||
|
||||
# Display the spend per key as a table
|
||||
st.write("Spend per Key - Full Table:")
|
||||
st.table(spend_df)
|
||||
|
||||
else:
|
||||
st.error(f"Failed to get models. Status code: {response.status_code}")
|
||||
except Exception as e:
|
||||
st.error(f"An error occurred while requesting models: {e}")
|
||||
else:
|
||||
st.warning(
|
||||
f"Please configure the Proxy Endpoint and Proxy Key on the Proxy Setup page. Currently set Proxy Endpoint: {st.session_state.get('api_url', None)} and Proxy Key: {st.session_state.get('proxy_key', None)}"
|
||||
)
|
||||
|
||||
|
||||
def spend_per_user():
|
||||
import streamlit as st
|
||||
import requests
|
||||
|
||||
# Check if the necessary configuration is available
|
||||
if (
|
||||
st.session_state.get("api_url", None) is not None
|
||||
and st.session_state.get("proxy_key", None) is not None
|
||||
):
|
||||
# Make the GET request
|
||||
try:
|
||||
complete_url = ""
|
||||
if isinstance(st.session_state["api_url"], str) and st.session_state[
|
||||
"api_url"
|
||||
].endswith("/"):
|
||||
complete_url = f"{st.session_state['api_url']}/spend/users"
|
||||
else:
|
||||
complete_url = f"{st.session_state['api_url']}/spend/users"
|
||||
response = requests.get(
|
||||
complete_url,
|
||||
headers={"Authorization": f"Bearer {st.session_state['proxy_key']}"},
|
||||
)
|
||||
# Check if the request was successful
|
||||
if response.status_code == 200:
|
||||
spend_per_user = response.json()
|
||||
# Create DataFrame
|
||||
spend_df = pd.DataFrame(spend_per_user)
|
||||
|
||||
# Display the spend per key as a graph
|
||||
st.header("Spend ($) per User:")
|
||||
top_10_df = spend_df.nlargest(10, "spend")
|
||||
fig = px.bar(
|
||||
top_10_df,
|
||||
x="user_id",
|
||||
y="spend",
|
||||
title="Top 10 Spend per User",
|
||||
height=550, # Adjust the height
|
||||
width=1200, # Adjust the width)
|
||||
hover_data=["user_id", "spend", "max_budget"],
|
||||
)
|
||||
st.plotly_chart(fig)
|
||||
|
||||
# Display the spend per key as a table
|
||||
st.write("Spend per User - Full Table:")
|
||||
st.table(spend_df)
|
||||
|
||||
else:
|
||||
st.error(f"Failed to get models. Status code: {response.status_code}")
|
||||
except Exception as e:
|
||||
st.error(f"An error occurred while requesting models: {e}")
|
||||
else:
|
||||
st.warning(
|
||||
f"Please configure the Proxy Endpoint and Proxy Key on the Proxy Setup page. Currently set Proxy Endpoint: {st.session_state.get('api_url', None)} and Proxy Key: {st.session_state.get('proxy_key', None)}"
|
||||
)
|
||||
|
||||
|
||||
def create_key():
|
||||
import streamlit as st
|
||||
import requests
|
||||
|
||||
if (
|
||||
st.session_state.get("api_url", None) is None
|
||||
and st.session_state.get("proxy_key", None) is None
|
||||
):
|
||||
st.warning(
|
||||
f"Please configure the Proxy Endpoint and Proxy Key on the Proxy Setup page. Currently set Proxy Endpoint: {st.session_state.get('api_url', None)} and Proxy Key: {st.session_state.get('proxy_key', None)}"
|
||||
)
|
||||
|
||||
duration = st.text_input("Duration - Can be in (h,m,s)", placeholder="1h")
|
||||
|
||||
models = st.text_input("Models it can access (separated by comma)", value="")
|
||||
models = models.split(",") if models else []
|
||||
|
||||
additional_params = json.loads(
|
||||
st.text_area(
|
||||
"Additional Key Params (JSON dictionary). [See all possible inputs](https://litellm-api.up.railway.app/#/key%20management/generate_key_fn_key_generate_post)",
|
||||
value={},
|
||||
)
|
||||
)
|
||||
|
||||
if st.button("Submit"):
|
||||
try:
|
||||
key_post_body = {
|
||||
"duration": duration,
|
||||
"models": models,
|
||||
**additional_params,
|
||||
}
|
||||
# Make the POST request to the specified URL
|
||||
complete_url = ""
|
||||
if st.session_state["api_url"].endswith("/"):
|
||||
complete_url = f"{st.session_state['api_url']}key/generate"
|
||||
else:
|
||||
complete_url = f"{st.session_state['api_url']}/key/generate"
|
||||
|
||||
headers = {"Authorization": f"Bearer {st.session_state['proxy_key']}"}
|
||||
response = requests.post(complete_url, json=key_post_body, headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
st.success(f"Key added successfully! - {response.json()}")
|
||||
else:
|
||||
st.error(f"Failed to add Key. Status code: {response.status_code}")
|
||||
|
||||
st.success("Form submitted successfully!")
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
def update_config():
|
||||
if (
|
||||
st.session_state.get("api_url", None) is None
|
||||
and st.session_state.get("proxy_key", None) is None
|
||||
):
|
||||
st.warning(
|
||||
f"Please configure the Proxy Endpoint and Proxy Key on the Proxy Setup page. Currently set Proxy Endpoint: {st.session_state.get('api_url', None)} and Proxy Key: {st.session_state.get('proxy_key', None)}"
|
||||
)
|
||||
|
||||
st.markdown("#### Alerting")
|
||||
input_slack_webhook = st.text_input(
|
||||
"Slack Webhook URL (Optional)",
|
||||
value=st.session_state.get("slack_webhook", ""),
|
||||
placeholder="https://hooks.slack.com/services/...",
|
||||
)
|
||||
st.markdown(
|
||||
"More information on Slack alerting configuration can be found in the [documentation]"
|
||||
"(https://docs.litellm.ai/docs/proxy/alerting)."
|
||||
)
|
||||
alerting_threshold = st.text_input(
|
||||
"Alerting threshold (in seconds) (Optional)",
|
||||
value=st.session_state.get("alerting_threshold", 300),
|
||||
placeholder=300,
|
||||
)
|
||||
st.markdown("How long to wait before a request is considered hanging")
|
||||
st.markdown("#### Logging")
|
||||
|
||||
enable_langfuse_logging = st.checkbox("Enable Langfuse Logging")
|
||||
if enable_langfuse_logging == True:
|
||||
langfuse_host_url = st.text_input(
|
||||
"Langfuse Host",
|
||||
value=st.session_state.get("langfuse_host", "https://cloud.langfuse.com"),
|
||||
placeholder="https://cloud.langfuse.com",
|
||||
)
|
||||
langfuse_public_key = st.text_input(
|
||||
"Langfuse Public Key",
|
||||
value=st.session_state.get("langfuse_public_key", ""),
|
||||
placeholder="pk-lf-...",
|
||||
)
|
||||
langfuse_secret_key = st.text_input(
|
||||
"Langfuse Secret Key",
|
||||
value=st.session_state.get("langfuse_secret_key", ""),
|
||||
placeholder="sk-lf-...",
|
||||
)
|
||||
# When the "Save" button is clicked, update the session state
|
||||
if st.button("Save"):
|
||||
try:
|
||||
config_post_body = {}
|
||||
if (
|
||||
enable_langfuse_logging == True
|
||||
and langfuse_host_url is not None
|
||||
and langfuse_public_key is not None
|
||||
and langfuse_secret_key is not None
|
||||
):
|
||||
config_post_body["litellm_settings"] = {
|
||||
"success_callback": ["langfuse"]
|
||||
}
|
||||
config_post_body["environment_variables"] = {
|
||||
"LANGFUSE_HOST": langfuse_host_url,
|
||||
"LANGFUSE_PUBLIC_KEY": langfuse_public_key,
|
||||
"LANGFUSE_SECRET_KEY": langfuse_secret_key,
|
||||
}
|
||||
if input_slack_webhook is not None and alerting_threshold is not None:
|
||||
config_post_body["general_settings"] = {
|
||||
"alerting": ["slack"],
|
||||
"alerting_threshold": alerting_threshold,
|
||||
}
|
||||
config_post_body["environment_variables"] = {
|
||||
"SLACK_WEBHOOK_URL": input_slack_webhook
|
||||
}
|
||||
|
||||
# Make the POST request to the specified URL
|
||||
complete_url = ""
|
||||
if st.session_state["api_url"].endswith("/"):
|
||||
complete_url = f"{st.session_state.get('api_url')}config/update"
|
||||
else:
|
||||
complete_url = f"{st.session_state.get('api_url')}/config/update"
|
||||
|
||||
headers = {"Authorization": f"Bearer {st.session_state['proxy_key']}"}
|
||||
response = requests.post(
|
||||
complete_url, json=config_post_body, headers=headers
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
st.success(f"Config updated successfully! - {response.json()}")
|
||||
else:
|
||||
st.error(
|
||||
f"Failed to update config. Status code: {response.status_code}. Error message: {response.json()['detail']}"
|
||||
)
|
||||
|
||||
st.success("Form submitted successfully!")
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
def admin_page(is_admin="NOT_GIVEN", input_api_url=None, input_proxy_key=None):
|
||||
# Display the form for the admin to set the proxy URL and allowed email subdomain
|
||||
st.set_page_config(
|
||||
layout="wide", # Use "wide" layout for more space
|
||||
)
|
||||
st.header("Admin Configuration")
|
||||
st.session_state.setdefault("is_admin", is_admin)
|
||||
# Add a navigation sidebar
|
||||
st.sidebar.title("Navigation")
|
||||
|
||||
page = st.sidebar.radio(
|
||||
"Go to",
|
||||
(
|
||||
"Connect to Proxy",
|
||||
"View Spend Per Key",
|
||||
"View Spend Per User",
|
||||
"List Models",
|
||||
"Update Config",
|
||||
"Add Models",
|
||||
"Create Key",
|
||||
"End-User Auth",
|
||||
),
|
||||
)
|
||||
# Display different pages based on navigation selection
|
||||
if page == "Connect to Proxy":
|
||||
# Use text inputs with intermediary variables
|
||||
if input_api_url is None:
|
||||
input_api_url = st.text_input(
|
||||
"Proxy Endpoint",
|
||||
value=st.session_state.get("api_url", ""),
|
||||
placeholder="http://0.0.0.0:8000",
|
||||
)
|
||||
else:
|
||||
st.session_state["api_url"] = input_api_url
|
||||
|
||||
if input_proxy_key is None:
|
||||
input_proxy_key = st.text_input(
|
||||
"Proxy Key",
|
||||
value=st.session_state.get("proxy_key", ""),
|
||||
placeholder="sk-...",
|
||||
)
|
||||
else:
|
||||
st.session_state["proxy_key"] = input_proxy_key
|
||||
# When the "Save" button is clicked, update the session state
|
||||
if st.button("Save"):
|
||||
st.session_state["api_url"] = input_api_url
|
||||
st.session_state["proxy_key"] = input_proxy_key
|
||||
st.success("Configuration saved!")
|
||||
elif page == "Update Config":
|
||||
update_config()
|
||||
elif page == "End-User Auth":
|
||||
proxy_setup()
|
||||
elif page == "Add Models":
|
||||
add_new_model()
|
||||
elif page == "List Models":
|
||||
list_models()
|
||||
elif page == "Create Key":
|
||||
create_key()
|
||||
elif page == "View Spend Per Key":
|
||||
spend_per_key()
|
||||
elif page == "View Spend Per User":
|
||||
spend_per_user()
|
||||
|
||||
|
||||
# admin_page()
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--proxy_endpoint", type=str, help="Proxy Endpoint")
|
||||
@click.option("--proxy_master_key", type=str, help="Proxy Master Key")
|
||||
def main(proxy_endpoint, proxy_master_key):
|
||||
admin_page(input_api_url=proxy_endpoint, input_proxy_key=proxy_master_key)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
145
ui/pages/user.py
145
ui/pages/user.py
@ -1,145 +0,0 @@
|
||||
"""
|
||||
Auth in user, to proxy ui.
|
||||
|
||||
Uses supabase passwordless auth: https://supabase.com/docs/reference/python/auth-signinwithotp
|
||||
|
||||
Remember to set your redirect url to 8501 (streamlit default).
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
from dotenv import load_dotenv
|
||||
import requests
|
||||
import base64
|
||||
import binascii
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def is_base64(sb):
|
||||
try:
|
||||
if isinstance(sb, str):
|
||||
# Try to encode it to bytes if it's a unicode string
|
||||
sb_bytes = sb.encode("ascii")
|
||||
elif isinstance(sb, bytes):
|
||||
sb_bytes = sb
|
||||
else:
|
||||
# If it is not a byte or a string, it is not base64
|
||||
return False
|
||||
|
||||
# Check if decoding is successful.
|
||||
decoded_params = base64.urlsafe_b64decode(sb_bytes)
|
||||
params_str = decoded_params.decode("utf-8")
|
||||
param_dict = {}
|
||||
# split on the &
|
||||
params = params_str.split("&")
|
||||
# split on the =
|
||||
for param in params:
|
||||
split_val = param.split("=")
|
||||
param_dict[split_val[0].strip()] = split_val[1].strip()
|
||||
# If the decode was successful, the input is likely base64
|
||||
return True, param_dict
|
||||
except (binascii.Error, ValueError):
|
||||
# If an error occurs, return False, as the input is not base64
|
||||
return False
|
||||
|
||||
|
||||
def sign_in_with_otp(email: str, page_param: str):
|
||||
print(f"received page param: {page_param}")
|
||||
b64_flag, decoded_params = is_base64(sb=page_param)
|
||||
print(f"b64_flag: {b64_flag}")
|
||||
st.write(f"Decoded params: {decoded_params}")
|
||||
# requests.post()
|
||||
# data = supabase.auth.sign_in_with_otp(
|
||||
# {"email": email, "options": {"data": {"page_param": page_param}}}
|
||||
# )
|
||||
# print(f"data: {data}")
|
||||
# # Redirect to Supabase UI with the return data
|
||||
# st.write(f"Please check your email for a login link!")
|
||||
|
||||
|
||||
# def verify_with_otp(token: str):
|
||||
# res = supabase.auth.verify_otp({"token_hash": token, "type": "email"})
|
||||
# return res
|
||||
|
||||
|
||||
# Create the Streamlit app
|
||||
def auth_page(page_param: str):
|
||||
st.title("User Authentication")
|
||||
|
||||
# User email input
|
||||
email = st.text_input("Enter your email")
|
||||
|
||||
# Sign in button
|
||||
if st.button("Sign In"):
|
||||
b64_flag, decoded_params = is_base64(sb=page_param)
|
||||
# Define the endpoint you want to make a POST request to
|
||||
if decoded_params["proxy_url"].endswith("/"):
|
||||
post_endpoint = f"{decoded_params['proxy_url']}user/auth"
|
||||
else:
|
||||
post_endpoint = f"{decoded_params['proxy_url']}/user/auth"
|
||||
|
||||
if (
|
||||
decoded_params["accepted_email_subdomain"] == "*"
|
||||
): # if user wants to allow all emails
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
assert email.split("@")[1] in decoded_params["accepted_email_subdomain"]
|
||||
except Exception:
|
||||
raise Exception(
|
||||
f"Only emails from {decoded_params['accepted_email_subdomain']} are allowed"
|
||||
)
|
||||
response = requests.post(
|
||||
post_endpoint, json={"user_email": email, "page": page_param}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
# Success!
|
||||
st.success("Email sent successfully!")
|
||||
|
||||
|
||||
def user_page(page_param: str, user_id: str, token: str):
|
||||
st.title("User Configuration")
|
||||
|
||||
# When the button is clicked
|
||||
if st.button("Create Key"):
|
||||
b64_flag, decoded_params = is_base64(sb=page_param)
|
||||
# Define the endpoint you want to make a POST request to
|
||||
if decoded_params["proxy_url"].endswith("/"):
|
||||
post_endpoint = f"{decoded_params['proxy_url']}key/generate"
|
||||
else:
|
||||
post_endpoint = f"{decoded_params['proxy_url']}/key/generate"
|
||||
# Make a POST request to the endpoint
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
response = requests.post(
|
||||
post_endpoint, json={"duration": "1hr", "user_id": user_id}, headers=headers
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
# Success! You can handle the JSON response if you're expecting one
|
||||
st.success("Key created successfully!")
|
||||
response_data = response.json()
|
||||
st.success(f"API Key: {response_data['key']}")
|
||||
|
||||
|
||||
def router():
|
||||
query_params = st.experimental_get_query_params()
|
||||
page_param = query_params.get("page", None)
|
||||
if (
|
||||
query_params.get("token", None) is not None
|
||||
and query_params.get("user_id", None) is not None
|
||||
and page_param is not None
|
||||
):
|
||||
# render user page
|
||||
user_page(
|
||||
page_param=page_param[0],
|
||||
user_id=query_params.get("user_id")[0],
|
||||
token=query_params.get("token")[0],
|
||||
)
|
||||
elif page_param is not None:
|
||||
auth_page(page_param=page_param[0])
|
||||
else:
|
||||
st.write("Please setup proxy")
|
||||
|
||||
|
||||
router()
|
||||
@ -1,6 +0,0 @@
|
||||
streamlit
|
||||
python-dotenv
|
||||
supabase
|
||||
pandas
|
||||
plotly
|
||||
click
|
||||
Loading…
Reference in New Issue
Block a user