Skip to content
Open
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
110 changes: 110 additions & 0 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Publish Python Package to PyPI

# This workflow uses GitHub's OIDC trusted publishing to authenticate with PyPI.
# For this to work, you must configure trusted publishers on PyPI/TestPyPI:
# 1. Go to https://test.pypi.org/ or https://pypi.org/
# 2. Navigate to your project settings → Publishing
# 3. Add a new publisher with these details:
# - Owner: alexlib
# - Repository: openptv-python
# - Workflow: publish-to-pypi.yml
# - Environment: testpypi (for TestPyPI) or pypi (for PyPI)
#
# TROUBLESHOOTING:
# If you see "invalid-publisher" error, it means the trusted publisher is not configured
# correctly on PyPI/TestPyPI. The configuration MUST match these exact values:
# - Repository owner: alexlib
# - Repository name: openptv-python
# - Workflow filename: publish-to-pypi.yml (must be exact match)
# - Environment name: testpypi or pypi (must match exactly)
#
# For detailed setup instructions, see DEPLOYMENT.md

on:
release:
types: [published]
workflow_dispatch:
inputs:
deploy_target:
description: 'Deploy to PyPI or TestPyPI'
required: true
default: 'testpypi'
type: choice
options:
- pypi
- testpypi

jobs:
build:
name: Build distribution
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Build package
run: python -m build

- name: Check distribution
run: twine check dist/*

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/

publish-to-pypi:
name: Publish to PyPI
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_target == 'pypi')
needs: [build]
runs-on: ubuntu-latest
environment:
name: pypi # This must match the environment name in PyPI's trusted publisher config
url: https://pypi.org/p/openptv-python
permissions:
id-token: write # Required for trusted publishing via OIDC

steps:
- name: Download distributions
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

publish-to-testpypi:
name: Publish to TestPyPI
if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_target == 'testpypi'
needs: [build]
runs-on: ubuntu-latest
environment:
name: testpypi # This must match the environment name in TestPyPI's trusted publisher config
url: https://test.pypi.org/p/openptv-python
permissions:
id-token: write # Required for trusted publishing via OIDC

steps:
- name: Download distributions
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/

- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/

24 changes: 24 additions & 0 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Python application

on:
push:
branches: [ main, simple_yaml_with_tests ]
pull_request:
branches: [ main, simple_yaml_with_tests ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Run tests
run: |
make unit-tests
66 changes: 66 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version.py
# Sphinx automatic generation of API
docs/README.md
docs/_api/
docs/_generated/

# Combined environments
ci/combined-environment-*.yml
Expand Down Expand Up @@ -473,3 +474,68 @@ $RECYCLE.BIN/
.cruft.json
/.tmp
/tmp

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.pyc

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/




9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
PROJECT := openptv_python
CONDA := conda
CONDAFLAGS :=
UV := uv
UVFLAGS := --extra dev --upgrade
COV_REPORT := html
PYTHON ?= python

Expand All @@ -15,11 +17,16 @@ unit-tests:
type-check:
$(PYTHON) -m mypy .

env-update: uv-env-update

conda-env-update:
$(CONDA) install -y -c conda-forge conda-merge
$(CONDA) run conda-merge environment.yml ci/environment-ci.yml > ci/combined-environment-ci.yml
$(CONDA) env update $(CONDAFLAGS) -f ci/combined-environment-ci.yml

uv-env-update:
$(UV) sync $(UVFLAGS)

docker-build:
docker build -t $(PROJECT) .

Expand All @@ -30,6 +37,6 @@ template-update:
pre-commit run --all-files cruft -c .pre-commit-config-cruft.yaml

docs-build:
cp README.md docs/. && cd docs && rm -fr _api && make clean && make html
cp README.md docs/. && $(PYTHON) docs/render_native_stress_demo_include.py && cd docs && rm -fr _api && make clean && make html

# DO NOT EDIT ABOVE THIS LINE, ADD COMMANDS BELOW
42 changes: 32 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ execution modes behind that API:
use, so the Python implementation still benefits from acceleration.
- Native `optv` bindings: selected operations reuse the native OpenPTV
implementation when the `optv` package is available.
- PyPTV GUI: packaged in the same repository and installed as an optional
application package.

At the moment, automatic native delegation is implemented for image
preprocessing and full-frame target recognition. The rest of the library keeps
Expand All @@ -21,15 +23,11 @@ use.

## How this is started

This work started from the https://github.com/OpenPTV/openptv/tree/pure_python branch. It's a long-standing idea to convert all the C code to Python and now it's possible with ChatGPT to save
a lot of typing time.

This repo is created using a *cookiecutter* and the rest of the readme describes the way to work with
this structure
This work started from the https://github.com/OpenPTV/openptv/tree/pure_python branch. It now serves as the single repository for the Python core library and the GUI layer.

## Supported Python Versions

The project currently supports Python `>=3.12,<3.14`.
The project currently supports Python `>=3.11,<3.14`.

## Installation

Expand All @@ -55,6 +53,12 @@ platform and Python version, install the optional extra:
uv sync --extra native
```

If you also want the GUI application, install the GUI extra:

```bash
uv sync --extra gui
```

#### Alternative: pip

```bash
Expand All @@ -69,6 +73,12 @@ Optional native bindings:
pip install ".[native]"
```

Optional GUI application:

```bash
pip install ".[gui]"
```

### Developer install

#### Recommended: uv
Expand All @@ -92,8 +102,9 @@ pip install -e ".[dev]"
- The default install contains the runtime dependencies only.
- The optional `native` extra adds `optv` bindings for automatic native
delegation on supported platforms.
- The optional `dev` extra adds test, docs, typing, and pre-commit tooling for
contributors.
- The optional `gui` extra adds the PyPTV GUI and its runtime dependencies.
- The optional `dev` extra adds test, docs, typing, pre-commit, and GUI
tooling for contributors.
- The public API stays the same regardless of which backend extras are
installed.

Expand Down Expand Up @@ -184,17 +195,28 @@ OPENPTV_SKIP_STRESS_BENCHMARKS=1 uv run make

### Workflow for developers/contributors

For the best experience create a new conda environment (e.g. DEVELOP) with Python 3.12:
Recommended contributor workflow with `uv`:

```bash
uv venv
source .venv/bin/activate
make env-update
```

This keeps the local environment synced to the locked developer dependency set.

If you prefer the conda workflow instead:

```bash
conda create -n openptv-python -c conda-forge python=3.12
conda activate openptv-python
make conda-env-update
```

Before pushing to GitHub, use the developer install above and then run the
following commands:

1. Update conda environment: `make conda-env-update` or `uv venv` and `source .venv/bin/activate` followed by `uv sync --extra dev --upgrade`
1. Update the environment: `make env-update` by default, or `make conda-env-update` if you are using the conda workflow
1. If you are using pip instead of uv, install the editable developer environment: `pip install -e ".[dev]"`
1. Sync with the latest [template](https://github.com/ecmwf-projects/cookiecutter-conda-package) (optional): `make template-update`
1. Run quality assurance checks: `make qa`
Expand Down
9 changes: 9 additions & 0 deletions conda.recipe/conda_build_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
python:
- 3.6
- 3.7
- 3.8
- 3.9
- 3.10
- 3.11
- 3.12
- 3.13
Loading
Loading