diff --git a/CHANGES.rst b/CHANGES.rst index 4188d3c0dd..968da2ebdd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -51,6 +51,11 @@ vo_conesearch Service fixes and enhancements ------------------------------ +astrometry_net +^^^^^^^^^^^^^^ + +- Added ``get_query_payload`` kwarg to aid in debugging. [#3555] + svo_fps ^^^^^^^ diff --git a/astroquery/astrometry_net/core.py b/astroquery/astrometry_net/core.py index 751c4b8e57..7ba6a179f7 100644 --- a/astroquery/astrometry_net/core.py +++ b/astroquery/astrometry_net/core.py @@ -284,6 +284,7 @@ def solve_from_source_list(self, x, y, image_width, image_height, *, solve_timeout=TIMEOUT, verbose=True, return_submission_id=False, + get_query_payload=False, **settings ): """ @@ -307,6 +308,9 @@ def solve_from_source_list(self, x, y, image_width, image_height, *, Whether to print out information about the solving. return_submission_id : bool, optional Whether to return the Submission ID number. + get_query_payload : bool, optional + if set to `True` then returns the dictionary sent as the HTTP + request. Defaults to `False`. For a list of the remaining settings, use the method `~AstrometryNetClass.show_allowed_settings`. @@ -323,6 +327,8 @@ def solve_from_source_list(self, x, y, image_width, image_height, *, settings['image_height'] = image_height settings['session'] = self._session_id payload = self._construct_payload(settings) + if get_query_payload: + return payload url = url_helpers.join(self.API_URL, 'url_upload') response = self._request('POST', url, data=payload, cache=False) if response.status_code != 200: @@ -342,6 +348,7 @@ def solve_from_image(self, image_file_path, *, force_image_upload=False, solve_timeout=TIMEOUT, verbose=True, return_submission_id=False, + get_query_payload=False, **settings): """ Plate solve from an image, either by uploading the image to @@ -387,6 +394,9 @@ def solve_from_image(self, image_file_path, *, force_image_upload=False, return_submission_id : bool, optional Whether to return the Submission ID number. + get_query_payload : bool, optional + if set to `True` then returns the dictionary sent as the HTTP + request. Defaults to `False`. For a list of the remaining settings, use the method `~AstrometryNetClass.show_allowed_settings`. @@ -410,6 +420,8 @@ def solve_from_image(self, image_file_path, *, force_image_upload=False, self._login() settings['session'] = self._session_id payload = self._construct_payload(settings) + if get_query_payload: + return payload url = url_helpers.join(self.API_URL, 'upload') with open(image_file_path, 'rb') as f: response = self._request('POST', url, data=payload, @@ -464,6 +476,7 @@ def solve_from_image(self, image_file_path, *, force_image_upload=False, solve_timeout=solve_timeout, verbose=verbose, return_submission_id=return_submission_id, + get_query_payload=get_query_payload, **settings) if response.status_code != 200: raise RuntimeError('Post of job failed') diff --git a/astroquery/astrometry_net/tests/test_astrometry_net.py b/astroquery/astrometry_net/tests/test_astrometry_net.py index 1a79aeb3ac..0d3eead2e7 100644 --- a/astroquery/astrometry_net/tests/test_astrometry_net.py +++ b/astroquery/astrometry_net/tests/test_astrometry_net.py @@ -3,6 +3,7 @@ import json import pytest +from unittest.mock import patch, mock_open from .. import AstrometryNet @@ -186,3 +187,43 @@ def test_invalid_setting_in_solve_from_source_list_name_raises_error(): # The keyword argument is definitely not one of the allowed ones. anet.solve_from_source_list([], [], [], [], im_a_bad_setting_name=5) assert 'im_a_bad_setting_name is not allowed' in str(e.value) + + +def test_get_query_payload_solve_from_source_list(): + anet = AstrometryNet() + anet.api_key = 'fakekey' + # Mock the _login method to prevent actual HTTP requests + with patch.object(anet, '_login'): + # Test that get_query_payload=True returns the payload dict + payload = anet.solve_from_source_list([1, 2, 3], [4, 5, 6], 100, 100, + get_query_payload=True) + assert isinstance(payload, dict) + assert 'request-json' in payload + settings = json.loads(payload['request-json']) + assert settings['x'] == [1.0, 2.0, 3.0] + assert settings['y'] == [4.0, 5.0, 6.0] + assert settings['image_width'] == 100 + assert settings['image_height'] == 100 + + +def test_get_query_payload_solve_from_image(): + anet = AstrometryNet() + anet.api_key = 'fakekey' + with patch.object(anet, '_login'): + anet._session_id = 'fakesessionid' + with patch('builtins.open', mock_open()): + payload = anet.solve_from_image('fake_image.fits', + get_query_payload=True, + center_ra=10.5, + center_dec=20.3) + assert isinstance(payload, dict) + assert 'request-json' in payload + settings = json.loads(payload['request-json']) + assert settings['session'] == 'fakesessionid' + assert settings['center_ra'] == 10.5 + assert settings['center_dec'] == 20.3 + # Verify that source list specific parameters are not present + assert 'x' not in settings + assert 'y' not in settings + assert 'image_width' not in settings + assert 'image_height' not in settings diff --git a/docs/astrometry_net/astrometry_net.rst b/docs/astrometry_net/astrometry_net.rst index 1d9aed171b..6b046588ad 100644 --- a/docs/astrometry_net/astrometry_net.rst +++ b/docs/astrometry_net/astrometry_net.rst @@ -397,6 +397,18 @@ There are two parameters that describe setting a license: other users. This can either be set to ``y``, ``n``, or ``d``, which uses the default license associated with the api key. +Debugging Options +^^^^^^^^^^^^^^^^^ + +To inspect the data being sent to the server for debugging purposes without +making a network call, you can use the following parameter: + +``get_query_payload`` + If set to ``True``, returns the prepared query payload and does not send + the request to the external server. No job is created and no solution is + returned. This allows verification of parameters, source lists, or image + headers before submitting an actual solve operation. + Reference/API =============