Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
544 Deprecation notice for API versions 1.0 to 2.0 (#554)
- Deprecation notices in response headers - Sunset notices in response headers - Documentation regarding monitoring of deprecation and sunsetting - Log warnings in case users call deprecated endpoints * Add and test deprecation warnings to API users Signed-off-by: F.N. Claessen <felix@seita.nl> * Provide deprecation information via headers instead of via JSON message, which is the approach recommended by the Internet Engineering Task Force (IETF) Signed-off-by: F.N. Claessen <felix@seita.nl> * API changelog entries Signed-off-by: F.N. Claessen <felix@seita.nl> * black Signed-off-by: F.N. Claessen <felix@seita.nl> * Log warning Signed-off-by: F.N. Claessen <felix@seita.nl> * Clean up Signed-off-by: F.N. Claessen <felix@seita.nl> * Add release notice for FlexMeasures hosts Signed-off-by: F.N. Claessen <felix@seita.nl> * Changelog entry Signed-off-by: F.N. Claessen <felix@seita.nl> * Fix header links Signed-off-by: F.N. Claessen <felix@seita.nl> * Also test asset API v2 Signed-off-by: F.N. Claessen <felix@seita.nl> * Add missing deprecation checks Signed-off-by: F.N. Claessen <felix@seita.nl> Signed-off-by: F.N. Claessen <felix@seita.nl>
- Loading branch information
Showing
28 changed files
with
299 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
from __future__ import annotations | ||
|
||
from flask import current_app, request, Blueprint, Response | ||
from flask_security.core import current_user | ||
import pandas as pd | ||
|
||
from flexmeasures.utils.time_utils import to_http_time | ||
|
||
|
||
def deprecate_blueprint( | ||
blueprint: Blueprint, | ||
deprecation_date: pd.Timestamp | str | None = None, | ||
deprecation_link: str | None = None, | ||
sunset_date: pd.Timestamp | str | None = None, | ||
sunset_link: str | None = None, | ||
): | ||
"""Deprecates every route on a blueprint by adding the "Deprecation" header with a deprecation date. | ||
>>> from flask import Flask, Blueprint | ||
>>> app = Flask('some_app') | ||
>>> deprecated_bp = Blueprint('API version 1', 'v1_bp') | ||
>>> app.register_blueprint(deprecated_bp, url_prefix='/v1') | ||
>>> deprecate_blueprint( | ||
deprecated_bp, | ||
deprecation_date="2022-12-14", | ||
deprecation_link="https://flexmeasures.readthedocs.org/some-deprecation-notice", | ||
sunset_date="2023-02-01", | ||
sunset_link="https://flexmeasures.readthedocs.org/some-sunset-notice", | ||
) | ||
:param blueprint: The blueprint to be deprecated | ||
:param deprecation_date: date indicating when the API endpoint was deprecated, used for the "Deprecation" header | ||
if no date is given, defaults to "true" | ||
see https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-deprecation-header#section-2-1 | ||
:param deprecation_link: url providing more information about the deprecation | ||
:param sunset_date: date indicating when the API endpoint is likely to become unresponsive | ||
:param sunset_link: url providing more information about the sunset | ||
References | ||
---------- | ||
- Deprecation field: https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-deprecation-header | ||
- Sunset field: https://www.rfc-editor.org/rfc/rfc8594 | ||
""" | ||
if deprecation_date: | ||
deprecation = to_http_time(pd.Timestamp(deprecation_date) - pd.Timedelta("1s")) | ||
else: | ||
deprecation = "true" | ||
if sunset_date: | ||
sunset = to_http_time(pd.Timestamp(sunset_date) - pd.Timedelta("1s")) | ||
|
||
def _after_request_handler(response: Response) -> Response: | ||
return _add_headers( | ||
response, | ||
deprecation, | ||
deprecation_link, | ||
sunset, | ||
sunset_link, | ||
) | ||
|
||
blueprint.after_request(_after_request_handler) | ||
|
||
|
||
def _add_headers( | ||
response: Response, | ||
deprecation: str, | ||
deprecation_link: str | None, | ||
sunset: str | None, | ||
sunset_link: str | None, | ||
) -> Response: | ||
response.headers["Deprecation"] = deprecation | ||
if sunset: | ||
response.headers["Sunset"] = sunset | ||
if deprecation_link: | ||
response = _add_link(response, deprecation_link, "deprecation") | ||
if sunset_link: | ||
response = _add_link(response, sunset_link, "sunset") | ||
current_app.logger.warning( | ||
f"Deprecated endpoint {request.endpoint} called by {current_user}" | ||
) | ||
return response | ||
|
||
|
||
def _add_link(response: Response, link: str, rel: str) -> Response: | ||
link_text = f'<{link}>; rel="{rel}"; type="text/html"' | ||
if response.headers.get("Link"): | ||
response.headers["Link"] += f", {link_text}" | ||
else: | ||
response.headers["Link"] = link_text | ||
return response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.