diff --git a/hvpy/api_groups/screenshots/download_screenshot.py b/hvpy/api_groups/screenshots/download_screenshot.py new file mode 100644 index 0000000..41cbbe3 --- /dev/null +++ b/hvpy/api_groups/screenshots/download_screenshot.py @@ -0,0 +1,26 @@ +from hvpy.io import HvpyParameters, OutputType + + +class downloadScreenshotInputParameters(HvpyParameters): + """ + Handles the input parameters of the downloadScreenshot API. + + Attributes + ---------- + {Shared} + id: int + Unique screenshot identifier (provided by the response to a takeScreenshot request). + + References + ---------- + * ``__ + {Shared} + """ + + id: int + + def get_output_type(self) -> OutputType: + """ + Returns the output type of the API call. + """ + return OutputType.RAW diff --git a/hvpy/api_groups/screenshots/take_screenshot.py b/hvpy/api_groups/screenshots/take_screenshot.py new file mode 100644 index 0000000..579f751 --- /dev/null +++ b/hvpy/api_groups/screenshots/take_screenshot.py @@ -0,0 +1,90 @@ +from typing import Optional +from datetime import datetime + +from pydantic import validator + +from hvpy.io import HvpyParameters, OutputType +from hvpy.utils import convert_date_to_isoformat + + +class takeScreenshotInputParameters(HvpyParameters): + """ + Handles the input parameters of the takeScreenshot API. + + Attributes + ---------- + {Shared} + date : datetime.datetime + Desired date/time of the image. + imageScale : float + Image scale in arcseconds per pixel. + layers : str + Image datasource layer(s) to include in the screenshot. + eventLabels : bool + Optionally annotate each event marker with a text label. + events : str, optional + List feature/event types and FRMs to use to annoate the movie. Use the empty string to indicate that no feature/event annotations should be shown. + scale : bool, optional + Optionally overlay an image scale indicator. + scaleType : str, optional + Image scale indicator. + scaleX : int, optional + Horizontal offset of the image scale indicator in arcseconds with respect to the center of the Sun. + scaleY : int, optional + Vertical offset of the image scale indicator in arcseconds with respect to the center of the Sun. + width : str, optional + Width of the field of view in pixels. (Used in conjunction width x0,`y0`, and height). + height : str, optional + Height of the field of view in pixels. (Used in conjunction width x0,`y0`, and width). + x0 : str, optional + The horizontal offset of the center of the field of view from the center of the Sun. Used in conjunction with y0, width, and height. + y0 : str, optional + The vertical offset of the center of the field of view from the center of the Sun. Used in conjunction with x0, width, and height. + x1 : str, optional + The horizontal offset of the top-left corner of the field of view with respect to the center of the Sun (in arcseconds). Used in conjunction with y1, x2, and y2. + y1 : str, optional + The vertical offset of the top-left corner of the field of view with respect to the center of the Sun (in arcseconds). Used in conjunction with x1, x2, and y2. + x2 : str, optional + The horizontal offset of the bottom-right corner of the field of view with respect to the center of the Sun (in arcseconds). Used in conjunction with x1, y1, and y2. + y2 : str, optional + The vertical offset of the bottom-right corner of the field of view with respect to the center of the Sun (in arcseconds). Used in conjunction with x1, y1, and x2. + display : bool, optional + Set to true to directly output binary PNG image data. Default is `False` (which outputs a JSON object). + watermark : bool, optional + Optionally overlay a watermark consisting of a Helioviewer logo and the datasource abbreviation(s) and timestamp(s) displayed in the screenshot. + callback : str, optional + Wrap the response object in a function call of your choosing. + + References + ---------- + * ``__ + {Shared} + """ + + date: datetime + imageScale: float + layers: str + events: Optional[str] = None + eventLabels: Optional[bool] = False + scale: Optional[bool] = False + scaleType: Optional[str] = None + scaleX: Optional[int] = None + scaleY: Optional[int] = None + width: Optional[str] = None + height: Optional[str] = None + x0: Optional[str] = None + y0: Optional[str] = None + x1: Optional[str] = None + y1: Optional[str] = None + x2: Optional[str] = None + y2: Optional[str] = None + display: Optional[bool] = False + watermark: Optional[bool] = False + callback: Optional[str] = None + _date_vaidator = validator("date", allow_reuse=True)(convert_date_to_isoformat) + + def get_output_type(self) -> OutputType: + """ + Returns the output type of the API call. + """ + return OutputType.RAW if self.display else OutputType.JSON diff --git a/hvpy/api_groups/screenshots/tests/test_download_screenshot.py b/hvpy/api_groups/screenshots/tests/test_download_screenshot.py new file mode 100644 index 0000000..f29bf72 --- /dev/null +++ b/hvpy/api_groups/screenshots/tests/test_download_screenshot.py @@ -0,0 +1,19 @@ +import pytest + +from hvpy import downloadScreenshot +from hvpy.api_groups.screenshots.download_screenshot import downloadScreenshotInputParameters + + +def test_raw_response(): + response = downloadScreenshot(id=3240748) + assert isinstance(response, bytes) + + +def test_url_property(): + params = downloadScreenshotInputParameters(id=3240748) + assert params.url == "https://api.helioviewer.org/v2/downloadScreenshot/" + + +def test_error_handling(): + with pytest.raises(TypeError, match="missing 1 required positional argument: 'id'"): + downloadScreenshot() diff --git a/hvpy/api_groups/screenshots/tests/test_take_screenshot.py b/hvpy/api_groups/screenshots/tests/test_take_screenshot.py new file mode 100644 index 0000000..fbf9925 --- /dev/null +++ b/hvpy/api_groups/screenshots/tests/test_take_screenshot.py @@ -0,0 +1,64 @@ +from datetime import datetime + +import pytest + +from hvpy import takeScreenshot +from hvpy.api_groups.screenshots.take_screenshot import takeScreenshotInputParameters + + +def test_json_response(): + response = takeScreenshot( + date=datetime(2014, 1, 1, 23, 59, 59), + imageScale=2.4204409, + layers="[3,1,100]", + width=1920, + height=1200, + x0=0, + y0=0, + ) + assert "id" in response + + +def test_raw_response(): + response = takeScreenshot( + display=True, + date=datetime(2014, 1, 1, 23, 59, 59), + imageScale=2.4204409, + layers="[3,1,100]", + width=1920, + height=1200, + x0=0, + y0=0, + ) + assert isinstance(response, bytes) + + +def test_url_property(): + params = takeScreenshotInputParameters( + date=datetime(2014, 1, 1, 23, 59, 59), + imageScale=2.4204409, + layers="[3,1,100]", + width=1920, + height=1200, + x0=0, + y0=0, + ) + assert params.url == "https://api.helioviewer.org/v2/takeScreenshot/" + + +def test_error_handling(): + with pytest.raises(TypeError, match="missing 1 required positional argument: 'date'"): + takeScreenshot( + imageScale=2.4204409, + layers="[3,1,100]", + ) + with pytest.raises(TypeError, match="missing 1 required positional argument: 'imageScale'"): + takeScreenshot( + date=datetime(2014, 1, 1, 23, 59, 59), + layers="[3,1,100]", + ) + with pytest.raises(TypeError, match="missing 1 required positional argument: 'layers'"): + takeScreenshot( + date=datetime(2014, 1, 1, 23, 59, 59), + imageScale=2.4204409, + ) diff --git a/hvpy/facade.py b/hvpy/facade.py index a031ba3..4b26ea9 100644 --- a/hvpy/facade.py +++ b/hvpy/facade.py @@ -13,6 +13,8 @@ "getStatus", "getClosestImage", "getDataSources", + "takeScreenshot", + "downloadScreenshot", ] @@ -208,3 +210,91 @@ def getDataSources( callback=callback, ) return execute_api_call(input_parameters=params) + + +@add_shared_docstring(takeScreenshotInputParameters) +def takeScreenshot( + date: datetime, + imageScale: float, + layers: str, + events: Optional[str] = None, + eventLabels: Optional[bool] = False, + scale: Optional[bool] = False, + scaleType: Optional[str] = None, + scaleX: Optional[int] = None, + scaleY: Optional[int] = None, + width: Optional[str] = None, + height: Optional[str] = None, + x0: Optional[str] = None, + y0: Optional[str] = None, + x1: Optional[str] = None, + y1: Optional[str] = None, + x2: Optional[str] = None, + y2: Optional[str] = None, + display: Optional[bool] = False, + watermark: Optional[bool] = False, + callback: Optional[str] = None, +): + """ + Generate a custom screenshot. + + Parameters + ---------- + {Insert} + Examples + -------- + >>> from hvpy import takeScreenshot + >>> from datetime import datetime + >>> takeScreenshot( + ... date=datetime(2014, 1, 1, 23, 59, 59), + ... imageScale=2.44, + ... layers="[3,1,100]", + ... x0=0, + ... y0=0, + ... width=1920, + ... height=1200, + ... ) + {'id': ...} + """ + params = takeScreenshotInputParameters( + date=date, + imageScale=imageScale, + layers=layers, + events=events, + eventLabels=eventLabels, + scale=scale, + scaleType=scaleType, + scaleX=scaleX, + scaleY=scaleY, + width=width, + height=height, + x0=x0, + y0=y0, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + display=display, + watermark=watermark, + callback=callback, + ) + return execute_api_call(input_parameters=params) + + +@add_shared_docstring(downloadScreenshotInputParameters) +def downloadScreenshot(id: int) -> Union[bytes, str, Dict[str, Any]]: + """ + Download a custom screenshot (that was generated using the `takeScreenshot` + API endpoint). + + Parameters + ---------- + {Insert} + Examples + -------- + >>> from hvpy import downloadScreenshot + >>> downloadScreenshot(id=26728529) + b'...' + """ + params = downloadScreenshotInputParameters(id=id) + return execute_api_call(input_parameters=params) diff --git a/hvpy/parameters.py b/hvpy/parameters.py index e10de4f..2b6bfd1 100644 --- a/hvpy/parameters.py +++ b/hvpy/parameters.py @@ -5,6 +5,8 @@ from hvpy.api_groups.jpeg2000.get_status import getStatusInputParameters from hvpy.api_groups.official_clients.get_closest_image import getClosestImageInputParameters from hvpy.api_groups.official_clients.get_data_sources import getDataSourcesInputParameters +from hvpy.api_groups.screenshots.download_screenshot import downloadScreenshotInputParameters +from hvpy.api_groups.screenshots.take_screenshot import takeScreenshotInputParameters __all__ = [ "getJP2ImageInputParameters", @@ -14,4 +16,6 @@ "getStatusInputParameters", "getClosestImageInputParameters", "getDataSourcesInputParameters", + "takeScreenshotInputParameters", + "downloadScreenshotInputParameters", ]