Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ jobs:
with:
submodules: false
coverage: codecov
libraries: |
apt:
- libopenjp2-7
envs: |
- linux: py310
- linux: codestyle
Expand All @@ -38,22 +35,10 @@ jobs:
libraries: |
apt:
- libopenjp2-7
brew:
- openjpeg
- graphviz
envs: |
- macos: py38
- windows: py39
online:
needs: [test]
uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@main
with:
submodules: false
coverage: codecov
libraries: |
apt:
- libopenjp2-7
envs: |
- linux: py39-online
- linux: build_docs
publish:
# Build wheels when pushing to any branch except main
Expand Down
51 changes: 28 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,31 @@ repos:
- id: autoflake
args: ['--in-place', '--remove-all-unused-imports', '--remove-unused-variable']
exclude: ".*(.fits|.fts|.fit|.txt|tca.*|extern.*|.rst|.md|__init__.py|docs/conf.py)$"
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- repo: https://github.com/timothycrosley/isort
rev: 5.10.1
hooks:
- id: isort
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
hooks:
- id: check-ast
- id: check-case-conflict
- id: trailing-whitespace
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: mixed-line-ending
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: end-of-file-fixer
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: check-yaml
- id: debug-statements
- repo: https://github.com/psf/black
rev: 22.6.0
hooks:
- id: black
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- repo: https://github.com/timothycrosley/isort
rev: 5.10.1
hooks:
- id: isort
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: check-ast
- id: check-case-conflict
- id: trailing-whitespace
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: mixed-line-ending
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: end-of-file-fixer
exclude: ".*(.fits|.fts|.fit|.txt|.csv)$"
- id: check-yaml
- id: debug-statements
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v0.961'
hooks:
- id: mypy
additional_dependencies: [types-requests==2.28.0]
3 changes: 3 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ build:
os: ubuntu-20.04
tools:
python: "3.9"
apt_packages:
- libopenjp2-7
- graphviz

sphinx:
builder: html
Expand Down
9 changes: 7 additions & 2 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,10 @@ API Reference
*************

.. automodapi:: hvpy
:inherited-members:
:include-all-objects:

.. automodapi:: hvpy.core

.. automodapi:: hvpy.io

.. automodapi:: hvpy.parameters
:allowed-package-names: hvpy.api_groups
10 changes: 9 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
# -- General configuration ---------------------------------------------------
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.inheritance_diagram",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"sphinx.ext.doctest",
"sphinx.ext.mathjax",
"sphinx_automodapi.automodapi",
Expand All @@ -31,6 +31,14 @@

# Enable nitpicky mode, which forces links to be non-broken
nitpicky = True
# This is not used. See docs/nitpick-exceptions file for the actual listing.
nitpick_ignore = []
for line in open("nitpick-exceptions"):
if line.strip() == "" or line.startswith("#"):
continue
dtype, target = line.split(None, 1)
target = target.strip()
nitpick_ignore.append((dtype, target))

# -- Options for intersphinx extension -----------------------------------------
# Example configuration for intersphinx: refer to the Python standard library.
Expand Down
5 changes: 5 additions & 0 deletions docs/nitpick-exceptions
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
py:class optional
py:class pydantic.main.BaseModel
py:class pydantic.utils.Representation
py:class rtype
py:obj typing.Literal[<OutputType.RAW: 1>, <OutputType.JSON: 3>, <OutputType.STRING: 2>]
20 changes: 11 additions & 9 deletions hvpy/api_groups/jpeg2000/get_jp2_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@

class getJP2ImageInputParameters(HvpyParameters):
"""
Handles the input parameters of the `getJP2Image API.

<https://api.helioviewer.org/docs/v2/api/api_groups/jpeg2000.html#getjp2image>`__.
Handles the input parameters of the getJP2Image API.

Attributes
----------
date : datetime
date : datetime.datetime
Desired date/time of the JP2 image.
sourceId : int
Unique image datasource identifier.
jpip : bool, optional
Returns a JPIP URI instead of the binary data of the image if set to `True`, defaults to `False`.
json : bool, optional
Returns the JSON if set to `True`, defaults to `False`.

References
----------
* `<https://api.helioviewer.org/docs/v2/api/api_groups/jpeg2000.html#getjp2image>`__
"""

date: datetime
Expand All @@ -29,19 +31,19 @@ class getJP2ImageInputParameters(HvpyParameters):
Json: bool = Field(False, alias="json")

@validator("date")
def convert_date_to_isoformat(cls, v):
def convert_date_to_isoformat(cls, v) -> str:
"""
Converts the date from a datetime object to a string in the ISO format.
"""
return v.isoformat() + "Z"

