Spaces:
Running
Running
|
Download README.md from stevafernandes/AnatoBot: direct link, hf CLI and curl.
- Browser
- Download file 6.37 kB
-
https://huggingface.co/spaces/stevafernandes/AnatoBot/resolve/main/README.md
- Command line
-
hf download hf://spaces/stevafernandes/AnatoBot/README.md
-
curl -L -o README.md https://huggingface.co/spaces/stevafernandes/AnatoBot/resolve/main/README.md
6.37 kB
| title: Creighton Anatomy Learning Platform | |
| colorFrom: blue | |
| colorTo: blue | |
| sdk: gradio | |
| sdk_version: 5.49.1 | |
| python_version: "3.10" | |
| app_file: app.py | |
| pinned: false | |
| # Creighton Anatomy Learning Platform | |
| A chat-based anatomy tutor grounded in the course lecture slides. Answers, quizzes, and clinical | |
| correlations cite the lecture and slide they come from, and the slide viewer renders the cited | |
| pages directly from the lecture PDFs. | |
| - Students sign in with a user ID and email (new users create an account with the same two fields). | |
| Accounts, every chat message, time spent on the site, and every button click are stored in Supabase, | |
| and a returning student sees their earlier questions and answers again. | |
| - Every request is answered from the slides first. When the slides do not cover it, the tutor looks the | |
| topic up on [TeachMeAnatomy](https://teachmeanatomy.info/) and | |
| [Kenhub](https://www.kenhub.com/en/library/education/the-human-anatomy) and answers from those | |
| articles instead. Every answer ends with a **Source** line naming the slides or the article pages it | |
| came from. The tutor never answers from its own knowledge. | |
| - Articles are looked up per anatomical structure: a question about the knee and the ankle gets the knee | |
| joint and ankle joint articles, and a page is never chosen because of a word such as "injury", | |
| "fracture", or "layers" alone. | |
| - **Clinical Correlation** has two sections, each citing its source: "From the lecture slides" and | |
| "From TeachMeAnatomy" / "From Kenhub" / "From TeachMeAnatomy and Kenhub" (the clinical sections of the | |
| articles about the topic's structures). | |
| - While the tutor works, the chat shows a "Thinking" message with a spinner that reports each step. | |
| - Answers are written on a background thread, so an answer is finished and saved even when the | |
| student's connection drops while it is being written. When the connection comes back, the page | |
| reloads by itself, signs the student back in, and shows the chat with that answer; the question | |
| being typed is kept. After a Space restart the open page signs back in the same way. The sign-in is | |
| remembered only by that browser tab (`sessionStorage`) and used only for that automatic reload: a | |
| manual reload, a new tab or window, or a closed tab reopened by the next person on a shared computer | |
| starts at the sign-in form, and **Sign out** forgets it. | |
| - The viewer shows only the slides an answer actually rests on: slides cited in the answer and the | |
| figure slides that follow them. | |
| ## Files | |
| - `app.py` - the application. | |
| - `supabase_store.py` - accounts, chat history, sessions, and click events in Supabase (standard library only). | |
| - `web_sources.py` - looks up reference articles on TeachMeAnatomy and Kenhub through their sitemaps. | |
| - `supabase_schema.sql` - the tables and analytics views; run once in Supabase. | |
| - `verify_supabase.py` - checks a Supabase project end to end with a throwaway account. | |
| - `test_app.py` - offline tests (Gemini, Supabase, and the web are stubbed). | |
| - `requirements.txt` - Python dependencies (Gradio comes from the Space SDK). | |
| - `Lectures/` - the lecture PDFs (`Lecture #N - Title.pdf`) and the logo (`creighton-bluejays@logotyp.us.png`, | |
| or `resize.webp` as a fallback) shown at the bottom of the page. Copy the folder | |
| here as-is; it is read at startup. Uploading the folder zipped as `Lectures.zip` next to `app.py` also | |
| works: the app unpacks it on first start. | |
| ## Set up Supabase (once) | |
| 1. In your Supabase project open **SQL Editor**, paste the contents of `supabase_schema.sql`, and run it. | |
| It creates `anatomy_users`, `anatomy_messages`, `anatomy_sessions`, `anatomy_events`, and two views. | |
| 2. Copy the project URL and the **service_role** key from **Project Settings > API**. The app runs | |
| server-side, so the key never reaches a browser; the tables have Row Level Security on with no | |
| policies, so the public anon key can read nothing. | |
| 3. Check the wiring: | |
| ```bash | |
| export SUPABASE_URL="https://YOUR-PROJECT-REF.supabase.co" | |
| export SUPABASE_KEY="YOUR-SERVICE-ROLE-KEY" | |
| python3 verify_supabase.py | |
| ``` | |
| ### Analytics | |
| - `anatomy_time_per_user` - sessions and seconds on the site per user (the open tab reports every 30 s, | |
| so a session's length is `last_seen_at - started_at`). When a tab loses its connection (a laptop going | |
| to sleep), its session is closed; when the student comes back a new session starts, so the time away | |
| is not counted. | |
| - `anatomy_button_clicks` - clicks per user and button (`ask`, `quiz`, `clinical`, `simplify`, `show_image`, | |
| `clear`, `previous`, `next`, `browse_lecture`, `browse_slide`, `example`, `sign_in`, `create_account`, `sign_out`), | |
| plus `resume` when a page signed the student back in by itself after a reload or a Space restart. | |
| - `anatomy_events` holds the raw click log with a `detail` JSON column (question length, lecture and slide | |
| numbers); `anatomy_messages` holds every question and answer with its `source` (`slides`, `web`, | |
| `slides+web` for a clinical correlation from both, `none`, `error`). | |
| ## Deploy to Hugging Face Spaces | |
| 1. Create a new Space with the Gradio SDK. | |
| 2. In the Space settings, add these secrets: `GEMINI_API_KEY` (your Gemini API key), `SUPABASE_URL`, and | |
| `SUPABASE_KEY` (the service_role key). Optional: a variable `GEMINI_MODEL` to change the model | |
| (default `gemini-2.5-flash`; the app falls back to `gemini-3.8-flash` and `gemini-3.5-flash` when the | |
| configured model is not available to the key). | |
| 3. Copy the `Lectures` folder (or `Lectures.zip`) into this directory, then upload everything: | |
| ```bash | |
| hf upload <your-username>/<space-name> . . --repo-type space --exclude "__pycache__/*" --exclude ".DS_Store" --exclude "**/.DS_Store" | |
| ``` | |
| PDFs larger than 10 MB are stored with Git LFS automatically. The Space indexes the slides | |
| when it starts, which takes well under a minute; the reference-site sitemaps are downloaded in the | |
| background on startup and refreshed daily. | |
| ## Run locally | |
| ```bash | |
| pip install -r requirements.txt gradio==5.49.1 | |
| export GEMINI_API_KEY=your_key | |
| export SUPABASE_URL=https://YOUR-PROJECT-REF.supabase.co | |
| export SUPABASE_KEY=YOUR-SERVICE-ROLE-KEY | |
| python app.py | |
| ``` | |
| Set `LECTURES_DIR` to point at the lecture folder if it is not next to `app.py`. Run the offline tests with: | |
| ```bash | |
| LECTURES_DIR=/path/to/Lectures GEMINI_API_KEY=test python -m unittest -v test_app | |
| ``` | |