theme-extractor
Python toolkit to compare theme/topic extraction strategies on the same corpus, with:
- one unified CLI
- one unified JSON output schema
- offline-first execution options
- Elasticsearch/OpenSearch backend support
Why this project
theme-extractor helps you answer one practical question:
"Which extraction strategy works best for my corpus and constraints?"
It lets you run baseline lexical methods, embedding-based methods, and LLM-assisted methods with consistent outputs for easier comparison.
Core Commands
theme-extractor ingesttheme-extractor extracttheme-extractor benchmarktheme-extractor evaluatetheme-extractor reporttheme-extractor doctor
Quickstart
Prerequisite: start one backend first (local Docker guide: /howto/docker-local.md).
uv sync --group elasticsearch
uv sync --group ingestion
uv run theme-extractor doctor --output data/out/doctor.json
uv run theme-extractor ingest --input data/raw --output data/out/ingest.json
uv run theme-extractor ingest \
--input data/raw \
--reset-index \
--index-backend \
--cleaning-options all \
--default-stopwords \
--manual-stopwords "de,le,la,the,and,of" \
--output data/out/ingest_indexed.json
uv run theme-extractor benchmark \
--methods baseline_tfidf,terms,significant_terms,keybert,bertopic \
--backend elasticsearch \
--backend-url http://localhost:9200 \
--index theme_extractor \
--focus both \
--output data/out/benchmark.json
uv run theme-extractor evaluate \
--input data/out/benchmark.json \
--output data/out/evaluation.json
uv run theme-extractor report \
--input data/out/benchmark.json \
--output data/out/report_benchmark.md
ingest always generates a local JSON QA payload; with --index-backend, it also indexes cleaned/filtered text into Elasticsearch/OpenSearch.
Run significant_text separately with --agg-field content (see /howto/benchmark.md).
Methods Available
- Baselines:
baseline_tfidftermssignificant_termssignificant_text
- Semantic:
keybertbertopic(embedding on/off, reductionnone/svd/nmf/umap, clusteringkmeans/hdbscan)
- Generative:
llm(offline fallback behavior supported)
What You Get
- Unified extraction schema:
- topic-first output (
topics) - optional document-topic links (
document_topics) - execution notes and metadata (
notes,metadata)
- topic-first output (
- Benchmark output:
- per-method outputs
- comparison block
- Quantitative proxies via
evaluate:- topic coherence proxy
- inter-topic diversity
- run-to-run stability
Documentation Map (How-To)
Detailed operations are intentionally kept in /howto:
/howto/ingest.md: ingestion, cleaning, stopwords, streaming mode/howto/extract.md: single-method extraction and interpretation/howto/benchmark.md: multi-method comparison workflow/howto/evaluation.md: evaluation command, Jaccard, and metric interpretation/howto/report.md: markdown reporting workflow/howto/release.md: PyPI/TestPyPI release workflow/howto/docker-local.md: local Docker stacks (Elasticsearch/OpenSearch)/howto/troubleshooting.md: common failures and fixes
Sphinx documentation is available under /docs (includes README, how-to pages, and API docstrings).
CLI code is now organized under src/theme_extractor/cli/:
__init__.py: CLI entrypoint (main)argument_parser.py: parser and flagscommand_handlers.py: command execution logicingest_backend_indexing.py: ingest-side backend indexing helperscommon_runtime.py: shared runtime helpers
Build locally:
uv run sphinx-build -b html docs docs/_build/html
Configuration
Use .env.template as bootstrap:
cp .env.template .env
set -a; source .env; set +a
Important variable groups:
- backend/runtime (
THEME_EXTRACTOR_BACKEND*,THEME_EXTRACTOR_PROXY_URL) - ingestion stopwords (
THEME_EXTRACTOR_DEFAULT_STOPWORDS_ENABLED,THEME_EXTRACTOR_AUTO_STOPWORDS_*) - PDF OCR fallback (
THEME_EXTRACTOR_PDF_OCR_*) for scanned PDFs .msgextraction (THEME_EXTRACTOR_MSG_*) for metadata and attachment policy- local model resolution (
THEME_EXTRACTOR_LOCAL_MODELS_DIR) - BERTopic embedding cache (
THEME_EXTRACTOR_BERTOPIC_EMBEDDING_CACHE_*)
Dependency Groups
Install optional runtime groups with uv:
uv sync --group ingestion
ingestion includes parsers for PDF/Office/MSG formats (pymupdf, python-docx, openpyxl, python-pptx, extract-msg).
Project Governance
Community Standards
Metadata
Release files for theme-extractor 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| theme_extractor-0.2.0.tar.gz | 53.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| theme_extractor-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.7 kB
Release files / theme_extractor-0.2.0.tar.gz
| Download URL | theme_extractor-0.2.0.tar.gz |
|---|---|
| Size | 53.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9f6601bb96204482290839d8406926b81bcedf3ed16b22f4cb695c253293b2c1
|
|
BLAKE2b-256 checksum How to use checksums |
5532376c0d67dfd2f607acc029b11645e1d9501b03d3220102f5b8f344e3156e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 14, 2026.
Transparency logRelease files / theme_extractor-0.2.0-py3-none-any.whl
| Download URL | theme_extractor-0.2.0-py3-none-any.whl |
|---|---|
| Size | 68.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3c8a64f6583a629c602c4c868f2184b096a26266b2c4fee86f6deaeef53c37d1
|
|
BLAKE2b-256 checksum How to use checksums |
f8de2f8a18ef747e47a101c96366c9687f1d2606f4752c3980ed9153a12ee97d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 14, 2026.
Transparency log