licensing / gradio_bot.py
ShrimpLeopold's picture
Upload folder using huggingface_hub
51d56de verified
Raw
History Blame Contribute Delete
6.48 kB
# grad_bot2.py
import sys
import logging
# 1) Configure logging to go to stdout
logging.basicConfig(
level=logging.INFO,
stream=sys.stdout,
format="%(asctime)s %(levelname)s %(name)s | %(message)s",
)
# 2) (optional) Redirect built-in print → logging.info
import builtins
_original_print = builtins.print
def _patched_print(*args, **kwargs):
msg = " ".join(str(a) for a in args)
logging.info(msg)
builtins.print = _patched_print
import gradio as gr
import aiohttp
import builtins
# Configure logging to capture all stdout and stderr
debug_format = '%(asctime)s - %(levelname)s - %(message)s'
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format=debug_format)
# Redirect other loggers (uvicorn, gradio internal) to our root logger
for logger_name in ['uvicorn', 'uvicorn.error', 'uvicorn.access', 'fastapi', 'gradio']:
logger = logging.getLogger(logger_name)
logger.handlers = logging.getLogger().handlers
logger.propagate = True
# Redirect stdout and stderr to logging
class LoggerWriter:
def __init__(self, level_func):
self.level_func = level_func
def write(self, message):
message = message.strip()
if message:
self.level_func(message)
def flush(self):
pass
sys.stdout = LoggerWriter(logging.info)
sys.stderr = LoggerWriter(logging.error)
# Also capture any print calls into logging
_orig_print = builtins.print
builtins.print = lambda *args, **kwargs: logging.info(' '.join(str(a) for a in args))
# Configuration for the licensing service
LICENSING_SERVICE_BASE = 'https://gbdlicensing01containerapp.delightfulocean-00db0bf9.westeurope.azurecontainerapps.io'
async def call_licensing_api(
endpoint: str,
index_name: str,
api_key: str,
input_text: str = None,
question: str = None,
) -> dict:
"""
Sends a POST to either /create_index or /answer_question on your FastAPI service.
"""
if endpoint not in ("create_index", "answer_question"):
raise ValueError("`endpoint` must be either 'create_index' or 'answer_question'")
if endpoint == "create_index" and input_text is None:
raise ValueError("When calling 'create_index', you must provide `input_text`")
if endpoint == "answer_question" and question is None:
raise ValueError("When calling 'answer_question', you must provide `question`")
headers = {"X-API-Key": api_key, "Content-Type": "application/json"}
payload = {"index_name": index_name}
if endpoint == "create_index":
payload["input_text"] = input_text
else:
payload["question"] = question
timeout = aiohttp.ClientTimeout(total=60)
async with aiohttp.ClientSession(timeout=timeout) as session:
url = f"{LICENSING_SERVICE_BASE}/{endpoint}"
logging.info(f"Calling licensing API at {url} with payload: {payload}")
async with session.post(url, json=payload, headers=headers) as resp:
resp.raise_for_status()
result = await resp.json()
logging.info(f"Received response: {result}")
return result
async def get_answer(api_key: str, final_selection: str, question: str) -> str:
"""Fetches an answer for the question based on the final topic selection."""
index_map = {
'Office 365': 'licensing-fundamentals'
}
index_name = index_map.get(final_selection)
logging.info(f"Final selection: {final_selection} -> index: {index_name}")
response = await call_licensing_api(
endpoint="answer_question",
index_name=index_name,
api_key=api_key,
question=question
)
answer = response.get('answer', '')
logging.info(f"Extracted answer: {answer}")
return answer
def main():
with gr.Blocks() as demo:
# API key input
api_key_input = gr.Textbox(
label='Licensing Service API Key',
placeholder='Paste your API key here',
type='password'
)
# Step 1: Primary topic selection
primary_topic = gr.Radio(
choices=['License Program', 'Products', 'Customer info'],
label='What would you like to learn about?'
)
# Step 2: Product type, shown only if 'Products' selected
product_container = gr.Column(visible=False)
with product_container:
product_type = gr.Radio(
choices=['Software', 'Online services'],
label='Which products?'
)
# Step 3: Service type, shown only if 'Online services' selected
service_container = gr.Column(visible=False)
with service_container:
service_type = gr.Radio(
choices=['Office 365'],
label='Select an online service'
)
# Step 4: QA, shown only after service_type selection
qa_container = gr.Column(visible=False)
with qa_container:
question = gr.Textbox(
lines=3,
placeholder='Type your question here...',
label='Your Question'
)
answer = gr.Textbox(
lines=5,
interactive=False,
label='Answer'
)
submit = gr.Button('Submit')
submit.click(
fn=get_answer,
inputs=[api_key_input, service_type, question],
outputs=[answer]
)
# Callbacks to reveal steps
primary_topic.change(
fn=lambda sel: gr.update(visible=(sel=='Products')),
inputs=[primary_topic],
outputs=[product_container]
)
primary_topic.change(
fn=lambda sel: gr.update(visible=False),
inputs=[primary_topic],
outputs=[service_container, qa_container]
)
product_type.change(
fn=lambda sel: gr.update(visible=(sel=='Online services')),
inputs=[product_type],
outputs=[service_container]
)
product_type.change(
fn=lambda sel: gr.update(visible=False),
inputs=[product_type],
outputs=[qa_container]
)
service_type.change(
fn=lambda sel: gr.update(visible=(sel=='Office 365')),
inputs=[service_type],
outputs=[qa_container]
)
# Launch with public sharing enabled
demo.launch(share=True)
if __name__ == '__main__':
main()