diff --git a/CHANGELOG.md b/CHANGELOG.md index 891f7b3..2feb7af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.0] - 2020-09-21 +### Added +- `keepachangelog.flask_restx.add_changelog_endpoint` function to add a changelog endpoint to a [Flask-RestX](https://flask-restx.readthedocs.io/en/latest/) application. + ## [0.3.1] - 2020-07-13 ### Fixed - Keep star character at the end of a line as it can be used to mark as italic. @@ -26,7 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release. -[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v0.3.1...HEAD +[Unreleased]: https://github.com/Colin-b/keepachangelog/compare/v0.4.0...HEAD +[0.4.0]: https://github.com/Colin-b/keepachangelog/compare/v0.3.1...v0.4.0 [0.3.1]: https://github.com/Colin-b/keepachangelog/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/Colin-b/keepachangelog/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/Colin-b/keepachangelog/compare/v0.1.0...v0.2.0 diff --git a/README.md b/README.md index 491adfb..571ea24 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Build status Coverage Code style: black -Number of tests +Number of tests Number of downloads

@@ -133,6 +133,24 @@ add_changelog_endpoint(app, "path/to/CHANGELOG.md") Note: [starlette](https://pypi.python.org/pypi/starlette) module must be installed. +### Flask-RestX + +An helper function is available to create a [Flask-RestX](https://flask-restx.readthedocs.io/en/latest/) endpoint to retrieve changelog as JSON. + +```python +import flask +import flask_restx +from keepachangelog.flask_restx import add_changelog_endpoint + + +app = flask.Flask(__name__) +api = flask_restx.Api(app) +# /changelog endpoint will return the dict extracted from the changelog as JSON. +add_changelog_endpoint(api, "path/to/CHANGELOG.md") +``` + +Note: [flask-restx](https://pypi.python.org/pypi/flask-restx) module must be installed. + ## How to install 1. [python 3.6+](https://www.python.org/downloads/) must be installed 2. Use pip to install module: diff --git a/keepachangelog/flask_restx.py b/keepachangelog/flask_restx.py new file mode 100644 index 0000000..3e2710c --- /dev/null +++ b/keepachangelog/flask_restx.py @@ -0,0 +1,78 @@ +from typing import Union + +import flask_restx +import flask + +from keepachangelog._changelog import to_dict + + +def add_changelog_endpoint( + namespace: Union[flask_restx.Namespace, flask_restx.Api], changelog_path: str +): + """ + Create /changelog: Changelog endpoint parsing https://keepachangelog.com/en/1.0.0/ + + :param namespace: The Flask-RestX namespace. + :param changelog_path: Path to CHANGELOG.md. + """ + + @namespace.route("/changelog") + @namespace.doc( + responses={ + 200: ( + "Service changelog.", + [ + namespace.model( + "ChangelogReleaseModel", + { + "version": flask_restx.fields.String( + description="Release version following semantic versioning.", + required=True, + example="3.12.5", + ), + "release_date": flask_restx.fields.Date( + description="Release date.", + required=True, + example="2019-12-31", + ), + "added": flask_restx.fields.List( + flask_restx.fields.String(description="New features.") + ), + "changed": flask_restx.fields.List( + flask_restx.fields.String( + description="Changes in existing functionaliy." + ) + ), + "deprecated": flask_restx.fields.List( + flask_restx.fields.String( + description="Soon-to-be removed features." + ) + ), + "removed": flask_restx.fields.List( + flask_restx.fields.String( + description="Removed features." + ) + ), + "fixed": flask_restx.fields.List( + flask_restx.fields.String(description="Any bug fixes.") + ), + "security": flask_restx.fields.List( + flask_restx.fields.String( + description="Vulnerabilities." + ) + ), + }, + ) + ], + ) + } + ) + class Changelog(flask_restx.Resource): + def get(self): + """ + Retrieve service changelog. + """ + try: + return flask.jsonify(to_dict(changelog_path)) + except FileNotFoundError: + return flask.jsonify({}) diff --git a/keepachangelog/version.py b/keepachangelog/version.py index 2d79c2c..151e68f 100644 --- a/keepachangelog/version.py +++ b/keepachangelog/version.py @@ -3,4 +3,4 @@ # Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0) # Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0) # Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9) -__version__ = "0.3.1" +__version__ = "0.4.0" diff --git a/setup.py b/setup.py index b314b92..8931555 100644 --- a/setup.py +++ b/setup.py @@ -38,8 +38,10 @@ extras_require={ "testing": [ # Used to check starlette endpoint + "requests", "starlette==0.13.*", - "requests==2.*", + # Used to check flask-restx endpoint + "flask-restx==0.2.*", # Used to check coverage "pytest-cov==2.*", ] diff --git a/tests/test_flask_restx.py b/tests/test_flask_restx.py new file mode 100644 index 0000000..7c850a9 --- /dev/null +++ b/tests/test_flask_restx.py @@ -0,0 +1,116 @@ +import os + +import flask +import flask_restx + +from keepachangelog.flask_restx import add_changelog_endpoint + + +def test_changelog_endpoint_with_file(tmpdir): + changelog_file_path = os.path.join(tmpdir, "CHANGELOG.md") + with open(changelog_file_path, "wt") as file: + file.write( + """# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +### Changed +- Release note 1. +- Release note 2. + +### Added +- Enhancement 1 +- sub enhancement 1 +- sub enhancement 2 +- Enhancement 2 + +### Fixed +- Bug fix 1 +- sub bug 1 +- sub bug 2 +- Bug fix 2 + +### Security +- Known issue 1 +- Known issue 2 + +### Deprecated +- Deprecated feature 1 +- Future removal 2 + +### Removed +- Deprecated feature 2 +- Future removal 1 + +## [1.1.0] - 2018-05-31 +### Changed +- Enhancement 1 (1.1.0) +- sub enhancement 1 +- sub enhancement 2 +- Enhancement 2 (1.1.0) + +## [1.0.1] - 2018-05-31 +### Fixed +- Bug fix 1 (1.0.1) +- sub bug 1 +- sub bug 2 +- Bug fix 2 (1.0.1) + +## [1.0.0] - 2017-04-10 +### Deprecated +- Known issue 1 (1.0.0) +- Known issue 2 (1.0.0) + +[Unreleased]: https://github.test_url/test_project/compare/v1.1.0...HEAD +[1.1.0]: https://github.test_url/test_project/compare/v1.0.1...v1.1.0 +[1.0.1]: https://github.test_url/test_project/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.test_url/test_project/releases/tag/v1.0.0 +""" + ) + + app = flask.Flask(__name__) + api = flask_restx.Api(app) + add_changelog_endpoint(api, changelog_file_path) + with app.test_client() as client: + response = client.get("/changelog") + assert response.status_code == 200 + assert response.json == { + "1.1.0": { + "changed": [ + "Enhancement 1 (1.1.0)", + "sub enhancement 1", + "sub enhancement 2", + "Enhancement 2 (1.1.0)", + ], + "release_date": "2018-05-31", + "version": "1.1.0", + }, + "1.0.1": { + "fixed": [ + "Bug fix 1 (1.0.1)", + "sub bug 1", + "sub bug 2", + "Bug fix 2 (1.0.1)", + ], + "release_date": "2018-05-31", + "version": "1.0.1", + }, + "1.0.0": { + "deprecated": ["Known issue 1 (1.0.0)", "Known issue 2 (1.0.0)"], + "release_date": "2017-04-10", + "version": "1.0.0", + }, + } + + +def test_changelog_endpoint_without_file(): + app = flask.Flask(__name__) + api = flask_restx.Api(app) + add_changelog_endpoint(api, "non existing") + with app.test_client() as client: + response = client.get("/changelog") + assert response.status_code == 200 + assert response.json == {}