Update app.py
Browse files
app.py
CHANGED
|
@@ -1,86 +1,132 @@
|
|
| 1 |
-
from dotenv import load_dotenv
|
| 2 |
import os
|
| 3 |
-
import
|
| 4 |
import time
|
| 5 |
import requests
|
| 6 |
-
import
|
| 7 |
-
|
| 8 |
|
| 9 |
-
|
| 10 |
|
| 11 |
-
# Clear the console
|
| 12 |
-
os.system('cls' if os.name=='nt' else 'clear')
|
| 13 |
|
|
|
|
| 14 |
try:
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
-
# Get the business card schema
|
| 17 |
-
with open("biz-card.json", "r") as file:
|
| 18 |
-
schema_json = json.load(file)
|
| 19 |
-
|
| 20 |
-
card_schema = json.dumps(schema_json)
|
| 21 |
-
|
| 22 |
-
# Get config settings
|
| 23 |
-
load_dotenv()
|
| 24 |
-
ai_svc_endpoint = os.getenv('ENDPOINT')
|
| 25 |
-
ai_svc_key = os.getenv('KEY')
|
| 26 |
-
analyzer = os.getenv('ANALYZER_NAME')
|
| 27 |
-
|
| 28 |
-
# Create the analyzer
|
| 29 |
-
create_analyzer (card_schema, analyzer, ai_svc_endpoint, ai_svc_key)
|
| 30 |
|
| 31 |
-
|
|
|
|
|
|
|
| 32 |
|
| 33 |
-
except Exception as ex:
|
| 34 |
-
print(ex)
|
| 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
|
| 38 |
-
def create_analyzer
|
| 39 |
-
|
| 40 |
-
# Create a Content Understanding analyzer
|
| 41 |
-
print (f"Creating {analyzer}")
|
| 42 |
-
|
| 43 |
-
# Set the API version
|
| 44 |
-
CU_VERSION = "2025-05-01-preview"
|
| 45 |
-
|
| 46 |
-
# initiate the analyzer creation operation
|
| 47 |
-
headers = { "Ocp-Apim-Subscription-Key": key, "Content-Type": "application/json"}
|
| 48 |
url = f"{endpoint}/contentunderstanding/analyzers/{analyzer}?api-version={CU_VERSION}"
|
| 49 |
|
| 50 |
-
# Delete
|
| 51 |
-
|
| 52 |
-
print(response.status_code)
|
| 53 |
-
time.sleep(1)
|
| 54 |
|
| 55 |
-
#
|
| 56 |
-
|
| 57 |
-
print(response.status_code)
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
|
| 62 |
-
#
|
| 63 |
-
|
| 64 |
-
result_response = requests.get(callback_url, headers=headers)
|
| 65 |
-
|
| 66 |
-
# Keep polling until the operation is no longer running
|
| 67 |
-
status = result_response.json().get("status")
|
| 68 |
-
while status == "Running":
|
| 69 |
time.sleep(1)
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
|
| 85 |
if __name__ == "__main__":
|
| 86 |
-
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
+
import json
|
| 3 |
import time
|
| 4 |
import requests
|
| 5 |
+
import gradio as gr
|
| 6 |
+
from dotenv import load_dotenv
|
| 7 |
|
| 8 |
+
CU_VERSION = "2025-05-01-preview"
|
| 9 |
|
|
|
|
|
|
|
| 10 |
|
| 11 |
+
def safe_json(resp: requests.Response):
|
| 12 |
try:
|
| 13 |
+
return resp.json()
|
| 14 |
+
except Exception:
|
| 15 |
+
return {"text": resp.text}
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
+
def load_schema(path="biz-card.json"):
|
| 19 |
+
with open(path, "r", encoding="utf-8") as f:
|
| 20 |
+
return json.dumps(json.load(f))
|
| 21 |
|
|
|
|
|
|
|
| 22 |
|
| 23 |
+
def load_config():
|
| 24 |
+
load_dotenv()
|
| 25 |
+
endpoint = os.getenv("ENDPOINT")
|
| 26 |
+
key = os.getenv("KEY")
|
| 27 |
+
analyzer = os.getenv("ANALYZER_NAME")
|
| 28 |
+
missing = [n for n, v in [("ENDPOINT", endpoint), ("KEY", key), ("ANALYZER_NAME", analyzer)] if not v]
|
| 29 |
+
return endpoint, key, analyzer, missing
|
| 30 |
|
| 31 |
|
| 32 |
+
def create_analyzer(schema: str, analyzer: str, endpoint: str, key: str):
|
| 33 |
+
headers = {"Ocp-Apim-Subscription-Key": key, "Content-Type": "application/json"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
url = f"{endpoint}/contentunderstanding/analyzers/{analyzer}?api-version={CU_VERSION}"
|
| 35 |
|
| 36 |
+
# Delete if exists
|
| 37 |
+
del_resp = requests.delete(url, headers=headers, timeout=60)
|
|
|
|
|
|
|
| 38 |
|
| 39 |
+
# Create
|
| 40 |
+
put_resp = requests.put(url, headers=headers, data=schema, timeout=60)
|
|
|
|
| 41 |
|
| 42 |
+
op_loc = put_resp.headers.get("Operation-Location")
|
| 43 |
+
if not op_loc:
|
| 44 |
+
return (
|
| 45 |
+
False,
|
| 46 |
+
f"Missing Operation-Location header.\n"
|
| 47 |
+
f"delete status: {del_resp.status_code}\n"
|
| 48 |
+
f"create status: {put_resp.status_code}\n"
|
| 49 |
+
f"create body: {json.dumps(safe_json(put_resp), indent=2)}"
|
| 50 |
+
)
|
| 51 |
|
| 52 |
+
# Poll
|
| 53 |
+
for _ in range(180): # ~3 minutes max
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
time.sleep(1)
|
| 55 |
+
poll = requests.get(op_loc, headers=headers, timeout=60)
|
| 56 |
+
j = safe_json(poll)
|
| 57 |
+
status = (j or {}).get("status")
|
| 58 |
+
if status and status != "Running":
|
| 59 |
+
if status == "Succeeded":
|
| 60 |
+
return (
|
| 61 |
+
True,
|
| 62 |
+
f"Analyzer '{analyzer}' created successfully.\n"
|
| 63 |
+
f"delete status: {del_resp.status_code}\n"
|
| 64 |
+
f"create status: {put_resp.status_code}\n"
|
| 65 |
+
f"final status: {status}"
|
| 66 |
+
)
|
| 67 |
+
return (
|
| 68 |
+
False,
|
| 69 |
+
f"Analyzer creation failed.\n"
|
| 70 |
+
f"delete status: {del_resp.status_code}\n"
|
| 71 |
+
f"create status: {put_resp.status_code}\n"
|
| 72 |
+
f"final status: {status}\n"
|
| 73 |
+
f"details:\n{json.dumps(j, indent=2)}"
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
return (
|
| 77 |
+
False,
|
| 78 |
+
f"Timed out waiting for analyzer creation.\n"
|
| 79 |
+
f"delete status: {del_resp.status_code}\n"
|
| 80 |
+
f"create status: {put_resp.status_code}"
|
| 81 |
+
)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def handle_message(user_text, chat_history):
|
| 85 |
+
"""
|
| 86 |
+
Gradio ChatInterface handler signature:
|
| 87 |
+
(message: str, history: list[tuple[str,str]]) -> str | tuple
|
| 88 |
+
We'll append to history outside via ChatInterface; just return assistant text.
|
| 89 |
+
"""
|
| 90 |
+
text = (user_text or "").strip().lower()
|
| 91 |
+
|
| 92 |
+
if text in {"help", "/help", "commands"}:
|
| 93 |
+
return (
|
| 94 |
+
"Commands:\n"
|
| 95 |
+
"- **create analyzer** : delete (if exists) + create analyzer from `biz-card.json`\n"
|
| 96 |
+
"- **show config** : show whether ENDPOINT/KEY/ANALYZER_NAME are set\n"
|
| 97 |
+
"- **help** : show this message"
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
if text in {"show config", "config"}:
|
| 101 |
+
endpoint, key, analyzer, missing = load_config()
|
| 102 |
+
if missing:
|
| 103 |
+
return f"Missing env vars: {', '.join(missing)}"
|
| 104 |
+
return f"Config loaded ✅\n- ENDPOINT: {endpoint}\n- ANALYZER_NAME: {analyzer}\n- KEY: (set)"
|
| 105 |
+
|
| 106 |
+
if text in {"create analyzer", "create", "make analyzer", "build analyzer"}:
|
| 107 |
+
endpoint, key, analyzer, missing = load_config()
|
| 108 |
+
if missing:
|
| 109 |
+
return f"Cannot create analyzer. Missing env vars: {', '.join(missing)}"
|
| 110 |
+
|
| 111 |
+
try:
|
| 112 |
+
schema = load_schema("biz-card.json")
|
| 113 |
+
except Exception as ex:
|
| 114 |
+
return f"Could not load biz-card.json: {ex}"
|
| 115 |
+
|
| 116 |
+
ok, msg = create_analyzer(schema, analyzer, endpoint, key)
|
| 117 |
+
return msg
|
| 118 |
+
|
| 119 |
+
return "Type **help** to see commands. Try **create analyzer**."
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
demo = gr.ChatInterface(
|
| 123 |
+
fn=handle_message,
|
| 124 |
+
title="Content Understanding Chat App",
|
| 125 |
+
description="Type **help** or **create analyzer** to create your Content Understanding analyzer from biz-card.json.",
|
| 126 |
+
examples=["help", "show config", "create analyzer"],
|
| 127 |
+
theme="soft",
|
| 128 |
+
)
|
| 129 |
|
| 130 |
|
| 131 |
if __name__ == "__main__":
|
| 132 |
+
demo.launch()
|