Skip to content

Commit

Permalink
initial test
Browse files Browse the repository at this point in the history
  • Loading branch information
TomHodson committed Oct 28, 2024
1 parent 410760f commit e8eed21
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 32 deletions.
54 changes: 54 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
########################################################################################################################
cmake_minimum_required( VERSION 3.15 FATAL_ERROR )

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(eckit REQUIRED)
find_package(eccodes REQUIRED)
find_package(metkit REQUIRED)
find_package(fdb5 REQUIRED)

# Find the module development requirements (requires FindPython from 3.17 or
# scikit-build-core's built-in backport)
set(PYBIND11_FINDPYTHON ON)
find_package(pybind11 CONFIG REQUIRED)
# find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)

# Scikit-build-core sets these values for you, or you can just hard-code the
# name and version.
project(
${SKBUILD_PROJECT_NAME}
VERSION ${SKBUILD_PROJECT_VERSION}
LANGUAGES CXX)



# Add a library using FindPython's tooling (pybind11 also provides a helper like
# this)
pybind11_add_module(_core src/pyfdb.cpp)

# This is passing in the version as a define just as an example
target_compile_definitions(_core PRIVATE VERSION_INFO=${PROJECT_VERSION})

target_link_libraries(_core PRIVATE
eckit
eccodes
metkit
fdb5
pybind11::module
pybind11::lto
pybind11::windows_extras)


pybind11_extension(_core)
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
# Strip unnecessary sections of the binary on Linux/macOS
pybind11_strip(_core)
endif()

set_target_properties(_core PROPERTIES CXX_VISIBILITY_PRESET "hidden"
CUDA_VISIBILITY_PRESET "hidden")

# The install directory is the output (wheel) directory
install(TARGETS _core DESTINATION ${SKBUILD_PROJECT_NAME})
97 changes: 92 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,93 @@
[tool.black]
line-length = 120
[build-system]
requires = ["scikit-build-core>=0.10", "pybind11"]
build-backend = "scikit_build_core.build"

[tool.isort]
profile = "black"
line_length = 120

[project]
name = "pyfdb"
version = "0.0.1"
description="A minimal example package (with pybind11)"
readme = "README.md"
authors = [
{ name = "My Name", email = "me@email.com" },
]
requires-python = ">=3.9"
classifiers = [
"Development Status :: 4 - Beta",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]

[project.optional-dependencies]
test = ["pytest"]


[tool.scikit-build]
# Some older versions of pip are unable to load standard universal tags
# scikit-build-core can expand the macOS universal tags for you for maximum historic compatibility if you’d like
wheel.expand-macos-universal-tags = true
minimum-version = "build-system.requires"
build.verbose = true
logging.level = "INFO"
build-dir="build"


[tool.pytest.ini_options]
minversion = "8.0"
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
xfail_strict = true
log_cli_level = "INFO"
filterwarnings = [
"error",
"ignore::pytest.PytestCacheWarning",
]
testpaths = ["tests"]


[tool.cibuildwheel]
build-frontend = "build[uv]"
test-command = "pytest {project}/tests"
test-extras = ["test"]

[tool.cibuildwheel.pyodide]
build-frontend = {name = "build", args = ["--exports", "whole_archive"]}

[tool.ruff.lint]
extend-select = [
"B", # flake8-bugbear
"I", # isort
"ARG", # flake8-unused-arguments
"C4", # flake8-comprehensions
"EM", # flake8-errmsg
"ICN", # flake8-import-conventions
"G", # flake8-logging-format
"PGH", # pygrep-hooks
"PIE", # flake8-pie
"PL", # pylint
"PT", # flake8-pytest-style
"PTH", # flake8-use-pathlib
"RET", # flake8-return
"RUF", # Ruff-specific
"SIM", # flake8-simplify
"T20", # flake8-print
"UP", # pyupgrade
"YTT", # flake8-2020
"EXE", # flake8-executable
"NPY", # NumPy specific rules
"PD", # pandas-vet
]
ignore = [
"PLR09", # Too many X
"PLR2004", # Magic comparison
]
isort.required-imports = ["from __future__ import annotations"]

[tool.ruff.lint.per-file-ignores]
"tests/**" = ["T20"]
27 changes: 0 additions & 27 deletions setup.py

