From b7e538c966a4def2be9e95397d148f4ee8a96cfe Mon Sep 17 00:00:00 2001 From: Mikael Frykholm Date: Mon, 23 Feb 2026 15:56:21 +0100 Subject: [PATCH 1/7] Start of 2.1.6.dev0 --- NEWS.txt | 4 ++++ RELEASE.txt | 8 ++++---- docs/conf.py | 34 +++++++++++++++++++--------------- pyproject.toml | 6 +++--- uv.lock | 4 ++-- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index d088b7d8..4542fb5f 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -189,3 +189,7 @@ to sign using HSMs. The only mandatory non-python dependency now is lxml. 2.1.5 ----- +* Release date: Mon Feb 23 15:11:40 CET 2026 + +* Switch to uv.lock for reproducable builds. +* temp dir fix diff --git a/RELEASE.txt b/RELEASE.txt index 21dba0e2..f687b16a 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -6,11 +6,11 @@ To make a release, 1) remove dev suffix on version in pyproject.toml 2) set release date in NEWS.txt 2b) update the version in docs/conf.py - 3) commit the changes to setup.py and NEWS.txt + 3) commit the changes to pyproject.toml and NEWS.txt 4) git tag 5) git push && git push --tag 6) cd docs && make html - 6) Upload to PyPI: twine upload dist/pyFF-.tar.gz - 7) Increase version in pyproject.toml (for next release) with dev suffix - 8) Create NEWS.txt entry for next release + 7) uv build && uv publish + 8) Increase version in pyproject.toml (for next release) with dev suffix + 9) Create NEWS.txt entry for next release diff --git a/docs/conf.py b/docs/conf.py index 2f42b4b7..6802b6f3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,11 +16,15 @@ import sphinx sys.path.insert(0, os.path.abspath('./../')) -autodoc_mock_imports = ["alpha","beta"] +autodoc_mock_imports = ["alpha", "beta"] -#import sphinx.apidoc + +# import sphinx.apidoc def setup(app): - sphinx.ext.apidoc.main(['-f', '-T', '-e', '-M', '-o', './code/', '../src', '../src/localconfig.py', '../src/pyff/test']) + sphinx.ext.apidoc.main( + ['-f', '-T', '-e', '-M', '-o', './code/', '../src', '../src/localconfig.py', '../src/pyff/test'] + ) + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -59,7 +63,7 @@ def setup(app): # The short X.Y version. version = '2.1' # The full version, including alpha/beta/rc tags. -release = '2.1.4' +release = '2.1.6.dev0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -181,10 +185,8 @@ def setup(app): latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. #'preamble': '', } @@ -192,8 +194,7 @@ def setup(app): # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'FederationFeeder.tex', 'Federation Feeder Documentation', - 'Leif Johansson', 'manual'), + ('index', 'FederationFeeder.tex', 'Federation Feeder Documentation', 'Leif Johansson', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -221,10 +222,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'federationfeeder', 'Federation Feeder Documentation', - ['Leif Johansson'], 1) -] +man_pages = [('index', 'federationfeeder', 'Federation Feeder Documentation', ['Leif Johansson'], 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -236,9 +234,15 @@ def setup(app): # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'FederationFeeder', 'Federation Feeder Documentation', - 'Leif Johansson', 'FederationFeeder', 'One line description of project.', - 'Miscellaneous'), + ( + 'index', + 'FederationFeeder', + 'Federation Feeder Documentation', + 'Leif Johansson', + 'FederationFeeder', + 'One line description of project.', + 'Miscellaneous', + ), ] # Documents to append as an appendix to all manuals. diff --git a/pyproject.toml b/pyproject.toml index 5693f4c9..6a51b6c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pyFF" -version = "2.1.5-dev" +version = "2.1.6.dev0" readme = "README.rst" description = "Federation Feeder" requires-python = ">=3.9" @@ -102,5 +102,5 @@ all_files = "1" upload-dir = "docs/build/html" [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["uv_build>=0.10.4,<0.11.0"] +build-backend = "uv_build" diff --git a/uv.lock b/uv.lock index a34aad3a..8eab7d33 100644 --- a/uv.lock +++ b/uv.lock @@ -731,7 +731,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -1444,7 +1444,7 @@ wheels = [ [[package]] name = "pyff" -version = "2.1.5.dev0" +version = "2.1.6.dev0" source = { editable = "." } dependencies = [ { name = "accept-types" }, From e8b2459dad560a53625087fe8e7d1131a5479084 Mon Sep 17 00:00:00 2001 From: Mikael Frykholm Date: Tue, 10 Mar 2026 12:25:31 +0100 Subject: [PATCH 2/7] Pin to older gunicorn until https://github.com/benoitc/gunicorn/issues/3529 is released. --- pyproject.toml | 1 + uv.lock | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6a51b6c2..0e815b3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ dependencies = [ "apscheduler==3.6.3", "cachetools>=5.5.2", "eval-type-backport>=0.2.2 ; python_full_version == '3.9.*'", + "gunicorn==25.0.3 ; python_full_version >= '3.10'", "gunicorn>=23.0.0", "lxml>=4.1.1", "mako>=1.3.10", diff --git a/uv.lock b/uv.lock index 8eab7d33..ee4c91a1 100644 --- a/uv.lock +++ b/uv.lock @@ -778,7 +778,7 @@ wheels = [ [[package]] name = "gunicorn" -version = "25.1.0" +version = "25.0.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.13'", @@ -789,9 +789,9 @@ resolution-markers = [ dependencies = [ { name = "packaging", marker = "python_full_version >= '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/13/ef67f59f6a7896fdc2c1d62b5665c5219d6b0a9a1784938eb9a28e55e128/gunicorn-25.1.0.tar.gz", hash = "sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616", size = 594377, upload-time = "2026-02-13T11:09:58.989Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/e5/e1d2225d2b75fe4988821715d2c526fdf7b39f4a7260aa7e2bb4b25ec65c/gunicorn-25.0.3.tar.gz", hash = "sha256:b53a7fff1a07b825b962af320554de44ae77a26abfa373711ff3f83d57d3506d", size = 9702357, upload-time = "2026-02-07T16:53:52.72Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/73/4ad5b1f6a2e21cf1e85afdaad2b7b1a933985e2f5d679147a1953aaa192c/gunicorn-25.1.0-py3-none-any.whl", hash = "sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b", size = 197067, upload-time = "2026-02-13T11:09:57.146Z" }, + { url = "https://files.pythonhosted.org/packages/5e/84/117f39896ded517149be72d16c02252885690e9b0d1b84281944928f61aa/gunicorn-25.0.3-py3-none-any.whl", hash = "sha256:aca364c096c81ca11acd4cede0aaeea91ba76ca74e2c0d7f879154db9d890f35", size = 171728, upload-time = "2026-02-07T16:53:49.546Z" }, ] [[package]] @@ -1453,7 +1453,7 @@ dependencies = [ { name = "cachetools", version = "7.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "eval-type-backport", marker = "python_full_version < '3.10'" }, { name = "gunicorn", version = "23.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "gunicorn", version = "25.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "gunicorn", version = "25.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "lxml" }, { name = "mako" }, { name = "pyconfig" }, @@ -1505,6 +1505,7 @@ requires-dist = [ { name = "cachetools", specifier = ">=5.5.2" }, { name = "eval-type-backport", marker = "python_full_version == '3.9.*'", specifier = ">=0.2.2" }, { name = "gunicorn", specifier = ">=23.0.0" }, + { name = "gunicorn", marker = "python_full_version >= '3.10'", specifier = "==25.0.3" }, { name = "lxml", specifier = ">=4.1.1" }, { name = "mako", specifier = ">=1.3.10" }, { name = "pyconfig", specifier = ">=3.2.3,<3.3.0" }, From b619d50dd8a2566cc38e63df6449b0d2739b20df Mon Sep 17 00:00:00 2001 From: Mikael Frykholm Date: Tue, 10 Mar 2026 12:26:34 +0100 Subject: [PATCH 3/7] Run via uv. --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 4bbd9cb3..4466729b 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,7 +3,7 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = sphinx-build +SPHINXBUILD = uv run sphinx-build SOURCEDIR = . BUILDDIR = _build From 64a50db7fd719d8bd4ce3792663fc4824d75cfc8 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Tue, 24 Jun 2025 08:17:34 +0200 Subject: [PATCH 4/7] Don't loose track of trailing slashes Slashses might be part of the entityID Related to #298 --- src/pyff/api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pyff/api.py b/src/pyff/api.py index 10e7b3ad..9763b287 100644 --- a/src/pyff/api.py +++ b/src/pyff/api.py @@ -205,6 +205,10 @@ def _d(x: Optional[str], do_split: bool = True) -> tuple[Optional[str], Optional # Ugly workaround bc WSGI drops double-slashes. path = path.replace(':/', '://') + # Ugly workaround bc request.matchdict drops trailing slashes which could be part of the entityID + if request.path and request.path[-1] == "/": + path = path + "/" + msg = "handling entry={}, alias={}, path={}" log.debug(msg.format(entry, alias, path)) From 1fe4d9d855c9673fe2f962bf10d3488f60489db3 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Thu, 26 Jun 2025 11:42:18 +0200 Subject: [PATCH 5/7] Cache per Content-Type --- src/pyff/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyff/api.py b/src/pyff/api.py index 9763b287..eb49e805 100644 --- a/src/pyff/api.py +++ b/src/pyff/api.py @@ -140,7 +140,7 @@ def request_handler(request: Request) -> Response: :param request: the HTTP request object :return: the data to send to the client """ - key = request.path_qs + key = f"{request.path_qs}_{request.accept}" r = None try: r = request.registry.cache[key] From 7bd27204431acfbf741e9ed12e4d7c933e86e0a3 Mon Sep 17 00:00:00 2001 From: publiccode-pr-bot <227970070+publiccode-pr-bot@users.noreply.github.com> Date: Fri, 22 Aug 2025 13:59:56 +0200 Subject: [PATCH 6/7] ci: add publiccode.yml validation workflow Closes #303 --- .github/workflows/publiccode-yml-validation.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/publiccode-yml-validation.yml diff --git a/.github/workflows/publiccode-yml-validation.yml b/.github/workflows/publiccode-yml-validation.yml new file mode 100644 index 00000000..8d9609cf --- /dev/null +++ b/.github/workflows/publiccode-yml-validation.yml @@ -0,0 +1,12 @@ +name: publiccode.yml validation + +on: [pull_request, push] + +jobs: + publiccode_yml_validation: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: italia/publiccode-parser-action@v1 + with: + publiccode: 'publiccode.yml' From 031a9b5b01ee1e31b7b95dfe53aa5342dafa7f42 Mon Sep 17 00:00:00 2001 From: Johan Wassberg Date: Mon, 1 Jun 2026 14:12:24 +0200 Subject: [PATCH 7/7] Allow for only read --- .github/workflows/publiccode-yml-validation.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publiccode-yml-validation.yml b/.github/workflows/publiccode-yml-validation.yml index 8d9609cf..40a75f9a 100644 --- a/.github/workflows/publiccode-yml-validation.yml +++ b/.github/workflows/publiccode-yml-validation.yml @@ -2,6 +2,9 @@ name: publiccode.yml validation on: [pull_request, push] +permissions: + contents: read + jobs: publiccode_yml_validation: runs-on: ubuntu-latest