From 43179defb148a8a92659eadf75e7837895d1ef45 Mon Sep 17 00:00:00 2001 From: "duncan.macleod" <duncan.macleod@ligo.org> Date: Wed, 1 Nov 2023 17:59:25 +0000 Subject: [PATCH] api.ldr: move default API to LDR in preparation for supporting multiple APIs --- gwdatafind/api/__init__.py | 23 +++++++++++++++ gwdatafind/api/common.py | 27 ++++++++++++++++++ gwdatafind/{api.py => api/ldr.py} | 0 .../tests/{test_api.py => test_api_ldr.py} | 16 +++++------ gwdatafind/tests/test_ui.py | 24 ++++++++-------- gwdatafind/ui.py | 28 +++++++++---------- 6 files changed, 83 insertions(+), 35 deletions(-) create mode 100644 gwdatafind/api/__init__.py create mode 100644 gwdatafind/api/common.py rename gwdatafind/{api.py => api/ldr.py} (100%) rename gwdatafind/tests/{test_api.py => test_api_ldr.py} (83%) diff --git a/gwdatafind/api/__init__.py b/gwdatafind/api/__init__.py new file mode 100644 index 0000000..1fc7e50 --- /dev/null +++ b/gwdatafind/api/__init__.py @@ -0,0 +1,23 @@ +# Copyright (C) 2025 Cardiff University +# +# This file is part of GWDataFind. +# +# GWDataFind is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GWDataFind is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GWDataFind. If not, see <http://www.gnu.org/licenses/>. + +"""API definitions for the GWDataFind Client.""" + +# list of APIs +APIS = ( + "ldr", +) diff --git a/gwdatafind/api/common.py b/gwdatafind/api/common.py new file mode 100644 index 0000000..8e6d1fa --- /dev/null +++ b/gwdatafind/api/common.py @@ -0,0 +1,27 @@ +# Copyright (C) 2025 Cardiff University +# +# This file is part of GWDataFind. +# +# GWDataFind is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GWDataFind is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GWDataFind. If not, see <http://www.gnu.org/licenses/>. + +"""Common API definitions for the GWDataFind Client. + +This module provides API definitions that all APIs support in the +same way. +""" + + +def version_path(): + """Path for the API version endpoint.""" + return "api/version" diff --git a/gwdatafind/api.py b/gwdatafind/api/ldr.py similarity index 100% rename from gwdatafind/api.py rename to gwdatafind/api/ldr.py diff --git a/gwdatafind/tests/test_api.py b/gwdatafind/tests/test_api_ldr.py similarity index 83% rename from gwdatafind/tests/test_api.py rename to gwdatafind/tests/test_api_ldr.py index fb5cc69..5b5e521 100644 --- a/gwdatafind/tests/test_api.py +++ b/gwdatafind/tests/test_api_ldr.py @@ -23,19 +23,19 @@ from the v1 API for gwdatfind_server. import pytest -from gwdatafind import api +from gwdatafind.api import ldr as api_ldr __author__ = "Duncan Macleod <duncan.macleod@ligo.org>" def test_ping_path(): """Test `ping_path()`.""" - assert api.ping_path() == "LDR/services/data/v1/gwf/H/R/1,2" + assert api_ldr.ping_path() == "LDR/services/data/v1/gwf/H/R/1,2" def test_find_observatories_path(): """Test `find_observatories_path()`.""" - assert api.find_observatories_path() == "LDR/services/data/v1/gwf.json" + assert api_ldr.find_observatories_path() == "LDR/services/data/v1/gwf.json" @pytest.mark.parametrize(("site", "result"), [ @@ -45,19 +45,19 @@ def test_find_observatories_path(): ]) def test_find_types_path(site, result): """Test `find_types_path()`.""" - assert api.find_types_path(site) == result + assert api_ldr.find_types_path(site) == result def test_find_times_path(): """Test `find_times_path()`.""" - assert api.find_times_path("X", "TEST", 0, 1) == ( + assert api_ldr.find_times_path("X", "TEST", 0, 1) == ( "LDR/services/data/v1/gwf/X/TEST/segments/0,1.json" ) def test_find_url_path(): """Test `find_url_path()`.""" - assert api.find_url_path("/data/X-TEST-0-1.gwf") == ( + assert api_ldr.find_url_path("/data/X-TEST-0-1.gwf") == ( "LDR/services/data/v1/gwf/X/TEST/X-TEST-0-1.gwf.json" ) @@ -68,7 +68,7 @@ def test_find_url_path(): ]) def test_find_latest_path(urltype, result): """Test `find_latest_path()`.""" - assert api.find_latest_path("X", "TEST", urltype) == result + assert api_ldr.find_latest_path("X", "TEST", urltype) == result @pytest.mark.parametrize(("urltype", "match", "result"), [ @@ -80,7 +80,7 @@ def test_find_latest_path(urltype, result): ]) def find_urls_path(urltype, match, result): """Test `find_urls_path()`.""" - assert api.find_urls_path( + assert api_ldr.find_urls_path( "X", "TEST", 0, diff --git a/gwdatafind/tests/test_ui.py b/gwdatafind/tests/test_ui.py index dee7d1f..f2e9439 100644 --- a/gwdatafind/tests/test_ui.py +++ b/gwdatafind/tests/test_ui.py @@ -29,10 +29,8 @@ from unittest import mock import igwn_segments as segments import pytest -from gwdatafind import ( - api, - ui, -) +from gwdatafind import ui +from gwdatafind.api import ldr as api_ldr __author__ = "Duncan Macleod <duncan.macleod@ligo.org>" @@ -137,7 +135,7 @@ def test_url_scheme_handling(in_, url): def test_ping(requests_mock): """Test `ping()`.""" - requests_mock.get(_url(api.ping_path()), status_code=200) + requests_mock.get(_url(api_ldr.ping_path()), status_code=200) ui.ping() @@ -148,7 +146,7 @@ def test_ping(requests_mock): def test_find_observatories(match, result, requests_mock): """Test `find_observatories()`.""" requests_mock.get( - _url(api.find_observatories_path()), + _url(api_ldr.find_observatories_path()), json=list(TEST_DATA), ) assert ui.find_observatories(match=match) == list(set(result)) @@ -181,7 +179,7 @@ def test_find_types(site, match, result, requests_mock): else: respdata = [ft for site in TEST_DATA for ft in TEST_DATA[site]] requests_mock.get( - _url(api.find_types_path(site=site)), + _url(api_ldr.find_types_path(site=site)), json=respdata, ) assert ui.find_types( @@ -195,7 +193,7 @@ def test_find_times(requests_mock): site = "A" frametype = "A1_TEST" requests_mock.get( - _url(api.find_times_path(site, frametype, 1, 100)), + _url(api_ldr.find_times_path(site, frametype, 1, 100)), json=TEST_DATA[site][frametype], ) assert ui.find_times(site, frametype, 1, 100) == segments.segmentlist([ @@ -212,7 +210,7 @@ def test_find_url(requests_mock): "gsiftp://localhost:2811/data/A/A1_TEST/A-A1_TEST-0-1.gwf", ] requests_mock.get( - _url(api.find_url_path("A-A1_TEST-0-1.gwf")), + _url(api_ldr.find_url_path("A-A1_TEST-0-1.gwf")), json=urls, ) assert ui.find_url("/my/data/A-A1_TEST-0-1.gwf") == urls[:1] @@ -249,7 +247,7 @@ def test_find_url_on_missing(requests_mock, on_missing, ctx): """Test `find_url` handling of missing data.""" # mock the request requests_mock.get( - _url(api.find_url_path("A-A1_TEST-0-1.gwf")), + _url(api_ldr.find_url_path("A-A1_TEST-0-1.gwf")), json=[], ) @@ -269,7 +267,7 @@ def test_find_latest(requests_mock): "gsiftp://localhost:2811/data/A/A1_TEST/A-A1_TEST-0-1.gwf", ] requests_mock.get( - _url(api.find_latest_path("A", "A1_TEST", "file")), + _url(api_ldr.find_latest_path("A", "A1_TEST", "file")), json=urls[:1], ) assert ui.find_latest("A", "A1_TEST") == urls[:1] @@ -284,7 +282,7 @@ def test_find_urls(requests_mock): """Test `find_urls()`.""" urls = list(map(_file_url, TEST_DATA["A"]["A1_TEST"][:2])) requests_mock.get( - _url(api.find_urls_path("A", "A1_TEST", 0, 20, "file")), + _url(api_ldr.find_urls_path("A", "A1_TEST", 0, 20, "file")), json=urls, ) assert ui.find_urls("A", "A1_TEST", 0, 20, on_gaps="error") == urls @@ -317,7 +315,7 @@ def test_find_urls_on_gaps(requests_mock, on_gaps, ctx): # configure the mock request urls = list(map(_file_url, TEST_DATA["A"]["A1_TEST"])) requests_mock.get( - _url(api.find_urls_path("A", "A1_TEST", 0, 100, "file")), + _url(api_ldr.find_urls_path("A", "A1_TEST", 0, 100, "file")), json=urls, ) diff --git a/gwdatafind/ui.py b/gwdatafind/ui.py index c4bc38e..e210bcb 100644 --- a/gwdatafind/ui.py +++ b/gwdatafind/ui.py @@ -31,7 +31,7 @@ import igwn_segments as segments import requests from igwn_auth_utils.requests import get as _get -from . import api +from .api import ldr as api_ldr from .utils import ( file_segment, get_default_host, @@ -127,7 +127,7 @@ def _url(host, api_func, *args, **kwargs): return f"{host.rstrip('/')}/{path}" -def ping(host=None, ext=api.DEFAULT_EXT, session=None, **request_kw): +def ping(host=None, ext=api_ldr.DEFAULT_EXT, session=None, **request_kw): """Ping the GWDataFind host to test for life. Parameters @@ -161,7 +161,7 @@ def ping(host=None, ext=api.DEFAULT_EXT, session=None, **request_kw): requests.RequestException if the request fails for any reason """ - qurl = _url(host, api.ping_path, ext=ext) + qurl = _url(host, api_ldr.ping_path, ext=ext) response = get(qurl, session=session, **request_kw) response.raise_for_status() @@ -169,7 +169,7 @@ def ping(host=None, ext=api.DEFAULT_EXT, session=None, **request_kw): def find_observatories( match=None, host=None, - ext=api.DEFAULT_EXT, + ext=api_ldr.DEFAULT_EXT, session=None, **request_kw, ): @@ -222,7 +222,7 @@ def find_observatories( >>> find_observatories(match="H", host="datafind.gwosc.org") ['H'] """ - qurl = _url(host, api.find_observatories_path, ext=ext) + qurl = _url(host, api_ldr.find_observatories_path, ext=ext) sites = set(get_json(qurl, session=session, **request_kw)) if match: match = compile_regex(match).search @@ -234,7 +234,7 @@ def find_types( site=None, match=None, host=None, - ext=api.DEFAULT_EXT, + ext=api_ldr.DEFAULT_EXT, session=None, **request_kw, ): @@ -292,7 +292,7 @@ def find_types( (accurate as of Nov 18 2021) """ # noqa: E501 - qurl = _url(host, api.find_types_path, site=site, ext=ext) + qurl = _url(host, api_ldr.find_types_path, site=site, ext=ext) types = set(get_json(qurl, session=session, **request_kw)) if match: match = compile_regex(match).search @@ -306,7 +306,7 @@ def find_times( gpsstart=None, gpsend=None, host=None, - ext=api.DEFAULT_EXT, + ext=api_ldr.DEFAULT_EXT, session=None, **request_kw, ): @@ -377,7 +377,7 @@ def find_times( """ # noqa: E501 qurl = _url( host, - api.find_times_path, + api_ldr.find_times_path, site, frametype, gpsstart, @@ -465,7 +465,7 @@ def find_url( RuntimeError if no matching URLs are found and ``on_missing="error"`` was given """ - qurl = _url(host, api.find_url_path, framefile) + qurl = _url(host, api_ldr.find_url_path, framefile) return _get_urls( qurl, scheme=urltype, @@ -481,7 +481,7 @@ def find_latest( urltype="file", on_missing="error", host=None, - ext=api.DEFAULT_EXT, + ext=api_ldr.DEFAULT_EXT, session=None, **request_kw, ): @@ -549,7 +549,7 @@ def find_latest( """ # noqa: E501 qurl = _url( host, - api.find_latest_path, + api_ldr.find_latest_path, site, frametype, ext=ext, @@ -567,7 +567,7 @@ def find_urls( urltype="file", on_gaps="warn", host=None, - ext=api.DEFAULT_EXT, + ext=api_ldr.DEFAULT_EXT, session=None, **request_kw, ): @@ -635,7 +635,7 @@ def find_urls( """ qurl = _url( host, - api.find_urls_path, + api_ldr.find_urls_path, site, frametype, gpsstart, -- GitLab