Spaces:
Sleeping
Sleeping
import streamlit as st | |
import asyncio | |
import tokonomics | |
from utils import create_model_hierarchy | |
st.set_page_config(page_title="LLM Pricing App", layout="wide") | |
# -------------------------- | |
# Async Data Loading Function | |
# -------------------------- | |
async def load_data(): | |
"""Simulate loading data asynchronously.""" | |
AVAILABLE_MODELS = await tokonomics.get_available_models() | |
hierarchy = create_model_hierarchy(AVAILABLE_MODELS) | |
FILTERED_MODELS = [] | |
MODEL_PRICING = {} | |
PROVIDERS = list(hierarchy.keys()) | |
for provider in PROVIDERS: | |
for model_family in hierarchy[provider]: | |
for model_version in hierarchy[provider][model_family].keys(): | |
for region in hierarchy[provider][model_family][model_version]: | |
model_id = hierarchy[provider][model_family][model_version][region] | |
MODEL_PRICING[model_id] = await tokonomics.get_model_costs(model_id) | |
FILTERED_MODELS.append(model_id) | |
return FILTERED_MODELS, MODEL_PRICING, PROVIDERS | |
# -------------------------- | |
# Provider Change Function | |
# -------------------------- | |
def provider_change(provider, selected_type, all_types=["text", "vision", "video", "image"]): | |
"""Filter models based on the selected provider and type.""" | |
all_models = st.session_state.get("models", []) | |
new_models = [] | |
others = [a_type for a_type in all_types if selected_type != a_type] | |
for model_name in all_models: | |
if provider in model_name: | |
if selected_type in model_name: | |
new_models.append(model_name) | |
elif any(other in model_name for other in others): | |
continue | |
else: | |
new_models.append(model_name) | |
return new_models if new_models else all_models | |
# -------------------------- | |
# Estimate Cost Function (Updated) | |
# -------------------------- | |
def estimate_cost(num_alerts, input_size, output_size, model_id): | |
pricing = st.session_state.get("pricing", {}) | |
cost_token = pricing.get(model_id) | |
if not cost_token: | |
return "NA" | |
input_tokens = round(input_size * 1.3) | |
output_tokens = round(output_size * 1.3) | |
price_day = cost_token.get("input_cost_per_token", 0) * input_tokens + \ | |
cost_token.get("output_cost_per_token", 0) * output_tokens | |
price_total = price_day * num_alerts | |
return f"""## Estimated Cost: | |
Day Price: {price_total:0.2f} USD | |
Month Price: {price_total * 31:0.2f} USD | |
Year Price: {price_total * 365:0.2f} USD | |
""" | |
# -------------------------- | |
# Load Data into Session State (only once) | |
# -------------------------- | |
if "data_loaded" not in st.session_state: | |
with st.spinner("Loading pricing data..."): | |
models, pricing, providers = asyncio.run(load_data()) | |
st.session_state["models"] = models | |
st.session_state["pricing"] = pricing | |
st.session_state["providers"] = providers | |
st.session_state["data_loaded"] = True | |
# -------------------------- | |
# Sidebar | |
# -------------------------- | |
with st.sidebar: | |
st.image("https://cdn.prod.website-files.com/630f558f2a15ca1e88a2f774/631f1436ad7a0605fecc5e15_Logo.svg", | |
use_container_width=True) | |
st.markdown( | |
""" Visit: [https://www.priam.ai](https://www.priam.ai) | |
""" | |
) | |
st.divider() | |
st.sidebar.title("LLM Pricing Calculator") | |
# -------------------------- | |
# Main Content Layout (Model Selection Tab) | |
# -------------------------- | |
tab1, tab2 = st.tabs(["Model Selection", "About"]) | |
with tab1: | |
st.header("LLM Pricing App") | |
# --- Row 1: Provider/Type and Model Selection --- | |
col_left, col_right = st.columns(2) | |
with col_left: | |
selected_provider = st.selectbox( | |
"Select a provider", | |
st.session_state["providers"], | |
index=st.session_state["providers"].index("azure") if "azure" in st.session_state["providers"] else 0 | |
) | |
selected_type = st.radio("Select type", options=["text", "image"], index=0) | |
with col_right: | |
# Filter models based on the selected provider and type | |
filtered_models = provider_change(selected_provider, selected_type) | |
if filtered_models: | |
# Force "gpt-4-turbo" as default if available; otherwise, default to the first model. | |
default_model = "o1" if "o1" in filtered_models else filtered_models[0] | |
selected_model = st.selectbox( | |
"Select a model", | |
options=filtered_models, | |
index=filtered_models.index(default_model) | |
) | |
else: | |
selected_model = None | |
st.write("No models available") | |
# --- Row 2: Alert Stats --- | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
num_alerts = st.number_input( | |
"Security Alerts Per Day", | |
value=100, | |
min_value=1, | |
step=1, | |
help="Number of security alerts to analyze daily" | |
) | |
with col2: | |
input_size = st.number_input( | |
"Alert Content Size (characters)", | |
value=1000, | |
min_value=1, | |
step=1, | |
help="Include logs, metadata, and context per alert" | |
) | |
with col3: | |
output_size = st.number_input( | |
"Analysis Output Size (characters)", | |
value=500, | |
min_value=1, | |
step=1, | |
help="Expected length of security analysis and recommendations" | |
) | |
# --- Row 3: Buttons --- | |
btn_col1, btn_col2 = st.columns(2) | |
with btn_col1: | |
if st.button("Estimate"): | |
if selected_model: | |
st.session_state["result"] = estimate_cost(num_alerts, input_size, output_size, selected_model) | |
else: | |
st.session_state["result"] = "No model selected." | |
with btn_col2: | |
if st.button("Refresh Pricing Data"): | |
with st.spinner("Refreshing pricing data..."): | |
models, pricing, providers = asyncio.run(load_data()) | |
st.session_state["models"] = models | |
st.session_state["pricing"] = pricing | |
st.session_state["providers"] = providers | |
st.success("Pricing data refreshed!") | |
st.divider() | |
# --- Display Results --- | |
st.markdown("### Results") | |
if "result" in st.session_state: | |
st.write(st.session_state["result"]) | |
else: | |
st.write("Use the buttons above to estimate costs.") | |
# --- Clear Button Below Results --- | |
if st.button("Clear"): | |
st.session_state.pop("result", None) | |
st.rerun() | |
with tab2: | |
st.markdown( | |
""" | |
## About This App | |
This is based on the tokonomics package. | |
- The app downloads the latest pricing from the LiteLLM repository. | |
- Using simple maths to estimate the total tokens. | |
- Version 0.1 | |
Website: [https://www.priam.ai](https://www.priam.ai) | |
""" | |
) | |