typer-examples 1.1.1__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.
- typer_examples-1.1.1/.github/workflows/ci.yml +96 -0
- typer_examples-1.1.1/.github/workflows/release.yml +102 -0
- typer_examples-1.1.1/.github/workflows/typer-compat.yml +157 -0
- typer_examples-1.1.1/.gitignore +8 -0
- typer_examples-1.1.1/CHANGELOG.md +83 -0
- typer_examples-1.1.1/CHANGELOG_RELEASE.md +12 -0
- typer_examples-1.1.1/LICENSE +21 -0
- typer_examples-1.1.1/PKG-INFO +143 -0
- typer_examples-1.1.1/README.md +118 -0
- typer_examples-1.1.1/cliff.toml +100 -0
- typer_examples-1.1.1/docs/api.md +152 -0
- typer_examples-1.1.1/docs/configuration.md +100 -0
- typer_examples-1.1.1/docs/how-it-works.md +153 -0
- typer_examples-1.1.1/docs/template-variables.md +92 -0
- typer_examples-1.1.1/examples/app.py +223 -0
- typer_examples-1.1.1/examples/simple.py +74 -0
- typer_examples-1.1.1/pyproject.toml +40 -0
- typer_examples-1.1.1/tests/test_basic.py +366 -0
- typer_examples-1.1.1/typer_examples/__init__.py +51 -0
- typer_examples-1.1.1/typer_examples/_hook.py +83 -0
- typer_examples-1.1.1/typer_examples/_models.py +47 -0
- typer_examples-1.1.1/typer_examples/_providers.py +102 -0
- typer_examples-1.1.1/typer_examples/_renderer.py +92 -0
- typer_examples-1.1.1/typer_examples/docs.py +91 -0
- typer_examples-1.1.1/uv.lock +365 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6.0.2
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
cache-dependency-glob: uv.lock
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: uv sync --extra dev
|
|
30
|
+
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: uv run pytest tests/ -v
|
|
33
|
+
|
|
34
|
+
changelog:
|
|
35
|
+
name: Update changelog
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
# Only on pushes to main by humans; skip when the bot itself pushes the changelog back.
|
|
38
|
+
if: github.event_name == 'push' && github.actor != 'github-actions[bot]'
|
|
39
|
+
permissions:
|
|
40
|
+
contents: write
|
|
41
|
+
pull-requests: read
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v6.0.2
|
|
44
|
+
with:
|
|
45
|
+
fetch-depth: 0
|
|
46
|
+
|
|
47
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.12"
|
|
50
|
+
cache-dependency-glob: uv.lock
|
|
51
|
+
|
|
52
|
+
- name: Install dev dependencies
|
|
53
|
+
run: uv sync --extra dev
|
|
54
|
+
|
|
55
|
+
- name: Regenerate CHANGELOG.md
|
|
56
|
+
env:
|
|
57
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
58
|
+
run: uv run git-cliff --output CHANGELOG.md
|
|
59
|
+
|
|
60
|
+
- name: Commit if changed
|
|
61
|
+
run: |
|
|
62
|
+
git config user.name "github-actions[bot]"
|
|
63
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
64
|
+
git add CHANGELOG.md
|
|
65
|
+
git diff --cached --quiet || git commit -m "chore(changelog): update unreleased section [skip ci]"
|
|
66
|
+
git push origin HEAD:main
|
|
67
|
+
|
|
68
|
+
summary:
|
|
69
|
+
needs: test
|
|
70
|
+
if: always()
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
steps:
|
|
73
|
+
- name: Write job summary
|
|
74
|
+
env:
|
|
75
|
+
RESULT: ${{ needs.test.result }}
|
|
76
|
+
REF: ${{ github.ref_name }}
|
|
77
|
+
SHA: ${{ github.sha }}
|
|
78
|
+
EVENT: ${{ github.event_name }}
|
|
79
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
80
|
+
run: |
|
|
81
|
+
echo "## CI — $(date -u +'%Y-%m-%d %H:%M UTC')" >> $GITHUB_STEP_SUMMARY
|
|
82
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
83
|
+
echo "| | |" >> $GITHUB_STEP_SUMMARY
|
|
84
|
+
echo "|---|---|" >> $GITHUB_STEP_SUMMARY
|
|
85
|
+
echo "| **Trigger** | \`$EVENT\` |" >> $GITHUB_STEP_SUMMARY
|
|
86
|
+
echo "| **Ref** | \`$REF\` |" >> $GITHUB_STEP_SUMMARY
|
|
87
|
+
echo "| **Commit** | \`${SHA:0:7}\` |" >> $GITHUB_STEP_SUMMARY
|
|
88
|
+
echo "| **Python versions** | \`3.9\`, \`3.10\`, \`3.11\`, \`3.12\` |" >> $GITHUB_STEP_SUMMARY
|
|
89
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
90
|
+
if [ "$RESULT" = "success" ]; then
|
|
91
|
+
echo "### ✅ All checks passed" >> $GITHUB_STEP_SUMMARY
|
|
92
|
+
else
|
|
93
|
+
echo "### ❌ One or more checks failed" >> $GITHUB_STEP_SUMMARY
|
|
94
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
95
|
+
echo "See [matrix results]($RUN_URL) for per-version details." >> $GITHUB_STEP_SUMMARY
|
|
96
|
+
fi
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
pull-requests: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
release:
|
|
17
|
+
name: Create GitHub release
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6.0.2
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 0
|
|
24
|
+
|
|
25
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
cache-dependency-glob: uv.lock
|
|
29
|
+
|
|
30
|
+
- name: Install dev dependencies
|
|
31
|
+
run: uv sync --extra dev
|
|
32
|
+
|
|
33
|
+
# Generate changelog body for this tag only (since previous tag)
|
|
34
|
+
- name: Generate changelog
|
|
35
|
+
id: changelog
|
|
36
|
+
env:
|
|
37
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
+
run: |
|
|
39
|
+
uv run git-cliff --current --strip header --output CHANGELOG_RELEASE.md
|
|
40
|
+
echo "body<<EOF" >> "$GITHUB_OUTPUT"
|
|
41
|
+
cat CHANGELOG_RELEASE.md >> "$GITHUB_OUTPUT"
|
|
42
|
+
echo "EOF" >> "$GITHUB_OUTPUT"
|
|
43
|
+
|
|
44
|
+
# Regenerate the full CHANGELOG.md and push it back to the repo.
|
|
45
|
+
# Switch to main explicitly — checkout leaves us in detached HEAD on the tag.
|
|
46
|
+
- name: Update CHANGELOG.md
|
|
47
|
+
env:
|
|
48
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
49
|
+
run: |
|
|
50
|
+
git config user.name "github-actions[bot]"
|
|
51
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
52
|
+
git fetch origin main
|
|
53
|
+
git checkout -B main origin/main
|
|
54
|
+
uv run git-cliff --output CHANGELOG.md
|
|
55
|
+
git add CHANGELOG.md
|
|
56
|
+
git diff --cached --quiet || git commit -m "chore(changelog): update for ${{ github.ref_name }} [skip ci]" --no-verify
|
|
57
|
+
git push origin main
|
|
58
|
+
|
|
59
|
+
- name: Build distributions
|
|
60
|
+
run: uv build
|
|
61
|
+
|
|
62
|
+
- uses: actions/upload-artifact@v7.0.1
|
|
63
|
+
with:
|
|
64
|
+
name: dist
|
|
65
|
+
path: |
|
|
66
|
+
dist/*.whl
|
|
67
|
+
dist/*.tar.gz
|
|
68
|
+
if-no-files-found: error
|
|
69
|
+
|
|
70
|
+
- name: Create GitHub release
|
|
71
|
+
uses: softprops/action-gh-release@v2
|
|
72
|
+
with:
|
|
73
|
+
tag_name: ${{ github.ref_name }}
|
|
74
|
+
name: ${{ github.ref_name }}
|
|
75
|
+
body: ${{ steps.changelog.outputs.body }}
|
|
76
|
+
draft: false
|
|
77
|
+
prerelease: ${{ contains(github.ref_name, '-') }}
|
|
78
|
+
files: |
|
|
79
|
+
dist/*.whl
|
|
80
|
+
dist/*.tar.gz
|
|
81
|
+
|
|
82
|
+
publish:
|
|
83
|
+
name: Publish to PyPI
|
|
84
|
+
needs: release
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
# Trusted publishing: PyPI verifies this workflow's OIDC token, so no API
|
|
87
|
+
# token is stored. Configure the publisher once at
|
|
88
|
+
# https://pypi.org/manage/project/typer-examples/settings/publishing/
|
|
89
|
+
# (workflow: release.yml, environment: pypi).
|
|
90
|
+
environment:
|
|
91
|
+
name: pypi
|
|
92
|
+
url: https://pypi.org/p/typer-examples
|
|
93
|
+
permissions:
|
|
94
|
+
id-token: write
|
|
95
|
+
|
|
96
|
+
steps:
|
|
97
|
+
- uses: actions/download-artifact@v8.0.1
|
|
98
|
+
with:
|
|
99
|
+
name: dist
|
|
100
|
+
path: dist
|
|
101
|
+
|
|
102
|
+
- uses: pypa/gh-action-pypi-publish@v1.14.2
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
name: Typer Compatibility
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "0 6 * * *" # 06:00 UTC daily
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
issues: write
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
get-versions:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
outputs:
|
|
19
|
+
versions: ${{ steps.fetch.outputs.versions }}
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Fetch Typer versions from PyPI
|
|
23
|
+
id: fetch
|
|
24
|
+
run: |
|
|
25
|
+
versions=$(python3 -c "
|
|
26
|
+
import json
|
|
27
|
+
from urllib.request import urlopen
|
|
28
|
+
|
|
29
|
+
with urlopen('https://pypi.org/pypi/typer/json') as r:
|
|
30
|
+
data = json.load(r)
|
|
31
|
+
|
|
32
|
+
best = {}
|
|
33
|
+
for v in data['releases']:
|
|
34
|
+
parts = v.split('.')
|
|
35
|
+
if len(parts) < 2:
|
|
36
|
+
continue
|
|
37
|
+
try:
|
|
38
|
+
major, minor = int(parts[0]), int(parts[1])
|
|
39
|
+
except ValueError:
|
|
40
|
+
continue
|
|
41
|
+
# skip pre-releases; require >= 0.9
|
|
42
|
+
if (major, minor) < (0, 9):
|
|
43
|
+
continue
|
|
44
|
+
if any(c in v for c in ('a', 'b', 'rc', 'dev')):
|
|
45
|
+
continue
|
|
46
|
+
key = (major, minor)
|
|
47
|
+
cur = best.get(key)
|
|
48
|
+
vt = tuple(int(x) for x in v.split('.'))
|
|
49
|
+
if cur is None or vt > tuple(int(x) for x in cur.split('.')):
|
|
50
|
+
best[key] = v
|
|
51
|
+
|
|
52
|
+
result = sorted(best.values(), key=lambda v: tuple(int(x) for x in v.split('.')))
|
|
53
|
+
print(json.dumps(result))
|
|
54
|
+
")
|
|
55
|
+
echo "versions=$versions" >> $GITHUB_OUTPUT
|
|
56
|
+
|
|
57
|
+
test:
|
|
58
|
+
needs: get-versions
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
|
|
61
|
+
strategy:
|
|
62
|
+
fail-fast: false
|
|
63
|
+
matrix:
|
|
64
|
+
typer-version: ${{ fromJson(needs.get-versions.outputs.versions) }}
|
|
65
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
66
|
+
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v6.0.2
|
|
69
|
+
|
|
70
|
+
- uses: astral-sh/setup-uv@v8.0.0
|
|
71
|
+
with:
|
|
72
|
+
python-version: ${{ matrix.python-version }}
|
|
73
|
+
cache-dependency-glob: uv.lock
|
|
74
|
+
|
|
75
|
+
- name: Install project
|
|
76
|
+
run: uv sync --extra dev
|
|
77
|
+
|
|
78
|
+
- name: Override Typer to ${{ matrix.typer-version }}
|
|
79
|
+
id: install-typer
|
|
80
|
+
continue-on-error: true
|
|
81
|
+
run: uv pip install "typer[all]==${{ matrix.typer-version }}"
|
|
82
|
+
|
|
83
|
+
- name: Verify installed Typer version
|
|
84
|
+
if: steps.install-typer.outcome == 'success'
|
|
85
|
+
run: uv run python -c "import typer; print('typer', typer.__version__)"
|
|
86
|
+
|
|
87
|
+
- name: Run tests
|
|
88
|
+
id: pytest
|
|
89
|
+
if: steps.install-typer.outcome == 'success'
|
|
90
|
+
run: uv run pytest tests/ -v
|
|
91
|
+
|
|
92
|
+
- name: Skip notice (Python incompatible with this Typer version)
|
|
93
|
+
if: steps.install-typer.outcome == 'failure'
|
|
94
|
+
run: echo "Typer ${{ matrix.typer-version }} does not support Python ${{ matrix.python-version }} — skipping."
|
|
95
|
+
|
|
96
|
+
summary:
|
|
97
|
+
needs: [get-versions, test]
|
|
98
|
+
if: always()
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
|
|
101
|
+
steps:
|
|
102
|
+
- uses: actions/checkout@v6.0.2
|
|
103
|
+
|
|
104
|
+
- name: Write job summary
|
|
105
|
+
env:
|
|
106
|
+
RESULT: ${{ needs.test.result }}
|
|
107
|
+
VERSIONS: ${{ needs.get-versions.outputs.versions }}
|
|
108
|
+
TRIGGER: ${{ github.event_name }}
|
|
109
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
110
|
+
run: |
|
|
111
|
+
echo "## Typer Compatibility — $(date -u +'%Y-%m-%d')" >> $GITHUB_STEP_SUMMARY
|
|
112
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
113
|
+
echo "| | |" >> $GITHUB_STEP_SUMMARY
|
|
114
|
+
echo "|---|---|" >> $GITHUB_STEP_SUMMARY
|
|
115
|
+
echo "| **Trigger** | \`$TRIGGER\` |" >> $GITHUB_STEP_SUMMARY
|
|
116
|
+
echo "| **Python versions** | \`3.9\`, \`3.10\`, \`3.11\`, \`3.12\` |" >> $GITHUB_STEP_SUMMARY
|
|
117
|
+
echo "| **Typer versions tested** | \`$VERSIONS\` |" >> $GITHUB_STEP_SUMMARY
|
|
118
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
119
|
+
if [ "$RESULT" = "success" ]; then
|
|
120
|
+
echo "### ✅ All Typer versions passed" >> $GITHUB_STEP_SUMMARY
|
|
121
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
122
|
+
echo "No compatibility issues detected." >> $GITHUB_STEP_SUMMARY
|
|
123
|
+
else
|
|
124
|
+
echo "### ❌ One or more Typer versions failed" >> $GITHUB_STEP_SUMMARY
|
|
125
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
126
|
+
echo "See [matrix results]($RUN_URL) for per-version details." >> $GITHUB_STEP_SUMMARY
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
- name: Open issue on failure (once per day)
|
|
130
|
+
if: needs.test.result == 'failure'
|
|
131
|
+
env:
|
|
132
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
133
|
+
VERSIONS: ${{ needs.get-versions.outputs.versions }}
|
|
134
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
135
|
+
run: |
|
|
136
|
+
TITLE="Typer compatibility failure — $(date -u +'%Y-%m-%d')"
|
|
137
|
+
|
|
138
|
+
# Skip if an open issue with the same title already exists today
|
|
139
|
+
existing=$(gh issue list --state open --search "$TITLE" --json number --jq length)
|
|
140
|
+
if [ "$existing" -gt 0 ]; then
|
|
141
|
+
echo "Issue already open for today — skipping."
|
|
142
|
+
exit 0
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
gh issue create \
|
|
146
|
+
--title "$TITLE" \
|
|
147
|
+
--label "bug,compatibility" \
|
|
148
|
+
--body "$(cat <<EOF
|
|
149
|
+
One or more combinations failed the daily compatibility test.
|
|
150
|
+
|
|
151
|
+
**Typer versions tested:** \`$VERSIONS\`
|
|
152
|
+
**Python versions tested:** \`3.9, 3.10, 3.11, 3.12\`
|
|
153
|
+
**Run:** $RUN_URL
|
|
154
|
+
|
|
155
|
+
Check the matrix results in the run above to see which Typer × Python combinations failed.
|
|
156
|
+
EOF
|
|
157
|
+
)"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog
|
|
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.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
Generated by [git-cliff](https://github.com/orhun/git-cliff).
|
|
9
|
+
|
|
10
|
+
## [v1.1.1](https://github.com/Xieyt/typer-examples/compare/v1.1.0...v1.1.1) - 2026-07-31
|
|
11
|
+
|
|
12
|
+
### 🐛 Bug Fixes
|
|
13
|
+
|
|
14
|
+
- Derive __version__ from installed package metadata ([`02a46fc`](https://github.com/Xieyt/typer-examples/commit/02a46fca3b004c79f646c3538a6dee8e84874dc2)) by [@Xieyt](https://github.com/Xieyt)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### ⚙️ CI/CD
|
|
18
|
+
|
|
19
|
+
- Add PyPI publishing workflow ([`ef7bdb7`](https://github.com/Xieyt/typer-examples/commit/ef7bdb795c290edd7544021ab3a3c930134ce650)) by [@Xieyt](https://github.com/Xieyt)
|
|
20
|
+
|
|
21
|
+
## [v1.1.0](https://github.com/Xieyt/typer-examples/compare/v1.0.0...v1.1.0) - 2026-04-11
|
|
22
|
+
|
|
23
|
+
### 🐛 Bug Fixes
|
|
24
|
+
|
|
25
|
+
- Argv wins over per-example kwargs; strip subcommand tokens from argv ([`5f1c328`](https://github.com/Xieyt/typer-examples/commit/5f1c3283df5dc85baac012a45ff40a34af356687)) by [@Xieyt](https://github.com/Xieyt)
|
|
26
|
+
- Strip all command_path tokens from argv; use click.Group over MultiCommand ([`8562fd8`](https://github.com/Xieyt/typer-examples/commit/8562fd8ee724eefe1b2b23d573aa4b46f21be6f9)) by [@Xieyt](https://github.com/Xieyt)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### 📦 Miscellaneous
|
|
30
|
+
|
|
31
|
+
- Add .gitignore to exclude pycache and build artifacts ([`004a7f6`](https://github.com/Xieyt/typer-examples/commit/004a7f6f6b2dcc831ec5179bfd68c417f7a438c7)) by [@Xieyt](https://github.com/Xieyt)
|
|
32
|
+
- Remove accidentally committed __pycache__ files ([`f132346`](https://github.com/Xieyt/typer-examples/commit/f1323469816a650ca812812ed00148a3cd8a16a7)) by [@Xieyt](https://github.com/Xieyt)
|
|
33
|
+
- Remove typer-examples-design.md ([`d4d3c3e`](https://github.com/Xieyt/typer-examples/commit/d4d3c3e6c3305502cd0d99b0904bd44a917912df)) by [@Xieyt](https://github.com/Xieyt)
|
|
34
|
+
|
|
35
|
+
## v1.0.0 - 2026-04-05
|
|
36
|
+
|
|
37
|
+
### ✨ Features
|
|
38
|
+
|
|
39
|
+
- Introduce typer-examples library ([`1eebd55`](https://github.com/Xieyt/typer-examples/commit/1eebd55408477d0a6ca2add25c31fe8f06529ac6)) by [@Xieyt](https://github.com/Xieyt)
|
|
40
|
+
- Add per-application configuration for examples ([`f51b30d`](https://github.com/Xieyt/typer-examples/commit/f51b30d983730a063f53403b1dcc3656ee322360)) by [@Xieyt](https://github.com/Xieyt)
|
|
41
|
+
- Add new example apps and refine config hook ([`7f8616b`](https://github.com/Xieyt/typer-examples/commit/7f8616bfcc8226d38dff3c5f717b8c9364bc5e64)) by [@Xieyt](https://github.com/Xieyt)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### 📚 Documentation
|
|
45
|
+
|
|
46
|
+
- Add comprehensive README for typer-examples ([`1415556`](https://github.com/Xieyt/typer-examples/commit/14155561d0659862265fa0e21b52c70a511ea969)) by [@Xieyt](https://github.com/Xieyt)
|
|
47
|
+
- Rewrite README as landing page, add docs/ reference directory ([`aa13118`](https://github.com/Xieyt/typer-examples/commit/aa131184eee2d225cd0cf91d10c4b6802a6c9168)) by [@Xieyt](https://github.com/Xieyt)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### ⚙️ CI/CD
|
|
51
|
+
|
|
52
|
+
- Add CI and Typer compatibility workflows ([`ce81d25`](https://github.com/Xieyt/typer-examples/commit/ce81d255421b7b89bb692bbdbc1106942443c67f)) by [@Xieyt](https://github.com/Xieyt)
|
|
53
|
+
- Add summaries, fix Node.js warning, fix cache key and failure detection ([`b14a720`](https://github.com/Xieyt/typer-examples/commit/b14a72087a6637ccac3a2eb4caae2f6679685a8d)) by [@Xieyt](https://github.com/Xieyt)
|
|
54
|
+
- Fix cache input name (cache-dependency-glob, not cache-dependency-path) ([`f332d29`](https://github.com/Xieyt/typer-examples/commit/f332d2956a12c2c290eb80819fbaf50c0239f5d7)) by [@Xieyt](https://github.com/Xieyt)
|
|
55
|
+
- **compat:** Expand matrix to Typer versions × Python 3.9-3.12 ([`cab9541`](https://github.com/Xieyt/typer-examples/commit/cab95415249c80a762522660b1ab7a5c2ad26c28)) by [@Xieyt](https://github.com/Xieyt)
|
|
56
|
+
- Bump actions to Node.js 24 native versions (checkout@v6.0.2, setup-uv@v8.0.0) ([`599594e`](https://github.com/Xieyt/typer-examples/commit/599594efa3f3e220b5121de8c69872aa64588a6a)) by [@Xieyt](https://github.com/Xieyt)
|
|
57
|
+
- **compat:** Skip gracefully when Typer version is incompatible with Python version; fix missing compatibility label ([`c049234`](https://github.com/Xieyt/typer-examples/commit/c0492345eab2a7cea0a79285ecb91f7ad4dae46d)) by [@Xieyt](https://github.com/Xieyt)
|
|
58
|
+
- **changelog:** Update CHANGELOG.md on every push to main ([`ee2664e`](https://github.com/Xieyt/typer-examples/commit/ee2664e57bcca026ec0df8e689d506e8bc4b0505)) by [@Xieyt](https://github.com/Xieyt)
|
|
59
|
+
- **release:** Pull --rebase before pushing CHANGELOG.md to avoid race with ci changelog job ([`dca0674`](https://github.com/Xieyt/typer-examples/commit/dca0674302c44846db4257672873da3709e85f69)) by [@Xieyt](https://github.com/Xieyt)
|
|
60
|
+
- **release:** Fix detached HEAD when updating CHANGELOG.md on tag push ([`8d1ba07`](https://github.com/Xieyt/typer-examples/commit/8d1ba07b11a135293ae3160613284cad13bfd50e)) by [@Xieyt](https://github.com/Xieyt)
|
|
61
|
+
- **release:** Attach .whl and .tar.gz to GitHub release ([`f32578e`](https://github.com/Xieyt/typer-examples/commit/f32578e209dcc0591a9fc9c72e414cd755bfb51b)) by [@Xieyt](https://github.com/Xieyt)
|
|
62
|
+
- **release:** Use explicit *.whl and *.tar.gz globs to exclude dist/.gitignore ([`af74f98`](https://github.com/Xieyt/typer-examples/commit/af74f9857319f7119f259426d945587bd1dbbfda)) by [@Xieyt](https://github.com/Xieyt)
|
|
63
|
+
- Add pull-requests read permission for git-cliff GitHub API ([`155603e`](https://github.com/Xieyt/typer-examples/commit/155603e5ced45a1f9f88449cbdcbaa827e9be60f)) by [@Xieyt](https://github.com/Xieyt)
|
|
64
|
+
- **release:** Append date to release title ([`4d4641f`](https://github.com/Xieyt/typer-examples/commit/4d4641fd885109453e13772389801d49ab7eed35)) by [@Xieyt](https://github.com/Xieyt)
|
|
65
|
+
- **release:** Fix changelog heading to v1.0.0 format, revert release title ([`006dfcd`](https://github.com/Xieyt/typer-examples/commit/006dfcda9ab68a59d3dd8df9d4a43a9e3dc43796)) by [@Xieyt](https://github.com/Xieyt)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### 🏗️ Build
|
|
69
|
+
|
|
70
|
+
- Add uv.lock for reproducible dependencies ([`f52264d`](https://github.com/Xieyt/typer-examples/commit/f52264da2061220d574bf5b1ecf04febbcd13690)) by [@Xieyt](https://github.com/Xieyt)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### 📦 Miscellaneous
|
|
74
|
+
|
|
75
|
+
- Add git-cliff for changelog management ([`fa36e1b`](https://github.com/Xieyt/typer-examples/commit/fa36e1ba12f8de17aaf1b8b97433b266cbc57357)) by [@Xieyt](https://github.com/Xieyt)
|
|
76
|
+
- Add MIT license ([`760ee46`](https://github.com/Xieyt/typer-examples/commit/760ee46df884bf9e8e84e1c3da172909bfd36916)) by [@Xieyt](https://github.com/Xieyt)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## New Contributors ❤️
|
|
80
|
+
|
|
81
|
+
- [@Xieyt](https://github.com/Xieyt) made their first contribution
|
|
82
|
+
- [@github-actions[bot]](https://github.com/github-actions[bot]) made their first contribution
|
|
83
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## [v1.1.1](https://github.com/Xieyt/typer-examples/compare/v1.1.0...v1.1.1) - 2026-07-31
|
|
2
|
+
|
|
3
|
+
### 🐛 Bug Fixes
|
|
4
|
+
|
|
5
|
+
- Derive __version__ from installed package metadata ([`02a46fc`](https://github.com/Xieyt/typer-examples/commit/02a46fca3b004c79f646c3538a6dee8e84874dc2)) by [@Xieyt](https://github.com/Xieyt)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚙️ CI/CD
|
|
9
|
+
|
|
10
|
+
- Add PyPI publishing workflow ([`ef7bdb7`](https://github.com/Xieyt/typer-examples/commit/ef7bdb795c290edd7544021ab3a3c930134ce650)) by [@Xieyt](https://github.com/Xieyt)
|
|
11
|
+
|
|
12
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 aloksingh
|
|
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,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: typer-examples
|
|
3
|
+
Version: 1.1.1
|
|
4
|
+
Summary: Beautiful example rendering for Typer CLI help output
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: cli,examples,help,rich,typer
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Requires-Dist: typer>=0.9.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: git-cliff>=2.6; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: typer[all]>=0.9.0; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# typer-examples
|
|
27
|
+
|
|
28
|
+
[](https://github.com/Xieyt/typer-examples/actions/workflows/ci.yml)
|
|
29
|
+
[](https://github.com/Xieyt/typer-examples/actions/workflows/typer-compat.yml)
|
|
30
|
+
[](#compatibility)
|
|
31
|
+
[](#license)
|
|
32
|
+
|
|
33
|
+
Attach structured, syntax-highlighted usage examples to [Typer](https://typer.tiangolo.com/) commands. They appear automatically in `--help` output as a Rich panel — no subclassing, no epilog hacks.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Usage: myapp deploy [OPTIONS] ENV
|
|
37
|
+
|
|
38
|
+
╭─ Options ──────────────────────────────────────────────────────────╮
|
|
39
|
+
│ --tag TEXT Docker image tag to deploy. [default: latest] │
|
|
40
|
+
│ --yes Skip confirmation prompt. │
|
|
41
|
+
│ --help Show this message and exit. │
|
|
42
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
43
|
+
╭─ Examples ─────────────────────────────────────────────────────────╮
|
|
44
|
+
│ Deploy to staging with a pinned tag │
|
|
45
|
+
│ Pulls the image, runs migrations, and restarts services. │
|
|
46
|
+
│ $ myapp deploy staging --tag 1.4.2 │
|
|
47
|
+
│ │
|
|
48
|
+
│ Deploy to production and skip confirmation │
|
|
49
|
+
│ Pass --yes in CI pipelines to avoid interactive prompts. │
|
|
50
|
+
│ $ myapp deploy production --tag 2.0.0 --yes │
|
|
51
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install typer-examples
|
|
58
|
+
# or
|
|
59
|
+
uv add typer-examples
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Requires Python ≥ 3.9 and Typer ≥ 0.9.
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import typer
|
|
68
|
+
from typer_examples import example, install
|
|
69
|
+
|
|
70
|
+
app = typer.Typer()
|
|
71
|
+
install(app)
|
|
72
|
+
|
|
73
|
+
@app.command()
|
|
74
|
+
@example(
|
|
75
|
+
"Deploy to staging with a pinned tag",
|
|
76
|
+
"{env} --tag {version}",
|
|
77
|
+
env="staging",
|
|
78
|
+
version="1.4.2",
|
|
79
|
+
detail="Pulls the image, runs migrations, and restarts services.",
|
|
80
|
+
)
|
|
81
|
+
@example(
|
|
82
|
+
"Deploy to production and skip confirmation",
|
|
83
|
+
"{env} --tag {version} --yes",
|
|
84
|
+
env="production",
|
|
85
|
+
version="2.0.0",
|
|
86
|
+
detail="Pass --yes in CI pipelines to avoid interactive prompts.",
|
|
87
|
+
)
|
|
88
|
+
def deploy(env: str, tag: str = typer.Option("latest"), yes: bool = False):
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
app()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> **Decorator order**: `@example` must sit *below* `@app.command()` — closest to `def`. This ensures the metadata is attached to the raw function before Typer wraps it.
|
|
96
|
+
|
|
97
|
+
## Features
|
|
98
|
+
|
|
99
|
+
- **Decorator-first** — examples live next to the command, not buried in docstrings or epilog strings
|
|
100
|
+
- **Template variables** — `{placeholders}` resolved from per-example kwargs, app-level defaults, `sys.argv`, or Click parameter defaults → [details](docs/template-variables.md)
|
|
101
|
+
- **Per-app config** — each `Typer()` instance gets its own panel title, style theme, and variable defaults → [details](docs/configuration.md)
|
|
102
|
+
- **Docs generation** — export all examples to Markdown or reStructuredText for CI doc pipelines → [API](docs/api.md)
|
|
103
|
+
- **Chain-safe** — composes with `rich-click` and any other `rich_format_help` patch without clobbering
|
|
104
|
+
- **Graceful degradation** — if `rich` is absent, `install()` returns silently with no error
|
|
105
|
+
|
|
106
|
+
## Documentation
|
|
107
|
+
|
|
108
|
+
| Topic | |
|
|
109
|
+
|-------|--|
|
|
110
|
+
| [Template variables](docs/template-variables.md) | Resolution chain: per-example → app-level → argv → defaults |
|
|
111
|
+
| [Configuration](docs/configuration.md) | `ExamplesConfig` fields, global config, per-app config for sub-commands |
|
|
112
|
+
| [API reference](docs/api.md) | Full public API with signatures and return types |
|
|
113
|
+
| [How it works](docs/how-it-works.md) | Internal implementation and the `rich_format_help` hook |
|
|
114
|
+
|
|
115
|
+
## Try the examples
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Minimal single-app setup — three commands, each with examples
|
|
119
|
+
uv run python examples/simple.py deploy --help
|
|
120
|
+
uv run python examples/simple.py logs --help
|
|
121
|
+
uv run python examples/simple.py shell --help
|
|
122
|
+
|
|
123
|
+
# Root app + two sub-apps with independent per-app config
|
|
124
|
+
uv run python examples/app.py deploy --help
|
|
125
|
+
uv run python examples/app.py db migrate --help
|
|
126
|
+
uv run python examples/app.py server start --help
|
|
127
|
+
|
|
128
|
+
# Static docs generation
|
|
129
|
+
uv run python examples/app.py docs
|
|
130
|
+
uv run python examples/app.py docs --format rst
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Compatibility
|
|
134
|
+
|
|
135
|
+
| Typer | Python | rich-click |
|
|
136
|
+
|-------|--------|------------|
|
|
137
|
+
| ≥ 0.9 | 3.9 – 3.12 | Supported |
|
|
138
|
+
|
|
139
|
+
Compatibility is verified daily across all supported Typer × Python combinations in CI.
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|