specshift 1.0.0__py3-none-any.whl

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,340 @@
1
+ Metadata-Version: 2.4
2
+ Name: specshift
3
+ Version: 1.0.0
4
+ Summary: Detects, classifies, and optionally summarizes breaking changes in OpenAPI/Swagger contracts using AI
5
+ Author: Lethe044
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Lethe044/specshift
8
+ Project-URL: Repository, https://github.com/Lethe044/specshift
9
+ Project-URL: Issues, https://github.com/Lethe044/specshift/issues
10
+ Project-URL: Changelog, https://github.com/Lethe044/specshift/blob/main/CHANGELOG.md
11
+ Keywords: openapi,swagger,api,breaking-changes,contract-testing,api-diff,devtools,cli,ci-cd
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Software Development :: Testing
24
+ Classifier: Topic :: Software Development :: Quality Assurance
25
+ Classifier: Topic :: Internet :: WWW/HTTP
26
+ Requires-Python: >=3.9
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: pyyaml>=6.0
30
+ Requires-Dist: requests>=2.28
31
+ Provides-Extra: pretty
32
+ Requires-Dist: rich>=13.0; extra == "pretty"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.4; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
36
+ Requires-Dist: responses>=0.23; extra == "dev"
37
+ Requires-Dist: rich>=13.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # SpecShift
41
+
42
+ [![CI](https://github.com/Lethe044/specshift/actions/workflows/ci.yml/badge.svg)](https://github.com/Lethe044/specshift/actions/workflows/ci.yml)
43
+ [![PyPI version](https://img.shields.io/pypi/v/specshift.svg)](https://pypi.org/project/specshift/)
44
+ [![Python versions](https://img.shields.io/pypi/pyversions/specshift.svg)](https://pypi.org/project/specshift/)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
46
+
47
+ SpecShift detects changes in OpenAPI and Swagger contracts, classifies each
48
+ one as breaking, warning, or info, and can optionally summarize them in
49
+ plain language.
50
+
51
+ When an API changes from one version to the next, the real question isn't
52
+ "what changed" but "will this break me". SpecShift is built to answer
53
+ exactly that: it takes two specifications, evaluates every difference
54
+ between them individually, and tells you which ones actually matter.
55
+
56
+ ```
57
+ $ specshift diff examples/old_api.yaml examples/new_api.yaml
58
+
59
+ Bookstore API : 1.0.0 -> 2.0.0
60
+ 13 breaking, 2 warning, 3 info changes found.
61
+
62
+ [BREAKING] DELETE /books/{bookId} :: HTTP method removed
63
+ [BREAKING] GET /books > parameter 'category' :: Parameter 'category' is now required
64
+ [BREAKING] GET /books > response 200 > field 'author' :: field removed from response
65
+ ...
66
+
67
+ Result: 13 breaking change(s) make this update risky.
68
+ ```
69
+
70
+ ## Why SpecShift
71
+
72
+ Every team that keeps evolving its API eventually hits the same problem:
73
+ a field gets removed, a parameter becomes required, an enum value
74
+ disappears, and nobody notices until a client breaks in production.
75
+ Most existing diff tools just show you a raw JSON diff and leave it up to
76
+ you to figure out what actually matters.
77
+
78
+ SpecShift doesn't do that. It evaluates every change based on its context:
79
+
80
+ - Removing a field from a **response** is **breaking**, because clients
81
+ may depend on it being there.
82
+ - Removing the same field from a **request body** is usually just a
83
+ **warning**, because clients that send it are simply ignored, not broken.
84
+ - Adding a new required field to a request is **breaking**, but adding a
85
+ new field to a response is just **informational**.
86
+
87
+ These context-aware rules are the core of SpecShift, and they work
88
+ completely free, with no API key required. The optional AI-powered
89
+ natural-language summary is an additional layer on top, never a
90
+ requirement.
91
+
92
+ ## Features
93
+
94
+ - **Comprehensive structural diff**: deep comparison at the path, HTTP
95
+ method, parameter, request body, response, and schema level.
96
+ - **Context-aware classification**: the same change is weighted
97
+ differently depending on whether it occurs in a request or a response.
98
+ - **`$ref` resolution and `allOf` merging**: correctly follows the
99
+ reference and composition patterns common in real-world specifications.
100
+ - **Detects enum, format, nullable, and security scheme changes**.
101
+ - **Works entirely for free**: no API key or paid service is required.
102
+ - **Optional AI summary**: can generate a natural-language summary using
103
+ Groq, the Gemini free tier, or any OpenAI-compatible endpoint. If no key
104
+ is set, it automatically falls back to a rule-based summary and never
105
+ stops working.
106
+ - **CI/CD integration**: the `specshift check` command compares the
107
+ current specification against a branch and fails the build if a
108
+ breaking change is found.
109
+ - **Live monitoring**: the `specshift watch` command periodically checks
110
+ a remote API's specification and sends a Slack or Discord notification
111
+ when it changes.
112
+ - **Three output formats**: a colored console table, a Markdown report
113
+ (ideal for PR comments), and JSON (for integrating with other tools).
114
+
115
+ ## Installation
116
+
117
+ ```bash
118
+ pip install specshift
119
+ ```
120
+
121
+ For colored console output (optional, works fine without it too):
122
+
123
+ ```bash
124
+ pip install "specshift[pretty]"
125
+ ```
126
+
127
+ Installing from source:
128
+
129
+ ```bash
130
+ git clone https://github.com/Lethe044/specshift.git
131
+ cd specshift
132
+ pip install -e .
133
+ ```
134
+
135
+ ## Quick start
136
+
137
+ Compare two specifications directly:
138
+
139
+ ```bash
140
+ specshift diff old_openapi.yaml new_openapi.yaml
141
+ ```
142
+
143
+ You can also compare specifications from URLs:
144
+
145
+ ```bash
146
+ specshift diff https://api.example.com/v1/openapi.json https://api.example.com/v2/openapi.json
147
+ ```
148
+
149
+ To use it in CI, create a configuration file in your repo:
150
+
151
+ ```bash
152
+ specshift init
153
+ ```
154
+
155
+ This produces a `.specshift.yml` file similar to:
156
+
157
+ ```yaml
158
+ spec_path: openapi.yaml
159
+ base_ref: main
160
+ fail_on: breaking
161
+ ```
162
+
163
+ Then, in your CI pipeline:
164
+
165
+ ```bash
166
+ specshift check
167
+ ```
168
+
169
+ This command compares the current `openapi.yaml` file against its version
170
+ on the `main` branch and returns exit code 1 if a breaking change is found.
171
+
172
+ ## AI summary (optional)
173
+
174
+ SpecShift can use free-tier AI services to generate a natural-language
175
+ summary of the changes. This never requires any payment:
176
+
177
+ ```bash
178
+ export GROQ_API_KEY="your-groq-api-key"
179
+ specshift diff old.yaml new.yaml --ai
180
+ ```
181
+
182
+ You can also use Google Gemini's free tier instead of Groq:
183
+
184
+ ```bash
185
+ export GEMINI_API_KEY="your-gemini-api-key"
186
+ specshift diff old.yaml new.yaml --ai --ai-provider gemini
187
+ ```
188
+
189
+ If you want to use a more powerful (paid) model, you can connect any
190
+ OpenAI-compatible endpoint:
191
+
192
+ ```bash
193
+ export SPECSHIFT_API_KEY="your-api-key"
194
+ export SPECSHIFT_OPENAI_BASE_URL="https://api.openai.com/v1"
195
+ specshift diff old.yaml new.yaml --ai --ai-provider openai_compatible --ai-model gpt-4o-mini
196
+ ```
197
+
198
+ If no key is configured, the `--ai` flag still works, it simply produces a
199
+ rule-based summary instead of waiting on a network call. AI support is an
200
+ optional enhancement, never a requirement.
201
+
202
+ ## Commands
203
+
204
+ ### `specshift diff <old> <new>`
205
+
206
+ Compares two specifications. `<old>` and `<new>` can be a file path, an
207
+ http(s) URL, or raw JSON/YAML text.
208
+
209
+ Useful options:
210
+
211
+ | Option | Description |
212
+ |---|---|
213
+ | `--format console\|markdown\|json` | Output format (default: console) |
214
+ | `--output <file>` | Writes the output to a file |
215
+ | `--ai` | Adds a natural-language summary |
216
+ | `--ai-provider groq\|gemini\|openai_compatible` | Chooses the AI provider |
217
+ | `--fail-on breaking\|warning\|none` | Determines at which level exit code 1 is returned |
218
+ | `--quiet` | Only prints the summary line |
219
+
220
+ ### `specshift check`
221
+
222
+ Designed for CI/CD. Compares the current specification file against a git
223
+ reference (branch, tag, or commit) defined in `.specshift.yml`.
224
+
225
+ ```bash
226
+ specshift check --spec openapi.yaml --base-ref origin/main
227
+ ```
228
+
229
+ ### `specshift watch <url>`
230
+
231
+ Periodically checks a remote specification, compares it against the
232
+ previous snapshot, and sends a notification if a difference is found.
233
+
234
+ ```bash
235
+ specshift watch https://api.example.com/openapi.json \
236
+ --interval 600 \
237
+ --slack-webhook "$SLACK_WEBHOOK_URL"
238
+ ```
239
+
240
+ ### `specshift init`
241
+
242
+ Creates a sample `.specshift.yml` file.
243
+
244
+ ## Using it with GitHub Actions
245
+
246
+ The workflow below checks your API contract against the `main` branch on
247
+ every pull request and fails the build if a breaking change is found:
248
+
249
+ ```yaml
250
+ name: API Contract Check
251
+
252
+ on:
253
+ pull_request:
254
+ paths:
255
+ - "openapi.yaml"
256
+
257
+ jobs:
258
+ contract-check:
259
+ runs-on: ubuntu-latest
260
+ steps:
261
+ - uses: actions/checkout@v4
262
+ with:
263
+ fetch-depth: 0
264
+
265
+ - uses: actions/setup-python@v5
266
+ with:
267
+ python-version: "3.12"
268
+
269
+ - run: pip install specshift
270
+
271
+ - run: specshift check --base-ref origin/${{ github.base_ref }}
272
+ ```
273
+
274
+ If you want to add AI-powered PR comments, you can generate a Markdown
275
+ report with `specshift check --ai --format markdown --output report.md`
276
+ and post it as a PR comment using an action like
277
+ `peter-evans/create-or-update-comment`.
278
+
279
+ ## Configuration file (`.specshift.yml`)
280
+
281
+ ```yaml
282
+ spec_path: openapi.yaml
283
+ base_ref: main
284
+ fail_on: breaking
285
+
286
+ # optional
287
+ ai_provider: groq
288
+ ai_model: llama-3.3-70b-versatile
289
+ slack_webhook: https://hooks.slack.com/services/...
290
+ discord_webhook: https://discord.com/api/webhooks/...
291
+ ignore_paths: []
292
+ ```
293
+
294
+ ## When SpecShift calls something breaking
295
+
296
+ The table below summarizes which severity level applies in the most
297
+ common scenarios:
298
+
299
+ | Change | In a request | In a response |
300
+ |---|---|---|
301
+ | Field removed | Warning | Breaking |
302
+ | New required field added | Breaking | Info |
303
+ | New optional field added | Info | Info |
304
+ | Field no longer required | Info | Breaking |
305
+ | Field became required | Breaking | Info |
306
+ | Data type changed | Breaking | Breaking |
307
+ | Enum value removed | Breaking | Breaking |
308
+ | Endpoint or method removed | Breaking | Breaking |
309
+
310
+ ## Comparison with other tools
311
+
312
+ | | SpecShift | Raw JSON/YAML diff | oasdiff / openapi-diff style tools |
313
+ |---|---|---|---|
314
+ | Context-aware classification | Yes | No | Partially |
315
+ | Natural-language summary | Yes (optional) | No | No |
316
+ | Free to use | Fully free | Free | Usually free |
317
+ | CI integration | Built-in (`check`) | Manual | Varies |
318
+ | Live URL monitoring | Built-in (`watch`) | No | Rarely |
319
+
320
+ ## Roadmap
321
+
322
+ This project is under active development. Some planned areas:
323
+
324
+ - Support for gRPC/Protobuf contracts
325
+ - GraphQL schema diffing
326
+ - An official GitHub Action for posting automatic PR comments
327
+ - A web-based result viewer
328
+ - More semantic rules (path parameter pattern changes, content-type
329
+ changes, etc.)
330
+
331
+ Feel free to open an issue if you have a feature request.
332
+
333
+ ## Contributing
334
+
335
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution guide. Bug
336
+ reports, feature requests, and pull requests are always welcome.
337
+
338
+ ## License
339
+
340
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,16 @@
1
+ specshift/__init__.py,sha256=WhfM6D8G0Sx3mudCYAL63EhUWPzExzs84ahGag_1U8s,449
2
+ specshift/ai_summary.py,sha256=li5reA59j0tcm8gsf4UzcWI0UTmLcz4h2WlVuVHY81I,7397
3
+ specshift/cli.py,sha256=87mQ3Zjr5bnfigiOU_6tRUl5hzjn8nwTCBdHuRS3sm0,9606
4
+ specshift/config.py,sha256=bb7dQqUrx9ST8ww_YARxakq7_oeIp5u8lK9fHnQB7Bw,2662
5
+ specshift/differ.py,sha256=TOC_zzGEBW6Oxx4BetZagDEzwof5nong4C2H9scErZY,24748
6
+ specshift/git_utils.py,sha256=Z5dPC5LcrYq7n8F1fkgtZLNwpCYG0UyAp9y3Z0ODRqI,2626
7
+ specshift/models.py,sha256=7u76KMroItXKJbBY2_bWlKwRDzU8SdPukqDAw05rKEk,2950
8
+ specshift/notifier.py,sha256=3XJ8TjDmKGG1pOvZSrGKMhYrt3QgH9dNbZaBL-eHsdo,2387
9
+ specshift/reporter.py,sha256=5ZrUC4dVOmEGfk1ZxCmouwhVnbfuxIpK9jrPZkRVesw,5645
10
+ specshift/spec_loader.py,sha256=xqv4kBjhtD3Nns84iaowanjmf6X4OW-tdo4yJ6Bmku0,3582
11
+ specshift-1.0.0.dist-info/licenses/LICENSE,sha256=LswL_P6JxYnEs6eJjWIaEM0PJmLHTA-zcPuGzvd1Xvs,1065
12
+ specshift-1.0.0.dist-info/METADATA,sha256=yFNx5PP6e5qsEpRKZ-Q1NOTszDzhUGi3A_27QDEzl34,11061
13
+ specshift-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
14
+ specshift-1.0.0.dist-info/entry_points.txt,sha256=pVttt0AJt7aKriUe-AAwQKb86OkAMOJQ6xN-LwDeFSA,49
15
+ specshift-1.0.0.dist-info/top_level.txt,sha256=NShpKE9TRznqbG3NqkCPGi0ZKKCm68JoPnjp77IRCy4,10
16
+ specshift-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ specshift = specshift.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lethe044
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 @@
1
+ specshift