From 988124bab376dc832cfc348249e566abc5fd68fc Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Mon, 21 Sep 2020 19:07:46 +0200
Subject: [PATCH 1/2] Add a flask-restx endpoint
---
CHANGELOG.md | 7 +-
README.md | 20 +++++-
keepachangelog/flask_restx.py | 78 +++++++++++++++++++++++
keepachangelog/version.py | 2 +-
setup.py | 3 +-
tests/test_flask_restx.py | 116 ++++++++++++++++++++++++++++++++++
6 files changed, 222 insertions(+), 4 deletions(-)
create mode 100644 keepachangelog/flask_restx.py
create mode 100644 tests/test_flask_restx.py
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 @@
-
+
@@ -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..d3ea86d 100644
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,8 @@
"testing": [
# Used to check starlette endpoint
"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 == {}
From 293aa869ee52abcb5ae6a725834960549fdc8d63 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Mon, 21 Sep 2020 19:11:05 +0200
Subject: [PATCH 2/2] Add back requests as a testing requirement for starlette
test client
---
setup.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/setup.py b/setup.py
index d3ea86d..8931555 100644
--- a/setup.py
+++ b/setup.py
@@ -38,6 +38,7 @@
extras_require={
"testing": [
# Used to check starlette endpoint
+ "requests",
"starlette==0.13.*",
# Used to check flask-restx endpoint
"flask-restx==0.2.*",