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