Skip to content

Commit

Permalink
prototype of so-only wheel and cffi interface
Browse files Browse the repository at this point in the history
  • Loading branch information
tmi committed Dec 9, 2024
1 parent d94db61 commit 45c36f0
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 0 deletions.
91 changes: 91 additions & 0 deletions .github/workflows/build-wheel-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# (C) Copyright 2024- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.


name: Build Python Wheel for Linux

on:
# Trigger the workflow manually
workflow_dispatch: ~

# Allow to be called from another workflow
workflow_call: ~

# TODO automation trigger

jobs:

build:

runs-on: [self-hosted, Linux, platform-builder-Rocky-8.6]
# TODO which manylinux do we want to build for? 2014? 2_28? 2_34? Matrix?
container: wheelmaker_2_28:0.1

name: Build manylinux_2_28

steps:
# TODO which project do we build odc wheel from -- this, or some bundle? Or can we obtain the compiled eckit artifact somehow?
- run: git clone --branch develop --depth=1 https://github.com/ecmwf/eckit.git /src/eckit
- run: /buildscripts/compile.sh ./eckit/python_wrapper/buildconfig
- uses: actions/checkout@v2
- run: /buildscripts/compile.sh ./metkit/python_wrapper/buildconfig

################################################################
- run: /buildscripts/wheel-linux.sh ./metkit/python_wrapper/buildconfig 3.11
- uses: actions/upload-artifact@v4
name: Upload wheel 3.11
with:
name: wheel-manylinux2_28-3.11
path: /build/wheel/*.whl

# TODO other python versions, once the above is correct.
# NOTE if Matrix, then break into (compile & upload) ; (wheel & upload)[matix] steps

test:

needs: build
strategy:
fail-fast: false
matrix:
python-version: ["3.11"] # ["3.8", "3.9", "3.10", "3.11", "3.12"] # TODO enable

name: Test with ${{ matrix.python-version }}
runs-on: [self-hosted, Linux, platform-builder-Rocky-8.6]
container: wheelmaker_2_28:0.1
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v4
with:
name: wheel-manylinux2_28-${{ matrix.python-version }}
- run: /buildscripts/test-wheel.sh ${{ matrix.python-version }}

# TODO enable and test
# deploy:
#
# if: ${{ github.ref_type == 'tag' || github.event_name == 'release' }}
# needs: [test, build]
# strategy:
# fail-fast: false
# matrix:
# python-version: ["3.11"] # ["3.8", "3.9", "3.10", "3.11", "3.12"] # TODO enable
#
# name: Deploy wheel ${{ matrix.python-version }}
# runs-on: [self-hosted, Linux, platform-builder-Rocky-8.6]
# container: wheelmaker_2_28:0.1
# steps:
# - run: mkdir artifact-${{ matrix.python-version }}
# - uses: actions/checkout@v2
# - uses: actions/download-artifact@v4
# with:
# name: wheel-manylinux2_28-${{ matrix.python-version }}
# path: artifact-${{ matrix.python-version }}
# - run: |
# /buildsripts/upload-twine.sh ${{ matrix.python-version }}
# env:
# TWINE_USERNAME: __token__
# TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
7 changes: 7 additions & 0 deletions python_interface/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This is just a placeholder for proper python interface of metkit -- for now we just showcase `findlibs`-based finding of `.so`, and loading via cffi.

To demonstrate functionality, install `eckit` and `metkit` binary wheels in your venv, and then you can `pip install -e . && python -c 'import metkit; metkit.version()`.

To be done:
1. proper cffi setup
2. wheel building (note this is **not** a binary wheel! That happens in `../python_wrapper`, and contains no python code)
8 changes: 8 additions & 0 deletions python_interface/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "pymetkit"
version = "0.0.0"
dependencies = ["cffi", "findlibs"]
18 changes: 18 additions & 0 deletions python_interface/src/pymetkit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import cffi
import findlibs

_lib = None

# TODO expose the full functionality

def _get_lib():
global _lib
if _lib is None:
ffi = cffi.FFI()
ffi.cdef("unsigned int metkit_version_int();")
loc = findlibs.find("metkit", "metkitlibs")
_lib = ffi.dlopen(loc)
return _lib

def metkit_version_int() -> int:
return _get_lib().metkit_version_int()
14 changes: 14 additions & 0 deletions python_wrapper/buildconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# (C) Copyright 2024- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.

# to be source'd by wheelmaker's compile.sh *and* wheel-linux.sh
# NOTE replace the whole thing with pyproject.toml? Less powerful, and quaint to use for sourcing ecbuild invocation

NAME="metkit"
CMAKE_PARAMS="-DECKIT_PATH=/target/eckit"
PYPROJECT_DIR="python_wrapper"
5 changes: 5 additions & 0 deletions python_wrapper/setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[metadata]
description = "metkit"
long_description = file: README.md
long_description_content_type = text/markdown
author = file: AUTHORS
2 changes: 2 additions & 0 deletions python_wrapper/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from setup_utils import plain_setup
plain_setup()

0 comments on commit 45c36f0

Please sign in to comment.