Skip to content

Commit abd7ca7

Browse files
committed
Added status CLI command and tweaked json/text output choices.
1 parent b34f8ce commit abd7ca7

File tree

6 files changed

+117
-12
lines changed

6 files changed

+117
-12
lines changed

.claude/settings.local.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"permissions": {
33
"allow": [
4-
"Bash(UV_PROJECT_ENVIRONMENT=venv uv run pytest:*)"
4+
"Bash(UV_PROJECT_ENVIRONMENT=venv uv run pytest:*)",
5+
"Bash(./venv/bin/python -m talk_python_cli.app status:*)",
6+
"Bash(./venv/bin/talkpython status:*)",
7+
"Bash(./venv/bin/pip install:*)",
8+
"Bash(./venv/bin/talkpython:*)"
59
]
610
}
711
}

change-log.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.1.1] - 2026-02-07
9+
10+
### Added
11+
- `talkpython status` command to check MCP server health and display version info
12+
13+
### Changed
14+
- Version is now read dynamically from package metadata via `importlib.metadata`
15+
- Default output format is now always `text` (removed auto-detect that defaulted to `json` when piped)
16+
- Development status upgraded from Alpha to Beta
17+
- Added `readme` field to `pyproject.toml` so PyPI renders the README
18+
19+
---
20+
21+
## [0.1.0] - 2026-02-06
22+
23+
Initial release of the Talk Python CLI.
24+
25+
- Query podcast episodes by number or keyword
26+
- Look up guest appearances
27+
- Browse and search the Talk Python course catalog
28+
- Rich terminal output with Markdown rendering
29+
- JSON output mode via `--format json`
30+
- Configurable MCP server URL via `--url`
31+
32+
---
33+
34+
## Template for Future Entries
35+
36+
<!--
37+
## [X.Y.Z] - YYYY-MM-DD
38+
39+
### Added
40+
- New features or capabilities
41+
- Files: `path/to/new/file.ext`, `another/file.ext`
42+
43+
### Changed
44+
- Modifications to existing functionality
45+
- Files: `path/to/modified/file.ext` (summary if many files)
46+
47+
### Deprecated
48+
- Features that will be removed in future versions
49+
- Files affected: `path/to/deprecated/file.ext`
50+
51+
### Removed
52+
- Features or files that were deleted
53+
- Files: `path/to/removed/file.ext`
54+
55+
### Fixed
56+
- Bug fixes and corrections
57+
- Files: `path/to/fixed/file.ext`
58+
59+
### Security
60+
- Security patches or vulnerability fixes
61+
- Files: `path/to/security/file.ext`
62+
63+
### Notes
64+
- Additional context or important information
65+
- Major dependencies updated
66+
- Breaking changes explanation
67+
-->

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
[project]
22
name = "talk-python-cli"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
description = "CLI for the Talk Python to Me podcast and courses"
55
requires-python = ">=3.12"
66
license = "MIT"
77
authors = [
88
{ name = "Michael Kennedy", email = "michael@talkpython.fm" },
99
]
1010
classifiers = [
11-
"Development Status :: 3 - Alpha",
11+
"Development Status :: 4 - Beta",
1212
"Environment :: Console",
1313
"Intended Audience :: Developers",
1414
"License :: OSI Approved :: MIT License",
@@ -20,6 +20,7 @@ classifiers = [
2020
"Topic :: Multimedia :: Sound/Audio",
2121
"Topic :: Education",
2222
]
23+
readme = "README.md"
2324
dependencies = [
2425
"cyclopts>=3.0",
2526
"httpx>=0.27",

src/talk_python_cli/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
"""Talk Python to Me CLI — query podcast episodes, guests, and courses."""
22

3-
__version__ = '0.1.0'
3+
from importlib.metadata import version
4+
5+
__version__ = version("talk-python-cli")

src/talk_python_cli/app.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
from __future__ import annotations
44

5+
import json
56
import sys
7+
import time
68
from typing import Annotated, Literal
79

810
import cyclopts
11+
import httpx
912

1013
from talk_python_cli import __version__
1114
from talk_python_cli.client import DEFAULT_URL, MCPClient
12-
from talk_python_cli.formatting import is_tty, print_error
15+
from talk_python_cli.formatting import console, display_json, print_error
1316

1417
# ── Shared state ─────────────────────────────────────────────────────────────
1518
# The meta-app handler stores the client here so command modules can access it.
@@ -42,6 +45,38 @@ def get_client() -> MCPClient:
4245
app.command(courses_app)
4346

4447

48+
@app.command
49+
def status() -> None:
50+
"""Check whether the Talk Python MCP server is up and display its version info."""
51+
base = _client.base_url if _client else DEFAULT_URL
52+
t0 = time.monotonic()
53+
try:
54+
resp = httpx.get(base, timeout=15.0)
55+
elapsed_ms = (time.monotonic() - t0) * 1000
56+
resp.raise_for_status()
57+
data = resp.json()
58+
except httpx.HTTPError as exc:
59+
elapsed_ms = (time.monotonic() - t0) * 1000
60+
console.print(f'[tp.error]STATUS: FAILED ({elapsed_ms:.2f} ms)[/tp.error]')
61+
console.print(f'[red]{exc}[/red]')
62+
sys.exit(1)
63+
64+
# If piped / --format json, emit raw JSON
65+
if _client and _client.output_format == 'json':
66+
data['status'] = 'SUCCESS'
67+
data['response_ms'] = round(elapsed_ms, 2)
68+
display_json(json.dumps(data))
69+
return
70+
71+
console.print()
72+
console.print(f'[tp.success]STATUS: SUCCESS[/tp.success] [tp.dim]({elapsed_ms:.2f} ms)[/tp.dim]')
73+
console.print()
74+
for key in ('name', 'version', 'description', 'documentation'):
75+
if key in data:
76+
console.print(f'[tp.label]{key}:[/tp.label] {data[key]}')
77+
console.print()
78+
79+
4580
# ── Meta-app: handles global options before dispatching to sub-commands ──────
4681
@app.meta.default
4782
def launcher(
@@ -50,9 +85,9 @@ def launcher(
5085
Literal['text', 'json'],
5186
cyclopts.Parameter(
5287
name='--format',
53-
help="Output format: 'text' (rich Markdown) or 'json'. Defaults to 'json' when stdout is piped.",
88+
help="Output format: 'text' (rich Markdown) or 'json'.",
5489
),
55-
] = None, # type: ignore
90+
] = 'text',
5691
url: Annotated[
5792
str,
5893
cyclopts.Parameter(
@@ -64,10 +99,6 @@ def launcher(
6499
) -> None:
65100
global _client
66101

67-
# Auto-detect: default to json when piped, text when interactive
68-
if format is None:
69-
format = 'text' if is_tty() else 'json'
70-
71102
_client = MCPClient(base_url=url, output_format=format)
72103
try:
73104
app(tokens)

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)