This file was deleted.

86 changes: 86 additions & 0 deletions src/pyfdb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <pybind11/pybind11.h>
#include <pybind11/iostream.h>
#include <pybind11/stl.h>
#include <cstddef>

#include "eckit/config/Configuration.h"
#include "eckit/eckit_version.h"
#include "eckit/filesystem/PathName.h"
#include "eckit/io/DataHandle.h"
#include "eckit/io/TransferWatcher.h"
#include "eckit/message/Message.h"
#include "fdb5/api/FDB.h"
#include "fdb5/api/FDBFactory.h"
#include "fdb5/api/LocalFDB.h"
#include "fdb5/api/fdb_c.h"
#include "fdb5/api/helpers/FDBToolRequest.h"
#include "fdb5/config/Config.h"
#include "fdb5/database/Inspector.h"
#include "fdb5/database/Archiver.h"
#include "fdb5/database/Key.h"
#include "metkit/mars/Parameter.h"

namespace py = pybind11;


PYBIND11_MODULE(_core, module) {
module.doc() = "pybind11 example plugin"; // optional module docstring

py::class_<eckit::PathName>(module, "PathName")
.def(py::init<const std::string&, bool>())
.def("asString", &eckit::PathName::asString);

py::class_<eckit::LocalConfiguration>(module, "LocalConfiguration")
.def(py::init<const eckit::Configuration&, const eckit::PathName&>());

py::class_<fdb5::Config>(module, "Config")
.def(py::init<>())
.def(py::init<const eckit::Configuration&, const eckit::Configuration&>());

py::class_<metkit::mars::MarsRequest>(module, "MarsRequest")
.def(py::init<>())
.def(py::init<const std::string&>())
.def(py::init<const std::string&, const std::map<std::string, std::string>&>())
.def("asString", &metkit::mars::MarsRequest::asString);

py::class_<fdb5::FDBToolRequest>(module, "FDBToolRequest")
.def(py::init<const metkit::mars::MarsRequest&, bool, const std::vector<std::string>&>());

py::class_<fdb5::ListElement>(module, "ListElement")
.def(py::init<>())
.def("__str__", [](fdb5::ListElement& el){
std::stringstream buffer;
buffer << el;
return buffer.str();
});

py::class_<fdb5::APIIterator<fdb5::ListElement>>(module, "APIIterator");
py::class_<fdb5::ListIterator, fdb5::APIIterator<fdb5::ListElement>>(module, "ListIterator")
.def("__iter__", [](fdb5::ListIterator &it) -> fdb5::ListIterator& { return it; })
.def("__next__", &fdb5::ListIterator::next)
.def("next", &fdb5::ListIterator::next);

py::class_<eckit::DataHandle>(module, "DataHandle")
.def("open", &eckit::DataHandle::openForRead)
.def("close", &eckit::DataHandle::close)
.def("skip", &eckit::DataHandle::skip)
.def("seek", &eckit::DataHandle::seek)
.def("tell", &eckit::DataHandle::position)
.def("read", &eckit::DataHandle::read)
.def("save_into", [](eckit::DataHandle& dh, const eckit::PathName& path){
dh.saveInto(path);
});

py::class_<fdb5::FDB>(module, "FDB")
.def(py::init([](const fdb5::Config& config){
fdb_initialise();
return fdb5::FDB(config);
}))
.def("list", &fdb5::FDB::list)
.def("archive", pybind11::overload_cast<const void*, std::size_t>(&fdb5::FDB::archive), "Archive data given as a byte stream with the corresponding length")
.def("archive", pybind11::overload_cast<const metkit::mars::MarsRequest&, eckit::DataHandle&>(&fdb5::FDB::archive), "Archive a MarsRequest and its corresponding DataHandle&")
.def("flush", &fdb5::FDB::flush)
.def("retrieve", &fdb5::FDB::retrieve)
.doc() = "FDB instance.";

}
3 changes: 3 additions & 0 deletions src/pyfdb/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from __future__ import annotations

from ._core import FDB, Config, FDBToolRequest, ListElement, MarsRequest, PathName

0 comments on commit e8eed21

Please sign in to comment.