Skip to content

Commit

Permalink
Merge pull request #96 from ASFHyP3/develop
Browse files Browse the repository at this point in the history
Release v0.1.2
  • Loading branch information
AndrewPlayer3 authored Dec 17, 2024
2 parents 57744a6 + c50b6f4 commit f0b8278
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ on:

jobs:
call-changelog-check-workflow:
uses: ASFHyP3/actions/.github/workflows/reusable-changelog-check.yml@v0.11.2
uses: ASFHyP3/actions/.github/workflows/reusable-changelog-check.yml@v0.12.0
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
call-release-workflow:
uses: ASFHyP3/actions/.github/workflows/reusable-release.yml@v0.11.2
uses: ASFHyP3/actions/.github/workflows/reusable-release.yml@v0.12.0
with:
release_prefix: Sentinel-1 Orbits
secrets:
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ name: Static analysis
on: push

jobs:
secrets:
uses: ASFHyP3/actions/.github/workflows/[email protected]
call-secrets-analysis-workflow:
# Docs: https://github.com/ASFHyP3/actions
uses: ASFHyP3/actions/.github/workflows/[email protected]

flake8:
uses: ASFHyP3/actions/.github/workflows/[email protected]
with:
local_package_names: fetcher,api
call-ruff-workflow:
# Docs: https://github.com/ASFHyP3/actions
uses: ASFHyP3/actions/.github/workflows/[email protected]

cfn-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- uses: scottbrenner/[email protected].2
- run: cfn-lint --info --ignore-checks W3002 `find . -name cloudformation.yml`
- uses: scottbrenner/[email protected].6
- run: cfn-lint --info --ignore-checks W3002 --template `find . -name cloudformation.yml`
2 changes: 1 addition & 1 deletion .github/workflows/tag-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ on:

jobs:
call-bump-version-workflow:
uses: ASFHyP3/actions/.github/workflows/reusable-bump-version.yml@v0.11.2
uses: ASFHyP3/actions/.github/workflows/reusable-bump-version.yml@v0.12.0
secrets:
USER_TOKEN: ${{ secrets.TOOLS_BOT_PAK }}
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: mamba-org/setup-micromamba@v1
- uses: mamba-org/setup-micromamba@v2
with:
environment-file: environment.yml

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [PEP 440](https://www.python.org/dev/peps/pep-0440/)
and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.2]

### Changed
- The [`static-analysis`](.github/workflows/static-analysis.yml) Github Actions workflow now uses `ruff` rather than `flake8` for linting.

## [0.1.1]

### Fixed
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from connexion import AsyncApp
from mangum import Mangum


app = AsyncApp(__name__)
app.add_api('openapi.yml')
lambda_handler = Mangum(app)
Expand Down
11 changes: 6 additions & 5 deletions apps/fetcher/src/fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import boto3
import requests


ESA_CREATE_TOKEN_URL = 'https://identity.dataspace.copernicus.eu/auth/realms/CDSE/protocol/openid-connect/token'
ESA_DELETE_TOKEN_URL = 'https://identity.dataspace.copernicus.eu/auth/realms/CDSE/account/sessions'

Expand All @@ -17,10 +18,9 @@ class EsaToken:
"""Context manager for authentication tokens for the ESA Copernicus Data Space Ecosystem (CDSE)"""

def __init__(self, username: str, password: str):
"""
Args:
username: CDSE username
password: CDSE password
"""Args:
username: CDSE username
password: CDSE password
"""
self.username = username
self.password = password
Expand Down Expand Up @@ -78,7 +78,8 @@ def get_cdse_orbits(orbit_type: str) -> list[dict]:
{
'filename': feature['properties']['title'],
'id': feature['id'],
} for feature in response.json()['features']
}
for feature in response.json()['features']
]
cdse_orbits.extend(items)
params['page'] += 1
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ dependencies:
- python=3.12
- pip
- pytest
- ruff
- responses
- pip:
- -r requirements-api.txt
Expand Down
30 changes: 30 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[project]
requires-python = "==3.12"

[tool.ruff]
line-length = 120
# The directories to consider when resolving first- vs. third-party imports.
# See: https://docs.astral.sh/ruff/settings/#src
src = ["**/src", "tests"]

[tool.ruff.format]
indent-style = "space"
quote-style = "single"

[tool.ruff.lint]
extend-select = [
"I", # isort: https://docs.astral.sh/ruff/rules/#isort-i
"UP", # pyupgrade: https://docs.astral.sh/ruff/rules/#pyupgrade-up

# TODO: uncomment the following extensions and address their warnings:
#"D", # pydocstyle: https://docs.astral.sh/ruff/rules/#pydocstyle-d
#"ANN", # annotations: https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
#"PTH", # use-pathlib-pth: https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.isort]
case-sensitive = true
lines-after-imports = 2
6 changes: 3 additions & 3 deletions requirements-api.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
boto3==1.34.145
cachetools==5.4.0
boto3==1.35.76
cachetools==5.5.0
connexion[swagger-ui]==3.1.0
mangum==0.17.0
mangum==0.19.0
2 changes: 1 addition & 1 deletion requirements-fetcher.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
boto3==1.34.145
boto3==1.35.76
requests==2.32.3
86 changes: 46 additions & 40 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,20 @@ def s3_stubber():

def test_lambda_handler():
event = {
'version': '2.0',
'requestContext': {
'http': {
'method': 'GET',
'path': '/ui',
'sourceIp': '127.0.0.1',
'version': '2.0',
'requestContext': {
'http': {
'method': 'GET',
'path': '/ui',
'sourceIp': '127.0.0.1',
},
},
},
}
assert api.lambda_handler(event, None) == {
'body': '',
'headers': {
'content-length': '0',
'content-type': 'application/json',
'location': '/ui/'
},
'headers': {'content-length': '0', 'content-type': 'application/json', 'location': '/ui/'},
'isBase64Encoded': False,
'statusCode': 307
'statusCode': 307,
}

event['requestContext']['http']['path'] = '/ui/'
Expand All @@ -53,10 +49,7 @@ def test_build_url():
def test_list_bucket(s3_stubber):
s3_stubber.add_response(
method='list_objects_v2',
expected_params={
'Bucket': 'foo',
'Prefix': 'bar'
},
expected_params={'Bucket': 'foo', 'Prefix': 'bar'},
service_response={
'Contents': [
{'Key': 'a'},
Expand Down Expand Up @@ -94,22 +87,28 @@ def test_get_orbit_for_granule():
mock_list_bucket.return_value = [
'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230604T080854_V20230514T225942_20230516T005942.EOF',
]
assert api.get_orbit_for_granule(
granule='S1A_IW_GRDH_1SDV_20230515T075514_20230515T075542_048541_05D6B8_579B',
bucket='myBucket',
orbit_type='myOrbitType',
) == 'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230604T080854_V20230514T225942_20230516T005942.EOF'
assert (
api.get_orbit_for_granule(
granule='S1A_IW_GRDH_1SDV_20230515T075514_20230515T075542_048541_05D6B8_579B',
bucket='myBucket',
orbit_type='myOrbitType',
)
== 'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230604T080854_V20230514T225942_20230516T005942.EOF'
)
mock_list_bucket.assert_called_once_with(bucket='myBucket', prefix='myOrbitType/S1A')

with unittest.mock.patch('api.list_bucket') as mock_list_bucket:
mock_list_bucket.return_value = [
'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230604T080854_V20230514T225942_20230516T005942.EOF',
]
assert api.get_orbit_for_granule(
granule='S1A_IW_GRDH_1SDV_20240515T075514_20240515T075542_048541_05D6B8_579B',
bucket='myBucket',
orbit_type='myOrbitType',
) is None
assert (
api.get_orbit_for_granule(
granule='S1A_IW_GRDH_1SDV_20240515T075514_20240515T075542_048541_05D6B8_579B',
bucket='myBucket',
orbit_type='myOrbitType',
)
is None
)
mock_list_bucket.assert_called_once_with(bucket='myBucket', prefix='myOrbitType/S1A')

with unittest.mock.patch('api.list_bucket') as mock_list_bucket:
Expand All @@ -118,11 +117,14 @@ def test_get_orbit_for_granule():
'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230605T080854_V20240514T225942_20240516T005942.EOF',
'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230604T080854_V20240514T225942_20240516T005942.EOF',
]
assert api.get_orbit_for_granule(
granule='S1A_IW_GRDH_1SDV_20240515T075514_20240515T075542_048541_05D6B8_579B',
bucket='myBucket',
orbit_type='myOrbitType',
) == 'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230606T080854_V20240514T225942_20240516T005942.EOF'
assert (
api.get_orbit_for_granule(
granule='S1A_IW_GRDH_1SDV_20240515T075514_20240515T075542_048541_05D6B8_579B',
bucket='myBucket',
orbit_type='myOrbitType',
)
== 'AUX_POEORB/S1A_OPER_AUX_POEORB_OPOD_20230606T080854_V20240514T225942_20240516T005942.EOF'
)
mock_list_bucket.assert_called_once_with(bucket='myBucket', prefix='myOrbitType/S1A')


Expand All @@ -131,10 +133,12 @@ def test_get_url():
mock_get_orbit_for_granule.return_value = None
assert api.get_url(granule='myGranule', bucket='myBucket') is None
assert mock_get_orbit_for_granule.call_count == 2
mock_get_orbit_for_granule.assert_has_calls([
unittest.mock.call('myGranule', 'myBucket', 'AUX_POEORB'),
unittest.mock.call('myGranule', 'myBucket', 'AUX_RESORB'),
])
mock_get_orbit_for_granule.assert_has_calls(
[
unittest.mock.call('myGranule', 'myBucket', 'AUX_POEORB'),
unittest.mock.call('myGranule', 'myBucket', 'AUX_RESORB'),
]
)

with unittest.mock.patch('api.get_orbit_for_granule') as mock_get_orbit_for_granule:
mock_get_orbit_for_granule.return_value = 'foo'
Expand All @@ -145,10 +149,12 @@ def test_get_url():
mock_get_orbit_for_granule.side_effect = [None, 'bar']
assert api.get_url(granule='myGranule', bucket='myBucket') == 'https://myBucket.s3.amazonaws.com/bar'
assert mock_get_orbit_for_granule.call_count == 2
mock_get_orbit_for_granule.assert_has_calls([
unittest.mock.call('myGranule', 'myBucket', 'AUX_POEORB'),
unittest.mock.call('myGranule', 'myBucket', 'AUX_RESORB'),
])
mock_get_orbit_for_granule.assert_has_calls(
[
unittest.mock.call('myGranule', 'myBucket', 'AUX_POEORB'),
unittest.mock.call('myGranule', 'myBucket', 'AUX_RESORB'),
]
)


def test_get_orbit(monkeypatch):
Expand Down
9 changes: 2 additions & 7 deletions tests/test_fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ def test_esa_token():
def test_get_s3_orbits(s3_stubber):
s3_stubber.add_response(
method='list_objects_v2',
expected_params={
'Bucket': 'foo',
'Prefix': 'bar'
},
expected_params={'Bucket': 'foo', 'Prefix': 'bar'},
service_response={
'Contents': [
{'Key': 'bar/a'},
Expand Down Expand Up @@ -139,9 +136,7 @@ def test_get_cdse_orbits():
responses.get(
url=url,
match=[responses.matchers.query_param_matcher({'productType': 'AUX_RESORB', 'maxRecords': 1000, 'page': 3})],
json={
'features': []
},
json={'features': []},
)

assert fetcher.get_cdse_orbits('AUX_RESORB') == [
Expand Down

0 comments on commit f0b8278

Please sign in to comment.