Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Flask v3 #2484

Merged
merged 6 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ 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).

## [8.0.1]

### Fixed
- Upgrade from `flask==2.2.5` to `Flask==3.0.3`. Fixes a bug in which Dependabot was not tracking Flask upgrades because we specified the dependency name as lowercase.
- Specify our custom JSON encoder by subclassing `flask.json.provider.JSONProvider`. See <https://github.com/pallets/flask/pull/4692>

## [8.0.0]

### Added
Expand Down
14 changes: 13 additions & 1 deletion apps/api/src/hyp3_api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import yaml
from flask import abort, g, jsonify, make_response, redirect, render_template, request
from flask.json.provider import JSONProvider
from flask_cors import CORS
from openapi_core import OpenAPI
from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator
Expand Down Expand Up @@ -87,13 +88,24 @@ def default(self, o):

if isinstance(o, datetime.date):
return o.isoformat()

if isinstance(o, Decimal):
if o == int(o):
return int(o)
return float(o)

# Raises a TypeError
json.JSONEncoder.default(self, o)


class CustomJSONProvider(JSONProvider):
def dumps(self, o):
return json.dumps(o, cls=CustomEncoder)

def loads(self, s):
return json.loads(s)


class ErrorHandler(FlaskOpenAPIErrorsHandler):
def __init__(self):
super().__init__()
Expand All @@ -104,7 +116,7 @@ def __call__(self, errors):
return handlers.problem_format(error['status'], error['title'])


app.json_encoder = CustomEncoder
app.json = CustomJSONProvider(app)

openapi = FlaskOpenAPIViewDecorator(
api_spec,
Expand Down
3 changes: 2 additions & 1 deletion requirements-apps-api.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
flask==2.2.5
# TODO: verify that dependabot bumps to Flask 3.0.3 on Monday
Flask==3.0.2
Flask-Cors==5.0.0
jsonschema==4.23.0
openapi-core==0.19.4
Expand Down
6 changes: 3 additions & 3 deletions tests/test_api/test_patch_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_patch_new_user(client, tables):
assert response.json == {
'user_id': 'foo',
'application_status': APPLICATION_PENDING,
'remaining_credits': Decimal(0),
'remaining_credits': 0,
'job_names': [],
'use_case': 'I want data.',
}
Expand All @@ -45,7 +45,7 @@ def test_patch_pending_user(client, tables):
assert response.status_code == HTTPStatus.OK
assert response.json == {
'user_id': 'foo',
'remaining_credits': Decimal(0),
'remaining_credits': 0,
'application_status': APPLICATION_PENDING,
'use_case': 'New use case.',
'job_names': [],
Expand Down Expand Up @@ -92,7 +92,7 @@ def test_patch_user_access_code(client, tables):
assert response.json == {
'user_id': 'foo',
'application_status': APPLICATION_APPROVED,
'remaining_credits': Decimal(25),
'remaining_credits': 25,
'job_names': [],
'use_case': 'I want data.',
'access_code': '123',
Expand Down