Skip to main content

Python bindings for the Open-Meteo file format

Project description

Python Bindings for Open Meteo File Format

Python 3.9+ PyPI version Build and Test

Features

  • Read Open-Meteo (.om) files directly from cloud storage using Python
  • Traverse the hierarchical data structure
  • Arrays/array slices are returned directly as NumPy arrays
  • Support for fsspec and xarray
  • Chunked data access behind the scenes

Installation

pip install omfiles

Pre-Built Wheels & Platform Support

We provide pre-built wheels for the following platforms:

  • Linux x86_64 (manylinux_2_28)
  • Linux aarch64 (manylinux_2_28)
  • Linux musl x86_64 (musllinux_1_2)
  • Windows x64
  • macOS x86_64
  • macOS ARM64 (Apple Silicon)

Stability Notice

This project is now stable as of version 1.0.0. The public API is considered stable and will follow semantic versioning. Breaking changes will not be introduced in 1.x releases without a major version bump.

Reading

Reading Files without Hierarchy

OM files are structured like a tree of variables. The following example assumes that the file test_file.om contains an array variable as a root variable which has a dimensionality greater than 2 and a size of at least 2x100:

from omfiles import OmFileReader

reader = OmFileReader("test_file.om")
data = reader[0:2, 0:100, ...]
reader.close() # Close the reader to release resources

Reading Hierarchical Files, e.g. S3 Spatial Files

import fsspec
import numpy as np
from omfiles import OmFileReader

# Example: URI for a spatial data file in the `data_spatial` S3 bucket
# See data organization details: https://github.com/open-meteo/open-data?tab=readme-ov-file#data-organization
# Note: Spatial data is only retained for 7 days. The example file below may no longer exist.
# Please update the URI to match a currently available file.
s3_uri = "s3://openmeteo/data_spatial/dwd_icon/2025/09/23/0000Z/2025-09-30T0000.om"

# Create and open filesystem, wrapping it in a blockcache
backend = fsspec.open(
    f"blockcache::{s3_uri}",
    mode="rb",
    s3={"anon": True, "default_block_size": 65536},  # s3 settings
    blockcache={"cache_storage": "cache"},  # blockcache settings
)
# Create reader from the fsspec file object using a context manager.
# This will automatically close the file when the block is exited.
with OmFileReader(backend) as root:
    # We are at the root of the data hierarchy!
    # What type of node is this?
    print(f"root.is_array: {root.is_array}")  # False
    print(f"root.is_scalar: {root.is_scalar}")  # False
    print(f"root.is_group: {root.is_group}")  # True

    temperature_reader = root.get_child_by_name("temperature_2m")
    print(f"temperature_reader.is_array: {temperature_reader.is_array}")  # True
    print(f"temperature_reader.is_scalar: {temperature_reader.is_scalar}")  # False
    print(f"temperature_reader.is_group: {temperature_reader.is_group}")  # False

    # What shape does the stored array have?
    print(f"temperature_reader.shape: {temperature_reader.shape}")  # (1441, 2879)

    # Read all data from the array
    temperature_data = temperature_reader.read_array((...))
    print(f"temperature_data.shape: {temperature_data.shape}")  # (1441, 2879)

    # It's also possible to read any subset of the array
    temperature_data_subset1 = temperature_reader.read_array((slice(0, 10), slice(0, 10)))
    print(temperature_data_subset1)
    print(f"temperature_data_subset1.shape: {temperature_data_subset1.shape}")  # (10, 10)

    # Numpy basic indexing is supported for direct access if the reader is an array.
    temperature_data_subset2 = temperature_reader[0:10, 0:10]
    print(temperature_data_subset2)
    print(f"temperature_data_subset2.shape: {temperature_data_subset2.shape}")  # (10, 10)

    # Compare the two temperature subsets and verify that they are the same
    are_equal = np.array_equal(temperature_data_subset1, temperature_data_subset2, equal_nan=True)
    print(f"Are the two temperature subsets equal? {are_equal}")

Writing

Single Array

import numpy as np
from omfiles import OmFileWriter

# Create sample data
data = np.random.rand(100, 100).astype(np.float32)

# Initialize writer
writer = OmFileWriter("simple.om")

# Write array with compression
array_variable = writer.write_array(
    data,
    chunks=[50, 50],
    scale_factor=1.0,
    add_offset=0.0,
    compression="pfor_delta_2d",
    name="data"
)

# Finalize the file using array_variable as entry-point
writer.close(array_variable)

Hierarchical Structure

import numpy as np
from omfiles import OmFileWriter

# Create sample data
features = np.random.rand(1000, 64).astype(np.float32)
labels = np.random.randint(0, 10, size=(1000,), dtype=np.int32)

# Initialize writer
writer = OmFileWriter("hierarchical.om")

# Write child arrays first
features_var = writer.write_array(features, chunks=[100, 64], name="features", compression="pfor_delta_2d")
labels_var = writer.write_array(labels, chunks=[100], name="labels")
metadata_var = writer.write_scalar(42, name="metadata")

# Create root group with children
root_var = writer.write_group(
    name="root",
    children=[features_var, labels_var, metadata_var],
)
# Finalize the file using root_var as entry-point into the hierarchy
writer.close(root_var)

Development

# install the required dependencies in .venv directory
uv sync
# to run the tests
uv run pytest tests/
# to build the wheels
uv run build
# or to trigger maturin directly:
# maturin develop

Tests

cargo test

runs rust tests.

uv run pytest tests/

runs Python tests.

Python Type Stubs

Can be generated from the rust doc comments via

cargo run stub_gen

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

omfiles-1.0.1.tar.gz (202.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

omfiles-1.0.1-cp39-abi3-win_amd64.whl (805.0 kB view details)

Uploaded CPython 3.9+Windows x86-64

omfiles-1.0.1-cp39-abi3-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9+musllinux: musl 1.2+ x86-64

omfiles-1.0.1-cp39-abi3-manylinux_2_28_x86_64.whl (1.0 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ x86-64

omfiles-1.0.1-cp39-abi3-manylinux_2_28_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

omfiles-1.0.1-cp39-abi3-macosx_11_0_arm64.whl (939.8 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

omfiles-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl (923.1 kB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file omfiles-1.0.1.tar.gz.

File metadata

  • Download URL: omfiles-1.0.1.tar.gz
  • Upload date:
  • Size: 202.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.6

File hashes

Hashes for omfiles-1.0.1.tar.gz
Algorithm Hash digest
SHA256 7227427f3a3739c0fc623c5bf8afbaf809c03c8facdeed78c2489867c7a0fd17
MD5 cd8ecfeb3e1b13185cfc32ffab7df7fd
BLAKE2b-256 d56a2b2e52dfcdfe1024d0a60ff8f9ff09e30c98fea6e2bce9da89aaaaa140fe

See more details on using hashes here.

File details

Details for the file omfiles-1.0.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: omfiles-1.0.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 805.0 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.6

File hashes

Hashes for omfiles-1.0.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 aed81f8ea3148dd02fc345d5e262ee4ddb2ac9dac61bae8955bad98430e61672
MD5 3cd7450bbf0ee8c1b6881ff5d54e7713
BLAKE2b-256 367c726a57089455882b01edb76eeb9b7e9237fb5418a8dae147ace82a5ec125

See more details on using hashes here.

File details

Details for the file omfiles-1.0.1-cp39-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for omfiles-1.0.1-cp39-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 bf33a5af12f06f59bd6c8c98f852306a54af8ce0bae177754e54b3430005e2ea
MD5 59cfc94d5c48a40100b1dfa1ac9d96d3
BLAKE2b-256 41862f62782d6272ee34a63d8f4f5e0991d9397474f889132324c8c7e2764788

See more details on using hashes here.

File details

Details for the file omfiles-1.0.1-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for omfiles-1.0.1-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2f188c15d6f93e930f01dcb4ec647a9a74f44291b8ee16e65921bfd125be6d38
MD5 1f643b133706c7246e7cb89bc75856b1
BLAKE2b-256 8606254d71e7a247108d54c5de49f88a335c7f95afdeba428af37b6646a15ecd

See more details on using hashes here.

File details

Details for the file omfiles-1.0.1-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for omfiles-1.0.1-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 941a8c12b8b9647ed5a98181fbea22dcc0b7ed0b6985eaecf0bc6281c8b77d09
MD5 4a59bd3750125b7650e796ffeabfe7e2
BLAKE2b-256 db03f556f070d1c3e688d2d1ea1197d3c3014ae2e7444d72ebf8c6152e51ec4e

See more details on using hashes here.

File details

Details for the file omfiles-1.0.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for omfiles-1.0.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 327848ad2fb26f532a79e280c6b5b7bd67f1c7339169ea6360ecc1cdb26270f5
MD5 4eaa64c62751867c8823280d049dab9d
BLAKE2b-256 7148ff4112fbe97819d6909c74e47264a93fe0e9f32638eabdb4643858b8dafd

See more details on using hashes here.

File details

Details for the file omfiles-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for omfiles-1.0.1-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9d33954eee8ab879b5ee788427b9f95ab10a3a8fbc247b9c9308cfe8d1ceba32
MD5 f8ae60bc3986ebe53f8b14d430e5be9a
BLAKE2b-256 914b83abe68e94ca61f4b04b88ad797e48ca3b8d02758ee39a247ae16be393e5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page