Appearance
Hetnet
API do grafowej bazy wiedzy medycznej (Hetionet na Neo4j). PoC łączący choroby, symptomy, leki i anatomię – z wizualizacją, testbenchem i RAG na Cloudflare Workers.
Tech Stack
- Backend: Node.js ≥18, Express, Neo4j 5 (graph database)
- Frontend: Vanilla JS (D3.js visualization)
- RAG/Chat: Cloudflare Workers + Vectorize
- Translation: DeepL / LibreTranslate / MyMemory
- Deployment: Railway (Neo4j remote), Cloudflare (chat worker)
- Data: Hetionet TSV, Mendeley datasets, Infermedica docs (scraped)
Szybki start
bash
npm install
cp .env.example .env # ustaw NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD
# uruchom Neo4j + (opcjonalnie) LibreTranslate lokalnie
docker compose up -d neo4j libretranslate
# Neo4j: ~10s start, UI http://localhost:7474
# LibreTranslate: host :5010 (5000→5010 z uwagi na macOS AirPlay), pierwszy start pobiera modele en↔pl (~kilka minut)
npm run pipeline # load → neo4j → translate → export-rag (pełny pipeline)
npm start # uruchom API na :3000Dostępne interfejsy:
- Graf wizualizacja: http://localhost:3000/
- Testbench (choroba↔symptomy): http://localhost:3000/testbench
- API docs (OpenAPI): http://localhost:3000/docs
Struktura projektu
├── src/ # Express API (Neo4j driver)
├── public/ # Frontend (graf D3.js, testbench UI)
├── pipeline/ # ETL pipeline (load→parse→import→translate→export)
│ ├── parsers/ # Parsery źródeł danych (hetionet, sider, disease-ontology, etc.)
│ ├── steps/ # Kroki pipeline (1-load, 2-neo4j, 3-translate, 4-export-rag)
│ └── run.js # Runner pipeline
├── data/
│ ├── raw/ # Surowe dane (hetionet TSV, mendeley, etc.)
│ └── translations/ # Persystentny store tłumaczeń (pl.json, meta.json)
├── chat/ # Cloudflare Worker RAG (Vectorize + LLM)
├── scripts/ # Utility scripts (count-remaining, translate-and-update)
└── symptomate/ # Scraped docs Infermedica API (conditions, symptoms, risk factors)Pipeline
Główny flow ETL: źródła → parsing → Neo4j → tłumaczenia → eksport RAG chunks.
Komendy pipeline
bash
npm run pipeline # pełny przebieg (wszystkie kroki)
npm run pipeline:load # krok 1: ściągnięcie danych do data/raw/
npm run pipeline:neo4j # krok 2: import parsed data do Neo4j
npm run pipeline:translate # krok 3: tłumaczenia (DeepL/LibreTranslate/MyMemory)
npm run pipeline:rag # krok 4: eksport chunków do chat/export/Źródła danych (parsowane w pipeline/parsers/):
- Hetionet (nodes.tsv, edges.sif.gz) – główny graph
- SIDER, Disease Ontology, SymbiPredict, NeonatalADR, Health-KG, Mendeley datasets, HuggingFace, inne (sprawdź
pipeline/parsers/index.js)
Po imporcie do Neo4j masz ~138k węzłów i ~5.2M krawędzi (unverified — zależy od aktualnych źródeł).
Tłumaczenia
Pipeline krok 3 (npm run pipeline:translate) oraz standalone npm run translate używają persystentnego store data/translations/pl.json.
Backendy tłumaczeń:
- DeepL (domyślny): wymaga
DEEPL_API_KEYw.env. Przy przekroczeniu limitu quota → błądQuota Exceeded. - LibreTranslate lokalny:
npm run translate:libre:docker(Neo4j z.env) lubnpm run translate:libre:docker:railway(Neo4j z Railway). Wymaga Docker Desktop, kontenerlibretranslatemusi być up (:5010). - LibreTranslate publiczny: ustaw
LIBRETRANSLATE_API_KEY+LIBRETRANSLATE_URL. - MyMemory: darmowy, ale z rate limit (429). Testowo:
npm run translate:mymemory(tylko Disease+Symptom, max 500 nodes).
Filtrowanie (przyspiesza na start):
bash
TRANSLATE_KINDS=Disease,Symptom npm run translateRailway remote (tłumaczenie na zdalnym Neo4j):
bash
railway run --service hetnet node scripts/translate-and-update.jsNowe języki: dodaj plik store w data/translations/, rozszerz pipeline/config.js (krok translate obecnie wspiera tylko PL przez standalone skrypt).
Railway Deployment
Pipeline działa lokalnie, łączy się z Neo4j na Railway i importuje dane (nie potrzebujesz Docker lokalnie dla remote setup).
Setup projektu Railway (unverified — confirm steps with team)
- Projekt: Deploy from GitHub →
Wellysa/hetnet - Dodaj Neo4j service:
- Image:
neo4j:5-community - Variables:
NEO4J_AUTH=neo4j/hasło - Volume:
/data - Expose TCP Proxy na port 7687
- Image:
- Neo4j Variables: dodaj
BOLT_URI=bolt://${{TCP_PROXY_DOMAIN}}:${{TCP_PROXY_PORT}} - API Service Variables:
NEO4J_URI=${{Neo4j.BOLT_URI}}NEO4J_USER=neo4jNEO4J_PASSWORD= hasło z kroku 2
- Railway CLI:bash
npm i -g @railway/cli railway link # wybierz projekt
Import danych na remote
bash
railway run npm run pipelineUruchamia pełny pipeline (load → parse → import do Neo4j na Railway). Trwa kilka minut.
Opcjonalnie NeoDash (unverified): Image neo4jlabs/neodash, te same zmienne Neo4j co główny service.
API (endpoints unverified — verify in src/index.js)
| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /health | Health check |
| GET | /api/stats | Liczba węzłów i krawędzi |
| GET | /api/labels | Typy węzłów (labels) |
| GET | /api/search?q=aspirin&limit=20 | Full-text search |
| GET | /api/node/:id | Węzeł + bezpośrednie relacje |
| GET | /api/neighbors/:id?depth=1&limit=100 | Sąsiedzi do głębokości N |
| GET | /api/diseases | Lista chorób |
| GET | /api/symptoms | Lista symptomów |
| GET | /api/disease/:id/symptoms | Symptomy dla choroby |
| POST | /api/diseases-by-symptoms | Choroby pasujące do symptomów (koniunkcja) |
Query param ?lang=pl: zwraca name_pl gdzie dostępne (po uruchomieniu tłumaczeń).
OpenAPI: /docs (Swagger UI), /openapi.json
Testbench
/testbench – interaktywny UI do testowania:
- Wybierz chorobę → pokaż symptomy
- Wybierz symptomy → znajdź choroby (koniunkcja)
- Przełącznik PL/EN
Chat (RAG)
Czat z bazą wiedzy na Cloudflare Workers (Vectorize + embedding bge-m3 + Llama 3.1).
Setup (unverified — see chat/README.md):
- Uruchom pipeline (lub
npm run export:ragpo imporcie do Neo4j) – eksportuje chunki dochat/export/ - Ingest do Vectorize:bash
CHAT_URL=https://your-worker.workers.dev node chat/ingest-from-export.js - Deploy workera:bash
cd chat npx wrangler deploy
Szczegóły konfiguracji Vectorize, bindings, secrets → chat/README.md.
Symptomate
Folder symptomate/ zawiera scraped dokumentację Infermedica API (platform-api, engine-api, intake-api, overview). Tylko listy encji (conditions, symptoms, risk factors) – bez relacji choroba↔symptom (te są w Hetionet).
Ponowne scrapowanie (unverified): node symptomate/scrape-docs.js
Development
bash
npm install
# ustaw .env: NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD, (opcjonalnie) DEEPL_API_KEY
npm run dev # --watch mode (Node 18+)
npm start # produkcjaInne komendy:
bash
npm run count:remaining # policz pozostałe do przetłumaczenia
npm run export:rag # eksport RAG chunków (bez pełnego pipeline)Status
PoC – proof of concept dla grafowej bazy wiedzy medycznej. Produkcyjne deployment wymaga:
- Rate limiting, auth dla API
- Walidacja źródeł danych (licencje, aktualność)
- Monitoring tłumaczeń (quality check)
- CI/CD dla Railway + Cloudflare deploy
License & Data Sources
Hetionet: CC0 (public domain). Pozostałe źródła: sprawdź data/raw/MANUAL_SOURCES.md i licencje poszczególnych datasets.