Thanks to visit codestin.com
Credit goes to github.com

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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Test Windows
on:
push
workflow_dispatch:

jobs:
build:
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/full_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Test Windows and Linux

on:
push:
branches: [ master]
pull_request:
branches: [ master ]

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: [3.8, 3.13]

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
version: "0.7.21"

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

# this is installed by default on Ubuntu 22.04
- name: Install libnsl2 (Linux only)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libnsl2

- name: Install the project
run: uv sync

- name: Run tests
run: uv run pytest

5 changes: 0 additions & 5 deletions .github/workflows/test_linux.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
name: Test Linux

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

workflow_dispatch:

jobs:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,4 @@ bin
x64
/tmp/
/TestResults
uv.lock
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,33 @@ This library is the foundation for [MIKE IO](https://github.com/DHI/mikeio).
## Installation

```pip install mikecore```
```

## Development

All commands are run from the project root.

1. **Sync & Build**
```bash
uv sync
# Use 'uv sync --reinstall' to force-rebuild native components.
```

2. **Update EUM Types** (for new release, or whenever EUM.xml changes)
```bash
# Generate definitions from the new native build
uv run ./buildUtil/eumXMLProcess.py > eumItemUnit.txt

# Use a diff tool to merge changes into mikecore/eum.py.
```

3. **Run Tests**
```bash
uv run pytest
```

4. **Build Packages** (Optional)
```bash
uv build
```


107 changes: 107 additions & 0 deletions buildUtil/build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from __future__ import annotations

import shutil
import urllib.request
import xml.etree.ElementTree as ET
import zipfile
from pathlib import Path
from typing import Any
import subprocess
import platform

from hatchling.builders.hooks.plugin.interface import BuildHookInterface


def download_nuget_package(
package_id: str,
version: str,
output_dir: str | Path
) -> None:
"""
Download a NuGet package (.nupkg) to output_dir.
"""
package_id_lower: str = package_id.lower()
version_lower: str = version.lower()
url: str = f"https://api.nuget.org/v3-flatcontainer/{package_id_lower}/{version_lower}/{package_id_lower}.{version_lower}.nupkg"
output_dir = Path(output_dir)
nupkg_path: Path = output_dir / f"{package_id}.{version}.nupkg"
extract_path: Path = output_dir / f"{package_id}"

output_dir.mkdir(parents=True, exist_ok=True)

print(f"Downloading {package_id} {version} from {url}...")
with urllib.request.urlopen(url) as response, nupkg_path.open("wb") as f:
f.write(response.read())

print(f"Extracting {nupkg_path} to {extract_path}...")
with zipfile.ZipFile(nupkg_path, "r") as zip_ref:
zip_ref.extractall(extract_path)
print("Done.")

def copy_native_libs_to_bin(packages_dir: str | Path, bin_dir: str | Path) -> None:
"""
Copy native shared libraries from NuGet packages to bin directory.
"""
packages_dir = Path(packages_dir)
bin_windows = Path(bin_dir) / "windows"
bin_linux = Path(bin_dir) / "linux"
bin_windows.mkdir(parents=True, exist_ok=True)
bin_linux.mkdir(parents=True, exist_ok=True)

for package in packages_dir.iterdir():
win_native = package / "runtimes" / "win-x64" / "native"
linux_native = package / "runtimes" / "linux-x64" / "native"

if win_native.exists():
for lib in win_native.glob("*"):
dest = bin_windows / lib.name
print(f"Copying {lib} to {dest}")
shutil.copy2(lib, dest)

if linux_native.exists():
for lib in linux_native.glob("*"):
dest = bin_linux / lib.name
print(f"Copying {lib} to {dest}")
shutil.copy2(lib, dest)

def read_packages_config(filepath: str | Path) -> list[tuple[str, str]]:
"""
Reads NuGet packages.config and returns a list of (id, version) tuples.
"""
tree = ET.parse(filepath)
root = tree.getroot()
return [
(pkg.attrib["id"], pkg.attrib["version"])
for pkg in root.findall("package")
]

def modify_linux_so_rpath(bin_folder: str | Path):
patchelf_path = shutil.which("patchelf")
for so in Path(bin_folder).glob("*.so*"):
print(f"Setting RUNPATH for {so} to '$ORIGIN'")
subprocess.run(
[patchelf_path, "--set-rpath", "$ORIGIN", str(so.absolute())],
check=True,
)

def setup():
"""Setup function to download NuGet packages and copy native libraries into bin folder.
"""
packages = read_packages_config("buildUtil/packages.config")
for name, version in packages:
download_nuget_package(name, version, output_dir="packages")
copy_native_libs_to_bin("packages", "mikecore/bin")

if platform.system().lower() == "linux":
modify_linux_so_rpath("mikecore/bin/linux")


class BuildHook(BuildHookInterface):
"""Custom build hook to run setup during the build process."""

def initialize(self, version: str, build_data: dict[str : Any]) -> None:
"""Initialize the build hook."""
setup()

if __name__ == "__main__":
setup()
2 changes: 1 addition & 1 deletion buildUtil/eumXMLProcess.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import re

# Using readlines()
eumFile = open('build/lib/mikecore/bin/windows/EUM.xml', 'r')
eumFile = open('mikecore/bin/windows/EUM.xml', 'r')
eumLines = eumFile.readlines()
eumFile.close()

Expand Down
9 changes: 9 additions & 0 deletions buildUtil/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DHI.DFS" version="23.0.3" />
<package id="DHI.PFS" version="23.0.3" />
<package id="DHI.EUM" version="23.0.3" />
<package id="DHI.DHIfl" version="23.0.3" />
<package id="DHI.Projections" version="23.0.3" />
<package id="DHI.MikeCore.Linux.ubuntu22" version="23.0.3" />
</packages>
58 changes: 58 additions & 0 deletions mikecore/eum.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,50 @@ class eumItem(IntEnum):
eumIBladeThickness = 110318
eumIPlantDensity = 110319
eumIThickness = 110320
eumICarbonEmmisionFactor = 110321
eumIAluminiumAl = 110322
eumIBismuthBi = 110323
eumICalciumCa = 110324
eumICadmiumCd = 110325
eumICobaltCo = 110326
eumIChromiumCr = 110327
eumICopperCu = 110328
eumIIronFe = 110329
eumIPotassiumK = 110330
eumILithiumLi = 110331
eumIMagnesiumMg = 110332
eumIManganeseMn = 110333
eumISodiumNa = 110334
eumINickelNi = 110335
eumILeadPb = 110336
eumIStrontiumSr = 110337
eumIZincZn = 110338
eumISilverAg = 110339
eumIBariumBa = 110340
eumIBerylliumBe = 110341
eumIIndiumIn = 110342
eumIVanadiumV = 110343
eumIArsenicAs = 110344
eumISulfurS = 110345
eumIMolybdenumMo = 110346
eumIPhosphorusP = 110347
eumIMercuryHg = 110348
eumIAntimonySb = 110349
eumISeleniumSe = 110350
eumIUraniumU = 110351
eumIBoronB = 110352
eumIOxidationReductionPotentialORP = 110353
eumITotalSuspendedSolidsTSS = 110354
eumITotalDissolvedSolidsTDS = 110355
eumIChlorideCl = 110356
eumITurbidityNTU = 110357
eumISulphateSO4 = 110358
eumIPhosphatePO4 = 110359
eumINitrateNO3 = 110360
eumINitriteNO2 = 110361
eumIFluorideF = 110362
eumITotalAlkanlinity = 110363
eumIChemicalOxygenDemandCOD = 110364

# Predefined enums of EUM units.
#
Expand Down Expand Up @@ -886,6 +930,7 @@ class eumUnit(IntEnum):
eumUTonPerYear = 4218
eumUTonPerDay = 4219
eumUTonPerSec = 4220
eumUmilligramPerMin = 4221
eumUgramPerM2 = 4400
eumUkilogramPerM = 4401
eumUkilogramPerM2 = 4402
Expand Down Expand Up @@ -1024,6 +1069,8 @@ class eumUnit(IntEnum):
eumUexaJoule = 5608
eumUmegaWattHour = 5609
eumUgigaWattHour = 5610
eumUkilogramPerKiloWattHour = 5630
eumUpoundPerKiloWattHour = 5631
eumUperJoule = 5650
eumUperKiloJoule = 5651
eumUperMegaJoule = 5652
Expand Down Expand Up @@ -1124,6 +1171,17 @@ class eumUnit(IntEnum):
eumUMgalUKPerDayPerPsi = 7508
eumUacftPerDayPerPsi = 7509
eumUm3PerHourPerBar = 7510
eumUliterPerSecPerMeter2OneHalf = 7530
eumUliterPerMinPerMeter2OneHalf = 7531
eumUMegaLiterPerDayPerMeter2OneHalf = 7532
eumUm3PerHourPerMeter2OneHalf = 7533
eumUm3PerDayPerMeter2OneHalf = 7534
eumUft3PerSecPerPsi2OneHalf = 7535
eumUgallonPerMinPerPsi2OneHalf = 7536
eumUMgalPerDayPerPsi2OneHalf = 7537
eumUMgalUKPerDayPerPsi2OneHalf = 7538
eumUacftPerDayPerPsi2OneHalf = 7539
eumUm3PerHourPerBar2OneHalf = 7540
eumUKilogramPerS2 = 8100
eumUm2Perkilogram = 9100
eumUPerMeterPerSecond = 9200
Expand Down
38 changes: 38 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[build-system]
requires = ["hatchling", "patchelf; sys_platform == 'linux'"]
build-backend = "hatchling.build"

[tool.hatch.build.hooks.custom]
path = "buildUtil/build.py"

[tool.hatch.build.targets.sdist.force-include]
"mikecore/bin" = "mikecore/bin"

[tool.hatch.build.targets.wheel.force-include]
"mikecore/bin" = "mikecore/bin"

[project]
name = "mikecore"
version = "0.3.0a0"
description = "MIKE Core contains core libraries, like DFS (Data File System), EUM and more."
readme = "README.md"
license = { file = "LICENSE.txt" }
authors = [
{ name = "DHI", email = "[email protected]" }
]
requires-python = ">=3.5"
dependencies = [
"numpy"
]
classifiers = [
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3"
]

[project.urls]
Homepage = "https://github.com/DHI/mikecore-python"

[dependency-groups]
dev = [
"pytest>=6.1.2",
]
24 changes: 0 additions & 24 deletions setup.py

This file was deleted.