launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32649
[Merge] ~alvarocs/lp-signing/+git/lp-signing-1:upgrade-noble into lp-signing:master
Alvaro Crespo Serrano has proposed merging ~alvarocs/lp-signing/+git/lp-signing-1:upgrade-noble into lp-signing:master.
Commit message:
Upgrade application and dependencies to be compatible with Ubuntu Noble with Python 3.12
The lp-signing app currently runs on bionic and since focal will be the oldest supported Ubuntu version on PS8, we need to upgrade it to run on the latest Ubuntu LTS.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~alvarocs/lp-signing/+git/lp-signing-1/+merge/487377
Changes to upgrade lp-signing so it builds, tests and runs on Noble with Python 3.12. The dependencies repo merge proposal is in: https://code.launchpad.net/~alvarocs/lp-signing/+git/dependencies/+merge/487735
- Updated the base platform to reference noble from bionic.
- Update of requirements and requirements-dev to be compatible with Noble Python 3.12.
- Update and run pre-commit to all files
- Update tox with 3.12 and added lint
- Version bump in setup.py to 0.2
- Modify _get_data_for_json in auth.py to get_data as it has been deprecated in recent 2.3.x versions of Flask/Werkzeug.
- For tests where no json was sent (test_no_json) it would call twice get_data so it would error out in the Nonce.check() in the second call. For this I have added a flag 'boxed_plaintext' to only decrypt the body when it has not been decrypted already.
- Several codefixes for py3.12 (datetime, flask.g, assertCountEqual)
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~alvarocs/lp-signing/+git/lp-signing-1:upgrade-noble into lp-signing:master.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 86468c3..c60addf 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,7 +2,7 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.0.1
+ rev: v5.0.0
hooks:
- id: check-added-large-files
- id: check-ast
@@ -21,18 +21,18 @@ repos:
- id: check-yaml
- id: debug-statements
- repo: https://github.com/psf/black
- rev: 23.1.0
+ rev: 25.1.0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
- rev: 5.12.0
+ rev: 6.0.1
hooks:
- id: isort
- repo: https://github.com/PyCQA/flake8
- rev: 3.9.2
+ rev: 7.3.0
hooks:
- id: flake8
- repo: https://github.com/get-woke/woke
- rev: ee781d3ce0ddf835267764f27f4ffdd2dd21fa27
+ rev: v0.19.0
hooks:
- id: woke-from-source
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 6527c11..f553278 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -1,9 +1,9 @@
version: 2
build:
- os: ubuntu-22.04
+ os: ubuntu-24.04
tools:
- python: "3.10"
+ python: "3.12"
python:
install:
diff --git a/README.rst b/README.rst
index 8b40442..078b70a 100644
--- a/README.rst
+++ b/README.rst
@@ -7,9 +7,9 @@ A service for storing keys and signing messages.
Development environment
-----------------------
-Create a bionic LXD container::
+Create a noble LXD container::
- $ lxc launch ubuntu:bionic lp-signing-bionic
+ $ lxc launch ubuntu:noble lp-signing-noble
(You may want to use a profile to bind-mount your home directory as well.)
diff --git a/charm/lp-signing/metadata.yaml b/charm/lp-signing/metadata.yaml
index 00d6bab..779f942 100644
--- a/charm/lp-signing/metadata.yaml
+++ b/charm/lp-signing/metadata.yaml
@@ -4,5 +4,5 @@ summary: Launchpad signing service
maintainer: Colin Watson <cjwatson@xxxxxxxxxxxxx>
description: A service for storing keys and signing messages.
series:
- - bionic
+ - noble
subordinate: false
diff --git a/dependencies-devel.txt b/dependencies-devel.txt
index d9830fc..7fa4455 100644
--- a/dependencies-devel.txt
+++ b/dependencies-devel.txt
@@ -1,8 +1,8 @@
gcc
git
make
-postgresql-contrib-10
-postgresql-server-dev-10
+postgresql-contrib-16
+postgresql-server-dev-16
python3-dev
python3-pip
python3-swiftclient
diff --git a/lp_signing/auth.py b/lp_signing/auth.py
index c35080d..3b6d8fe 100644
--- a/lp_signing/auth.py
+++ b/lp_signing/auth.py
@@ -67,6 +67,7 @@ class BoxedRequest(Request):
client = None
private_key_index = 0
encrypted_response = False
+ boxed_plaintext = None
@property
def is_json(self):
@@ -98,7 +99,12 @@ class BoxedRequest(Request):
"Cannot decode {} header".format(header_name)
)
- def _get_data_for_json(self, cache):
+ def get_data(
+ self,
+ cache=True,
+ as_text=False,
+ parse_form_data=False,
+ ):
"""Read, authenticate, and decrypt incoming data.
This may call `Nonce.check`, so the caller must only call this
@@ -111,33 +117,43 @@ class BoxedRequest(Request):
that was used in `boxed_authentication.service_private_keys` (for
later response encryption).
- See `flask.wrappers.JSONMixin.get_json`, on which this is based.
+ See `werkzeug.wrappers.Request.get_data`, on which this is based.
:return: Unboxed JSON data.
:raises APIError: if authentication, decryption, or JSON decoding
failed.
+
"""
- data = self.get_data(cache)
- client_public_key = self.get_client_public_key()
- nonce = self.get_nonce("X-Nonce")
- Nonce.check(nonce)
- for i, private_key in enumerate(
- boxed_authentication.service_private_keys
- ):
- try:
- box = Box(private_key, client_public_key)
- data = box.decrypt(data, nonce, encoder=Base64Encoder)
- except Exception:
- continue
- self.private_key_index = i
- self.client = Client.getByPublicKey(client_public_key)
- if self.client is None:
- raise DataValidationError.single(
- "Unregistered client public key"
- )
- break
+
+ # If the body has already been decrypted, no need to decrypt again.
+ if self.boxed_plaintext is not None:
+ data = self.boxed_plaintext
else:
- raise DataValidationError.single("Authentication failed")
+ # Read the raw body
+ data = super().get_data(cache=False)
+
+ # Authenticate and decrypt the body
+ client_public_key = self.get_client_public_key()
+ nonce = self.get_nonce("X-Nonce")
+ Nonce.check(nonce)
+ for i, private_key in enumerate(
+ boxed_authentication.service_private_keys
+ ):
+ try:
+ box = Box(private_key, client_public_key)
+ data = box.decrypt(data, nonce, encoder=Base64Encoder)
+ except Exception:
+ continue
+ self.private_key_index = i
+ self.client = Client.getByPublicKey(client_public_key)
+ if self.client is None:
+ raise DataValidationError.single(
+ "Unregistered client public key"
+ )
+ break
+ else:
+ raise DataValidationError.single("Authentication failed")
+ self.boxed_plaintext = data
return data
diff --git a/lp_signing/cli.py b/lp_signing/cli.py
index c9cbe0f..9756f38 100644
--- a/lp_signing/cli.py
+++ b/lp_signing/cli.py
@@ -73,7 +73,7 @@ def generate_key_pair(private_key_path, public_key_path):
with open(public_key_path, "w") as public_key_file:
print(encode_key(key.public_key), file=public_key_file)
else:
- print(f"Public: {encode_key(key.public_key)}")
+ print(f"Public: {encode_key(key.public_key)}")
@cli.command("register-client")
diff --git a/lp_signing/model/key.py b/lp_signing/model/key.py
index 4e24383..d09906b 100644
--- a/lp_signing/model/key.py
+++ b/lp_signing/model/key.py
@@ -558,10 +558,12 @@ class Key(Storm):
"openssl",
"x509",
"-inform",
- "PEM"
- if key_type
- in (KeyType.UEFI, KeyType.FIT, KeyType.ANDROID_KERNEL)
- else "DER",
+ (
+ "PEM"
+ if key_type
+ in (KeyType.UEFI, KeyType.FIT, KeyType.ANDROID_KERNEL)
+ else "DER"
+ ),
"-noout",
"-fingerprint",
],
diff --git a/lp_signing/model/tests/test_client.py b/lp_signing/model/tests/test_client.py
index 1e72d65..36b4105 100644
--- a/lp_signing/model/tests/test_client.py
+++ b/lp_signing/model/tests/test_client.py
@@ -27,7 +27,7 @@ class TestClient(TestCase):
client.registerPublicKey(private_keys[0].public_key)
self.assertEqual([private_keys[0].public_key], client.public_keys)
client.registerPublicKey(private_keys[1].public_key)
- self.assertItemsEqual(
+ self.assertCountEqual(
[private_key.public_key for private_key in private_keys],
client.public_keys,
)
diff --git a/lp_signing/model/tests/test_key.py b/lp_signing/model/tests/test_key.py
index 3ac51a7..872fd58 100644
--- a/lp_signing/model/tests/test_key.py
+++ b/lp_signing/model/tests/test_key.py
@@ -713,7 +713,7 @@ class TestKey(TestCase):
self.assertTrue(key.isAuthorized(clients[0]))
self.assertFalse(key.isAuthorized(clients[1]))
key.addAuthorization(clients[1])
- self.assertItemsEqual(clients, key.authorizations)
+ self.assertCountEqual(clients, key.authorizations)
self.assertTrue(key.isAuthorized(clients[0]))
self.assertTrue(key.isAuthorized(clients[1]))
@@ -1325,7 +1325,7 @@ class TestKey(TestCase):
public_key = factory.generate_random_bytes(size=64)
fingerprint = factory.generate_fingerprint()
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
key = Key.inject(
@@ -1372,7 +1372,7 @@ class TestKey(TestCase):
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.KMOD, private_key, public_key, description, created_at
)
@@ -1417,7 +1417,7 @@ class TestKey(TestCase):
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.OPAL, private_key, public_key, description, created_at
)
@@ -1456,7 +1456,7 @@ class TestKey(TestCase):
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.SIPL, private_key, public_key, description, created_at
)
@@ -1495,7 +1495,7 @@ class TestKey(TestCase):
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.FIT, private_key, public_key, description, created_at
)
@@ -1537,7 +1537,7 @@ class TestKey(TestCase):
"~signing-owner/ubuntu/testing",
)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.OPENPGP, private_key, public_key, description, created_at
)
@@ -1564,7 +1564,7 @@ class TestKey(TestCase):
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.CV2_KERNEL,
private_key,
@@ -1600,7 +1600,7 @@ class TestKey(TestCase):
fake_openssl = FakeOpenSSL(private_key, public_key, fingerprint)
self.processes_fixture.add(fake_openssl)
description = "PPA signing-owner testing"
- created_at = datetime.utcnow().replace(tzinfo=timezone.utc)
+ created_at = datetime.now(timezone.utc)
key = Key.inject(
KeyType.ANDROID_KERNEL,
private_key,
diff --git a/lp_signing/tests/matchers.py b/lp_signing/tests/matchers.py
index e0f5843..a713398 100644
--- a/lp_signing/tests/matchers.py
+++ b/lp_signing/tests/matchers.py
@@ -72,7 +72,7 @@ class HasAPIError(BaseJSONResponseMatcher):
err = super().match(matchee)
if err:
return err
- data = json.loads(matchee.data.decode(matchee.charset))
+ data = json.loads(matchee.data.decode("utf-8"))
return AnyMatch(self.expected_message_matcher).match(
[error["message"] for error in data["error_list"]]
)
diff --git a/lp_signing/tests/test_webapi.py b/lp_signing/tests/test_webapi.py
index d997724..bc22156 100644
--- a/lp_signing/tests/test_webapi.py
+++ b/lp_signing/tests/test_webapi.py
@@ -3,7 +3,7 @@
import base64
import json
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
from pathlib import Path
from tempfile import TemporaryDirectory
@@ -2373,7 +2373,7 @@ class TestInjectView(TestCase):
"key-type": "UEFI",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "UEFI test description",
}
)
@@ -2400,7 +2400,7 @@ class TestInjectView(TestCase):
"key-type": "KMOD",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "KMOD test description",
}
)
@@ -2439,7 +2439,7 @@ class TestInjectView(TestCase):
"key-type": "KMOD",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2466,7 +2466,7 @@ class TestInjectView(TestCase):
"key-type": "OPAL",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2505,7 +2505,7 @@ class TestInjectView(TestCase):
"key-type": "OPAL",
"private-key": "",
"public-key": "",
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2532,7 +2532,7 @@ class TestInjectView(TestCase):
"key-type": "SIPL",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2571,7 +2571,7 @@ class TestInjectView(TestCase):
"key-type": "SIPL",
"private-key": "",
"public-key": "",
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2598,7 +2598,7 @@ class TestInjectView(TestCase):
"key-type": "FIT",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2637,7 +2637,7 @@ class TestInjectView(TestCase):
"key-type": "FIT",
"private-key": "",
"public-key": "",
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2697,7 +2697,7 @@ class TestInjectView(TestCase):
"key-type": "OPENPGP",
"private-key": base64.b64encode(b"").decode("UTF-8"),
"public-key": base64.b64encode(b"").decode("UTF-8"),
- "created-at": datetime.utcnow().isoformat(),
+ "created-at": datetime.now(timezone.utc).isoformat(),
"description": "OpenPGP test description",
}
)
@@ -2718,7 +2718,7 @@ class TestInjectView(TestCase):
"key-type": "CV2_KERNEL",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": datetime.utcnow().isoformat(),
+ "created-at": datetime.now(timezone.utc).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2753,7 +2753,7 @@ class TestInjectView(TestCase):
"key-type": "CV2_KERNEL",
"private-key": "",
"public-key": "",
- "created-at": datetime.utcnow().isoformat(),
+ "created-at": datetime.now(timezone.utc).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2782,7 +2782,7 @@ class TestInjectView(TestCase):
"public-key": base64.b64encode(bytes(public_key)).decode(
"UTF-8"
),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2818,7 +2818,7 @@ class TestInjectView(TestCase):
"public-key": base64.b64encode(bytes(public_key)).decode(
"UTF-8"
),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
},
index=1,
@@ -2864,7 +2864,7 @@ class TestInjectView(TestCase):
"key-type": "FIT",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2899,7 +2899,7 @@ class TestInjectView(TestCase):
"key-type": "FIT",
"private-key": base64.b64encode(private_key).decode("UTF-8"),
"public-key": base64.b64encode(public_key).decode("UTF-8"),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2944,7 +2944,7 @@ class TestInjectView(TestCase):
"public-key": base64.b64encode(bytes(public_key)).decode(
"UTF-8"
),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
}
)
@@ -2981,7 +2981,7 @@ class TestInjectView(TestCase):
"public-key": base64.b64encode(bytes(public_key)).decode(
"UTF-8"
),
- "created-at": (datetime.utcnow()).isoformat(),
+ "created-at": (datetime.now(timezone.utc)).isoformat(),
"description": "PPA test-owner test-archive",
},
index=1,
@@ -3006,7 +3006,7 @@ class TestInjectView(TestCase):
Path(tmp), KeyType.FIT, common_name
)
- existent_date = datetime.utcnow()
+ existent_date = datetime.now()
resp = self.post_inject(
{
"key-type": "FIT",
@@ -3043,7 +3043,7 @@ class TestInjectView(TestCase):
),
)
- older_date = datetime.utcnow() - timedelta(days=3)
+ older_date = datetime.now(timezone.utc) - timedelta(days=3)
resp = self.post_inject(
{
"key-type": "FIT",
@@ -3066,7 +3066,7 @@ class TestInjectView(TestCase):
authorizations=[self.clients[0], self.clients[1]],
),
)
- self.assertEqual(pytz.utc.localize(older_date), key.created_at)
+ self.assertEqual(older_date, key.created_at)
class TestAddAuthorizationView(TestCase):
diff --git a/lp_signing/webapp.py b/lp_signing/webapp.py
index ed39e4c..a39f9e6 100644
--- a/lp_signing/webapp.py
+++ b/lp_signing/webapp.py
@@ -84,8 +84,8 @@ def create_web_application():
@app.before_request
def before(logger=app.logger):
if statsd_client is not None:
- flask._request_ctx_stack.top.timer = statsd_client.timer("")
- flask._request_ctx_stack.top.timer.start()
+ flask.g.timer = statsd_client.timer("")
+ flask.g.timer.start()
@app.after_request
def after(response, logger=app.logger):
@@ -100,8 +100,8 @@ def create_web_application():
str(response.status_code),
)
)
- flask._request_ctx_stack.top.timer.stat = name
- flask._request_ctx_stack.top.timer.stop()
+ flask.g.timer.stat = name
+ flask.g.timer.stop()
return response
FlaskStorm().init_app(app)
diff --git a/ols-vms.conf b/ols-vms.conf
index 8c37174..19d1b16 100644
--- a/ols-vms.conf
+++ b/ols-vms.conf
@@ -1,6 +1,6 @@
# Options defined here provide defaults for all sections
vm.architecture = amd64
-vm.release = bionic
+vm.release = noble
apt.sources = ppa:launchpad/ppa
vm.packages = @dependencies.txt, @dependencies-devel.txt
diff --git a/requirements-dev.txt b/requirements-dev.txt
index d874339..9974268 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,12 +1,11 @@
-cffi==1.13.2
+cffi==1.17.1
coverage==4.5.4
cryptography==2.8
entrypoints==0.3
extras==1.0.0
fakesleep==0.1
-fixtures==3.0.0
+fixtures==4.2.5
flake8==3.7.9
-linecache2==1.0.0
mccabe==0.6.1
pbr==5.4.4
pycodestyle==2.5.0
@@ -16,6 +15,4 @@ python-mimeparse==1.6.0
requests-mock==1.7.0
systemfixtures==0.6.7
testresources==2.0.1
-testtools==2.3.0
-traceback2==1.4.0
-unittest2==1.1.0
+testtools==2.7.2
diff --git a/requirements.txt b/requirements.txt
index 9524caf..705e828 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,36 +1,36 @@
acceptable==0.21
-blinker==1.4
-certifi==2019.11.28
+blinker==1.9
+certifi==2025.4.26
chardet==3.0.4
-Click==7.0
+Click==8.2.1
contextvars==2.4
-Flask==1.0.2
+Flask==2.3.1
Flask-Storm==1.0.0
-future==0.16.0
+future==1.0
gunicorn==20.1.0
-idna==2.8
+idna==3.10
immutables==0.19.0
iso8601==0.1.12
-itsdangerous==1.1.0
-Jinja2==2.10
+itsdangerous==2.2.0
+Jinja2==3.1.6
jsonschema==2.6.0
lazr.enum==1.2
lazr.postgresql==0.0.4
-MarkupSafe==1.1.0
+MarkupSafe==3.0.2
pip==19.0.2
-psycopg2==2.7.7
+psycopg2==2.9.10
PyNaCl==1.3.0
-PyYAML==3.13
+PyYAML==6.0.2
pytz==2019.3
raven==6.10.0
-requests==2.22.0
-setuptools==42.0.2
-six==1.13.0
-sqlparse==0.2.4
+requests==2.32.4
+setuptools==80.9.0
+six==1.17.0
+sqlparse==0.5.3
statsd==3.3.0
-storm==0.22
-talisker==0.20.0
+storm==1.0
+talisker==0.22.0
typing_extensions==3.7.4.3
-urllib3==1.25.7
-Werkzeug==0.14.1
-wheel==0.33.1
+urllib3==2.4.0
+Werkzeug==2.3.8
+wheel==0.45.1
diff --git a/setup.cfg b/setup.cfg
index feb8a3d..6b4b9a9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,6 +2,7 @@
ignore =
# incompatible with black
E203
+ E231
# binary operator on same or next line; mutually exclusive
W503
W504
diff --git a/setup.py b/setup.py
index f5b5f71..f6d4f5d 100755
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ requires = [
"PyNaCl",
"pytz",
"storm",
- "talisker[flask,gunicorn,pg]",
+ "talisker[flask,gunicorn]",
]
test_requires = [
"coverage",
@@ -25,11 +25,12 @@ test_requires = [
"systemfixtures",
"testresources",
"testtools",
+ "psycopg2-binary>=2.9,<3",
]
setup(
name="lp-signing",
- version="0.1",
+ version="0.2",
packages=find_packages(),
include_package_data=True,
zip_safe=False,
diff --git a/tox.ini b/tox.ini
index a135452..8170fed 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,12 +1,21 @@
[tox]
envlist =
- docs
+ docs, lint
[testenv:docs]
description =
generate documentation
basepython =
- python3.10
+ python3.12
extras = docs
commands =
sphinx-build -W -b html -d docs/_build/doctrees docs docs/_build/html
+
+[testenv:lint]
+basepython = python3.12
+deps =
+ flake8
+ black
+ isort
+commands =
+ flake8 lp_signing
Follow ups