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
72 changes: 72 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Publish to PyPI

on:
release:
types: [published]

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: latest
virtualenvs-create: true
virtualenvs-in-project: true

- name: Extract version from pyproject.toml
id: get_version
run: |
# Extract version from [project] section
VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
echo "project_version=$VERSION" >> $GITHUB_OUTPUT
echo "Project version: $VERSION"

- name: Extract tag version
id: get_tag
run: |
# Remove 'refs/tags/' prefix and optional 'v' prefix
TAG_VERSION=${GITHUB_REF#refs/tags/}
TAG_VERSION=${TAG_VERSION#v}
echo "tag_version=$TAG_VERSION" >> $GITHUB_OUTPUT
echo "Tag version: $TAG_VERSION"

- name: Verify version matches tag
run: |
if [ "${{ steps.get_version.outputs.project_version }}" != "${{ steps.get_tag.outputs.tag_version }}" ]; then
echo "ERROR: Tag version (${{ steps.get_tag.outputs.tag_version }}) doesn't match project version (${{ steps.get_version.outputs.project_version }})"
echo "Please ensure your git tag matches the version in pyproject.toml [project] section"
exit 1
fi
echo "Version verification passed"

- name: Install dependencies
run: poetry install --only-root

- name: Build package
run: poetry build

- name: Verify build contents
run: |
echo "Built packages:"
ls -la dist/
echo "Checking wheel contents:"
python -m zipfile -l dist/*.whl | head -20

- name: Publish to PyPI
run: poetry publish --username __token__ --password ${{ secrets.PYPI_API_TOKEN }}

- name: Verify publication
run: |
echo "🎉 Successfully published ensemble-kalman-smoother v${{ steps.get_version.outputs.project_version }} to PyPI!"
echo "Package should be available at: https://pypi.org/project/ensemble-kalman-smoother/${{ steps.get_version.outputs.project_version }}/"
48 changes: 47 additions & 1 deletion eks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
from typing import Any

from eks import *

__version__ = '4.2.0'

# Hacky way to get version from pypackage.toml.
# Adapted from: https://github.com/python-poetry/poetry/issues/273#issuecomment-1877789967

__package_version = "unknown"


def __get_package_version() -> str:
"""Find the version of this package."""
global __package_version

if __package_version != "unknown":
# We already set it at some point in the past,
# so return that previous value without any
# extra work.
return __package_version

try:
# Try to get the version of the current package if
# it is running from a distribution.
__package_version = importlib.metadata.version("ensemble-kalman-smoother")
except importlib.metadata.PackageNotFoundError:
# Fall back on getting it from a local pyproject.toml.
# This works in a development environment where the
# package has not been installed from a distribution.
import warnings

import toml

warnings.warn(
"ensemble-kalman-smoother not pip-installed, getting version from pyproject.toml."
)

pyproject_toml_file = Path(__file__).parent.parent / "pyproject.toml"
__package_version = toml.load(pyproject_toml_file)["project"]["version"]

return __package_version


def __getattr__(name: str) -> Any:
"""Get package attributes."""
if name in ("version", "__version__"):
return __get_package_version()
else:
raise AttributeError(f"No attribute {name} in module {__name__}.")
95 changes: 95 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
[build-system]
requires = ["poetry-core>=2.0.0"]
build-backend = "poetry.core.masonry.api"

[project]
name = "ensemble-kalman-smoother"
version = "4.4.0"
description = "Ensembling and kalman smoothing for pose estimation"
license = "MIT"
readme = "README.md"
requires-python = ">=3.10"
authors = [
{ name = "Cole Hurwitz"},
{ name = "Keemin Lee"},
{ name = "Matt Whiteaway" },
]
maintainers = [
{ name = "Matt Whiteway"},
]
keywords = ["machine learning", "state space models", "pose estimation"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Scientific/Engineering :: Image Processing",
"Topic :: Scientific/Engineering :: Visualization",
]

dependencies = [
"aniposelib",
"dynamax",
"jax",
"jaxlib",
"matplotlib",
"numpy (>=2.0.0)",
"opencv-python-headless",
"optax",
"pandas",
"scikit-learn",
"scipy (>=1.2.0)",
"sleap_io",
"tqdm",
"typeguard",
"typing",
]

[project.urls]
repository = "https://github.com/paninski-lab/eks"
documentation = "https://github.com/paninski-lab/eks"

[tool.poetry]
packages = [
{include = "eks"}
]

# project.dependencies are used for metadata when building the project, tool.poetry.dependencies is only used to enrich
# project.dependencies for locking
[tool.poetry.dependencies]
python = ">=3.10,<3.13"

[project.optional-dependencies]
dev = [
"black",
"flake8",
"isort",
"pytest",
]

[tool.flake8]
max-line-length = 99
ignore = ["F821", "W503"]
extend-ignore = ["E203"]
exclude = [
".git",
"__pycache__",
"__init__.py",
"build",
"dist",
"docs/",
"scripts/",
]

[tool.isort]
line_length = 99
profile = "black"
src_paths = ["eks", "tests"]

[tool.pytest.ini_options]
testpaths = "tests"
generate_report_on_test = "True"
15 changes: 0 additions & 15 deletions setup.cfg

This file was deleted.

73 changes: 0 additions & 73 deletions setup.py

This file was deleted.

2 changes: 2 additions & 0 deletions tests/test_multicam_smoother.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def test_ensemble_kalman_smoother_multicam():
num_fields = len(data_fields)

# Create mock MarkerArray with explicit data_fields
np.random.seed(0)
markers_array = np.random.randn(n_models, n_cameras, n_frames, len(keypoint_names), num_fields)
marker_array = MarkerArray(markers_array, data_fields=data_fields)

Expand Down Expand Up @@ -164,6 +165,7 @@ def test_ensemble_kalman_smoother_multicam_no_smooth_param():
num_fields = len(data_fields)

# Create mock MarkerArray with explicit data_fields
np.random.seed(1)
markers_array = np.random.randn(3, n_cameras, n_frames, len(keypoint_names), num_fields)
markerArray = MarkerArray(markers_array, data_fields=data_fields) # Ensure data_fields is set

Expand Down