Spaces:
Sleeping
Sleeping
fix: sys.path for app module resolution in HF Spaces
Browse files- app/api_client.py +2 -1
- app/pages/predict.py +8 -4
- app/streamlit_app.py +9 -1
- src/storage/s3.py +2 -1
app/api_client.py
CHANGED
|
@@ -3,6 +3,7 @@ import os
|
|
| 3 |
import requests
|
| 4 |
import streamlit as st
|
| 5 |
|
|
|
|
| 6 |
API_BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8000")
|
| 7 |
|
| 8 |
|
|
@@ -59,4 +60,4 @@ def require_api():
|
|
| 59 |
f"Cannot connect to API at {API_BASE_URL}. "
|
| 60 |
"Start it with: `uv run uvicorn api.main:app --reload --port 8000`"
|
| 61 |
)
|
| 62 |
-
st.stop()
|
|
|
|
| 3 |
import requests
|
| 4 |
import streamlit as st
|
| 5 |
|
| 6 |
+
|
| 7 |
API_BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8000")
|
| 8 |
|
| 9 |
|
|
|
|
| 60 |
f"Cannot connect to API at {API_BASE_URL}. "
|
| 61 |
"Start it with: `uv run uvicorn api.main:app --reload --port 8000`"
|
| 62 |
)
|
| 63 |
+
st.stop()
|
app/pages/predict.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
|
| 4 |
-
sys.path.insert(0, str(Path(__file__).parent.parent))
|
| 5 |
|
| 6 |
import pandas as pd
|
| 7 |
import streamlit as st
|
|
@@ -11,7 +11,9 @@ from app.api_client import api_predict, require_api
|
|
| 11 |
require_api()
|
| 12 |
|
| 13 |
st.title("Predict Intent")
|
| 14 |
-
st.caption(
|
|
|
|
|
|
|
| 15 |
|
| 16 |
col1, col2 = st.columns([3, 1])
|
| 17 |
|
|
@@ -44,7 +46,9 @@ if st.button("Predict", type="primary", disabled=not text):
|
|
| 44 |
st.warning("This query was flagged as out-of-scope (low confidence).")
|
| 45 |
|
| 46 |
if result.get("ab_variant"):
|
| 47 |
-
st.info(
|
|
|
|
|
|
|
| 48 |
else:
|
| 49 |
st.info(f"Served by model `{result['model_used']}`")
|
| 50 |
|
|
@@ -64,4 +68,4 @@ samples = [
|
|
| 64 |
]
|
| 65 |
cols = st.columns(len(samples))
|
| 66 |
for col, sample in zip(cols, samples):
|
| 67 |
-
col.code(sample, language=None)
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
|
| 4 |
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
| 5 |
|
| 6 |
import pandas as pd
|
| 7 |
import streamlit as st
|
|
|
|
| 11 |
require_api()
|
| 12 |
|
| 13 |
st.title("Predict Intent")
|
| 14 |
+
st.caption(
|
| 15 |
+
"Test the intent classifier live, switching between models or letting the A/B router decide."
|
| 16 |
+
)
|
| 17 |
|
| 18 |
col1, col2 = st.columns([3, 1])
|
| 19 |
|
|
|
|
| 46 |
st.warning("This query was flagged as out-of-scope (low confidence).")
|
| 47 |
|
| 48 |
if result.get("ab_variant"):
|
| 49 |
+
st.info(
|
| 50 |
+
f"Served by A/B variant **{result['ab_variant']}** using model `{result['model_used']}`"
|
| 51 |
+
)
|
| 52 |
else:
|
| 53 |
st.info(f"Served by model `{result['model_used']}`")
|
| 54 |
|
|
|
|
| 68 |
]
|
| 69 |
cols = st.columns(len(samples))
|
| 70 |
for col, sample in zip(cols, samples):
|
| 71 |
+
col.code(sample, language=None)
|
app/streamlit_app.py
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
|
| 3 |
st.set_page_config(
|
|
@@ -11,4 +19,4 @@ compare_page = st.Page("pages/compare.py", title="Compare Models", icon=":materi
|
|
| 11 |
monitoring_page = st.Page("pages/monitoring.py", title="Monitoring", icon=":material/monitoring:")
|
| 12 |
|
| 13 |
pg = st.navigation([predict_page, compare_page, monitoring_page])
|
| 14 |
-
pg.run()
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
|
| 4 |
+
# ensure project root is on path so 'app' resolves correctly
|
| 5 |
+
root = Path(__file__).parent.parent
|
| 6 |
+
if str(root) not in sys.path:
|
| 7 |
+
sys.path.insert(0, str(root))
|
| 8 |
+
|
| 9 |
import streamlit as st
|
| 10 |
|
| 11 |
st.set_page_config(
|
|
|
|
| 19 |
monitoring_page = st.Page("pages/monitoring.py", title="Monitoring", icon=":material/monitoring:")
|
| 20 |
|
| 21 |
pg = st.navigation([predict_page, compare_page, monitoring_page])
|
| 22 |
+
pg.run()
|
src/storage/s3.py
CHANGED
|
@@ -7,14 +7,15 @@ from src.utils.settings import settings
|
|
| 7 |
|
| 8 |
|
| 9 |
def _get_client():
|
|
|
|
| 10 |
return boto3.client(
|
| 11 |
"s3",
|
| 12 |
aws_access_key_id=settings.aws_access_key_id,
|
| 13 |
aws_secret_access_key=settings.aws_secret_access_key,
|
| 14 |
region_name=settings.aws_region,
|
|
|
|
| 15 |
)
|
| 16 |
|
| 17 |
-
|
| 18 |
def upload_artifact(local_path: str, s3_key: str) -> None:
|
| 19 |
client = _get_client()
|
| 20 |
client.upload_file(local_path, settings.s3_bucket, s3_key)
|
|
|
|
| 7 |
|
| 8 |
|
| 9 |
def _get_client():
|
| 10 |
+
from botocore.config import Config
|
| 11 |
return boto3.client(
|
| 12 |
"s3",
|
| 13 |
aws_access_key_id=settings.aws_access_key_id,
|
| 14 |
aws_secret_access_key=settings.aws_secret_access_key,
|
| 15 |
region_name=settings.aws_region,
|
| 16 |
+
config=Config(signature_version="s3v4"),
|
| 17 |
)
|
| 18 |
|
|
|
|
| 19 |
def upload_artifact(local_path: str, s3_key: str) -> None:
|
| 20 |
client = _get_client()
|
| 21 |
client.upload_file(local_path, settings.s3_bucket, s3_key)
|