Stateless web-novel translation service with switchable engines
Project description
lncrawl-translator
A web-novel translation service — metadata (titles, author, synopsis, tags) and HTML chapter content — with a focus on Chinese / Korean / Japanese → English. Runs standalone (Docker/uvicorn) or embedded as a Python library inside a host application.
Built as a stateless translation API for lightnovel-crawler, with switchable translation engines (free-tier hosted APIs and CPU-friendly local models). Requests can carry a per-novel glossary that is injected into translations and returned with new terms, so the caller can maintain name/term consistency across thousands of chapters.
Quick start
No config file needed — a curated set of free providers is pre-wired, and the keyless Bing lane (no key required) is the default, so translation works even with zero keys:
docker compose up -d
curl http://localhost:8184/health # shows which engines came up
Then open http://localhost:8184/ and paste your provider API keys — the matching engines enable instantly, no restart needed.
See docs/deployment.md for engine keys, the keyless Bing lane, and API examples; docs/design.md for the API and architecture; docs/translation-engines.md for the engine research.
API
GET /— browser demo & config UI: try translations, watch engine status, and manage the runtime config without leaving the pageGET /health— liveness/readinessGET /engines— configured engines with live status (quota, cooldowns)POST /detect— local language detection (no engine quota)POST /translate/text— batched short strings (titles, tags, synopsis)POST /translate/html— one chapter per call, glossary in/new terms outGET /config+ CRUD on/providers,/engines,/routing— runtime config management; changes apply atomically and persist toconfig.yml
The API is unauthenticated by design — run it on localhost or a private network only (see docs/deployment.md).
Use as a library
Install the package (pip install lncrawl-translator; Python 3.9+) and use
the embedded service — a thread-safe, synchronous facade that runs the same
engine router on its own event loop:
from translator import TranslatorService
service = TranslatorService(config_path="translator.yml")
service.detect(["どこから来ましたか"]) # local, no quota
response = service.translate_text({
"texts": ["少年は勇者になった"],
"target_lang": "en",
"glossary": {"勇者": "Hero"},
})
print(response.translations, response.engine, response.new_terms)
service.close() # on shutdown
translate_text/translate_html accept an optional signal
(threading.Event) for cooperative cancellation and a timeout in seconds.
The dashboard and HTTP API can be mounted into a host ASGI app, sharing the service's live config — edits made in the dashboard apply to the embedded service immediately:
app.mount("/translator", service.create_app())
The mounted app carries no authentication (same as the standalone server) —
the host must gate access itself. Language detection is also available
without a service: from translator import detect_language.
Development
uv sync
uv run poe check # ruff + mypy + pytest
uv run poe dev # dev server with auto-reload
uv run poe start # production-style server (uvicorn on :8184)
uv run poe live-test # smoke-test real engines from config.yml (opt-in)
See AGENTS.md for project decisions and conventions.
Project details
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 lncrawl_translator-0.1.1.tar.gz.
File metadata
- Download URL: lncrawl_translator-0.1.1.tar.gz
- Upload date:
- Size: 131.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
754db3b27616532a443af8a27414bb84ae394f0cf82e6811097721e286cbf418
|
|
| MD5 |
2974ffcc719cd0aea47b98f47ed5fc03
|
|
| BLAKE2b-256 |
5f4af682ea0ac7b9af1e618c3102d5e4919680d55afa9044290f1d80b1b2f37f
|
Provenance
The following attestation bundles were made for lncrawl_translator-0.1.1.tar.gz:
Publisher:
publish.yml on lncrawl/translator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lncrawl_translator-0.1.1.tar.gz -
Subject digest:
754db3b27616532a443af8a27414bb84ae394f0cf82e6811097721e286cbf418 - Sigstore transparency entry: 2233710007
- Sigstore integration time:
-
Permalink:
lncrawl/translator@f491553cb47b2b8f88ba7516e43f76743cde7ed5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lncrawl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f491553cb47b2b8f88ba7516e43f76743cde7ed5 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file lncrawl_translator-0.1.1-py3-none-any.whl.
File metadata
- Download URL: lncrawl_translator-0.1.1-py3-none-any.whl
- Upload date:
- Size: 153.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a06d458d791d1654cf0699334f29a3595374109cda73cf25f5a3041ce8e4b459
|
|
| MD5 |
3bf9899c147a640deb44437e7f9bd28f
|
|
| BLAKE2b-256 |
c7b1706b771625b8330614539f6ea93d36cc246070157b8a614d2ef0b12c9c42
|
Provenance
The following attestation bundles were made for lncrawl_translator-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on lncrawl/translator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lncrawl_translator-0.1.1-py3-none-any.whl -
Subject digest:
a06d458d791d1654cf0699334f29a3595374109cda73cf25f5a3041ce8e4b459 - Sigstore transparency entry: 2233710384
- Sigstore integration time:
-
Permalink:
lncrawl/translator@f491553cb47b2b8f88ba7516e43f76743cde7ed5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lncrawl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f491553cb47b2b8f88ba7516e43f76743cde7ed5 -
Trigger Event:
workflow_dispatch
-
Statement type: