pretty-release-notes 1.4.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.
Files changed (55) hide show
  1. pretty_release_notes-1.4.0/LICENSE +7 -0
  2. pretty_release_notes-1.4.0/PKG-INFO +335 -0
  3. pretty_release_notes-1.4.0/README.md +295 -0
  4. pretty_release_notes-1.4.0/pretty_release_notes/__init__.py +38 -0
  5. pretty_release_notes-1.4.0/pretty_release_notes/__main__.py +6 -0
  6. pretty_release_notes-1.4.0/pretty_release_notes/adapters/__init__.py +1 -0
  7. pretty_release_notes-1.4.0/pretty_release_notes/adapters/cli_progress.py +25 -0
  8. pretty_release_notes-1.4.0/pretty_release_notes/api.py +239 -0
  9. pretty_release_notes-1.4.0/pretty_release_notes/core/__init__.py +1 -0
  10. pretty_release_notes-1.4.0/pretty_release_notes/core/config.py +166 -0
  11. pretty_release_notes-1.4.0/pretty_release_notes/core/config_loader.py +221 -0
  12. pretty_release_notes-1.4.0/pretty_release_notes/core/execution.py +74 -0
  13. pretty_release_notes-1.4.0/pretty_release_notes/core/interfaces.py +35 -0
  14. pretty_release_notes-1.4.0/pretty_release_notes/database.py +152 -0
  15. pretty_release_notes-1.4.0/pretty_release_notes/generator.py +317 -0
  16. pretty_release_notes-1.4.0/pretty_release_notes/github_client.py +232 -0
  17. pretty_release_notes-1.4.0/pretty_release_notes/main.py +245 -0
  18. pretty_release_notes-1.4.0/pretty_release_notes/models/__init__.py +15 -0
  19. pretty_release_notes-1.4.0/pretty_release_notes/models/_utils.py +47 -0
  20. pretty_release_notes-1.4.0/pretty_release_notes/models/change.py +34 -0
  21. pretty_release_notes-1.4.0/pretty_release_notes/models/commit.py +75 -0
  22. pretty_release_notes-1.4.0/pretty_release_notes/models/issue.py +17 -0
  23. pretty_release_notes-1.4.0/pretty_release_notes/models/pull_request.py +208 -0
  24. pretty_release_notes-1.4.0/pretty_release_notes/models/release_notes.py +241 -0
  25. pretty_release_notes-1.4.0/pretty_release_notes/models/release_notes_line.py +36 -0
  26. pretty_release_notes-1.4.0/pretty_release_notes/models/repository.py +20 -0
  27. pretty_release_notes-1.4.0/pretty_release_notes/openai_client.py +165 -0
  28. pretty_release_notes-1.4.0/pretty_release_notes/prompt.txt +34 -0
  29. pretty_release_notes-1.4.0/pretty_release_notes/py.typed +0 -0
  30. pretty_release_notes-1.4.0/pretty_release_notes/setup_command.py +336 -0
  31. pretty_release_notes-1.4.0/pretty_release_notes/ui.py +46 -0
  32. pretty_release_notes-1.4.0/pretty_release_notes/web/__init__.py +1 -0
  33. pretty_release_notes-1.4.0/pretty_release_notes/web/app.py +193 -0
  34. pretty_release_notes-1.4.0/pretty_release_notes/web/server.py +11 -0
  35. pretty_release_notes-1.4.0/pretty_release_notes.egg-info/PKG-INFO +335 -0
  36. pretty_release_notes-1.4.0/pretty_release_notes.egg-info/SOURCES.txt +53 -0
  37. pretty_release_notes-1.4.0/pretty_release_notes.egg-info/dependency_links.txt +1 -0
  38. pretty_release_notes-1.4.0/pretty_release_notes.egg-info/entry_points.txt +2 -0
  39. pretty_release_notes-1.4.0/pretty_release_notes.egg-info/requires.txt +18 -0
  40. pretty_release_notes-1.4.0/pretty_release_notes.egg-info/top_level.txt +1 -0
  41. pretty_release_notes-1.4.0/pyproject.toml +112 -0
  42. pretty_release_notes-1.4.0/setup.cfg +4 -0
  43. pretty_release_notes-1.4.0/tests/test_api.py +322 -0
  44. pretty_release_notes-1.4.0/tests/test_core.py +439 -0
  45. pretty_release_notes-1.4.0/tests/test_database.py +37 -0
  46. pretty_release_notes-1.4.0/tests/test_database_threading.py +261 -0
  47. pretty_release_notes-1.4.0/tests/test_execution.py +239 -0
  48. pretty_release_notes-1.4.0/tests/test_generator.py +184 -0
  49. pretty_release_notes-1.4.0/tests/test_main.py +109 -0
  50. pretty_release_notes-1.4.0/tests/test_models_utils.py +119 -0
  51. pretty_release_notes-1.4.0/tests/test_openai_client.py +167 -0
  52. pretty_release_notes-1.4.0/tests/test_pull_request.py +128 -0
  53. pretty_release_notes-1.4.0/tests/test_release_notes.py +637 -0
  54. pretty_release_notes-1.4.0/tests/test_setup_command.py +319 -0
  55. pretty_release_notes-1.4.0/tests/test_web_api.py +441 -0
