Skip to main content

Python wrapper for the Helios Software SOF (SQL on FHIR) toolkit.

Project description

pysof - SQL on FHIR for Python

PyPI version Python versions License: MIT Downloads

High-performance FHIR data transformation for Python. Transform FHIR resources into tabular formats (CSV, JSON, Parquet) using declarative ViewDefinitions from the SQL on FHIR specification.

Built in Rust for speed, exposed to Python with a simple, Pythonic API. Part of the Helios FHIR Server project.

โœจ Key Features

  • ๐Ÿš€ High Performance: Native Rust implementation with minimal Python overhead
  • ๐Ÿ“Š Multiple Output Formats: CSV, JSON, NDJSON, and Parquet
  • ๐Ÿ”„ Parallel Processing: Automatic multithreading with 5-7x speedup on multi-core systems
  • ๐Ÿ“ฆ Streaming Support: Memory-efficient chunked processing for large NDJSON files
  • ๐ŸŒ Multi-Version FHIR: Supports R4, R4B, R5, and R6 (based on build features)
  • ๐ŸŽฏ Type-Safe: Leverages Rust's type safety with a Pythonic interface
  • โšก GIL-Free: Python GIL released during processing for true parallelism

๐ŸŽฏ Why pysof?

Working with FHIR data in Python just got faster. pysof lets you:

  • Transform complex FHIR resources into clean, analyzable tables without writing custom parsers
  • Process large datasets efficiently with automatic parallel processing and Rust-level performance
  • Use standard SQL on FHIR ViewDefinitions for portable, maintainable data transformations
  • Export to multiple formats (CSV, JSON, NDJSON, Parquet) for analytics, ML, or reporting workflows

Perfect for healthcare data engineers, researchers, and developers building FHIR-based analytics pipelines.

๐Ÿ”— Quick Links

๐Ÿ“ฅ Installation

From PyPI (Recommended)

pip install pysof

Supported Platforms:

  • Linux: x86_64 (glibc and musl)
  • Windows: x86_64 (MSVC)
  • macOS: AArch64 (Apple Silicon)
  • Python: 3.10, 3.11, 3.12, 3.13, 3.14

From GitHub Releases

Download pre-built wheels from the releases page:

pip install pysof-*.whl

๐Ÿš€ Quick Start

Transform FHIR patient data to CSV in just a few lines:

import pysof

# Define what data to extract
view_definition = {
    "resourceType": "ViewDefinition",
    "id": "patient-demographics",
    "name": "PatientDemographics",
    "status": "active",
    "resource": "Patient",
    "select": [{
        "column": [
            {"name": "id", "path": "id"},
            {"name": "family_name", "path": "name.family"},
            {"name": "given_name", "path": "name.given.first()"},
            {"name": "gender", "path": "gender"},
            {"name": "birth_date", "path": "birthDate"}
        ]
    }]
}

# Sample FHIR Bundle
bundle = {
    "resourceType": "Bundle",
    "type": "collection",
    "entry": [{
        "resource": {
            "resourceType": "Patient",
            "id": "patient-1",
            "name": [{"family": "Doe", "given": ["John"]}],
            "gender": "male",
            "birthDate": "1990-01-01"
        }
    }]
}

# Transform to CSV
csv_output = pysof.run_view_definition(view_definition, bundle, "csv")
print(csv_output.decode('utf-8'))
# Output:
# id,family_name,given_name,gender,birth_date
# patient-1,Doe,John,male,1990-01-01

๐Ÿ“– Usage

Multiple Output Formats

import pysof
import json

# Transform to different formats
csv_result = pysof.run_view_definition(view_definition, bundle, "csv")
json_result = pysof.run_view_definition(view_definition, bundle, "json")
ndjson_result = pysof.run_view_definition(view_definition, bundle, "ndjson")
parquet_result = pysof.run_view_definition(view_definition, bundle, "parquet")

print("CSV Output:")
print(csv_result.decode('utf-8'))

print("\nJSON Output:")
data = json.loads(json_result.decode('utf-8'))
print(json.dumps(data, indent=2))

Advanced Options

import pysof

# Transform with pagination and filtering
result = pysof.run_view_definition_with_options(
    view_definition,
    bundle,
    "json",
    limit=10,                          # Limit results
    page=1,                            # Page number
    since="2023-01-01T00:00:00Z",     # Filter by modification date
    fhir_version="R4"                  # Specify FHIR version
)

Utility Functions

import pysof

# Validate structures
is_valid_view = pysof.validate_view_definition(view_definition)
is_valid_bundle = pysof.validate_bundle(bundle)

# Parse content types
format_str = pysof.parse_content_type("text/csv")  # Returns "csv_with_header"

# Check supported FHIR versions
versions = pysof.get_supported_fhir_versions()  # Returns ["R4"] or more
print(f"Supported FHIR versions: {versions}")

# Package info
print(f"Version: {pysof.get_version()}")
print(pysof.get_status())

Streaming Large NDJSON Files

For memory-efficient processing of large NDJSON files, use the ChunkedProcessor iterator or process_ndjson_to_file function:

import pysof

view_definition = {
    "resourceType": "ViewDefinition",
    "status": "active",
    "resource": "Patient",
    "select": [{"column": [
        {"name": "id", "path": "id"},
        {"name": "gender", "path": "gender"}
    ]}]
}

# Iterator approach - process chunks incrementally
for chunk in pysof.ChunkedProcessor(view_definition, "patients.ndjson", chunk_size=500):
    print(f"Chunk {chunk['chunk_index']}: {len(chunk['rows'])} rows")
    for row in chunk["rows"]:
        process_row(row)
    if chunk["is_last"]:
        print("Processing complete!")

# Access column names before iterating
processor = pysof.ChunkedProcessor(view_definition, "patients.ndjson")
print(f"Columns: {processor.columns}")
for chunk in processor:
    # Process chunks...
    pass

# File-to-file approach - most memory efficient
stats = pysof.process_ndjson_to_file(
    view_definition,
    "input.ndjson",
    "output.csv",
    "csv",  # or "csv_with_header", "ndjson"
    chunk_size=1000,
    skip_invalid=True,  # Continue past invalid JSON lines
    fhir_version="R4"
)
print(f"Processed {stats['resources_processed']} resources")
print(f"Output {stats['output_rows']} rows in {stats['chunks_processed']} chunks")
print(f"Skipped {stats['skipped_lines']} invalid lines")

When to use streaming:

  • Processing NDJSON files larger than available memory
  • Working with datasets of 100K+ resources
  • Building ETL pipelines that process data incrementally
  • When you need fault-tolerant processing (skip invalid lines)

Error Handling

import pysof

try:
    result = pysof.run_view_definition(view_definition, bundle, "json")
except pysof.InvalidViewDefinitionError as e:
    print(f"ViewDefinition validation error: {e}")
except pysof.SerializationError as e:
    print(f"JSON parsing error: {e}")
except pysof.UnsupportedContentTypeError as e:
    print(f"Unsupported format: {e}")
except pysof.SofError as e:
    print(f"General SOF error: {e}")

โšก Performance

Automatic Parallel Processing

pysof automatically processes FHIR resources in parallel using rayon:

  • 5-7x speedup on typical batch workloads with multi-core CPUs
  • Streaming benefits: ChunkedProcessor and process_ndjson_to_file also use parallel processing
  • Zero configuration - parallelization is always enabled
  • Python GIL released during processing for true parallel execution

Performance Benchmarks

Mode Dataset Time Memory Notes
Batch 10k Patients ~2.7s 1.6 GB All resources in memory
Streaming 10k Patients ~0.9s 45 MB 35x less memory, 2.9x faster
Batch 93k Encounters ~4s 3.9 GB All resources in memory
Streaming 93k Encounters ~2.8s 25 MB 155x less memory, 1.4x faster

Streaming mode (ChunkedProcessor, process_ndjson_to_file) is recommended for large NDJSON files.

Controlling Thread Count (RAYON_NUM_THREADS)

Set the RAYON_NUM_THREADS environment variable to control parallel processing:

import os
os.environ['RAYON_NUM_THREADS'] = '4'  # Must be set before first import

import pysof
result = pysof.run_view_definition(view_definition, bundle, "json")

Or from the command line:

# Linux/Mac
RAYON_NUM_THREADS=4 python my_script.py

# Windows PowerShell
$env:RAYON_NUM_THREADS=4
python my_script.py

When to adjust thread count:

  • Reduce threads (RAYON_NUM_THREADS=2-4): On shared systems, containers with CPU limits, or when running multiple instances
  • Increase threads: Rarely needed; rayon auto-detects available cores
  • Single thread (RAYON_NUM_THREADS=1): For debugging or deterministic output ordering

Performance Tips:

  • Use all available cores for large datasets (default behavior)
  • Limit threads on shared systems to avoid resource contention
  • Prefer streaming mode (ChunkedProcessor) for NDJSON files > 100MB

๐Ÿ“‹ Supported Features

Output Formats

Format Description Output
csv CSV with headers Comma-separated values with header row
json JSON array Array of objects, one per result row
ndjson Newline-delimited JSON One JSON object per line
parquet Parquet format Columnar binary format for analytics

FHIR Versions

  • R4 (default, always available)
  • R4B (if compiled with R4B feature)
  • R5 (if compiled with R5 feature)
  • R6 (if compiled with R6 feature)

Use pysof.get_supported_fhir_versions() to check available versions in your build.


๐Ÿ”ง Development

Requirements

  • Python 3.10 or later (3.10, 3.11, 3.12, 3.13, 3.14 supported)
  • uv (package and environment manager)
  • Rust toolchain (for building from source)

Note: This crate is excluded from the default workspace build. When running cargo build from the repository root, pysof will not be built automatically.

Building from Source

Building with Cargo

This crate is excluded from the default workspace build to allow building the core Rust components without Python. To build it explicitly:

# Your current directory MUST be the pysof crate:
cd crates/pysof

# From the pysof folder
cargo build

# Or build with specific FHIR version features
cargo build -p pysof --features R4,R5

Building with Maturin (Recommended)

For Python development, it's recommended to use maturin via uv:

# From repo root
cd crates/pysof

# Create a venv with your preferred Python version (3.10+)
uv venv --python 3.11  # or 3.10, 3.12, 3.13, 3.14

# Install the project dev dependencies
uv sync --group dev

# Build and install the Rust extension into the venv
uv run maturin develop --release

# Build distributable artifacts
uv run maturin build --release -o dist     # wheels
uv run maturin sdist -o dist               # source distribution

# Sanity checks
uv run python -c "import pysof; print(pysof.__version__); print(pysof.get_status()); print(pysof.get_supported_fhir_versions())"

Installing from Source

Requires Rust toolchain:

# Install directly
pip install -e .

# Or build wheel locally
maturin build --release --out dist
pip install dist/*.whl

Testing

The project has separate test suites for Python and Rust components:

Python Tests

Run the comprehensive Python test suite:

# Run all Python tests
uv run pytest python-tests/

# Run specific test files
uv run pytest python-tests/test_core_functions.py -v
uv run pytest python-tests/test_content_types.py -v
uv run pytest python-tests/test_import.py -v

# Run with coverage
uv run pytest python-tests/ --cov=pysof --cov-report=html

# Run tests with detailed output
uv run pytest python-tests/ -v --tb=short

Rust Tests

Run the Rust unit and integration tests:

# Run all Rust tests
cargo test

# Run unit tests only
cargo test --test lib_tests

# Run integration tests only
cargo test --test integration

# Run with verbose output
cargo test -- --nocapture

Configuring FHIR Version Support

By default, pysof is compiled with R4 support only. You can configure which FHIR versions are available by modifying the feature compilation settings.

Change Default FHIR Version

To change from R4 to another version (e.g., R5):

  1. Edit crates/pysof/Cargo.toml:

    [features]
    default = ["R5"]  # Changed from ["R4"]
    R4 = ["helios-sof/R4", "helios-fhir/R4"]
    R4B = ["helios-sof/R4B", "helios-fhir/R4B"]
    R5 = ["helios-sof/R5", "helios-fhir/R5"]
    R6 = ["helios-sof/R6", "helios-fhir/R6"]
    
  2. Rebuild the extension:

    cd crates/pysof
    uv run maturin develop --release
    
  3. Verify the change:

    uv run python -c "
    import pysof
    versions = pysof.get_supported_fhir_versions()
    print('Supported FHIR versions:', versions)
    "
    

    This should now show ['R5'] instead of ['R4'].

Enable Multiple FHIR Versions

To support multiple FHIR versions simultaneously:

  1. Edit crates/pysof/Cargo.toml:

    [features]
    default = ["R4", "R5"]  # Enable both R4 and R5
    # Or enable all versions:
    # default = ["R4", "R4B", "R5", "R6"]
    
  2. Rebuild and verify:

    uv run maturin develop --release
    uv run python -c "import pysof; print(pysof.get_supported_fhir_versions())"
    

    This should show ['R4', 'R5'] (or all enabled versions).

  3. Use specific versions in code:

    import pysof
    
    # Use R4 explicitly
    result_r4 = pysof.run_view_definition(view, bundle, "json", fhir_version="R4")
    
    # Use R5 explicitly  
    result_r5 = pysof.run_view_definition(view, bundle, "json", fhir_version="R5")
    

Build with Specific Features (Without Changing Default)

To temporarily build with different features without modifying Cargo.toml:

# Build with only R5
cargo build --features R5 --no-default-features

# Build with R4 and R6
cargo build --features R4,R6 --no-default-features

# With maturin
uv run --with maturin -- maturin develop --release --cargo-extra-args="--features R5 --no-default-features"

Testing After Version Changes

After changing FHIR version support, run the test suite to ensure compatibility:

# Run all tests
uv run pytest

# Run FHIR version-specific tests
uv run pytest tests/test_fhir_versions.py -v

# Test with your new default version
uv run python -c "
import pysof

# Test with default version (should be your new default)
view = {'resourceType': 'ViewDefinition', 'id': 'test', 'name': 'Test', 'status': 'active', 'resource': 'Patient', 'select': [{'column': [{'name': 'id', 'path': 'id'}]}]}
bundle = {'resourceType': 'Bundle', 'type': 'collection', 'entry': [{'resource': {'resourceType': 'Patient', 'id': 'test'}}]}

result = pysof.run_view_definition(view, bundle, 'json')
print('Default version test successful:', len(result), 'bytes')
"

Project layout

crates/pysof/
โ”œโ”€ pyproject.toml          # PEP 621 metadata, Python >=3.8, uv-compatible
โ”œโ”€ README.md
โ”œโ”€ src/
โ”‚  โ”œโ”€ pysof/
โ”‚  โ”‚  โ””โ”€ __init__.py       # Python package root
โ”‚  โ””โ”€ lib.rs               # Rust PyO3 bindings
โ”œโ”€ tests/                  # Rust tests (17 tests)
โ”‚  โ”œโ”€ lib_tests.rs         # Unit tests for core library functions
โ”‚  โ”œโ”€ integration.rs       # Integration tests for component interactions
โ”‚  โ””โ”€ integration/         # Organized integration test modules
โ”‚     โ”œโ”€ mod.rs
โ”‚     โ”œโ”€ content_types.rs
โ”‚     โ”œโ”€ error_handling.rs
โ”‚     โ””โ”€ fhir_versions.rs
โ”œโ”€ python-tests/           # Python test suite (58 tests)
โ”‚  โ”œโ”€ __init__.py
โ”‚  โ”œโ”€ test_core_functions.py
โ”‚  โ”œโ”€ test_content_types.py
โ”‚  โ”œโ”€ test_fhir_versions.py
โ”‚  โ”œโ”€ test_import.py
โ”‚  โ””โ”€ test_package_metadata.py
โ””โ”€ Cargo.toml              # Rust crate metadata

๐Ÿ“„ License

MIT License - See LICENSE.md for details.

Copyright (c) 2025 Helios Software

๐Ÿค Contributing

Contributions are welcome! Please see our Contributing Guidelines for details.

Reporting Issues

Development Setup

See the Development section above for instructions on setting up your development environment.

๐Ÿ™ Acknowledgments

Built with:

  • PyO3 - Rust bindings for Python
  • maturin - Build system for Rust Python extensions
  • helios-sof - Core SQL-on-FHIR implementation in Rust

Part of the Helios FHIR Server project.


Made with โค๏ธ by Helios Software

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

pysof-0.2.0.tar.gz (25.3 MB view details)

Uploaded Source

Built Distributions

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

pysof-0.2.0-cp314-cp314-win_amd64.whl (39.4 MB view details)

Uploaded CPython 3.14Windows x86-64

pysof-0.2.0-cp314-cp314-manylinux_2_34_x86_64.whl (33.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ x86-64

pysof-0.2.0-cp314-cp314-manylinux_2_28_aarch64.whl (33.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

pysof-0.2.0-cp314-cp314-macosx_11_0_arm64.whl (28.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

pysof-0.2.0-cp313-cp313-win_amd64.whl (39.4 MB view details)

Uploaded CPython 3.13Windows x86-64

pysof-0.2.0-cp313-cp313-manylinux_2_34_x86_64.whl (33.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

pysof-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl (33.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

pysof-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (28.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pysof-0.2.0-cp312-cp312-win_amd64.whl (39.4 MB view details)

Uploaded CPython 3.12Windows x86-64

pysof-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl (33.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

pysof-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl (33.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

pysof-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (28.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pysof-0.2.0-cp311-cp311-win_amd64.whl (39.4 MB view details)

Uploaded CPython 3.11Windows x86-64

pysof-0.2.0-cp311-cp311-manylinux_2_34_x86_64.whl (33.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

pysof-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl (33.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

pysof-0.2.0-cp311-cp311-macosx_11_0_arm64.whl (28.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pysof-0.2.0-cp310-cp310-win_amd64.whl (39.4 MB view details)

Uploaded CPython 3.10Windows x86-64

pysof-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl (33.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

pysof-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl (33.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

pysof-0.2.0-cp310-cp310-macosx_11_0_arm64.whl (28.6 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file pysof-0.2.0.tar.gz.

File metadata

  • Download URL: pysof-0.2.0.tar.gz
  • Upload date:
  • Size: 25.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pysof-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2162a6fd1568320fac8810032a6ed94fc71164981a17b9aedf5f8791ad6d924e
MD5 ed834cf69ba3e68454658f50c98387cd
BLAKE2b-256 55b2f077ecb0cb1a33dc260c141e4bfca2debda0ee3d3f7a96e755ba3faac295

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: pysof-0.2.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 39.4 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pysof-0.2.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 2ccf83fbc17acdcfacfc263f2e6a1919ba6f951f13c884bbe26342bfed570393
MD5 ddd029cccaa6d2774abe1897552001e4
BLAKE2b-256 2e0e0de9831090f17fb767fd987858575bf1562d450071399be98a6b4aeb15c3

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp314-cp314-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp314-cp314-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 693a1f7fc4ea9500ef6354e51009ecf773bbac5ccbd345500a52ba93bd96ad31
MD5 fb4808f5604914a3aa87e851b40dc3ee
BLAKE2b-256 8bbdbb2421137b21e7012c4948facaa962b47169c86b61c5935ebb8bffed1379

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp314-cp314-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f479f39d1905ecc5b9a903ef673c13c2ad33a31510dc4592e95b078860d0e4e3
MD5 746d8dbfc2d7e43b6d24c3602aa8ec9c
BLAKE2b-256 11e5c139f9eec5923985a3cb92e6f5d9396695b8088474121dc298fd22cd5291

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5753d7b2fb870957950e26ebe7596020a8e274d62d7126bb2a51d689d20c470e
MD5 84435a6ae1ceae5129618c8e9bc4f3ba
BLAKE2b-256 bbd358ed624e212878139909c92d60c5c3c39d199504a0cba8607450b6df7ee3

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pysof-0.2.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 39.4 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pysof-0.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 703ca70dd0d561072fbd79abc0d1bc764f14e5eecf78ab7baa369ebc45b40553
MD5 f130d32def990f0530ad81f66384dc9f
BLAKE2b-256 14e7eb54a2dda1bdfb38b916115885945c92081ab62e5b2b1bb82cb207a176e4

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d0904e408d98dc09db080bf7dd39b1e335ae8242d21f196b07e7d5f78be8f103
MD5 648b9039352c374c97a17751b19ec483
BLAKE2b-256 619508cb166029b6b4a5e542c5668cf70a32190975210972db2edc0da7d646eb

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cb8298ed5a058e9275bf78618a0c209c715ddfdef1d85aa2fa49dd04ff5e9ba0
MD5 f19b45aeac6cc40caa85910bc3265bd5
BLAKE2b-256 fc191638e1574f5f5ea9ddcea47dcd3a202e1ebcf1575782fbec0f84d32c6131

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2f130394f9e496ca072085cd68267f189fab7a6c3b3b641766965da0b01dd672
MD5 400fe2cdd867647068a29803d13ed7c4
BLAKE2b-256 d96fc1675839958bcbae3db670a2e5bd61188128260eed664f1346081f8a0d1b

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pysof-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 39.4 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pysof-0.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 171e586b2da28baacc42ac1229df7ca474ae2f9da63871f6a7632100b9d7d624
MD5 1864b553cccf0abd3f45b822145729e2
BLAKE2b-256 eb6bf0d7cf53b26d3b5a9b6cc052577319fa28b380ff14b352855ba11a9b2613

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 acb1e996f9dfea2f65cdee6a8670b959a67a5b03b6f3df952c50059c9b40406a
MD5 ee5fd5edca1b0fbb2658a9df42c33b06
BLAKE2b-256 3746af3282fe3d7474c7321ef567f78b8490bc053d5fe386c7693f653dcaf17a

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a010aa137acbd4065344234cb20546eb8d5d8741a15ad80abecc819000b00cba
MD5 9c3657d0c755e5abfdd04c2005f4c9a5
BLAKE2b-256 c614435c964400a412b138daa5ea796828d8e84aaa326b914b6a4d38c4f861b7

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cbf2be90c9e670c5574188fc90c658c7a044bfedc733d1aa013299ac3684f62e
MD5 e0363826acadef7a5ef1b333478911c0
BLAKE2b-256 0f31aeaaae3a98fe889ec2d0d7ea96d2d592bac9225363488f4ee04104226659

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pysof-0.2.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 39.4 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pysof-0.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 9d49ecec32c4d2d1b7ff0f6057f39e525379d06ef3e3319bdf20e3547dc6de6d
MD5 8f1011d8e97eeb441ab2fb3d71874e73
BLAKE2b-256 db95911ea38b28d9fccdaa2003f687b4a1b1682c37a113c67c6647b71d468369

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 b4fb9590067c65a4920cee5fda10a900692ce488465fef514f40d64079a55564
MD5 92fbe0714b169731ce1d266f93285a62
BLAKE2b-256 7942c6e5f5eea7a25938cf5d86c4640b4366cc1f8838fd9652ceb3762b8d3b9e

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a9522d568a881c558c2bf070659761a77450fb0e4966c340f36aca4f6ca13949
MD5 13ec7797ffdb0582b2ffbcbb852fec57
BLAKE2b-256 9191925c455cc094b541a9b5eb11f22b0d0a2a5f0cf06ab6130d303859633b42

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 27194146824ef578120fc0a4b5e7d06be4a59be987ebf93b222313f6fa176d92
MD5 b978a93eca905feb6d355a138167cac7
BLAKE2b-256 7f45e74022a660285d8fa0efad3337bfa3e90d6ea8ed44766eac965f9a388b0e

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pysof-0.2.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 39.4 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for pysof-0.2.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 9493d9deb3cb6f55300b79a383a3f8810afa24c93d5797cdfe6a98ca910dccfe
MD5 4c08ef57ee73509247646089759b85e3
BLAKE2b-256 0a9f299253d248e24bdc76b72983abef711dbf24e3fc8ffb45ff2c14bfa3b65e

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 65da5d3fc8c3654607ca9f51560bcedddf3f205c2a20418bd52f9d82e94feaa6
MD5 77a8146ccb31438f024083167fa89c48
BLAKE2b-256 c320f2f5144b5a41df7fa1441fd5535259f86475665d1797c6509f87c2bd9ac7

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2e994332b4ec95665d5e06ce29e80bd4348e5653120191a41e9bd074f55dd7d8
MD5 597018f5b50e511a0f48445a65b56c63
BLAKE2b-256 d0274f07bba26346ad99d53b5887776a654a300981aadfc642e8ab95571e35d1

See more details on using hashes here.

File details

Details for the file pysof-0.2.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pysof-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4c82e5b400f22be871ea75693f0cd104c9de1839c81a8e4021bea98c30c0f5ae
MD5 949c248537bfb926aa57879f73d71344
BLAKE2b-256 14671a11576ac50fefad6b41b0d3fd43b504d2cebf6cacf92a951434eb580467

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