From d0961f85ea0485091dc840b635920ecdb203589a Mon Sep 17 00:00:00 2001 From: Frazer McLean Date: Fri, 5 Jun 2026 19:03:35 +0200 Subject: [PATCH] Remove deprecated request classes that no longer exist --- docs/usage.rst | 2 +- src/spacetrack/aio.py | 12 +- src/spacetrack/base.py | 25 +--- tests/conftest.py | 314 +++++++++++++++++++++++++++++++++++++-- tests/test_aio.py | 52 +++---- tests/test_spacetrack.py | 78 +++++----- 6 files changed, 380 insertions(+), 103 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index 18bd3d9..63c73c6 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -12,7 +12,7 @@ Usage Request classes are presented as methods on the :class:`~spacetrack.base.SpaceTrackClient` object. For example, -``st.tle_publish()``. Each request class is part of a request controller. +``st.gp_history()``. Each request class is part of a request controller. Since most request classes are only part of one request controller, ``spacetrack`` looks up the controller for you. It can be specified explicitly in several ways. All the following are equivalent: diff --git a/src/spacetrack/aio.py b/src/spacetrack/aio.py index 2057e8d..6e4b438 100644 --- a/src/spacetrack/aio.py +++ b/src/spacetrack/aio.py @@ -174,8 +174,8 @@ async def generic_request( .. code-block:: python - st.tle_publish(*args, **kw) - st.basicspacedata.tle_publish(*args, **kw) + st.gp_history(*args, **kw) + st.basicspacedata.gp_history(*args, **kw) st.file(*args, **kw) st.fileshare.file(*args, **kw) st.spephemeris.file(*args, **kw) @@ -184,8 +184,8 @@ async def generic_request( .. code-block:: python - st.generic_request('tle_publish', *args, **kw) - st.generic_request('tle_publish', *args, controller='basicspacedata', **kw) + st.generic_request('gp_history', *args, **kw) + st.generic_request('gp_history', *args, controller='basicspacedata', **kw) st.generic_request('file', *args, **kw) st.generic_request('file', *args, controller='fileshare', **kw) st.generic_request('file', *args, controller='spephemeris', **kw) @@ -205,9 +205,9 @@ async def generic_request( .. code-block:: python spacetrack = SpaceTrackClient(...) - spacetrack.tle.get_predicates() + spacetrack.gp_history.get_predicates() # or - spacetrack.get_predicates('tle') + spacetrack.get_predicates('gp_history') See :func:`~spacetrack.operators._stringify_predicate_value` for which Python objects are converted appropriately. diff --git a/src/spacetrack/base.py b/src/spacetrack/base.py index 87d9206..95198d9 100644 --- a/src/spacetrack/base.py +++ b/src/spacetrack/base.py @@ -235,14 +235,10 @@ class SpaceTrackClient: "gp", "gp_history", "launch_site", - "omm", "satcat", "satcat_change", "satcat_debut", "tip", - "tle", - "tle_latest", - "tle_publish", } request_controllers["expandedspacedata"] = { @@ -282,14 +278,7 @@ class SpaceTrackClient: ("dirs", "publicfiles"): set(), ("download", "publicfiles"): set(), } - deprecated_controllers = { - "basicspacedata": { - "tle", - "tle_latest", - "tle_publish", - "omm", - }, - } + deprecated_controllers = {} param_fields = { ("download", "publicfiles"): {"name"}, } @@ -652,8 +641,8 @@ def generic_request( .. code-block:: python - st.tle_publish(*args, **kw) - st.basicspacedata.tle_publish(*args, **kw) + st.gp_history(*args, **kw) + st.basicspacedata.gp_history(*args, **kw) st.file(*args, **kw) st.fileshare.file(*args, **kw) st.spephemeris.file(*args, **kw) @@ -662,8 +651,8 @@ def generic_request( .. code-block:: python - st.generic_request('tle_publish', *args, **kw) - st.generic_request('tle_publish', *args, controller='basicspacedata', **kw) + st.generic_request('gp_history', *args, **kw) + st.generic_request('gp_history', *args, controller='basicspacedata', **kw) st.generic_request('file', *args, **kw) st.generic_request('file', *args, controller='fileshare', **kw) st.generic_request('file', *args, controller='spephemeris', **kw) @@ -685,9 +674,9 @@ def generic_request( .. code-block:: python spacetrack = SpaceTrackClient(...) - spacetrack.tle.get_predicates() + spacetrack.gp_history.get_predicates() # or - spacetrack.get_predicates('tle') + spacetrack.get_predicates('gp_history') See :func:`~spacetrack.operators._stringify_predicate_value` for which Python objects are converted appropriately. diff --git a/tests/conftest.py b/tests/conftest.py index a20d954..e3136e6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -47,34 +47,330 @@ def mock_predicates_empty(respx_mock): @pytest.fixture -def mock_tle_publish_predicates(respx_mock): - respx_mock.get("basicspacedata/modeldef/class/tle_publish").respond( +def mock_gp_predicates(respx_mock): + respx_mock.get("basicspacedata/modeldef/class/gp").respond( json={ "controller": "basicspacedata", "data": [ { - "Default": "0000-00-00 00:00:00", - "Extra": "", - "Field": "PUBLISH_EPOCH", + "Field": "CCSDS_OMM_VERS", + "Type": "varchar(3)", + "Null": "NO", "Key": "", + "Default": "", + "Extra": "", + }, + { + "Field": "COMMENT", + "Type": "varchar(33)", "Null": "NO", + "Key": "", + "Default": "", + "Extra": "", + }, + { + "Field": "CREATION_DATE", "Type": "datetime", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", }, { + "Field": "ORIGINATOR", + "Type": "varchar(7)", + "Null": "NO", + "Key": "", "Default": "", "Extra": "", - "Field": "TLE_LINE1", + }, + { + "Field": "OBJECT_NAME", + "Type": "varchar(25)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "OBJECT_ID", + "Type": "varchar(12)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "CENTER_NAME", + "Type": "varchar(5)", + "Null": "NO", "Key": "", + "Default": "", + "Extra": "", + }, + { + "Field": "REF_FRAME", + "Type": "varchar(4)", "Null": "NO", - "Type": "char(71)", + "Key": "", + "Default": "", + "Extra": "", }, { + "Field": "TIME_SYSTEM", + "Type": "varchar(3)", + "Null": "NO", + "Key": "", "Default": "", "Extra": "", - "Field": "TLE_LINE2", + }, + { + "Field": "MEAN_ELEMENT_THEORY", + "Type": "varchar(4)", + "Null": "NO", + "Key": "", + "Default": "", + "Extra": "", + }, + { + "Field": "EPOCH", + "Type": "datetime(6)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "MEAN_MOTION", + "Type": "decimal(13,8)", + "Null": "YES", "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "ECCENTRICITY", + "Type": "decimal(13,8)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "INCLINATION", + "Type": "decimal(7,4)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "RA_OF_ASC_NODE", + "Type": "decimal(7,4)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "ARG_OF_PERICENTER", + "Type": "decimal(7,4)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "MEAN_ANOMALY", + "Type": "decimal(7,4)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "EPHEMERIS_TYPE", + "Type": "tinyint(4)", + "Null": "YES", + "Key": "", + "Default": "0", + "Extra": "", + }, + { + "Field": "CLASSIFICATION_TYPE", + "Type": "char(1)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "NORAD_CAT_ID", + "Type": "int(10) unsigned", "Null": "NO", - "Type": "char(71)", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "ELEMENT_SET_NO", + "Type": "smallint(5) unsigned", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "REV_AT_EPOCH", + "Type": "mediumint(8) unsigned", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "BSTAR", + "Type": "decimal(19,14)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "MEAN_MOTION_DOT", + "Type": "decimal(9,8)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "MEAN_MOTION_DDOT", + "Type": "decimal(22,13)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "SEMIMAJOR_AXIS", + "Type": "double(12,3)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "PERIOD", + "Type": "double(12,3)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "APOAPSIS", + "Type": "double(12,3)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "PERIAPSIS", + "Type": "double(12,3)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "OBJECT_TYPE", + "Type": "varchar(12)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "RCS_SIZE", + "Type": "char(6)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "COUNTRY_CODE", + "Type": "char(6)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "LAUNCH_DATE", + "Type": "date", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "SITE", + "Type": "char(5)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "DECAY_DATE", + "Type": "date", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "FILE", + "Type": "bigint(20) unsigned", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "GP_ID", + "Type": "int(10) unsigned", + "Null": "NO", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "TLE_LINE0", + "Type": "varchar(27)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "TLE_LINE1", + "Type": "varchar(71)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", + }, + { + "Field": "TLE_LINE2", + "Type": "varchar(71)", + "Null": "YES", + "Key": "", + "Default": None, + "Extra": "", }, ], }, diff --git a/tests/test_aio.py b/tests/test_aio.py index be3ef03..4f51e4c 100644 --- a/tests/test_aio.py +++ b/tests/test_aio.py @@ -33,31 +33,35 @@ async def test_get_predicates_calls(async_runner, client): patch_get_predicates = patch.object(client, "get_predicates") with patch_get_predicates as mock_get_predicates: - await client.tle.get_predicates() - await client.basicspacedata.tle.get_predicates() - await client.basicspacedata.get_predicates("tle") - await client.get_predicates("tle") - await client.get_predicates("tle", "basicspacedata") + await client.gp.get_predicates() + await client.basicspacedata.gp.get_predicates() + await client.basicspacedata.get_predicates("gp") + await client.get_predicates("gp") + await client.get_predicates("gp", "basicspacedata") expected_calls = [ - call(class_="tle", controller="basicspacedata"), - call(class_="tle", controller="basicspacedata"), - call(class_="tle", controller="basicspacedata"), - call("tle"), - call("tle", "basicspacedata"), + call(class_="gp", controller="basicspacedata"), + call(class_="gp", controller="basicspacedata"), + call(class_="gp", controller="basicspacedata"), + call("gp"), + call("gp", "basicspacedata"), ] assert mock_get_predicates.await_args_list == expected_calls -async def test_get_predicates( - async_runner, client, mock_auth, mock_tle_publish_predicates -): - assert len(await client.tle_publish.get_predicates()) == 3 +async def test_get_predicates(async_runner, client, mock_auth, mock_gp_predicates): + predicates = await client.gp.get_predicates() + + assert {predicate.name for predicate in predicates} >= { + "ccsds_omm_vers", + "creation_date", + "norad_cat_id", + } async def test_generic_request( - client, async_runner, respx_mock, mock_auth, mock_tle_publish_predicates + client, async_runner, respx_mock, mock_auth, mock_gp_predicates ): tle = ( "1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927\r\n" @@ -66,15 +70,13 @@ async def test_generic_request( normalised_tle = tle.replace("\r\n", "\n") - respx_mock.get("basicspacedata/query/class/tle_publish/format/tle").respond( - text=tle - ) + respx_mock.get("basicspacedata/query/class/gp/format/tle").respond(text=tle) - assert await client.tle_publish(format="tle") == normalised_tle + assert await client.gp(format="tle") == normalised_tle - respx_mock.get("basicspacedata/query/class/tle_publish").respond(json={"a": 5}) + respx_mock.get("basicspacedata/query/class/gp").respond(json={"a": 5}) - result = await client.tle_publish() + result = await client.gp() assert result["a"] == 5 @@ -110,11 +112,11 @@ async def mock_aiter_text(): async def test_ratelimit_error( - async_runner, client, respx_mock, mock_auth, mock_tle_publish_predicates + async_runner, client, respx_mock, mock_auth, mock_gp_predicates ): from unittest.mock import AsyncMock - route = respx_mock.get("basicspacedata/query/class/tle_publish").mock( + route = respx_mock.get("basicspacedata/query/class/gp").mock( side_effect=[ httpx.Response(500, text="violated your query rate limit"), httpx.Response(200, json={"a": 1}), @@ -126,7 +128,7 @@ async def test_ratelimit_error( # Do it first without our own callback, then with. - assert await client.tle_publish() == {"a": 1} + assert await client.gp() == {"a": 1} assert route.call_count == 2 assert route.calls[0].response.status_code == 500 @@ -139,7 +141,7 @@ async def test_ratelimit_error( httpx.Response(200, json={"a": 1}), ] - assert await client.tle_publish() == {"a": 1} + assert await client.gp() == {"a": 1} assert route.call_count == 2 assert route.calls[0].response.status_code == 500 diff --git a/tests/test_spacetrack.py b/tests/test_spacetrack.py index 52e0dfb..d10f462 100644 --- a/tests/test_spacetrack.py +++ b/tests/test_spacetrack.py @@ -41,16 +41,16 @@ def mock_iter_text(): def test_generic_request_exceptions(client, mock_auth, mock_predicates_empty): with pytest.raises(ValueError): - client.generic_request(class_="tle", iter_lines=True, iter_content=True) + client.generic_request(class_="gp", iter_lines=True, iter_content=True) with pytest.raises(ValueError): client.generic_request(class_="thisclassdoesnotexist") with pytest.raises(TypeError): - client.generic_request("tle", madeupkeyword=None) + client.generic_request("gp", madeupkeyword=None) with pytest.raises(ValueError): - client.generic_request(class_="tle", controller="nonsense") + client.generic_request(class_="gp", controller="nonsense") with pytest.raises(ValueError): client.generic_request(class_="nonsense", controller="basicspacedata") @@ -61,7 +61,7 @@ def test_generic_request_exceptions(client, mock_auth, mock_predicates_empty): def test_get_predicates_exceptions(client): with pytest.raises(ValueError): - client.get_predicates(class_="tle", controller="nonsense") + client.get_predicates(class_="gp", controller="nonsense") with pytest.raises(ValueError): client.get_predicates(class_="nonsense", controller="basicspacedata") @@ -71,24 +71,24 @@ def test_get_predicates(client): patch_get_predicates = patch.object(SpaceTrackClient, "get_predicates") with patch_get_predicates as mock_get_predicates: - client.tle.get_predicates() - client.basicspacedata.tle.get_predicates() - client.basicspacedata.get_predicates("tle") - client.get_predicates("tle") - client.get_predicates("tle", "basicspacedata") + client.gp.get_predicates() + client.basicspacedata.gp.get_predicates() + client.basicspacedata.get_predicates("gp") + client.get_predicates("gp") + client.get_predicates("gp", "basicspacedata") expected_calls = [ - call(class_="tle", controller="basicspacedata"), - call(class_="tle", controller="basicspacedata"), - call(class_="tle", controller="basicspacedata"), - call("tle"), - call("tle", "basicspacedata"), + call(class_="gp", controller="basicspacedata"), + call(class_="gp", controller="basicspacedata"), + call(class_="gp", controller="basicspacedata"), + call("gp"), + call("gp", "basicspacedata"), ] assert mock_get_predicates.call_args_list == expected_calls -def test_generic_request(respx_mock, client, mock_auth, mock_tle_publish_predicates): +def test_generic_request(respx_mock, client, mock_auth, mock_gp_predicates): tle = ( "1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927\r\n" "2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537\r\n" @@ -96,29 +96,25 @@ def test_generic_request(respx_mock, client, mock_auth, mock_tle_publish_predica normalised_tle = tle.replace("\r\n", "\n") - respx_mock.get("basicspacedata/query/class/tle_publish/format/tle").respond( - text=tle - ) + respx_mock.get("basicspacedata/query/class/gp/format/tle").respond(text=tle) - assert client.tle_publish(format="tle") == normalised_tle + assert client.gp(format="tle") == normalised_tle - lines = list(client.tle_publish(iter_lines=True, format="tle")) + lines = list(client.gp(iter_lines=True, format="tle")) assert lines == [ "1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927", "2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537", ] - respx_mock.get("basicspacedata/query/class/tle_publish").respond(json={"a": 5}) + respx_mock.get("basicspacedata/query/class/gp").respond(json={"a": 5}) - result = client.tle_publish() + result = client.gp() assert result["a"] == 5 - respx_mock.get("basicspacedata/query/class/tle_publish").respond( - stream=[b"abc", b"def"] - ) + respx_mock.get("basicspacedata/query/class/gp").respond(stream=[b"abc", b"def"]) - result = list(client.tle_publish(iter_content=True)) + result = list(client.gp(iter_content=True)) assert "".join(result) == "abcdef" @@ -147,8 +143,8 @@ def test_bytes_response(client, respx_mock, mock_auth, mock_download_predicates) assert b"".join(result) == b"abcdef" -def test_ratelimit_error(client, respx_mock, mock_auth, mock_tle_publish_predicates): - route = respx_mock.get("basicspacedata/query/class/tle_publish").mock( +def test_ratelimit_error(client, respx_mock, mock_auth, mock_gp_predicates): + route = respx_mock.get("basicspacedata/query/class/gp").mock( side_effect=[ httpx.Response(500, text="violated your query rate limit"), httpx.Response(200, json={"a": 1}), @@ -160,7 +156,7 @@ def test_ratelimit_error(client, respx_mock, mock_auth, mock_tle_publish_predica # Do it first without our own callback, then with. - assert client.tle_publish() == {"a": 1} + assert client.gp() == {"a": 1} assert route.call_count == 2 assert route.calls[0].response.status_code == 500 @@ -173,28 +169,26 @@ def test_ratelimit_error(client, respx_mock, mock_auth, mock_tle_publish_predica httpx.Response(200, json={"a": 1}), ] - assert client.tle_publish() == {"a": 1} + assert client.gp() == {"a": 1} assert route.call_count == 2 assert route.calls[0].response.status_code == 500 assert mock_callback.call_count == 1 -def test_non_ratelimit_error( - client, respx_mock, mock_auth, mock_tle_publish_predicates -): +def test_non_ratelimit_error(client, respx_mock, mock_auth, mock_gp_predicates): # Change ratelimiter period to speed up test client._per_minute_throttle.rate = Quota.per_second(30) mock_callback = Mock() client.callback = mock_callback - respx_mock.get("basicspacedata/query/class/tle_publish").respond( + respx_mock.get("basicspacedata/query/class/gp").respond( 500, text="some other error" ) with pytest.raises(httpx.HTTPStatusError): - client.tle_publish() + client.gp() assert not mock_callback.called @@ -287,7 +281,7 @@ def test_predicate_parse_modeldef(client): def test_bare_spacetrack_methods(client): - """Verify that e.g. client.tle_publish calls client.generic_request('tle_publish')""" + """Verify that e.g. client.gp calls client.generic_request('gp')""" seen = set() with patch.object(SpaceTrackClient, "generic_request") as mock_generic_request: for controller, classes in client.request_controllers.items(): @@ -441,7 +435,6 @@ def test_dir(client): "launch_site", "maneuver", "maneuver_history", - "omm", "organization", "password", "publicfiles", @@ -451,9 +444,6 @@ def test_dir(client): "satellite", "spephemeris", "tip", - "tle", - "tle_latest", - "tle_publish", "upload", ] @@ -479,7 +469,7 @@ def test_predicate_parse_type(predicate, input, output): def test_parse_types(client, respx_mock, mock_auth): - respx_mock.get("basicspacedata/modeldef/class/tle_publish").respond( + respx_mock.get("basicspacedata/modeldef/class/gp").respond( json={ "controller": "basicspacedata", "data": [ @@ -519,7 +509,7 @@ def test_parse_types(client, respx_mock, mock_auth): }, ) - respx_mock.get("basicspacedata/query/class/tle_publish").respond( + respx_mock.get("basicspacedata/query/class/gp").respond( json=[ { # Test a type that is parsed. @@ -534,13 +524,13 @@ def test_parse_types(client, respx_mock, mock_auth): ], ) - (result,) = client.tle_publish(parse_types=True) + (result,) = client.gp(parse_types=True) assert result["PUBLISH_EPOCH"] == dt.datetime(2017, 1, 2, 3, 4, 5) assert result["TLE_LINE1"] == "The quick brown fox jumps over the lazy dog." assert result["OTHER_FIELD"] == "Spam and eggs." with pytest.raises(ValueError) as exc_info: - client.tle_publish(format="tle", parse_types=True) + client.gp(format="tle", parse_types=True) assert "parse_types" in exc_info.value.args[0]