-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ENH] Add new query param for nodes that defaults to a prepopulated i…
…ndex (#30) * add new query param that can receive a list of nodes * add validation for node url list query param * add test for unrecognized node URLs * rename expected env file * add startup event for creating federation node index * rename variable storing user-defined local nodes * raise warning and use local nodes when public nodes fetching fails * switch to using federation node index in endpoints * move dynamic default setting + validation of node url param out of query model * add and implement function for adding trailing slash to urls * add test for check_nodes_are_recognized() * refactor node url param validation into separate function and test * add tests of federation node index creation and nodes endpoint * update README * add test case for whitespace in local nodes parsing * add test case for query node URL list with duplicates * update regex for local nodes to be whitespace-insensitive Co-authored-by: Sebastian Urchs <[email protected]> * add template fed.env file --------- Co-authored-by: Sebastian Urchs <[email protected]>
- Loading branch information
Showing
10 changed files
with
333 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Replace the value of LOCAL_NB_NODES below with the URL-name pairs of | ||
# any locally hosted nodes you wish to make available for federation | ||
LOCAL_NB_NODES=(https://myfirstnode.org/,First Node)(https://mysecondnode.org/,Second Node) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import os | ||
|
||
import httpx | ||
import pytest | ||
|
||
from app.api import utility as util | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"local_nodes", | ||
[ | ||
"(https://mylocalnode.org, Local Node)", | ||
"(https://mylocalnode.org/, Local Node) (https://firstpublicnode.org/, First Public Node)", | ||
], | ||
) | ||
def test_nodes_discovery_endpoint(test_app, monkeypatch, local_nodes): | ||
"""Test that a federation node index is correctly created from locally set and remote node lists.""" | ||
monkeypatch.setenv("LOCAL_NB_NODES", local_nodes) | ||
monkeypatch.setattr( | ||
util, | ||
"LOCAL_NODES", | ||
os.environ.get( | ||
"LOCAL_NB_NODES", "(https://api.neurobagel.org/, OpenNeuro)" | ||
), | ||
) | ||
|
||
def mock_httpx_get(**kwargs): | ||
return httpx.Response( | ||
status_code=200, | ||
json=[ | ||
{ | ||
"NodeName": "First Public Node", | ||
"ApiURL": "https://firstpublicnode.org", | ||
}, | ||
{ | ||
"NodeName": "Second Public Node", | ||
"ApiURL": "https://secondpublicnode.org", | ||
}, | ||
], | ||
) | ||
|
||
monkeypatch.setattr(httpx, "get", mock_httpx_get) | ||
|
||
with test_app: | ||
response = test_app.get("/nodes/") | ||
assert util.FEDERATION_NODES == { | ||
"https://firstpublicnode.org/": "First Public Node", | ||
"https://secondpublicnode.org/": "Second Public Node", | ||
"https://mylocalnode.org/": "Local Node", | ||
} | ||
assert response.json() == [ | ||
{ | ||
"NodeName": "First Public Node", | ||
"ApiURL": "https://firstpublicnode.org/", | ||
}, | ||
{ | ||
"NodeName": "Second Public Node", | ||
"ApiURL": "https://secondpublicnode.org/", | ||
}, | ||
{"NodeName": "Local Node", "ApiURL": "https://mylocalnode.org/"}, | ||
] | ||
|
||
|
||
def test_failed_public_nodes_fetching_raises_warning(test_app, monkeypatch): | ||
"""Test that when request for remote list of public nodes fails, an informative warning is raised and the federation node index only includes local nodes.""" | ||
monkeypatch.setenv( | ||
"LOCAL_NB_NODES", "(https://mylocalnode.org, Local Node)" | ||
) | ||
monkeypatch.setattr( | ||
util, | ||
"LOCAL_NODES", | ||
os.environ.get( | ||
"LOCAL_NB_NODES", "(https://api.neurobagel.org/, OpenNeuro)" | ||
), | ||
) | ||
|
||
def mock_httpx_get(**kwargs): | ||
return httpx.Response( | ||
status_code=404, json={}, text="Some error message" | ||
) | ||
|
||
monkeypatch.setattr(httpx, "get", mock_httpx_get) | ||
|
||
with pytest.warns(UserWarning) as w: | ||
with test_app: | ||
response = test_app.get("/nodes/") | ||
assert util.FEDERATION_NODES == { | ||
"https://mylocalnode.org/": "Local Node" | ||
} | ||
assert response.json() == [ | ||
{ | ||
"NodeName": "Local Node", | ||
"ApiURL": "https://mylocalnode.org/", | ||
} | ||
] | ||
|
||
for warn_substr in [ | ||
"Unable to fetch directory of public Neurobagel nodes", | ||
"The federation API will only register the nodes defined locally for this API: {'https://mylocalnode.org/': 'Local Node'}", | ||
]: | ||
assert warn_substr in w[0].message.args[0] |
Oops, something went wrong.