Skip to content

Commit 2f47607

Browse files
authored
DAS-NONE: Random small fixes. (#38)
No functional differences. Code cleanup and refactor
1 parent 2775c15 commit 2f47607

23 files changed

+183
-205
lines changed

Diff for: .github/workflows/run_lib_tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
python-version: ['3.10', '3.11']
13+
python-version: ['3.10', '3.11', '3.12']
1414

1515
steps:
1616
- name: Checkout harmony-browse-image-generator repository

Diff for: .github/workflows/run_service_tests.yml

+3-9
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,8 @@ jobs:
2929
- name: Run test image
3030
run: ./bin/run-test
3131

32-
- name: Archive test results
32+
- name: Archive test results and coverage
3333
uses: actions/upload-artifact@v4
3434
with:
35-
name: Test results
36-
path: test-reports/
37-
38-
- name: Archive coverage report
39-
uses: actions/upload-artifact@v4
40-
with:
41-
name: Coverage report
42-
path: coverage/*
35+
name: reports
36+
path: reports/**/*

Diff for: .pre-commit-config.yaml

+4-7
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ repos:
1313
rev: v0.8.2
1414
hooks:
1515
- id: ruff
16-
args: ["--fix", "--show-fixes", "--extend-select", "I"]
17-
- repo: https://github.com/psf/black-pre-commit-mirror
18-
rev: 24.10.0
19-
hooks:
20-
- id: black-jupyter
21-
args: ["--skip-string-normalization"]
22-
language_version: python3.11
16+
args: ["--fix", "--show-fixes"]
17+
types_or: [python, jupyter]
18+
- id: ruff-format
19+
types_or: [python, jupyter]

Diff for: CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ HyBIG follows semantic versioning. All notable changes to this project will be
44
documented in this file. The format is based on [Keep a
55
Changelog](http://keepachangelog.com/en/1.0.0/).
66

7+
## [unreleased] - 2024-12-10
8+
9+
### Changed
10+
11+
* Changed pre-commit configuration to remove `black-jupyter` dependency [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
12+
* Updates service image's python to 3.12 [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
13+
* Simplifies test scripts to run with pytest and pytest plugins [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
14+
15+
### Removed
16+
17+
* Removes `test_code_format.py` in favor of `ruff` pre-commit configuration [#38](https://github.com/nasa/harmony-browse-image-generator/pull/38)
18+
19+
720
## [v2.0.2] - 2024-10-15
821

922
### Fixed

Diff for: bin/run-test

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ set -ex
1818
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
1919

2020
# Make the directory into which XML format test reports will be saved
21-
mkdir -p test-reports
21+
mkdir -p reports/test-reports
2222

2323
# Make the directory into which coverage reports will be saved
24-
mkdir -p coverage
24+
mkdir -p reports/coverage
2525

2626
# Run the tests in a Docker container with mounted volumes for XML report
2727
# output and test coverage reporting
2828
docker run --platform linux/amd64 --rm \
29-
-v $(pwd)/test-reports:/home/tests/reports \
30-
-v $(pwd)/coverage:/home/tests/coverage \
29+
-v $(pwd)/reports/test-reports:/home/reports/test-reports \
30+
-v $(pwd)/reports/coverage:/home/reports/coverage \
3131
ghcr.io/nasa/harmony-browse-image-generator-test "$@"

Diff for: docker/service.Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# and updates the entrypoint of the new service container
1616
#
1717
###############################################################################
18-
FROM python:3.11
18+
FROM python:3.12
1919

2020
WORKDIR "/home"
2121

Diff for: docs/HyBIG-Example-Usage.ipynb

+3-3
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
},
231231
"outputs": [],
232232
"source": [
233-
"# if gdalinfo is installed you can see the palette associated with the PNG image.\n",
233+
"# if gdalinfo is installed view the palette associated with the PNG image.\n",
234234
"!gdalinfo hybig-output/example1/VCF5KYR_1991001_001_2018224205008.png"
235235
]
236236
},
@@ -318,7 +318,7 @@
318318
"metadata": {},
319319
"outputs": [],
320320
"source": [
321-
"# If gdal is installed this will show you the corner points associated with the output files.\n",
321+
"# If gdal is installed, show the corner points associated with the output files.\n",
322322
"!gdalinfo hybig-output/example2/ASTGTMV003_N00E022_dem.jpg | grep -E \"Left|Right\""
323323
]
324324
},
@@ -690,7 +690,7 @@
690690
"name": "python",
691691
"nbconvert_exporter": "python",
692692
"pygments_lexer": "ipython3",
693-
"version": "3.11.5"
693+
"version": "3.12.6"
694694
},
695695
"name": "HyBIG-Example-Usage.ipynb"
696696
},

Diff for: harmony_service/adapter.py

+56-59
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
88
"""
99

10-
from os.path import basename
1110
from pathlib import Path
12-
from shutil import rmtree
13-
from tempfile import mkdtemp
11+
from tempfile import TemporaryDirectory
1412

1513
from harmony_service_lib import BaseHarmonyAdapter
1614
from harmony_service_lib.message import Source as HarmonySource
@@ -73,7 +71,8 @@ def get_asset_from_item(self, item: Item) -> Asset:
7371
This is used to select which asset is used by HyBIG to generate
7472
the browse image following these steps:
7573
76-
1. If found, return the first asset with 'visual' in any of the item's values' roles.
74+
1. If found, return the first asset with 'visual' in any of the item's
75+
values' roles.
7776
2. If found, return the first asset that has 'data' in its item's values' roles.
7877
3. Raise a StopIteration error.
7978
@@ -93,61 +92,59 @@ def get_asset_from_item(self, item: Item) -> Asset:
9392

9493
def process_item(self, item: Item, source: HarmonySource) -> Item:
9594
"""Processes a single input STAC item."""
96-
try:
97-
working_directory = mkdtemp()
98-
results = item.clone()
99-
results.assets = {}
100-
101-
asset = self.get_asset_from_item(item)
102-
103-
color_palette = get_color_palette_from_item(item)
104-
105-
# Download the input:
106-
input_data_filename = download(
107-
asset.href,
108-
working_directory,
109-
logger=self.logger,
110-
cfg=self.config,
111-
access_token=self.message.accessToken,
112-
)
95+
with TemporaryDirectory() as working_directory:
96+
try:
97+
results = item.clone()
98+
results.assets = {}
99+
100+
asset = self.get_asset_from_item(item)
101+
102+
color_palette = get_color_palette_from_item(item)
103+
104+
# Download the input:
105+
input_data_filename = download(
106+
asset.href,
107+
working_directory,
108+
logger=self.logger,
109+
cfg=self.config,
110+
access_token=self.message.accessToken,
111+
)
113112

114-
# Create browse images.
115-
image_file_list = create_browse_imagery(
116-
self.message,
117-
input_data_filename,
118-
source,
119-
color_palette,
120-
logger=self.logger,
121-
)
113+
# Create browse images.
114+
image_file_list = create_browse_imagery(
115+
self.message,
116+
input_data_filename,
117+
source,
118+
color_palette,
119+
logger=self.logger,
120+
)
122121

123-
# image_file_list is a list of tuples (image, world, auxiliary)
124-
# we need to stage them each individually, and then add their final
125-
# locations to a list before creating the stac item.
126-
item_assets = []
127-
128-
for (
129-
browse_image_name,
130-
world_file_name,
131-
aux_xml_file_name,
132-
) in image_file_list:
133-
# Stage the images:
134-
browse_image_url = self.stage_output(browse_image_name, asset.href)
135-
browse_aux_url = self.stage_output(aux_xml_file_name, asset.href)
136-
world_file_url = self.stage_output(world_file_name, asset.href)
137-
item_assets.append(('data', browse_image_url, 'data'))
138-
item_assets.append(('metadata', world_file_url, 'metadata'))
139-
item_assets.append(('auxiliary', browse_aux_url, 'metadata'))
140-
141-
manifest_url = self.stage_manifest(image_file_list, asset.href)
142-
item_assets.insert(0, ('data', manifest_url, 'metadata'))
143-
144-
return self.create_output_stac_item(item, item_assets)
145-
146-
except Exception as exception:
147-
self.logger.exception(exception)
148-
raise HyBIGServiceError from exception
149-
finally:
150-
rmtree(working_directory)
122+
# image_file_list is a list of tuples (image, world, auxiliary)
123+
# we need to stage them each individually, and then add their final
124+
# locations to a list before creating the stac item.
125+
item_assets = []
126+
127+
for (
128+
browse_image_name,
129+
world_file_name,
130+
aux_xml_file_name,
131+
) in image_file_list:
132+
# Stage the images:
133+
browse_image_url = self.stage_output(browse_image_name, asset.href)
134+
browse_aux_url = self.stage_output(aux_xml_file_name, asset.href)
135+
world_file_url = self.stage_output(world_file_name, asset.href)
136+
item_assets.append(('data', browse_image_url, 'data'))
137+
item_assets.append(('metadata', world_file_url, 'metadata'))
138+
item_assets.append(('auxiliary', browse_aux_url, 'metadata'))
139+
140+
manifest_url = self.stage_manifest(image_file_list, asset.href)
141+
item_assets.insert(0, ('data', manifest_url, 'metadata'))
142+
143+
return self.create_output_stac_item(item, item_assets)
144+
145+
except Exception as exception:
146+
self.logger.exception(exception)
147+
raise HyBIGServiceError(str(exception)) from exception
151148

152149
def stage_output(self, transformed_file: Path, input_file: str) -> str:
153150
"""Generate an output file name based on the input asset URL and the
@@ -174,7 +171,7 @@ def create_output_stac_item(
174171
"""Create an output STAC item used to access the browse imagery and
175172
ESRI world file as staged in S3.
176173
177-
asset_items are an array of tuples where the tuples should be: (name,
174+
item_assets is an array of tuples where the tuples should be: (name,
178175
url, role)
179176
180177
"""
@@ -191,7 +188,7 @@ def create_output_stac_item(
191188

192189
output_stac_item.assets[asset_name] = Asset(
193190
url,
194-
title=basename(url),
191+
title=Path(url).name,
195192
media_type=get_file_mime_type(url),
196193
roles=[role],
197194
)

Diff for: harmony_service/utilities.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def get_tiled_file_extension(file_name: Path) -> str:
2121
generate the correct one to pass in.
2222
2323
"""
24-
ext_pattern = r"(\.r\d+c\d+)?\.(png|jpg|pgw|jgw|txt)(.aux.xml)?"
24+
ext_pattern = r'(\.r\d+c\d+)?\.(png|jpg|pgw|jgw|txt)(.aux.xml)?'
2525
match = re.search(ext_pattern, file_name.name)
2626
return match.group()
2727

@@ -34,7 +34,7 @@ def get_asset_name(name: str, url: str) -> str:
3434
dictionary.
3535
3636
"""
37-
tiled_pattern = r"\.(r\d+c\d+)\."
37+
tiled_pattern = r'\.(r\d+c\d+)\.'
3838
tile_id = re.search(tiled_pattern, url)
3939
if tile_id is not None:
4040
name = f'{name}_{tile_id.groups()[0]}'

Diff for: hybig/browse_utility.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ def get_harmony_message_from_params(params: dict | None) -> HarmonyMessage:
2121

2222
return HarmonyMessage(
2323
{
24-
"format": {
25-
"mime": mime,
26-
"crs": crs,
27-
"srs": crs,
28-
"scaleExtent": scale_extent,
29-
"scaleSize": scale_size,
30-
"height": height,
31-
"width": width,
24+
'format': {
25+
'mime': mime,
26+
'crs': crs,
27+
'srs': crs,
28+
'scaleExtent': scale_extent,
29+
'scaleSize': scale_size,
30+
'height': height,
31+
'width': width,
3232
},
3333
}
3434
)

Diff for: hybig/crs.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ def choose_crs_from_srs(srs: SRS):
5454
5555
"""
5656
try:
57-
if srs.epsg is not None and srs.epsg != "":
57+
if srs.epsg is not None and srs.epsg != '':
5858
return CRS.from_string(srs.epsg)
59-
if srs.wkt is not None and srs.wkt != "":
59+
if srs.wkt is not None and srs.wkt != '':
6060
return CRS.from_string(srs.wkt)
6161
return CRS.from_string(srs.proj4)
6262
except Exception as exception:

Diff for: hybig/exceptions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
class HyBIGError(Exception):
5-
"""Base error class for exceptions rasied by HyBIG library."""
5+
"""Base error class for exceptions raised by HyBIG library."""
66

77
def __init__(self, message=None):
88
"""All HyBIG errors have a message field."""

Diff for: hybig/sizes.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -79,29 +79,29 @@ class Dimensions(TypedDict):
7979

8080
# This is Table 4.1.8-1 WGS84 (EPSG: 4326 Resolutions)
8181
epsg_4326_resolutions = [
82-
ResolutionInfo("2km", 0.017578125, 10240, 20480, 6, 2),
83-
ResolutionInfo("1km", 0.0087890625, 20480, 40960, 7, 2),
84-
ResolutionInfo("500m", 0.00439453125, 40960, 81920, 8, 2),
85-
ResolutionInfo("250m", 0.002197265625, 81920, 163840, 9, 2),
86-
ResolutionInfo("125m", 0.0010986328125, 163840, 327680, 10, 2),
87-
ResolutionInfo("62.5m", 0.00054931640625, 327680, 655360, 11, 2),
88-
ResolutionInfo("31.25m", 0.000274658203125, 655360, 1310720, 12, 2),
89-
ResolutionInfo("15.625m", 0.0001373291015625, 1310720, 2521440, 13, 2),
82+
ResolutionInfo('2km', 0.017578125, 10240, 20480, 6, 2),
83+
ResolutionInfo('1km', 0.0087890625, 20480, 40960, 7, 2),
84+
ResolutionInfo('500m', 0.00439453125, 40960, 81920, 8, 2),
85+
ResolutionInfo('250m', 0.002197265625, 81920, 163840, 9, 2),
86+
ResolutionInfo('125m', 0.0010986328125, 163840, 327680, 10, 2),
87+
ResolutionInfo('62.5m', 0.00054931640625, 327680, 655360, 11, 2),
88+
ResolutionInfo('31.25m', 0.000274658203125, 655360, 1310720, 12, 2),
89+
ResolutionInfo('15.625m', 0.0001373291015625, 1310720, 2521440, 13, 2),
9090
]
9191

9292
# Conversion used above: resolution / pixel_size
9393
METERS_PER_DEGREE = 113777.77777777778
9494

9595
# This is Table 4.1.8-2 NSIDC Sea Ice Polar Stereographic Extent (EPSG:3413) Resolutions
9696
epsg_3413_resolutions = [
97-
ResolutionInfo("2km", 2048, 4096, 4096, 3, 2),
98-
ResolutionInfo("1km", 1024, 8192, 8192, 4, 2),
99-
ResolutionInfo("500m", 512, 16384, 16384, 5, 2),
100-
ResolutionInfo("250m", 256, 32768, 32768, 6, 2),
101-
ResolutionInfo("125m", 128, 65536, 65536, 7, 2),
102-
ResolutionInfo("62.5m", 64, 131072, 131072, 8, 2),
103-
ResolutionInfo("31.25m", 32, 252144, 252144, 9, 2),
104-
ResolutionInfo("15.625m", 16, 524288, 524288, 10, 2),
97+
ResolutionInfo('2km', 2048, 4096, 4096, 3, 2),
98+
ResolutionInfo('1km', 1024, 8192, 8192, 4, 2),
99+
ResolutionInfo('500m', 512, 16384, 16384, 5, 2),
100+
ResolutionInfo('250m', 256, 32768, 32768, 6, 2),
101+
ResolutionInfo('125m', 128, 65536, 65536, 7, 2),
102+
ResolutionInfo('62.5m', 64, 131072, 131072, 8, 2),
103+
ResolutionInfo('31.25m', 32, 252144, 252144, 9, 2),
104+
ResolutionInfo('15.625m', 16, 524288, 524288, 10, 2),
105105
]
106106

107107
# The Antarctic resolutions match the northern resolutions precisely.

Diff for: pyproject.toml

+14
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,17 @@ exclude = [
5050

5151
[tool.hatch.build.targets.wheel]
5252
packages=["hybig"]
53+
54+
[tool.ruff]
55+
lint.select = [
56+
"E", # pycodestyle
57+
"F", # pyflakes
58+
"UP", # pyupgrade
59+
"I", # organize imports
60+
]
61+
62+
[tool.ruff.format]
63+
quote-style = "single"
64+
65+
[tool.ruff.lint.pydocstyle]
66+
convention = "google"

0 commit comments

Comments
 (0)