Skip to content

Installation

Complete first-time setup — backend, frontend, data.

Prerequisites

Tool Version Why
Python 3.11+ (3.12 recommended) Required by pyproject.toml
uv Latest The only supported package manager — do not use bare pip
Node.js 18+ Frontend build (Vite)
SQLite Bundled with Python DB — no separate install needed

Optional for the visual extra (Holo3 screenshots): - Chromium (auto-installed by Playwright — uv run playwright install chromium)


1. Clone & install

git clone https://github.com/khalilouardini/ogur.git
cd ogur
uv sync --extra dev     # installs runtime + dev deps (pytest, ruff)

To include the visual-intelligence extra (Holo3 scrapers):

uv sync --extra dev --extra visual
uv run playwright install chromium

2. Environment variables

Copy the template and fill what you have:

cp .env.example .env

Required

Var Purpose
ANTHROPIC_API_KEY Classifier (Haiku), synthesizer (Sonnet), per-tab analyzers, QueryEngine

Optional (source-specific — missing keys make that source no-op, never crash)

Var Source Where to get it
PUBMED_API_KEY PubMed / NCBI Entrez https://www.ncbi.nlm.nih.gov/account/ — raises rate limit 3 → 10 req/s
OPENALEX_API_KEY OpenAlex https://openalex.org/settings/api — free
LENS_API_KEY Lens.org patents https://www.lens.org/lens/user/subscriptions — free 14-day trial
EPO_CONSUMER_KEY + EPO_CONSUMER_SECRET EPO OPS patents https://developers.epo.org — free, instant registration
HOLO3_API_KEY H Company Holo3 (visual intel) https://hcompany.ai (enterprise)

Configuration

All env vars are defined in ogur/config.py via pydantic-settings. Other tunables that you can override via .env:

Var Default Purpose
DATABASE_URL sqlite:///ogur.db DB connection string
LLM_SYNTHESIS_MODEL claude-sonnet-4-6 Synthesizer
LLM_CLASSIFIER_MODEL claude-haiku-4-5-20251001 Classifier, analyzers, QueryEngine
BRIEFING_WINDOW_DAYS 7 Lookback window for ChangeDetector
MAX_SIGNALS_FOR_SYNTHESIS 20 Cap on signals included in a briefing
OPENTARGETS_DISEASE_ID EFO_0003060 (NSCLC) EFO disease ID for OpenTargets queries
CLINICALTRIALS_RPS / OPENFDA_RPS / PUBMED_RPS 10 / 4 / 3 Per-source request budgets (req/s)

3. Verify the install

make test

Should report 785 passed, 1 skipped, 1 deselected. The skipped test needs the GLiNER ML stack; the deselected test is the integration marker. Warnings about datetime.utcnow() being deprecated are expected and not blocking.

make lint

Should exit 0.


4. Seed the database

Two landscapes are pre-configured:

make seed                # nsclc-001 — oncology landscape, ~5 min
make seed-immunology     # immunology-001 — dupilumab / atopic dermatitis

Alternatively, for a fully reproducible immunology setup (clears DB, seeds, builds profiles, generates briefings, runs per-drug analysis):

make seed-immunology-full

Verify:

make inspect
# Prints signal counts by source, type, severity

5. Build profiles + target graph

make profiles   # Aggregates DrugProfile rows from Signal data (~5 s)
make targets    # Builds Target nodes + DrugTarget edges from DrugProfiles

Both read the DB only — no network calls.


6. Generate a briefing

make briefing                         # nsclc-001
make briefing-immunology              # immunology-001
make briefing-html                    # generate + HTML render
make briefing-since SINCE=2026-03-01  # custom lookback window

Output: latest_briefing_<landscape_id>.json at repo root. See api-reference.md for the schema.

Drug-focused briefing (deep-dive on one molecule):

make drug-briefing DRUG=pembrolizumab

7. Start the API

make dev    # uvicorn with reload, http://localhost:8000

Smoke-check:

curl http://localhost:8000/health
# {"status":"ok"}

curl 'http://localhost:8000/api/signals?landscape_id=nsclc-001&limit=5'

8. Start the frontend

make frontend-install    # first time only
make frontend            # http://localhost:5173

Vite proxies /api/* to http://localhost:8000 — run make dev and make frontend in separate terminals.


Troubleshooting

anthropic.APIError: 401 — Your ANTHROPIC_API_KEY is invalid or missing. The classifier and synthesizer will both fail. The detector and enricher still work (pure Python), so ingestion alone is unaffected.

Source returns 0 signals — Check the source's API status page. Ogur catches per-source failures and logs them; use make inspect to see per-source counts. Open Targets in particular has a retry policy up to 6 attempts on 503.

ModuleNotFoundError: bs4 or similar — Run uv sync --extra dev (not plain uv sync) to include dev extras.

Tests fail on DB import — Make sure you haven't set DATABASE_URL to a path that doesn't exist. Tests use in-memory SQLite via fixtures and ignore the prod URL; if you see file-not-found errors, something is bypassing the fixture.