Parse a corpus, manage it and extract themes from a corpus.
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file theme_extractor-0.2.0.tar.gz.
File metadata
- Download URL: theme_extractor-0.2.0.tar.gz
- Upload date:
- Size: 53.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f6601bb96204482290839d8406926b81bcedf3ed16b22f4cb695c253293b2c1
|
|
| MD5 |
b0895f6f17163c544777acd12c1b0e49
|
|
| BLAKE2b-256 |
5532376c0d67dfd2f607acc029b11645e1d9501b03d3220102f5b8f344e3156e
|
Provenance
The following attestation bundles were made for theme_extractor-0.2.0.tar.gz:
Publisher:
release.yml on Guillaume-Lombardo/theme-extractor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
theme_extractor-0.2.0.tar.gz -
Subject digest:
9f6601bb96204482290839d8406926b81bcedf3ed16b22f4cb695c253293b2c1 - Sigstore transparency entry: 953248912
- Sigstore integration time:
-
Permalink:
Guillaume-Lombardo/theme-extractor@081e937785e6c2c1290a9b4ac1026bb90c522a34 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Guillaume-Lombardo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@081e937785e6c2c1290a9b4ac1026bb90c522a34 -
Trigger Event:
release
-
Statement type:
File details
Details for the file theme_extractor-0.2.0-py3-none-any.whl.
File metadata
- Download URL: theme_extractor-0.2.0-py3-none-any.whl
- Upload date:
- Size: 68.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c8a64f6583a629c602c4c868f2184b096a26266b2c4fee86f6deaeef53c37d1
|
|
| MD5 |
9205ab01f75225ea7d2444804032c7d1
|
|
| BLAKE2b-256 |
f8de2f8a18ef747e47a101c96366c9687f1d2606f4752c3980ed9153a12ee97d
|
Provenance
The following attestation bundles were made for theme_extractor-0.2.0-py3-none-any.whl:
Publisher:
release.yml on Guillaume-Lombardo/theme-extractor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
theme_extractor-0.2.0-py3-none-any.whl -
Subject digest:
3c8a64f6583a629c602c4c868f2184b096a26266b2c4fee86f6deaeef53c37d1 - Sigstore transparency entry: 953248913
- Sigstore integration time:
-
Permalink:
Guillaume-Lombardo/theme-extractor@081e937785e6c2c1290a9b4ac1026bb90c522a34 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Guillaume-Lombardo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@081e937785e6c2c1290a9b4ac1026bb90c522a34 -
Trigger Event:
release
-
Statement type: