Metadata-Version: 2.5
Name: tubestoevsky
Version: 1.0.0
Summary: Turn YouTube transcripts into literary prose with an LLM
Project-URL: Homepage, https://github.com/iiw/tubestoevsky
Project-URL: Repository, https://github.com/iiw/tubestoevsky
Project-URL: Issues, https://github.com/iiw/tubestoevsky/issues
Author-email: Viktor Buzanov <viktor.buzanov@mailbox.org>
License-Expression: MIT
License-File: LICENSE
Keywords: langchain,llm,prose,subtitles,transcript,youtube,yt-dlp
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Text Processing
Requires-Python: >=3.12
Requires-Dist: curl-cffi>=0.16.3
Requires-Dist: langchain-core>=0.3
Requires-Dist: langchain-openai>=1.6.6
Requires-Dist: python-dotenv>=1.0
Requires-Dist: yt-dlp[default]>=2026.7.4
Description-Content-Type: text/markdown

# TubeStoevsky

Downloads a YouTube video transcript and turns it into literary prose through a LangChain LLM chain — outputs `TXT` + `MD`.

Works with any OpenAI-compatible chat completions API: a local gateway, Ollama, vLLM, OpenAI, or anything else speaking that protocol.

## How it works

```
URL
 ├─ yt-dlp       subtitles (manual > auto)  -> {title}.srt
 ├─ SRT parser   timecodes and rolling dupes -> raw text
 ├─ LangChain    prose -> title -> Markdown
 └─ output       {title}.txt, {title}.md
```

## Install

```bash
# as a CLI tool
uv tool install tubestoevsky   # or: pip install tubestoevsky
tubestoevsky --help

# from a checkout, for development
uv sync
```

## Configuration

Copy [`.env.example`](./.env.example) to `.env` and set `LLM_API_KEY`. The file
is read from the current directory, the project root, or
`~/.config/tubestoevsky/.env`.

| Variable | Purpose | Default |
|---|---|---|
| `LLM_BASE_URL` | OpenAI-compatible endpoint (`/v1` appended when absent) | `http://127.0.0.1:4000` |
| `LLM_API_KEY` | API key for that endpoint | **required** |
| `LLM_MODEL` | model name served by it | `gpt-4o-mini` |
| `TRANSCRIPT_LANG` | subtitle language | `en` |
| `OUTPUT_DIR` | output directory | `.` |
| `LLM_TEMPERATURE` | sampling temperature | `0.3` |
| `LLM_TIMEOUT` | request timeout, sec | `1800` |
| `YTDLP_COOKIES` / `YTDLP_COOKIES_FROM_BROWSER` | access to restricted videos | — |

## Usage

```bash
tubestoevsky <URL>
tubestoevsky <URL> --lang en --out ./out
tubestoevsky <URL> --model gpt-4o-mini

# or without installing:
uvx tubestoevsky <URL>

# from a checkout:
uv run python -m transcript_app <URL>
```

## Layout

```
transcript_app/
  __main__.py    CLI
  config.py      .env + CLI flags
  downloader.py  yt-dlp
  srt.py         subtitle parser
  chain.py       LangChain chain over the API
  prompts.py     step prompts
  outputs.py     .txt/.md writers
```

## Notes

- LLM steps stream: some gateways fail to return monolithic responses.
- `Accept-Encoding: identity` and `use_responses_api=False` work around proxy hangs.
- Run long requests in the foreground.