def get_output_type(self):
def get_output_type(self) -> OutputType:
"""
Returns the output type of the API call.
"""
if self.Json and self.jpip:
return OutputType.Json
return OutputType.JSON
elif not self.Json and self.jpip:
return OutputType.String
return OutputType.STRING
else:
return OutputType.Raw
return OutputType.RAW
27 changes: 16 additions & 11 deletions hvpy/core.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,52 @@
from typing import Any, Dict, Union

import requests

from hvpy.io import HvpyParameters, OutputType

__all__ = ["execute_api_call", "parse_response"]


def parse_response(response: requests.Response, output_parameters: OutputType):
def parse_response(response: requests.Response, output_type: OutputType) -> Union[bytes, str, Dict[str, Any]]:
"""
Parses the response from the API call based on the output type.

Parameters
----------
response : requests.Response
The response from the API call.
output_parameters : OutputType
output_type : hvpy.io.OutputType
The output type.

Returns
-------
binary | str | json
Union[bytes, str, Dict[str, Any]]
The parsed response.
"""

if output_parameters == OutputType.Raw:
if output_type == OutputType.RAW:
return response.content
elif output_parameters == OutputType.String:
elif output_type == OutputType.STRING:
return response.content.decode("utf-8")
elif output_parameters == OutputType.Json:
elif output_type == OutputType.JSON:
return response.json()
else:
raise ValueError(f"Unknown output type: {output_type}")


def execute_api_call(input_parameters: HvpyParameters):
def execute_api_call(input_parameters: HvpyParameters) -> Union[bytes, str, Dict[str, Any]]:
"""
Executes the API call and returns a parsed response.

Parameters
----------
input_parameters : HvpyParameters
input_parameters : hvpy.io.HvpyParameters
The input parameters.

Returns
-------
Parsed response from the API.
Union[bytes, str, Dict[str, Any]]
Parsed response from the API.
"""

response = requests.get(input_parameters.url, params=input_parameters.dict())
response.raise_for_status()
return parse_response(response, input_parameters.get_output_type())
56 changes: 41 additions & 15 deletions hvpy/io.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,57 @@
from enum import Enum, auto
from typing import Any, Dict

from pydantic import BaseModel
from pydantic.main import BaseModel

__all__ = ["HvpyParameters", "OutputType"]

BASE_URL = "https://api.helioviewer.org/v2/"


class OutputType(Enum):
RAW = auto()
"""
Defines the RAW output type.
"""
STRING = auto()
"""
Defines the STRING output type.
"""
JSON = auto()
"""
Defines the JSON output type.
"""


class HvpyParameters(BaseModel):
def dict(self):
"""
Pydantic doesn't allow using lowercase 'json' as a field, so we
override it.
"""
"""
Base model for all Helioviewer API parameters.
"""

def dict(self) -> Dict[str, Any]: # type: ignore
# pydantic doesn't allow using lowercase 'json' as a field
d = super().dict()
if "Json" in d:
d["json"] = d["Json"]
del d["Json"]
return d

def get_output_type(self):
return OutputType.Raw
def get_output_type(self) -> OutputType:
"""
Works out the return type of the API call.

This by default is RAW, subclasses should redefine this.

Returns
-------
hvpy.io.OutputType
Output type based on the model.
"""
return OutputType.RAW

@property
def url(self):
def url(self) -> str:
"""
Final API endpoint URL.
"""
return BASE_URL + self.__class__.__name__[:-15] + "/"


class OutputType(Enum):
Raw = auto()
String = auto()
Json = auto()
3 changes: 3 additions & 0 deletions hvpy/parameters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from hvpy.api_groups.jpeg2000.get_jp2_image import getJP2ImageInputParameters

__all__ = ["getJP2ImageInputParameters"]
8 changes: 8 additions & 0 deletions hvpy/tests/test_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pytest

from hvpy.core import parse_response


def test_wrong_input_type():
with pytest.raises(ValueError, match="Unknown output type: 42"):
parse_response(None, 42)
2 changes: 1 addition & 1 deletion hvpy/tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

def test_default_get_output_type_is_raw():
params = HvpyParameters()
assert params.get_output_type() == OutputType.Raw
assert params.get_output_type() == OutputType.RAW


def test_url_property():
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ exclude = '''
)/
)
'''

[tool.mypy]
python_version = "3.10"
ignore_missing_imports = true
exclude = [
'setup.py',
'docs/conf.py',
]
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = hvpy
author = The Helioviewer Project
author_email = contact@helioviewer.org
license = BSD 2-Clause
license_file = licenses/LICENSE.rst
license_files = licenses/LICENSE.rst
url = https://helioviewer.org/
description = Helioviewer Python API Wrapper
long_description = file: README.rst
Expand Down