Skip to content

Commit 4252983

Browse files
Make updates for Python 3.12 & update various packages to their latest versions (#206)
## Ticket #205 ## Changes Make package updates to make Python 3.12 work without warnings ## Context for reviewers Package updates were done via `poetry add <package>@latest [--group dev]` (the group being included for dev dependencies). I did skim the changelogs for any of the libraries we updated, at least the major versions to see if there was anything signficantly breaking, but most of the packages are pretty minimal in changes (bug fixes, small feature updates). The package updates fall into a few categories: 1. Broken due to new version of Python (cffi was the main one) 2. Warnings through linting or pytest deprecation warnings - newer package versions had corrected the issue (SQLAlchemy, APIFlask, pytz, pytest, mypy) 3. Package only had a few minor updates, figured we might as well update (alembic, isort, flake8, Faker, factory-boy) The only package of note that I didn't update was Pydantic, which I'll do in a follow-up as I know it has several breaking changes. This also resolves a few Dependabot alerts for the gitpython, cryptography and urllib3 packages (package.lock has been updated to have the latest version for each of those past the required ones). ## Testing Running `make format lint test` both inside and outside of the Docker container to verify that there are no issues reported / pytest warnings given. Will verify that this builds as well in CI successfully when the PR is created / later merged. --------- Co-authored-by: nava-platform-bot <[email protected]>
1 parent 58610f4 commit 4252983

File tree

14 files changed

+1065
-862
lines changed

14 files changed

+1065
-862
lines changed

app/.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.11
1+
3.12

app/openapi.generated.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ components:
239239
properties:
240240
type:
241241
description: The name of the role
242+
enum:
243+
- USER
244+
- ADMIN
242245
User:
243246
type: object
244247
properties:

app/poetry.lock

Lines changed: 1022 additions & 824 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/pyproject.toml

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,38 @@ authors = ["Nava Engineering <[email protected]>"]
77

88
[tool.poetry.dependencies]
99
python = "^3.10"
10-
SQLAlchemy = {extras = ["mypy"], version = "2.0"}
11-
alembic = "^1.8.1"
10+
SQLAlchemy = {version = "^2.0.21", extras = ["mypy"]}
11+
alembic = "^1.12.0"
1212
python-dotenv = "^0.20.0"
1313
pydantic = "^1.10.0"
14-
botocore = "^1.27.67"
15-
boto3 = "~1.24.67"
14+
botocore = "^1.31.62"
15+
boto3 = "^1.28.62"
1616
smart-open = "^6.1.0"
17-
pytz = "^2022.2.1"
18-
APIFlask = "^1.1.3"
17+
pytz = "^2023.3.post1"
18+
APIFlask = "^2.0.2"
1919
marshmallow-dataclass = {extras = ["enum", "union"], version = "^8.5.8"}
20-
marshmallow = "^3.18.0"
20+
marshmallow = "^3.20.1"
2121
gunicorn = "^21.2.0"
2222
psycopg = {extras = ["binary"], version = "^3.1.10"}
2323

2424
[tool.poetry.group.dev.dependencies]
25-
black = "^22.6.0"
26-
flake8 = "^5.0.4"
27-
flake8-bugbear = "^22.8.23"
25+
black = "^23.9.1"
26+
flake8 = "^6.1.0"
27+
flake8-bugbear = "^23.9.16"
2828
flake8-alfred = "^1.1.1"
29-
isort = "^5.10.1"
30-
mypy = "^0.971"
29+
isort = "^5.12.0"
30+
mypy = "^1.5.1"
3131
moto = {extras = ["s3"], version = "^4.0.2"}
32-
types-pytz = "^2022.2.1"
33-
coverage = "^6.4.4"
34-
Faker = "^14.2.0"
35-
factory-boy = "^3.2.1"
36-
bandit = "^1.7.4"
37-
pytest = "^6.0.0"
32+
types-pytz = "^2023.3.1.1"
33+
coverage = "^7.3.2"
34+
Faker = "^19.8.0"
35+
factory-boy = "^3.3.0"
36+
bandit = "^1.7.5"
37+
pytest = "^7.4.2"
3838
pytest-watch = "^4.2.0"
3939
pytest-lazy-fixture = "^0.6.3"
4040
types-pyyaml = "^6.0.12.11"
41+
setuptools = "^68.2.2"
4142

4243
[build-system]
4344
requires = ["poetry-core>=1.0.0"]
@@ -81,6 +82,8 @@ warn_redundant_casts = true
8182
warn_unreachable = true
8283
warn_unused_ignores = true
8384

85+
plugins = ["pydantic.mypy"]
86+
8487
[tool.bandit]
8588
# Ignore audit logging test file since test audit logging requires a lot of operations that trigger bandit warnings
8689
exclude_dirs = ["./tests/src/logging/test_audit.py"]
@@ -98,9 +101,7 @@ disallow_untyped_defs = false
98101
# When a library has addressed its deprecation issues and we've updated the
99102
# library, we can remove the ignore filter for that library.
100103
filterwarnings = [
101-
"ignore::DeprecationWarning:botocore.*",
102-
"ignore::DeprecationWarning:apispec.*",
103-
"ignore::DeprecationWarning:certifi.*"] # pytest-watch errors if the closing bracket is on it's own line
104+
"ignore::DeprecationWarning:botocore.*"] # pytest-watch errors if the closing bracket is on it's own line
104105

