Spaces:
Sleeping
Sleeping
import gradio as gr | |
import json | |
import os | |
import logging | |
import requests | |
# Configure logging | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
# Anthropic API key - can be set as HuggingFace secret or environment variable | |
ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY", "") | |
# Check if API key is available | |
if ANTHROPIC_API_KEY: | |
logger.info("Claude API key found") | |
else: | |
logger.warning("Claude API key not found - using demo mode") | |
def call_claude_api(prompt): | |
"""Call Claude API directly""" | |
if not ANTHROPIC_API_KEY: | |
return "β Claude API key not configured. Please set ANTHROPIC_API_KEY environment variable." | |
try: | |
headers = { | |
"Content-Type": "application/json", | |
"x-api-key": ANTHROPIC_API_KEY, | |
"anthropic-version": "2023-06-01" | |
} | |
data = { | |
"model": "claude-3-5-sonnet-20241022", | |
"max_tokens": 4096, | |
"messages": [ | |
{ | |
"role": "user", | |
"content": prompt | |
} | |
] | |
} | |
response = requests.post( | |
"https://api.anthropic.com/v1/messages", | |
headers=headers, | |
json=data, | |
timeout=60 | |
) | |
if response.status_code == 200: | |
response_json = response.json() | |
return response_json['content'][0]['text'] | |
else: | |
logger.error(f"Claude API error: {response.status_code} - {response.text}") | |
return f"β Claude API Error: {response.status_code}" | |
except Exception as e: | |
logger.error(f"Error calling Claude API: {str(e)}") | |
return f"β Error: {str(e)}" | |
def process_file(file): | |
"""Process uploaded file""" | |
if file is None: | |
return "Please upload a file first." | |
try: | |
# Read file content | |
with open(file.name, 'r', encoding='utf-8', errors='ignore') as f: | |
content = f.read() | |
if not content.strip(): | |
return "File appears to be empty." | |
return content | |
except Exception as e: | |
return f"Error reading file: {str(e)}" | |
def analyze_transcript(file, age, gender, slp_notes): | |
"""Simple CASL analysis""" | |
if file is None: | |
return "Please upload a transcript file first." | |
# Get transcript content | |
transcript = process_file(file) | |
if transcript.startswith("Error") or transcript.startswith("Please"): | |
return transcript | |
# Add SLP notes to the prompt if provided | |
notes_section = "" | |
if slp_notes and slp_notes.strip(): | |
notes_section = f""" | |
SLP CLINICAL NOTES: | |
{slp_notes.strip()} | |
""" | |
# Simple analysis prompt | |
prompt = f""" | |
You are a speech-language pathologist analyzing a transcript for CASL assessment. | |
Patient: {age}-year-old {gender} | |
TRANSCRIPT: | |
{transcript}{notes_section} | |
Please provide a CASL analysis including: | |
1. SPEECH FACTORS (with counts and severity): | |
- Difficulty producing fluent speech | |
- Word retrieval issues | |
- Grammatical errors | |
- Repetitions and revisions | |
2. CASL SKILLS ASSESSMENT: | |
- Lexical/Semantic Skills (Standard Score, Percentile, Level) | |
- Syntactic Skills (Standard Score, Percentile, Level) | |
- Supralinguistic Skills (Standard Score, Percentile, Level) | |
3. TREATMENT RECOMMENDATIONS: | |
- List 3-5 specific intervention strategies | |
4. CLINICAL SUMMARY: | |
- Brief explanation of findings and prognosis | |
Use exact quotes from the transcript as evidence. | |
Provide realistic standard scores (70-130 range, mean=100). | |
{f"Consider the SLP clinical notes in your analysis." if slp_notes and slp_notes.strip() else ""} | |
""" | |
# Get analysis from Claude API | |
result = call_claude_api(prompt) | |
return result | |
# Create simple interface | |
with gr.Blocks(title="Simple CASL Analysis", theme=gr.themes.Soft()) as app: | |
gr.Markdown("# π£οΈ Simple CASL Analysis Tool") | |
gr.Markdown("Upload a speech transcript and get instant CASL assessment results.") | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown("### Upload & Settings") | |
file_upload = gr.File( | |
label="Upload Transcript File", | |
file_types=[".txt", ".cha"] | |
) | |
age = gr.Number( | |
label="Patient Age", | |
value=8, | |
minimum=1, | |
maximum=120 | |
) | |
gender = gr.Radio( | |
["male", "female", "other"], | |
label="Gender", | |
value="male" | |
) | |
slp_notes = gr.Textbox( | |
label="SLP Clinical Notes (Optional)", | |
placeholder="Enter any additional clinical observations, context, or notes...", | |
lines=3 | |
) | |
analyze_btn = gr.Button( | |
"π Analyze Transcript", | |
variant="primary" | |
) | |
with gr.Column(): | |
gr.Markdown("### Analysis Results") | |
output = gr.Textbox( | |
label="CASL Analysis Report", | |
placeholder="Analysis results will appear here...", | |
lines=25, | |
max_lines=30 | |
) | |
# Connect the analyze button | |
analyze_btn.click( | |
analyze_transcript, | |
inputs=[file_upload, age, gender, slp_notes], | |
outputs=[output] | |
) | |
if __name__ == "__main__": | |
print("π Starting Simple CASL Analysis Tool...") | |
if not ANTHROPIC_API_KEY: | |
print("β οΈ ANTHROPIC_API_KEY not configured - analysis will show error message") | |
print(" For HuggingFace Spaces: Add ANTHROPIC_API_KEY as a secret in your space settings") | |
print(" For local use: export ANTHROPIC_API_KEY='your-key-here'") | |
else: | |
print("β Claude API configured") | |
app.launch(show_api=False) |