@@ -0,0 +1,7 @@
1
+ Copyright 2024 Raffael Meyer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,335 @@
1
+ Metadata-Version: 2.4
2
+ Name: pretty-release-notes
3
+ Version: 1.4.0
4
+ Summary: Transform GitHub release notes with AI
5
+ Author: Raffael Meyer
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/alyf-de/pretty_release_notes
8
+ Project-URL: Documentation, https://github.com/alyf-de/pretty_release_notes#readme
9
+ Project-URL: Repository, https://github.com/alyf-de/pretty_release_notes
10
+ Project-URL: Issues, https://github.com/alyf-de/pretty_release_notes/issues
11
+ Keywords: github,release-notes,llm,cli
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Documentation
19
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: typer~=0.24.0
24
+ Requires-Dist: rich~=15.0
25
+ Requires-Dist: requests~=2.33
26
+ Requires-Dist: python-dotenv~=1.2
27
+ Requires-Dist: tenacity~=9.1
28
+ Requires-Dist: any-llm-sdk[all]~=1.13
29
+ Provides-Extra: web
30
+ Requires-Dist: fastapi~=0.136.0; extra == "web"
31
+ Requires-Dist: uvicorn~=0.44.0; extra == "web"
32
+ Requires-Dist: pydantic~=2.13; extra == "web"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest~=9.0; extra == "dev"
35
+ Requires-Dist: pytest-cov~=7.1; extra == "dev"
36
+ Requires-Dist: mypy~=1.20; extra == "dev"
37
+ Requires-Dist: ruff~=0.15.0; extra == "dev"
38
+ Requires-Dist: types-requests~=2.33.0.20260408; extra == "dev"
39
+ Dynamic: license-file
40
+
41
+ Turn GitHub's auto-generated release notes into human-readable sentences.
42
+
43
+ Go from this:
44
+
45
+ ![Original](img/original.png)
46
+
47
+ To this:
48
+
49
+ ![Modified](img/modified.png)
50
+
51
+ ## Features
52
+
53
+ - **AI-Powered Summaries** - Converts technical PR titles into clear, user-friendly sentences
54
+ - **Smart Filtering** - Automatically excludes non-user-facing changes (chore, ci, refactor, test, style)
55
+ - **Revert Detection** - Automatically filters out PRs that were reverted within the same release
56
+ - **Backport Intelligence** - Reuses summaries from original PRs for backports, maintaining consistency
57
+ - **Author & Reviewer Attribution** - Credits human contributors while excluding bots
58
+ - **Intelligent Caching** - Stores generated summaries to avoid redundant API calls and reduce costs
59
+ - **Grouped Release Notes** - Optional grouping by conventional commit type (Features, Bug Fixes, Performance, etc.)
60
+ - **Multi-Mode Architecture** - Use as CLI tool, Python library, or REST API backend
61
+ - **Rich Context** - Incorporates PR descriptions, linked issues, and code diffs for accurate summaries
62
+ - **Interactive Setup** - Guided configuration with validation and migration from legacy formats
63
+
64
+ > [!NOTE]
65
+ > The default prompt is geared towards [ERPNext](https://github.com/frappe/erpnext) and the [Frappe Framework](https://github.com/frappe/frappe). If you want to use this for different projects, set your own `prompt_path` in `config.toml`.
66
+
67
+ ## Configuration
68
+
69
+ ### Interactive Setup (Recommended)
70
+
71
+ The easiest way to configure the tool is using the interactive setup command:
72
+
73
+ ```bash
74
+ pretty-release-notes setup
75
+ ```
76
+
77
+ This will:
78
+ - Guide you through all configuration options with helpful prompts
79
+ - Show sane defaults for each setting
80
+ - Create the config file at `~/.pretty-release-notes/config.toml`
81
+
82
+ **First-time migration from .env?** Use the `--migrate-env` flag:
83
+ ```bash
84
+ pretty-release-notes setup --migrate-env
85
+ ```
86
+ This will read your existing `.env` file and suggest those values as defaults.
87
+
88
+ ### Manual Setup
89
+
90
+ Alternatively, copy `config.toml.example` to `~/.pretty-release-notes/config.toml` and fill in your credentials:
91
+
92
+ ```bash
93
+ # Create config directory
94
+ mkdir -p ~/.pretty-release-notes
95
+
96
+ # Copy example config
97
+ cp config.toml.example ~/.pretty-release-notes/config.toml
98
+
99
+ # Edit with your credentials
100
+ nano ~/.pretty-release-notes/config.toml
101
+ ```
102
+
103
+ ### Configuration Format
104
+
105
+ The configuration file uses TOML format with sections for GitHub credentials, LLM settings, database caching, and filters. The canonical section name is `[llm]`, while the legacy `[openai]` section is still accepted for backward compatibility. Prefer fully qualified `provider:model` values such as `openai:gpt-4.1`; unqualified model names are still accepted and default to OpenAI for backward compatibility. You can also set `reasoning_effort` to `none`, `low`, `medium`, `high`, or `xhigh` for supported models/providers. See [`config.toml.example`](config.toml.example) for the complete structure and all available options.
106
+
107
+ You can override the config location using the `--config-path` flag.
108
+
109
+ ## Installation
110
+
111
+ ```bash
112
+ # Clone the repository
113
+ git clone https://github.com/barredterra/pretty_release_notes
114
+ cd pretty_release_notes
115
+
116
+ # Create virtual environment and install
117
+ python -m venv env
118
+ source env/bin/activate
119
+ pip install -e .
120
+ ```
121
+
122
+ ## Usage
123
+
124
+ ### CLI
125
+
126
+ After installation, you can use the CLI in several ways:
127
+
128
+ ```bash
129
+ # View all commands
130
+ pretty-release-notes --help
131
+
132
+ # Generate release notes
133
+ pretty-release-notes generate erpnext v15.38.4 # using owner from config.toml
134
+ pretty-release-notes generate --owner alyf-de banking v0.0.1
135
+
136
+ # Use a custom config file
137
+ pretty-release-notes generate --config-path /path/to/config.toml erpnext v15.38.4
138
+
139
+ # Specify custom comparison range
140
+ pretty-release-notes generate erpnext v15.38.4 --previous-tag v15.38.0
141
+
142
+ # Override reasoning effort for a single run
143
+ pretty-release-notes generate erpnext v15.38.4 --reasoning-effort high
144
+ ```
145
+
146
+ Example output:
147
+
148
+ ```markdown
149
+ ---- Original ----
150
+ ## What's Changed
151
+ * fix: list view and form status not same for purchase order (backport #43690) (backport #43692) by @mergify in https://github.com/frappe/erpnext/pull/43706
152
+
153
+
154
+ **Full Changelog**: https://github.com/frappe/erpnext/compare/v15.38.3...v15.38.4
155
+
156
+ ---- Modified ----
157
+ ## What's Changed
158
+ * Removes unnecessary decimal precision checks for _per_received_ and _per_billed_ fields in **Purchase Order**, so the list view status and form status remain consistent. https://github.com/frappe/erpnext/pull/43706
159
+
160
+
161
+ **Full Changelog**: https://github.com/frappe/erpnext/compare/v15.38.3...v15.38.4
162
+ **Authors**: @rohitwaghchaure
163
+ ```
164
+
165
+ ### Library Usage
166
+
167
+ You can also use `pretty_release_notes` as a Python library in your own projects:
168
+
169
+ ```python
170
+ from pretty_release_notes import ReleaseNotesBuilder
171
+
172
+ # Build a client with configuration
173
+ client = (
174
+ ReleaseNotesBuilder()
175
+ .with_github_token("ghp_your_token")
176
+ .with_llm(
177
+ "sk_your_key",
178
+ model="openai:gpt-4.1", # or model="anthropic:claude-sonnet-4-5"
179
+ reasoning_effort="medium",
180
+ )
181
+ .with_database("sqlite")
182
+ .with_filters(
183
+ exclude_types={"chore", "ci", "refactor"},
184
+ exclude_labels={"skip-release-notes"},
185
+ )
186
+ .build()
187
+ )
188
+
189
+ # Generate release notes
190
+ notes = client.generate_release_notes(
191
+ owner="frappe",
192
+ repo="erpnext",
193
+ tag="v15.38.4",
194
+ previous_tag_name="v15.38.0", # Optional: custom comparison range
195
+ )
196
+ print(notes)
197
+
198
+ # Optionally update on GitHub
199
+ client.update_github_release("frappe", "erpnext", "v15.38.4", notes)
200
+ ```
201
+
202
+ For more examples, see [`examples/library_usage.py`](examples/library_usage.py).
203
+
204
+ ### Web API
205
+
206
+ The tool can also be run as a REST API server for integration with web frontends.
207
+
208
+ #### Starting the Server
209
+
210
+ First, install the web dependencies:
211
+
212
+ ```bash
213
+ source env/bin/activate
214
+ pip install -e .[web]
215
+ ```
216
+
217
+ Then start the server:
218
+
219
+ ```bash
220
+ # Using uvicorn directly
221
+ python -m uvicorn pretty_release_notes.web.app:app --host 0.0.0.0 --port 8000
222
+
223
+ # Or using the provided server script
224
+ python -m pretty_release_notes.web.server
225
+ ```
226
+
227
+ The API will be available at `http://localhost:8000` with interactive documentation at `http://localhost:8000/docs`.
228
+
229
+ #### API Endpoints
230
+
231
+ **Health Check**
232
+ ```bash
233
+ curl http://localhost:8000/health
234
+ ```
235
+
236
+ **Create Release Notes Job**
237
+ ```bash
238
+ curl -X POST http://localhost:8000/generate \
239
+ -H "Content-Type: application/json" \
240
+ -d '{
241
+ "owner": "frappe",
242
+ "repo": "erpnext",
243
+ "tag": "v15.38.4",
244
+ "previous_tag_name": "v15.38.0",
245
+ "github_token": "ghp_your_token_here",
246
+ "llm_key": "sk-your_key_here",
247
+ "llm_model": "openai:gpt-4.1",
248
+ "reasoning_effort": "medium",
249
+ "exclude_types": ["chore", "ci", "refactor"],
250
+ "exclude_labels": ["skip-release-notes"],
251
+ "exclude_authors": ["dependabot[bot]"],
252
+ "no_read": false,
253
+ "no_write": false
254
+ }'
255
+ ```
256
+
257
+ Legacy `openai_key`, `openai_model`, and `openai_reasoning_effort` request fields are still accepted for backward compatibility. Use `no_database` to skip both cache reads and writes.
258
+
259
+ Response:
260
+ ```json
261
+ {
262
+ "job_id": "550e8400-e29b-41d4-a716-446655440000",
263
+ "status": "pending",
264
+ "created_at": "2025-01-19T10:30:00.000000"
265
+ }
266
+ ```
267
+
268
+ **Check Job Status**
269
+ ```bash
270
+ curl http://localhost:8000/jobs/{job_id}
271
+ ```
272
+
273
+ Response:
274
+ ```json
275
+ {
276
+ "job_id": "550e8400-e29b-41d4-a716-446655440000",
277
+ "status": "completed",
278
+ "created_at": "2025-01-19T10:30:00.000000",
279
+ "completed_at": "2025-01-19T10:30:15.000000",
280
+ "result": "## What's Changed\n* Fixed bug...",
281
+ "progress": [
282
+ {
283
+ "timestamp": "2025-01-19T10:30:05.000000",
284
+ "type": "success",
285
+ "message": "Downloaded PRs in 0.42 seconds."
286
+ }
287
+ ],
288
+ "error": null
289
+ }
290
+ ```
291
+
292
+ ### Automated Polling
293
+
294
+ Run release note generation automatically whenever a new release is published. Add the repos you want to watch to your config:
295
+
296
+ ```toml
297
+ [poll]
298
+ repos = ["frappe/erpnext", "frappe/frappe"]
299
+ ```
300
+
301
+ Then set it up:
302
+
303
+ ```bash
304
+ # Seed state with current releases (so existing ones aren't reprocessed)
305
+ pretty-release-notes poll --seed
306
+
307
+ # Install a cron job that polls every 15 minutes
308
+ pretty-release-notes poll --install-cron
309
+ ```
310
+
311
+ You can also run a single poll cycle manually:
312
+
313
+ ```bash
314
+ pretty-release-notes poll
315
+ ```
316
+
317
+ The poll command uses the same config, database, and filters as `generate`. Processed releases are tracked in `~/.pretty-release-notes/processed_releases.json`.
318
+
319
+ ## Authors and Reviewers
320
+
321
+ The authors and reviewers of the PRs are added to the release notes.
322
+
323
+ - An author who reviewed or merged their own PR or backport is not a reviewer.
324
+ - A non-author who reviewed or merged someone else's PR is a reviewer.
325
+ - The author of the original PR is also the author of the backport.
326
+
327
+ ## Backports
328
+
329
+ We try to use the same message for backports as for the original PR. For this, we look for `(backport #<number>)` _at the end_ of the PR title and check if we have existing messages for that PR in our database. If we do, we use the message for the original PR. If we don't, we create a new message for the backport.
330
+
331
+ This means that backports of backports are currently not supported / will get a new message. To get the same message, PRs must be a direct backport of the original PR.
332
+
333
+ ## Contributing
334
+
335
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, testing, code quality tools, and commit conventions.
@@ -0,0 +1,295 @@
1
+ Turn GitHub's auto-generated release notes into human-readable sentences.
2
+
3
+ Go from this:
4
+
5
+ ![Original](img/original.png)
6
+
7
+ To this:
8
+
9
+ ![Modified](img/modified.png)
10
+
11
+ ## Features
12
+
13
+ - **AI-Powered Summaries** - Converts technical PR titles into clear, user-friendly sentences
14
+ - **Smart Filtering** - Automatically excludes non-user-facing changes (chore, ci, refactor, test, style)
15
+ - **Revert Detection** - Automatically filters out PRs that were reverted within the same release
16
+ - **Backport Intelligence** - Reuses summaries from original PRs for backports, maintaining consistency
17
+ - **Author & Reviewer Attribution** - Credits human contributors while excluding bots
18
+ - **Intelligent Caching** - Stores generated summaries to avoid redundant API calls and reduce costs
19
+ - **Grouped Release Notes** - Optional grouping by conventional commit type (Features, Bug Fixes, Performance, etc.)
20
+ - **Multi-Mode Architecture** - Use as CLI tool, Python library, or REST API backend
21
+ - **Rich Context** - Incorporates PR descriptions, linked issues, and code diffs for accurate summaries
22
+ - **Interactive Setup** - Guided configuration with validation and migration from legacy formats
23
+
24
+ > [!NOTE]
25
+ > The default prompt is geared towards [ERPNext](https://github.com/frappe/erpnext) and the [Frappe Framework](https://github.com/frappe/frappe). If you want to use this for different projects, set your own `prompt_path` in `config.toml`.
26
+
27
+ ## Configuration
28
+
29
+ ### Interactive Setup (Recommended)
30
+
31
+ The easiest way to configure the tool is using the interactive setup command:
32
+
33
+ ```bash
34
+ pretty-release-notes setup
35
+ ```
36
+
37
+ This will:
38
+ - Guide you through all configuration options with helpful prompts
39
+ - Show sane defaults for each setting
40
+ - Create the config file at `~/.pretty-release-notes/config.toml`
41
+
42
+ **First-time migration from .env?** Use the `--migrate-env` flag:
43
+ ```bash
44
+ pretty-release-notes setup --migrate-env
45
+ ```
46
+ This will read your existing `.env` file and suggest those values as defaults.
47
+
48
+ ### Manual Setup
49
+
50
+ Alternatively, copy `config.toml.example` to `~/.pretty-release-notes/config.toml` and fill in your credentials:
51
+
52
+ ```bash
53
+ # Create config directory
54
+ mkdir -p ~/.pretty-release-notes
55
+
56
+ # Copy example config
57
+ cp config.toml.example ~/.pretty-release-notes/config.toml
58
+
59
+ # Edit with your credentials
60
+ nano ~/.pretty-release-notes/config.toml
61
+ ```
62
+
63
+ ### Configuration Format
64
+
65
+ The configuration file uses TOML format with sections for GitHub credentials, LLM settings, database caching, and filters. The canonical section name is `[llm]`, while the legacy `[openai]` section is still accepted for backward compatibility. Prefer fully qualified `provider:model` values such as `openai:gpt-4.1`; unqualified model names are still accepted and default to OpenAI for backward compatibility. You can also set `reasoning_effort` to `none`, `low`, `medium`, `high`, or `xhigh` for supported models/providers. See [`config.toml.example`](config.toml.example) for the complete structure and all available options.
66
+
67
+ You can override the config location using the `--config-path` flag.
68
+
69
+ ## Installation
70
+
71
+ ```bash
72
+ # Clone the repository
73
+ git clone https://github.com/barredterra/pretty_release_notes
74
+ cd pretty_release_notes
75
+
76
+ # Create virtual environment and install
77
+ python -m venv env
78
+ source env/bin/activate
79
+ pip install -e .
80
+ ```
81
+
82
+ ## Usage
83
+
84
+ ### CLI
85
+
86
+ After installation, you can use the CLI in several ways:
87
+
88
+ ```bash
89
+ # View all commands
90
+ pretty-release-notes --help
91
+
92
+ # Generate release notes
93
+ pretty-release-notes generate erpnext v15.38.4 # using owner from config.toml
94
+ pretty-release-notes generate --owner alyf-de banking v0.0.1
95
+
96
+ # Use a custom config file
97
+ pretty-release-notes generate --config-path /path/to/config.toml erpnext v15.38.4
98
+
99
+ # Specify custom comparison range
100
+ pretty-release-notes generate erpnext v15.38.4 --previous-tag v15.38.0
101
+
102
+ # Override reasoning effort for a single run
103
+ pretty-release-notes generate erpnext v15.38.4 --reasoning-effort high
104
+ ```
105
+
106
+ Example output:
107
+
108
+ ```markdown
109
+ ---- Original ----
110
+ ## What's Changed
111
+ * fix: list view and form status not same for purchase order (backport #43690) (backport #43692) by @mergify in https://github.com/frappe/erpnext/pull/43706
112
+
113
+
114
+ **Full Changelog**: https://github.com/frappe/erpnext/compare/v15.38.3...v15.38.4
115
+
116
+ ---- Modified ----
117
+ ## What's Changed
118
+ * Removes unnecessary decimal precision checks for _per_received_ and _per_billed_ fields in **Purchase Order**, so the list view status and form status remain consistent. https://github.com/frappe/erpnext/pull/43706
119
+
120
+
121
+ **Full Changelog**: https://github.com/frappe/erpnext/compare/v15.38.3...v15.38.4
122
+ **Authors**: @rohitwaghchaure
123
+ ```
124
+
125
+ ### Library Usage
126
+
127
+ You can also use `pretty_release_notes` as a Python library in your own projects:
128
+
129
+ ```python
130
+ from pretty_release_notes import ReleaseNotesBuilder
131
+
132
+ # Build a client with configuration
133
+ client = (
134
+ ReleaseNotesBuilder()
135
+ .with_github_token("ghp_your_token")
136
+ .with_llm(
137
+ "sk_your_key",
138
+ model="openai:gpt-4.1", # or model="anthropic:claude-sonnet-4-5"
139
+ reasoning_effort="medium",
140
+ )
141
+ .with_database("sqlite")
142
+ .with_filters(
143
+ exclude_types={"chore", "ci", "refactor"},
144
+ exclude_labels={"skip-release-notes"},
145
+ )
146
+ .build()
147
+ )
148
+
149
+ # Generate release notes
150
+ notes = client.generate_release_notes(
151
+ owner="frappe",
152
+ repo="erpnext",
153
+ tag="v15.38.4",
154
+ previous_tag_name="v15.38.0", # Optional: custom comparison range
155
+ )
156
+ print(notes)
157
+
158
+ # Optionally update on GitHub
159
+ client.update_github_release("frappe", "erpnext", "v15.38.4", notes)
160
+ ```
161
+
162
+ For more examples, see [`examples/library_usage.py`](examples/library_usage.py).
163
+
164
+ ### Web API
165
+
166
+ The tool can also be run as a REST API server for integration with web frontends.
167
+
168
+ #### Starting the Server
169
+
170
+ First, install the web dependencies:
171
+
172
+ ```bash
173
+ source env/bin/activate
174
+ pip install -e .[web]
175
+ ```
176
+
177
+ Then start the server:
178
+
179
+ ```bash
180
+ # Using uvicorn directly
181
+ python -m uvicorn pretty_release_notes.web.app:app --host 0.0.0.0 --port 8000
182
+
183
+ # Or using the provided server script
184
+ python -m pretty_release_notes.web.server
185
+ ```
186
+
187
+ The API will be available at `http://localhost:8000` with interactive documentation at `http://localhost:8000/docs`.
188
+
189
+ #### API Endpoints
190
+
191
+ **Health Check**
192
+ ```bash
193
+ curl http://localhost:8000/health
194
+ ```
195
+
196
+ **Create Release Notes Job**
197
+ ```bash
198
+ curl -X POST http://localhost:8000/generate \
199
+ -H "Content-Type: application/json" \
200
+ -d '{
201
+ "owner": "frappe",
202
+ "repo": "erpnext",
203
+ "tag": "v15.38.4",
204
+ "previous_tag_name": "v15.38.0",
205
+ "github_token": "ghp_your_token_here",
206
+ "llm_key": "sk-your_key_here",
207
+ "llm_model": "openai:gpt-4.1",
208
+ "reasoning_effort": "medium",
209
+ "exclude_types": ["chore", "ci", "refactor"],
210
+ "exclude_labels": ["skip-release-notes"],
211
+ "exclude_authors": ["dependabot[bot]"],
212
+ "no_read": false,
213
+ "no_write": false
214
+ }'
215
+ ```
216
+
217
+ Legacy `openai_key`, `openai_model`, and `openai_reasoning_effort` request fields are still accepted for backward compatibility. Use `no_database` to skip both cache reads and writes.
218
+
219
+ Response:
220
+ ```json
221
+ {
222
+ "job_id": "550e8400-e29b-41d4-a716-446655440000",
223
+ "status": "pending",
224
+ "created_at": "2025-01-19T10:30:00.000000"
225
+ }
226
+ ```
227
+
228
+ **Check Job Status**
229
+ ```bash
230
+ curl http://localhost:8000/jobs/{job_id}
231
+ ```
232
+
233
+ Response:
234
+ ```json
235
+ {
236
+ "job_id": "550e8400-e29b-41d4-a716-446655440000",
237
+ "status": "completed",
238
+ "created_at": "2025-01-19T10:30:00.000000",
239
+ "completed_at": "2025-01-19T10:30:15.000000",
240
+ "result": "## What's Changed\n* Fixed bug...",
241
+ "progress": [
242
+ {
243
+ "timestamp": "2025-01-19T10:30:05.000000",
244
+ "type": "success",
245
+ "message": "Downloaded PRs in 0.42 seconds."
246
+ }
247
+ ],
248
+ "error": null
249
+ }
250
+ ```
251
+
252
+ ### Automated Polling
253
+
254
+ Run release note generation automatically whenever a new release is published. Add the repos you want to watch to your config:
255
+
256
+ ```toml
257
+ [poll]
258
+ repos = ["frappe/erpnext", "frappe/frappe"]
259
+ ```
260
+
261
+ Then set it up:
262
+
263
+ ```bash
264
+ # Seed state with current releases (so existing ones aren't reprocessed)
265
+ pretty-release-notes poll --seed
266
+
267
+ # Install a cron job that polls every 15 minutes
268
+ pretty-release-notes poll --install-cron
269
+ ```
270
+
271
+ You can also run a single poll cycle manually:
272
+
273
+ ```bash
274
+ pretty-release-notes poll
275
+ ```
276
+
277
+ The poll command uses the same config, database, and filters as `generate`. Processed releases are tracked in `~/.pretty-release-notes/processed_releases.json`.
278
+
279
+ ## Authors and Reviewers
280
+
281
+ The authors and reviewers of the PRs are added to the release notes.
282
+
283
+ - An author who reviewed or merged their own PR or backport is not a reviewer.
284
+ - A non-author who reviewed or merged someone else's PR is a reviewer.
285
+ - The author of the original PR is also the author of the backport.
286
+
287
+ ## Backports
288
+
289
+ We try to use the same message for backports as for the original PR. For this, we look for `(backport #<number>)` _at the end_ of the PR title and check if we have existing messages for that PR in our database. If we do, we use the message for the original PR. If we don't, we create a new message for the backport.
290
+
291
+ This means that backports of backports are currently not supported / will get a new message. To get the same message, PRs must be a direct backport of the original PR.
292
+
293
+ ## Contributing
294
+
295
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, testing, code quality tools, and commit conventions.
@@ -0,0 +1,38 @@
1
+ """Pretty Release Notes - Transform GitHub release notes with AI."""
2
+
3
+ # Public API exports for library usage
4
+ from .api import ReleaseNotesBuilder, ReleaseNotesClient
5
+ from .core.config import (
6
+ DatabaseConfig,
7
+ FilterConfig,
8
+ GitHubConfig,
9
+ LLMConfig,
10
+ OpenAIConfig,
11
+ ReleaseNotesConfig,
12
+ )
13
+ from .core.interfaces import (
14
+ CompositeProgressReporter,
15
+ NullProgressReporter,
16
+ ProgressEvent,
17
+ ProgressReporter,
18
+ )
19
+
20
+ __version__ = "1.4.0"
21
+
22
+ __all__ = [
23
+ # Client classes
24
+ "ReleaseNotesBuilder",
25
+ "ReleaseNotesClient",
26
+ # Configuration
27
+ "ReleaseNotesConfig",
28
+ "GitHubConfig",
29
+ "LLMConfig",
30
+ "OpenAIConfig",
31
+ "DatabaseConfig",
32
+ "FilterConfig",
33
+ # Progress reporting
34
+ "ProgressReporter",
35
+ "ProgressEvent",
36
+ "NullProgressReporter",
37
+ "CompositeProgressReporter",
38
+ ]
@@ -0,0 +1,6 @@
1
+ """Entry point for running pretty_release_notes as a module."""
2
+
3
+ from .main import app
4
+
5
+ if __name__ == "__main__":
6
+ app()
@@ -0,0 +1 @@
1
+ """Adapters for integrating core abstractions with external systems."""