talk-python-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(UV_PROJECT_ENVIRONMENT=venv uv run pytest:*)"
5
+ ]
6
+ }
7
+ }
@@ -0,0 +1,205 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # uv.lock is committed to version control for reproducible installs.
99
+ # uv.lock
100
+
101
+ # poetry
102
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
103
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
104
+ # commonly ignored for libraries.
105
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
106
+ #poetry.lock
107
+ #poetry.toml
108
+
109
+ # pdm
110
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
111
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
112
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
113
+ #pdm.lock
114
+ #pdm.toml
115
+ .pdm-python
116
+ .pdm-build/
117
+
118
+ # pixi
119
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
120
+ #pixi.lock
121
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
122
+ # in the .venv directory. It is recommended not to include this directory in version control.
123
+ .pixi
124
+
125
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
126
+ __pypackages__/
127
+
128
+ # Celery stuff
129
+ celerybeat-schedule
130
+ celerybeat.pid
131
+
132
+ # SageMath parsed files
133
+ *.sage.py
134
+
135
+ # Environments
136
+ .env
137
+ .envrc
138
+ .venv
139
+ env/
140
+ venv/
141
+ ENV/
142
+ env.bak/
143
+ venv.bak/
144
+
145
+ # Spyder project settings
146
+ .spyderproject
147
+ .spyproject
148
+
149
+ # Rope project settings
150
+ .ropeproject
151
+
152
+ # mkdocs documentation
153
+ /site
154
+
155
+ # mypy
156
+ .mypy_cache/
157
+ .dmypy.json
158
+ dmypy.json
159
+
160
+ # Pyre type checker
161
+ .pyre/
162
+
163
+ # pytype static type analyzer
164
+ .pytype/
165
+
166
+ # Cython debug symbols
167
+ cython_debug/
168
+
169
+ # PyCharm
170
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
171
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
172
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
173
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
174
+ #.idea/
175
+
176
+ # Abstra
177
+ # Abstra is an AI-powered process automation framework.
178
+ # Ignore directories containing user credentials, local state, and settings.
179
+ # Learn more at https://abstra.io/docs
180
+ .abstra/
181
+
182
+ # Visual Studio Code
183
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
184
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
185
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
186
+ # you could uncomment the following to ignore the entire vscode folder
187
+ # .vscode/
188
+
189
+ # Ruff stuff:
190
+ .ruff_cache/
191
+
192
+ # PyPI configuration file
193
+ .pypirc
194
+
195
+ # Cursor
196
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
197
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
198
+ # refer to https://docs.cursor.com/context/ignore-files
199
+ .cursorignore
200
+ .cursorindexingignore
201
+
202
+ # Marimo
203
+ marimo/_static/
204
+ marimo/_lsp/
205
+ __marimo__/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Talk Python
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: talk-python-cli
3
+ Version: 0.1.0
4
+ Summary: CLI for the Talk Python to Me podcast and courses
5
+ Project-URL: Homepage, https://github.com/talkpython/talk-python-cli
6
+ Project-URL: Source, https://github.com/talkpython/talk-python-cli
7
+ Project-URL: Documentation, https://github.com/talkpython/talk-python-cli
8
+ Author-email: Michael Kennedy <michael@talkpython.fm>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: 3.15
20
+ Classifier: Topic :: Education
21
+ Classifier: Topic :: Multimedia :: Sound/Audio
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: cyclopts>=3.0
24
+ Requires-Dist: httpx>=0.27
25
+ Requires-Dist: rich>=13.0
@@ -0,0 +1,132 @@
1
+ # Talk Python CLI
2
+
3
+ [![PyPI version](https://badge.fury.io/py/talk-python-cli.svg)](https://pypi.org/project/talk-python-cli/)
4
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Unlock 500+ episodes of [Talk Python to Me](https://talkpython.fm), full transcripts, guest profiles, and 50+ [Talk Python Training](https://training.talkpython.fm) courses — all from your terminal. Search, browse, and pipe structured data into your scripts, AI agents, or automation workflows.
8
+
9
+ ## Why use this?
10
+
11
+ - **Automation** — Query episode data, guest info, and course catalogs from scripts and pipelines.
12
+ - **LLM & AI integration** — Pipe JSON or Markdown output directly into AI agents, RAG systems, or chat workflows. Feed transcripts into RAG pipelines, build podcast assistants, or enrich your AI tools with real Python community knowledge.
13
+ - **Quick lookups** — Search episodes, pull transcripts, and browse courses without leaving the terminal.
14
+
15
+ ## Installation
16
+
17
+ Requires Python 3.12+.
18
+
19
+ ```bash
20
+ # Try it instantly with uvx (no install needed)
21
+ uvx --from talk-python-cli talkpython episodes recent
22
+
23
+ # Or install it permanently with uv
24
+ uv tool install talk-python-cli
25
+
26
+ # Or with pip
27
+ pip install talk-python-cli
28
+ ```
29
+
30
+ This installs the `talkpython` command.
31
+
32
+ ## Quick start
33
+
34
+ ```bash
35
+ # Search for episodes about FastAPI
36
+ talkpython episodes search "FastAPI"
37
+
38
+ # Get full details for a specific episode
39
+ talkpython episodes get 535
40
+
41
+ # Pull the transcript for an episode
42
+ talkpython episodes transcript 535
43
+
44
+ # List recent episodes
45
+ talkpython episodes recent --limit 5
46
+
47
+ # Search for a guest
48
+ talkpython guests search "Hynek"
49
+
50
+ # Browse all training courses
51
+ talkpython courses list
52
+ ```
53
+
54
+ ## Commands
55
+
56
+ ### Episodes
57
+
58
+ | Command | Description |
59
+ |---------|-------------|
60
+ | `talkpython episodes search <query> [--limit N]` | Search episodes by keyword (default limit: 10) |
61
+ | `talkpython episodes get <show_id>` | Get full details for an episode |
62
+ | `talkpython episodes list` | List all episodes |
63
+ | `talkpython episodes recent [--limit N]` | Get the most recent episodes |
64
+ | `talkpython episodes transcript <show_id>` | Get the plain-text transcript |
65
+ | `talkpython episodes transcript-vtt <show_id>` | Get the WebVTT transcript (with timestamps) |
66
+
67
+ ### Guests
68
+
69
+ | Command | Description |
70
+ |---------|-------------|
71
+ | `talkpython guests search <query> [--limit N]` | Search guests by name |
72
+ | `talkpython guests get <guest_id>` | Get details for a specific guest |
73
+ | `talkpython guests list` | List all guests, sorted by number of appearances |
74
+
75
+ ### Courses
76
+
77
+ | Command | Description |
78
+ |---------|-------------|
79
+ | `talkpython courses search <query> [--course_id N]` | Search courses, chapters, and lectures |
80
+ | `talkpython courses get <course_id>` | Get full course details including chapters and lectures |
81
+ | `talkpython courses list` | List all available training courses |
82
+
83
+ ## Output formats
84
+
85
+ The CLI auto-detects the best output format:
86
+
87
+ - **Interactive terminal** — Rich-formatted Markdown with styled panels and color.
88
+ - **Piped / redirected** — Compact JSON, ready for processing.
89
+
90
+ Override the default with `--format`:
91
+
92
+ ```bash
93
+ # Force JSON output in the terminal
94
+ talkpython --format json episodes search "async"
95
+
96
+ # Force rich text output even when piping
97
+ talkpython --format text episodes recent | less -R
98
+ ```
99
+
100
+ ## Piping JSON to other tools
101
+
102
+ Because the CLI outputs JSON automatically when piped, it integrates naturally with tools like `jq`, `llm`, or your own scripts:
103
+
104
+ ```bash
105
+ # Extract episode titles with jq
106
+ talkpython episodes search "testing" | jq '.title'
107
+
108
+ # Feed episode data into an LLM
109
+ talkpython episodes get 535 | llm "Summarize this podcast episode"
110
+
111
+ # Grab a transcript for RAG ingestion
112
+ talkpython episodes transcript 535 | your-rag-pipeline ingest
113
+ ```
114
+
115
+ ## Global options
116
+
117
+ | Option | Description |
118
+ |--------|-------------|
119
+ | `--format text\|json` | Force output format (auto-detected by default) |
120
+ | `--url <mcp-url>` | Override the MCP server URL (default: `https://talkpython.fm/api/mcp`) |
121
+ | `--version`, `-V` | Show version |
122
+
123
+ ## Part of the Talk Python ecosystem
124
+
125
+ Talk Python CLI is one way to tap into the data behind the [Talk Python to Me](https://talkpython.fm) podcast and [Talk Python Training](https://training.talkpython.fm) courses. It connects to the same public [MCP server](https://talkpython.fm/api/mcp) that powers Talk Python's AI integrations — so whether you're building an agent, a search tool, or just want quick answers from the terminal, you're working with the real data.
126
+
127
+ - [Talk Python to Me Podcast](https://talkpython.fm)
128
+ - [Talk Python Training](https://training.talkpython.fm)
129
+
130
+ ## License
131
+
132
+ MIT
@@ -0,0 +1,197 @@
1
+ # Plan 001: Talk Python CLI — Standalone Package
2
+
3
+ ## Context
4
+
5
+ The Talk Python MCP server at `https://talkpython.fm/api/mcp` exposes 12 tools for querying
6
+ podcast episodes, guests, transcripts, and courses via JSON-RPC 2.0. This project is a
7
+ **standalone, open-source CLI tool** (`talkpython`) that wraps those MCP tools as terminal
8
+ commands.
9
+
10
+ Full server documentation (tool names, parameters, descriptions):
11
+ **https://talkpython.fm/api/mcp/docs**
12
+
13
+ The package will be published to PyPI as `talk-python-cli` with the command name `talkpython`.
14
+
15
+ ### MCP server tools (reference)
16
+
17
+ The server (v1.3.0) is public, read-only, no authentication required. Transport: Streamable HTTP.
18
+
19
+ | CLI command | MCP tool name | Parameters |
20
+ |----------------------------------|----------------------------|-----------------------------------------|
21
+ | `episodes search` | `search_episodes` | `query` (str), `limit` (int, optional) |
22
+ | `episodes get` | `get_episode` | `show_id` (int) |
23
+ | `episodes list` | `get_episodes` | *(none)* |
24
+ | `episodes recent` | `get_recent_episodes` | `limit` (int, optional) |
25
+ | `episodes transcript` | `get_transcript_for_episode` | `show_id` (int) |
26
+ | `episodes transcript-vtt` | `get_transcript_vtt` | `show_id` (int) |
27
+ | `guests search` | `search_guests` | `query` (str), `limit` (int, optional) |
28
+ | `guests get` | `get_guest_by_id` | `guest_id` (int) |
29
+ | `guests list` | `get_guests` | *(none)* |
30
+ | `courses search` | `search_courses` | `query` (str), `course_id` (int, opt.) |
31
+ | `courses get` | `get_course_details` | `course_id` (int) |
32
+ | `courses list` | `get_courses` | *(none)* |
33
+
34
+ ### Server-side prerequisite
35
+
36
+ The MCP server needs `?format=json` query parameter support so the CLI can receive structured
37
+ data instead of pre-formatted Markdown. That change lives in the main Talk Python web app repo
38
+ (not this one) and must be deployed before the CLI's `--format json` and auto-JSON-on-pipe
39
+ features work. The CLI should:
40
+
41
+ - Default to requesting `format=text` (works with the server today)
42
+ - Support `--format json` for when the server-side change is deployed
43
+ - Degrade gracefully if the server ignores the format parameter
44
+
45
+ ## Project structure
46
+
47
+ Package lives at the repo root (not nested in a subdirectory):
48
+
49
+ Managed with **uv** — no manual venv creation, use `uv run`, `uv sync`, `uv lock`, etc.
50
+
51
+ ```
52
+ talk-python-cli/
53
+ ├── pyproject.toml
54
+ ├── uv.lock # Committed to version control
55
+ ├── LICENSE
56
+ ├── README.md
57
+ ├── .gitignore
58
+ ├── src/
59
+ │ └── talk_python_cli/
60
+ │ ├── __init__.py # Version string
61
+ │ ├── __main__.py # python -m talk_python_cli support
62
+ │ ├── app.py # Root Cyclopts app + global options
63
+ │ ├── client.py # MCP HTTP client (httpx JSON-RPC wrapper)
64
+ │ ├── formatting.py # Output formatting (rich Markdown or JSON)
65
+ │ ├── episodes.py # Episode commands sub-app
66
+ │ ├── guests.py # Guest commands sub-app
67
+ │ └── courses.py # Course commands sub-app
68
+ └── tests/
69
+ ├── __init__.py
70
+ ├── conftest.py # Shared fixtures (mock MCP responses)
71
+ ├── test_client.py # MCPClient unit tests
72
+ ├── test_episodes.py # Episode command tests
73
+ ├── test_guests.py # Guest command tests
74
+ └── test_courses.py # Course command tests
75
+ ```
76
+
77
+ ## Dependencies (pyproject.toml)
78
+
79
+ Created via `uv init`, then `uv add cyclopts httpx rich` and `uv add --dev pytest pytest-httpx`.
80
+
81
+ ```toml
82
+ [project]
83
+ name = "talk-python-cli"
84
+ version = "0.1.0"
85
+ description = "CLI for the Talk Python to Me podcast and courses"
86
+ requires-python = ">=3.12"
87
+ license = "MIT"
88
+ authors = [
89
+ { name = "Michael Kennedy", email = "michael@talkpython.fm" },
90
+ ]
91
+ dependencies = [
92
+ "cyclopts>=3.0",
93
+ "httpx>=0.27",
94
+ "rich>=13.0",
95
+ ]
96
+
97
+ [project.scripts]
98
+ talkpython = "talk_python_cli.app:main"
99
+
100
+ [dependency-groups]
101
+ dev = [
102
+ "pytest>=8.0",
103
+ "pytest-httpx>=0.34",
104
+ ]
105
+
106
+ [build-system]
107
+ requires = ["hatchling"]
108
+ build-backend = "hatchling.build"
109
+ ```
110
+
111
+ The `uv.lock` file is committed for reproducible installs.
112
+
113
+ ## CLI commands
114
+
115
+ ```
116
+ talkpython [--format text|json] [--url URL]
117
+
118
+ talkpython episodes search QUERY [--limit N]
119
+ talkpython episodes get SHOW_ID
120
+ talkpython episodes list
121
+ talkpython episodes recent [--limit N]
122
+ talkpython episodes transcript SHOW_ID
123
+ talkpython episodes transcript-vtt SHOW_ID
124
+
125
+ talkpython guests search QUERY [--limit N]
126
+ talkpython guests get GUEST_ID
127
+ talkpython guests list
128
+
129
+ talkpython courses search QUERY [--course-id ID]
130
+ talkpython courses get COURSE_ID
131
+ talkpython courses list
132
+ ```
133
+
134
+ Global option `--format` defaults to `text` (rendered Markdown) but can be set to `json`
135
+ for machine-readable output. `--url` defaults to `https://talkpython.fm/api/mcp`.
136
+
137
+ ### Auto-detection for piped output
138
+
139
+ When stdout is not a TTY (piped to another command), default to JSON format
140
+ for scripting convenience: `talkpython episodes recent | jq '.[]'`
141
+
142
+ ## Key module designs
143
+
144
+ **`client.py`** — Thin wrapper around httpx making JSON-RPC calls:
145
+ ```python
146
+ class MCPClient:
147
+ def __init__(self, base_url: str, output_format: str = 'text'):
148
+ self.base_url = base_url
149
+ self.output_format = output_format
150
+ self._msg_id = 0
151
+
152
+ def call_tool(self, tool_name: str, arguments: dict) -> dict:
153
+ # POST to base_url?format={output_format}
154
+ # JSON-RPC 2.0 envelope: {"jsonrpc":"2.0","id":N,"method":"tools/call","params":{...}}
155
+ # Returns the result content text
156
+ ```
157
+
158
+ **`formatting.py`** — Handles display:
159
+ - `text` format: render Markdown from server using rich
160
+ - `json` format: print with optional pretty-printing
161
+
162
+ **`app.py`** — Root app with global params:
163
+ ```python
164
+ app = cyclopts.App(name='talkpython', help='Talk Python to Me CLI')
165
+ # Register sub-apps
166
+ app.command(episodes_app)
167
+ app.command(guests_app)
168
+ app.command(courses_app)
169
+ ```
170
+
171
+ **`episodes.py`**, **`guests.py`**, **`courses.py`** — Each defines a sub-app:
172
+ ```python
173
+ episodes_app = cyclopts.App(name='episodes', help='Podcast episode commands')
174
+
175
+ @episodes_app.command
176
+ def search(query: str, *, limit: int = 10):
177
+ ...
178
+ ```
179
+
180
+ ## Implementation order
181
+
182
+ 1. `uv init` — create `pyproject.toml`, then add dependencies with `uv add`
183
+ 2. Implement `client.py` (HTTP JSON-RPC client)
184
+ 3. Implement `formatting.py` (output rendering)
185
+ 4. Implement `app.py` + command modules (`episodes.py`, `guests.py`, `courses.py`)
186
+ 5. Add `__main__.py` for `python -m` support
187
+ 6. Add tests with mocked HTTP responses (`uv add --dev pytest pytest-httpx`)
188
+ 7. Verify against live server
189
+
190
+ ## Verification
191
+
192
+ 1. **Sync**: `uv sync` (installs all deps including dev group)
193
+ 2. **Unit tests**: `uv run pytest tests/ -v`
194
+ 3. **Smoke test**: `uv run talkpython episodes recent --limit 3`
195
+ 4. **JSON output**: `uv run talkpython --format json episodes recent --limit 3`
196
+ 5. **Piped output**: `uv run talkpython episodes recent | head` — should auto-detect JSON format
197
+ 6. **Module entry**: `uv run python -m talk_python_cli episodes recent --limit 3`
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "talk-python-cli"
3
+ version = "0.1.0"
4
+ description = "CLI for the Talk Python to Me podcast and courses"
5
+ requires-python = ">=3.12"
6
+ license = "MIT"
7
+ authors = [
8
+ { name = "Michael Kennedy", email = "michael@talkpython.fm" },
9
+ ]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Environment :: Console",
13
+ "Intended Audience :: Developers",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ "Programming Language :: Python :: 3.14",
19
+ "Programming Language :: Python :: 3.15",
20
+ "Topic :: Multimedia :: Sound/Audio",
21
+ "Topic :: Education",
22
+ ]
23
+ dependencies = [
24
+ "cyclopts>=3.0",
25
+ "httpx>=0.27",
26
+ "rich>=13.0",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/talkpython/talk-python-cli"
31
+ Source = "https://github.com/talkpython/talk-python-cli"
32
+ Documentation = "https://github.com/talkpython/talk-python-cli"
33
+
34
+ [project.scripts]
35
+ talkpython = "talk_python_cli.app:main"
36
+
37
+ [dependency-groups]
38
+ dev = [
39
+ "pytest>=8.0",
40
+ "pytest-httpx>=0.34",
41
+ ]
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["src/talk_python_cli"]
45
+
46
+ [build-system]
47
+ requires = ["hatchling"]
48
+ build-backend = "hatchling.build"
@@ -0,0 +1,45 @@
1
+ ###### configuring what to type check and where to import from
2
+
3
+ # check all files in "."
4
+ project-includes = ["."]
5
+ # exclude dotfiles
6
+ project-excludes = ["**/.[!/.]*", "**/*venv/**"]
7
+ # perform an upward search for `.gitignore`, `.ignore`, and `.git/info/exclude`, and
8
+ # add those to `project-excludes` automatically
9
+ use-ignore-files = true
10
+ # import project files from "src" (main package) and "." (tests)
11
+ search-path = ["src", "."]
12
+ # let Pyrefly try to guess your search path
13
+ disable-search-path-heuristics = false
14
+ # do not include any third-party packages (except those provided by an interpreter)
15
+ site-package-path = []
16
+
17
+ ###### configuring your python environment
18
+
19
+ python-platform = "darwin"
20
+ # assume the Python version we're using is 3.14, without querying an interpreter
21
+ python-version = "3.14"
22
+ # is Pyrefly disallowed from querying for an interpreter to automatically determine your
23
+ # `python-platform`, `python-version`, and extra entries to `site-package-path`?
24
+ skip-interpreter-query = false
25
+ # query the default Python interpreter on your system, if installed and `python_platform`,
26
+ # `python-version`, or `site-package-path` are unset.
27
+ # python-interpreter = null # this is commented out because there are no `null` values in TOML
28
+
29
+ #### configuring your type check settings
30
+
31
+ # wildcards for which Pyrefly will unconditionally replace the import with `typing.Any`
32
+ replace-imports-with-any = []
33
+ # wildcards for which Pyrefly will replace the import with `typing.Any` if it can't be found
34
+ ignore-missing-imports = []
35
+ # should Pyrefly skip type checking if we find a generated file?
36
+ ignore-errors-in-generated-code = false
37
+ # what should Pyrefly do when it encounters a function that is untyped?
38
+ untyped-def-behavior = "check-and-infer-return-type"
39
+ # can Pyrefly recognize ignore directives other than `# pyrefly: ignore` and `# type: ignore`
40
+ permissive-ignores = false
41
+
42
+ [errors]
43
+ # this is an empty table, meaning all errors are enabled by default
44
+
45
+ # no `[[sub-config]]` entries are included, since there are none by default