105106
markers = [
106107
"audit: mark a test as a security audit log test, to be run isolated from other tests"]

app/src/adapters/db/flask_db.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def health():
3939
# db_client.get_connection() or db_client.get_session()
4040
"""
4141
from functools import wraps
42-
from typing import Any, Callable, Concatenate, ParamSpec, TypeVar
42+
from typing import Callable, Concatenate, ParamSpec, TypeVar
4343

4444
from flask import Flask, current_app
4545

@@ -115,10 +115,13 @@ def fiz(db_session: db.Session, x, y, z):
115115

116116
def decorator(f: Callable[Concatenate[db.Session, P], T]) -> Callable[P, T]:
117117
@wraps(f)
118-
def wrapper(*args: Any, **kwargs: Any) -> T:
118+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
119119
with get_db(current_app, client_name=client_name).get_session() as session:
120120
return f(session, *args, **kwargs)
121121

122122
return wrapper
123123

124-
return decorator
124+
# mypy says the type should be something slightly different
125+
# Callable[[Arg(Callable[[Session, **P], T], 'f')], Callable[P, T]]
126+
# but also mentions that "Arg" is deprecated, so not sure how to make it happy
127+
return decorator # type: ignore

app/src/api/users/user_routes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
@user_blueprint.post("/v1/users")
18-
@user_blueprint.input(user_schemas.UserSchema)
18+
@user_blueprint.input(user_schemas.UserSchema, arg_name="user_params")
1919
@user_blueprint.output(user_schemas.UserSchema, status_code=201)
2020
@user_blueprint.auth_required(api_key_auth)
2121
@flask_db.with_db_session()
@@ -32,7 +32,7 @@ def user_post(db_session: db.Session, user_params: users.CreateUserParams) -> di
3232
# Allow partial updates. partial=true means requests that are missing
3333
# required fields will not be rejected.
3434
# https://marshmallow.readthedocs.io/en/stable/quickstart.html#partial-loading
35-
@user_blueprint.input(user_schemas.UserSchema(partial=True))
35+
@user_blueprint.input(user_schemas.UserSchema(partial=True), arg_name="patch_user_params")
3636
@user_blueprint.output(user_schemas.UserSchema)
3737
@user_blueprint.auth_required(api_key_auth)
3838
@flask_db.with_db_session()

app/src/db/migrations/env.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
# Initialize logging
1818
with src.logging.init("migrations"):
19-
2019
# add your model's MetaData object here
2120
# for 'autogenerate' support
2221
# from myapp import mymodel

app/src/db/models/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Base(DeclarativeBase):
5151
}
5252

5353
def _dict(self) -> dict:
54-
return {c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs} # type: ignore
54+
return {c.key: getattr(self, c.key) for c in inspect(self).mapper.column_attrs}
5555

5656
def for_json(self) -> dict:
5757
json_valid_dict = {}

app/src/logging/audit.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ def handle_audit_event(event_name: str, args: tuple[Any, ...]) -> None:
7272
def log_audit_event(event_name: str, args: Sequence[Any], arg_names: Sequence[str]) -> None:
7373
"""Log a message but only log recently repeated messages at intervals."""
7474
extra = {
75-
f"audit.args.{arg_name}": arg for arg_name, arg in zip(arg_names, args) if arg_name != "_"
75+
f"audit.args.{arg_name}": arg
76+
for arg_name, arg in zip(arg_names, args, strict=True)
77+
if arg_name != "_"
7678
}
7779

7880
key = (event_name, repr(args))

app/src/logging/formatters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def __init__(self, message_width: int = HUMAN_READABLE_FORMATTER_DEFAULT_MESSAGE
101101
def format(self, record: logging.LogRecord) -> str:
102102
message = super().format(record)
103103
return decodelog.format_line(
104-
datetime.utcfromtimestamp(record.created),
104+
datetime.fromtimestamp(record.created),
105105
record.name,
106106
record.funcName,
107107
record.levelname,

0 commit comments

Comments
 (0)