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

urls: introduce invenio_url_for-compatible links #609

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fenekku
Copy link
Contributor

@fenekku fenekku commented Feb 20, 2025

  • requires:

Not required for initial invenio-rdm-records PR - we can introduce the constructs from this PR into it later. But inveniosoftware/invenio-rdm-records#1962 is required before this is released.

The high number of changed files is just because of the tests/__init__.py pattern (see inveniosoftware/invenio-rdm-records#1954).

A guided commentary tour is provided.

@fenekku fenekku force-pushed the integrate_invenio_url_for_on_top_master branch from 59134ea to dba04a3 Compare February 20, 2025 19:40
@@ -10,13 +10,14 @@
"""Base Service API."""

from .config import ServiceConfig
from .links import ConditionalLink, Link, LinksTemplate, NestedLinks
from .links import ConditionalLink, Link, Link2, LinksTemplate, NestedLinks
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for the release of this package to not take down other packages using Link, a different name is used (different class rather than editing same class). The name Link2 (and so on for other constructs) was the simplest.

:param endpoint: str. endpoint of the URL
:param when: fn(obj, dict) -> bool, when the URL should be rendered
:param vars: fn(ob, dict), mutate dict in preparation for expansion
:param params: list, parameters (excluding querystrings) used for expansion
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise a bunch of other stuff gets shoved into the built url, see explainer below. If anything, we have less to specify when defining Link2s than Links (no {api/ui}, no {args}).

}
# Inheriting resource config should define these
# TODO: Edit rdm-records such that it doesn't rely on this first
file_links_list = {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return LinksTemplate(
# Until all modules have transitioned to using invenio_url_for,
# we have to keep `id` in context for URL expansion
self.config.file_links_list,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In following major bump, we can remove.

# Invenio-RDM-Records is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.

"""Tests."""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and most following changes is as inveniosoftware/invenio-rdm-records#1954 (for pytest v8 and better entry_point module discovery to be honest)

Comment on lines +26 to +28
service_for_records = RecordService(ServiceConfig)
service_for_records_w_files = RecordService(ServiceWithFilesConfig)
service_for_files = FileService(FileServiceConfig)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to be done because of pre-existing tests.

"self": RecordLink("{+api}/mocks/{id}"),
"files": RecordLink("{+api}/mocks/{id}/files"),
"files-archive": RecordLink("{+api}/mocks/{id}/files-archive"),
"self": RecordLink2("mocks.read", params=["pid_value"]),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new way to define links serialization in action.

def base_app(base_app, record_resource):
"""Application factory fixture."""
base_app.register_blueprint(record_resource.as_blueprint())
yield base_app
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By relying on entry points to load blueprints, this kind of thing is not needed anymore.

@@ -279,8 +279,7 @@ def test_links_keep_facets(client, headers, three_indexed_records):
response_links = response.json["links"]
expected_links = {
"self": (
"https://127.0.0.1:5000/api/mocks?"
"page=1&size=25&sort=newest&type=A%2A%2AB"
"https://127.0.0.1:5000/api/mocks?page=1&size=25&sort=newest&type=A**B"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invenio_url_for (really werkzeug url building) doesn't % encode (it's fine).

ids=[item_one.id, item_two.id],
# NOTE: "id" and "pid" are needed to produce the links in the result
# Previous link generation would silently produce incorrect links
fields=["id", "pid", "metadata.type.type"],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion: yeah this is good and bad. Essentially the new way of generating links informs us of cases where urls were malformed... by throwing a BuildError. I don't think "id" and "pid" are universal though... If they are, we could add them to https://github.com/inveniosoftware/invenio-records-resources/blob/master/invenio_records_resources/services/records/service.py#L440 or make those default dumper fields configurable in RecordServiceConfig.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant