Skip to content

Commit

Permalink
move configuration into pyproject.toml (#150)
Browse files Browse the repository at this point in the history
* move configuration into `pyproject.toml`

* update test workflows

* formatting

* pin `stormevents` version

* add `pytest-mock`

* also test upon update to `pyproject.toml`
  • Loading branch information
zacharyburnett authored Apr 20, 2022
1 parent 1c05e8d commit e1edc14
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 191 deletions.
65 changes: 11 additions & 54 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,19 @@ on:
- published

jobs:
build_wheels:
name: build wheel
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest ]
python-version: [ '3.x' ]
steps:
- name: checkout repository
uses: actions/checkout@v2
- name: install Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: load cached Python installation
id: cache
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: build-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'setup.*') }}
- name: build wheel
run: pip wheel . -w dist --no-deps
- name: save wheel
uses: actions/upload-artifact@v2
with:
name: build
path: ./dist/*.whl
build_sdist:
name: package source
publish:
name: publish package to PyPI
runs-on: ubuntu-latest
steps:
- name: checkout repository
uses: actions/checkout@v2
- name: install Python
uses: actions/setup-python@v2
- name: install dependencies
- name: install Poetry
uses: abatilo/actions-poetry@v2.1.3
- name: install Dunamai
run: pip install dunamai
- name: package source
run: python setup.py sdist
- name: save source package
uses: actions/upload-artifact@v2
with:
name: build
path: ./dist/*.tar.gz
upload_pypi:
name: publish to PyPI
needs: [ build_wheels, build_sdist ]
runs-on: ubuntu-latest
steps:
- name: retrieve wheel(s) and source
uses: actions/download-artifact@v2
with:
name: build
path: dist
- name: upload wheel(s) and source
uses: pypa/[email protected]
with:
user: __token__
password: ${{ secrets.PYPI_TOKEN }}
- name: extract version from VCS
run: poetry version $(dunamai from any)
- name: build wheel and source
run: poetry build
- name: upload wheel and source
run: poetry publish --username __token__ --password ${{ secrets.PYPI_TOKEN }}
59 changes: 42 additions & 17 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,54 @@
name: tests

on: [ push ]
on:
push:
branches:
- main
paths:
- '**.py'
- '.github/workflows/tests.yml'
- 'pyproject.toml'
pull_request:
branches:
- main

jobs:
lint:
name: lint
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.x' ]
steps:
- name: clone repository
uses: actions/checkout@v2
- name: install Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: load cached Python installation
id: cache
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: lint-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'setup.*') }}
- name: install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install ".[development]"
key: lint-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}
- name: install linters
run: pip install flake8 oitnb
- name: lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: lint with oitnb
run: oitnb . --check
test:
needs: lint
name: test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
python-version: [ '3.6', '3.x' ]
os: [ ubuntu-latest, macos-latest ]
python-version: [ '3.6', '3.7', '3.8', '3.9', '3.x' ]
exclude:
- os: macos-latest
python-version: '3.x'
steps:
- name: clone repository
uses: actions/checkout@v2
Expand All @@ -51,18 +61,33 @@ jobs:
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: test-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'setup.*') }}
key: test-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}
- name: install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install ".[testing]"
- name: run tests
if: matrix.python-version != '3.x' || matrix.os != 'ubuntu-latest'
run: pytest --numprocesses auto
test_with_coverage:
needs: [ lint, test ]
name: test with coverage
runs-on: ubuntu-latest
steps:
- name: clone repository
uses: actions/checkout@v2
- name: install Python
uses: actions/setup-python@v2
- name: load cached Python installation
id: cache
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: test-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}
- name: install dependencies
run: pip install ".[testing]"
- name: run tests with coverage
if: matrix.python-version == '3.x' && matrix.os == 'ubuntu-latest'
run: pytest --numprocesses auto --cov . --cov-report xml:coverage.xml
- name: show coverage report
run: coverage report
- name: upload coverage to Codecov
if: matrix.python-version == '3.x' && matrix.os == 'ubuntu-latest'
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/tests_simple.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: tests

on:
push:
branches-ignore:
- main
paths:
- '**.py'
- '.github/workflows/tests_simple.yml'
- 'pyproject.toml'

jobs:
lint:
name: lint
runs-on: ubuntu-latest
steps:
- name: clone repository
uses: actions/checkout@v2
- name: install Python
uses: actions/setup-python@v2
- name: load cached Python installation
id: cache
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: lint-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}
- name: install linters
run: pip install flake8 oitnb
- name: lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: lint with oitnb
run: oitnb . --check
test:
needs: lint
name: test
runs-on: ubuntu-latest
steps:
- name: clone repository
uses: actions/checkout@v2
- name: install Python
uses: actions/setup-python@v2
- name: load cached Python installation
id: cache
uses: actions/cache@v2
with:
path: ${{ env.pythonLocation }}
key: test-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}
- name: install dependencies
run: pip install ".[testing]"
- name: run tests
run: pytest --numprocesses auto
86 changes: 40 additions & 46 deletions adcircpy/forcing/winds/best_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,49 @@

class BestTrackForcing(VortexTrack, WindForcing):
def __init__(
self,
storm: Union[str, PathLike, DataFrame, io.BytesIO],
nws: int = None,
interval_seconds: int = None,
start_date: datetime = None,
end_date: datetime = None,
self,
storm: Union[str, PathLike, DataFrame, io.BytesIO],
nws: int = None,
interval_seconds: int = None,
start_date: datetime = None,
end_date: datetime = None,
):
if nws is None:
nws = 20

valid_nws_values = [8, 19, 20]
assert (
nws in valid_nws_values
nws in valid_nws_values
), f'ATCF BestTrack can only use `nws` values in {valid_nws_values}'

if interval_seconds is None:
interval_seconds = 3600

VortexTrack.__init__(
self,
storm=storm,
start_date=start_date,
end_date=end_date,
file_deck='b',
advisories=['BEST'],
self,
storm=storm,
start_date=start_date,
end_date=end_date,
file_deck='b',
advisories=['BEST'],
)
WindForcing.__init__(self, nws=nws, interval_seconds=interval_seconds)

@classmethod
def from_fort22(
cls,
fort22: PathLike,
nws: int = None,
interval_seconds: int = None,
start_date: datetime = None,
end_date: datetime = None,
cls,
fort22: PathLike,
nws: int = None,
interval_seconds: int = None,
start_date: datetime = None,
end_date: datetime = None,
) -> 'WindForcing':
instance = cls.from_file(path=fort22, start_date=start_date,
end_date=end_date)
WindForcing.__init__(instance, nws=nws,
interval_seconds=interval_seconds)
instance = cls.from_file(path=fort22, start_date=start_date, end_date=end_date)
WindForcing.__init__(instance, nws=nws, interval_seconds=interval_seconds)
return instance

def summary(
self, output: Union[str, os.PathLike] = None,
overwrite: bool = False,
self, output: Union[str, os.PathLike] = None, overwrite: bool = False,
):
min_storm_speed = numpy.min(self.data['speed'])
max_storm_speed = numpy.max(self.data['speed'])
Expand All @@ -77,8 +74,7 @@ def summary(
min_central_pressure = numpy.min(self.data['central_pressure'])
max_wind_speed = numpy.max(self.data['max_sustained_wind_speed'])
start_loc = (self.data['longitude'][0], self.data['latitude'][0])
end_loc = (
self.data['longitude'].iloc[-1], self.data['latitude'].iloc[-1])
end_loc = (self.data['longitude'].iloc[-1], self.data['latitude'].iloc[-1])
f = [
f'Summary of storm: {self.nhc_code}',
f'min./max. track speed: {min_storm_speed} m/s, {max_storm_speed} m/s',
Expand Down Expand Up @@ -144,13 +140,13 @@ def clip_to_bbox(self, bbox, bbox_crs):
msg = f'bbox must be a {Bbox} instance.'
assert isinstance(bbox, Bbox), msg
bbox_pol = Polygon(
[
[bbox.xmin, bbox.ymin],
[bbox.xmax, bbox.ymin],
[bbox.xmax, bbox.ymax],
[bbox.xmin, bbox.ymax],
[bbox.xmin, bbox.ymin],
]
[
[bbox.xmin, bbox.ymin],
[bbox.xmax, bbox.ymin],
[bbox.xmax, bbox.ymax],
[bbox.xmin, bbox.ymax],
[bbox.xmin, bbox.ymin],
]
)
_switch = True
unique_dates = numpy.unique(self.data['datetime'])
Expand All @@ -167,8 +163,7 @@ def clip_to_bbox(self, bbox, bbox_crs):
transformer = Transformer.from_crs(df_crs, utm_crs, always_xy=True)
p = Point(*transformer.transform(lon, lat))
pol = p.buffer(radii)
transformer = Transformer.from_crs(utm_crs, bbox_crs,
always_xy=True)
transformer = Transformer.from_crs(utm_crs, bbox_crs, always_xy=True)
pol = ops.transform(transformer.transform, pol)
if _switch is True:
if not pol.intersects(bbox_pol):
Expand All @@ -187,16 +182,15 @@ def clip_to_bbox(self, bbox, bbox_crs):
break

if _found_start_date is False:
raise Exception(
f'No data within mesh bounding box for storm {self.storm_id}.')
raise Exception(f'No data within mesh bounding box for storm {self.storm_id}.')

def plot_track(
self,
axis: Axis = None,
show: bool = False,
color: str = 'k',
coastline: bool = True,
**kwargs,
self,
axis: Axis = None,
show: bool = False,
color: str = 'k',
coastline: bool = True,
**kwargs,
):
kwargs.update({'color': color})
if axis is None:
Expand All @@ -210,7 +204,7 @@ def plot_track(
axis.quiver(row['longitude'], row['latitude'], U, V, **kwargs)
if i % 6 == 0:
axis.annotate(
row['datetime'], (row['longitude'], row['latitude']),
row['datetime'], (row['longitude'], row['latitude']),
)
if show:
axis.axis('scaled')
Expand All @@ -224,6 +218,6 @@ def plot_wind_swath(self, isotach: int, segments: int = 91):
plot_polygons(isotachs)
plot_polygons(swath)
pyplot.suptitle(
f'{self.nhc_code} - isotach {isotach} kt ({self.start_date} - {self.end_date})'
f'{self.nhc_code} - isotach {isotach} kt ({self.start_date} - {self.end_date})'
)
pyplot.show()
Loading

0 comments on commit e1edc14

Please sign in to comment.