Skip to main content

MolFrame

Documentation · GitHub High-performance structural bioinformatics for Python and Rust.

Read, transform, analyze, and compare molecular structures through a single semantics-preserving data model.

License: MIT Rust Python


MolFrame is a structural bioinformatics engine for macromolecular structures, trajectories, and derived scientific data.

It combines high-performance Rust kernels with native Python bindings and a columnar molecular representation shared across I/O, selection, geometry, chemistry, surfaces, validation, structural comparison, trajectories, and machine-learning workflows.

The guiding principle is simple:

Structural data is more than coordinates.

Alternate conformations, biological assemblies, insertion codes, identifier namespaces, missing atoms, and provenance can all change the interpretation of a result. MolFrame is designed to preserve that context throughout the analysis pipeline.

Why MolFrame?

Structural workflows often combine parsers, hierarchy libraries, array representations, trajectory packages, and specialized analysis tools.

Each conversion introduces another data model — and another opportunity to lose structural meaning.

MolFrame keeps the workflow inside one representation.

  • One structural model — parse, query, analyze, compare, and export without translating between unrelated representations.
  • Semantics-preserving I/O — retain alternate locations, insertion codes, author and label identifiers, assemblies, and format-specific information.
  • Native performance — core parsing and analysis kernels are implemented in Rust with parallel and vectorized execution where appropriate.
  • Zero-copy interoperability — expose coordinates directly to NumPy and columnar annotations through Apache Arrow.
  • Explicit scientific context — analysis APIs can carry ambiguity, coverage, diagnostics, policy, and provenance instead of hiding important decisions behind defaults.
  • Python and Rust — native interfaces over the same computational engine.
  • Modular Rust API — use the complete engine or compile only the format and analysis domains an application requires.

Installation

Python

pip install molframe
import molframe

Rust

cargo add molframe
use molframe::prelude::*;

MolFrame is currently pre-1.0. Public APIs may evolve while the core contracts are finalized.

Quick start

Python

import molframe

structure = molframe.read("1ubq.cif")

print(structure.atom_count)
print(structure.chain_count)

coordinates = structure.coordinates
print(coordinates.shape)

structure.coordinates exposes coordinates as an N × 3 read-only float32 NumPy view without rebuilding the molecular structure in Python. A Selection.to_coordinates() call is intentionally named because a discontiguous selection must be materialized.

The same structure can be used directly for querying and analysis:

structure = molframe.read("1ubq.cif")

backbone = structure.select("name CA")
print(backbone.to_coordinates().shape)

Rust

use molframe::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (structure, diagnostics) =
        molframe::read_with_diagnostics("1ubq.cif")?;

    println!(
        "{} atoms in {} chains",
        structure.atom_count(),
        structure.chain_count()
    );

    for diagnostic in diagnostics {
        eprintln!("{diagnostic}");
    }

    Ok(())
}

A first Rust program usually wants four things: a selection, a surface area, the contacts, and a bound on memory. Everything below comes from use molframe::prelude::*; SASA needs the surface and chemistry features (or full) and contacts need analysis.

use molframe::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let structure = molframe::read("1ubq.cif")?;

    // Iterate atoms directly; `Atoms` is a collection, not an index range.
    let carbons = structure
        .atoms()
        .into_iter()
        .filter(|atom| atom.element() == Some(Element::C))
        .count();

    // Select by query and gather the coordinates of model 0.
    let alpha = structure.select("name CA", &AnalysisPolicy::default())?;
    let alpha_positions = alpha.to_coordinates(ModelIndex::new(0));

    // Per-atom and per-residue SASA (1.4 A probe, 960 points) with the radius
    // table the profile's `vdw-radii` line names; see `data/README.md`.
    // An atom whose element has no radius gets NaN and does not occlude.
    let store = molframe::chemistry::TableStore::global();
    let atom_areas = structure.sasa(&store)?;
    let residue_areas = structure.residue_sasa(&store)?;

    // Every contact within 4.5 A, under an explicit memory ceiling.
    let context = ExecutionContext::builder()
        .memory_budget(MemoryBudget::new(512 << 20)?)
        .build()?;
    let contacts = structure.atom_contacts_with(4.5, SpatialBackend::Auto, &context)?;

    println!(
        "{carbons} C, {} CA, {} atom areas, {} residue areas, {} contacts",
        alpha_positions.len(),
        atom_areas.len(),
        residue_areas.len(),
        contacts.len()
    );
    Ok(())
}

A multi-model file whose models share one atom set is a dense ensemble: structure.ensemble_coordinates(None)? returns every model as one (models, atoms, 3) block (block.as_flat(), block.model(i)), and Python's structure.model_coordinates() returns the same as a float32 array. A file whose models differ is a ragged ensemble with no shared atom axis; every structure-level call refuses it with an error naming ragged_models, and the way forward is structure.ragged_models(), one independent structure per model.

read_with_diagnostics preserves problems and ambiguities encountered while loading a structure instead of reducing parsing to a success/failure decision.

molframe read parses a path, bytes, or reader; it does not turn an identifier into a guessed network URL. Use the CLI verified acquisition boundary when retrieving an external resource:

molframe fetch 1HHO --url-template 'https://example.org/structures/{id}.cif' --sha256 <64-hex-digest> --max-bytes 50000000 --timeout-seconds 30 --redirect-limit 0 --output 1HHO.cif

The URL must contain {id}. The fetch command enforces the byte limit, timeout, redirect policy, and SHA-256 digest before atomically creating the destination; existing files are not replaced. A digest proves that the bytes match the expected value, not who published them, so retain the HTTPS origin and provider/version metadata. CCD downloads use molframe ccd update with the same verification controls and require --replace for replacement. The Python API intentionally keeps acquisition separate from parsing.

Workflow and data-movement contract

Workflow builds an immutable typed DAG with named inputs and outputs. Compile once, then reuse the CompiledWorkflow; compilation validates types and cycles, removes dead and common nodes, fixes deterministic execution order, plans value lifetimes, and estimates peak retained memory. Kernels keep their bounded internal parallelism while graph nodes run in stable topological order.

Logical and physical explanations label movement explicitly: Borrow aliases a live input, Adopt retains an owner without copying its payload, Decode converts encoded data, Copy duplicates native storage, and Materialize computes or gathers a new representation. Python follows the same rule: compatible contiguous arrays are borrowed for eager calls, non-contiguous arrays are rejected with an instruction to use numpy.ascontiguousarray, and values retained by a compiled workflow require the explicit copy=True choice.

Potentially large interaction results are native structure-of-arrays tables. Their columns are borrowed directly in Rust, reducer blocks append column by column, and Python arrays retain native owners. A Selection is structure-bound and zero-copy; Selection.to_coordinates() is the explicit gather operation.

One model from file to result

flowchart LR
    Input["PDB · mmCIF · BinaryCIF · ModelCIF · PQR · PDBQT"]

    Input --> Structure["MolFrame Structure"]

    Structure --> Query["Selection & Query"]
    Structure --> Geometry["Geometry & Spatial"]
    Structure --> Chemistry["Chemistry"]
    Structure --> Trajectory["Trajectories"]

    Query --> Analysis["Analysis"]
    Geometry --> Analysis
    Chemistry --> Analysis
    Trajectory --> Analysis

    Analysis --> Validation["Validation"]
    Analysis --> Compare["Structural Comparison"]
    Analysis --> Surface["Surfaces & Contacts"]
    Analysis --> ML["Scientific / ML Export"]

    Structure --> NumPy["NumPy"]
    Structure --> Arrow["Apache Arrow"]

All of these operations share the same underlying structural representation.

Formats are inputs and outputs. The model between them is the core of MolFrame.

Capabilities

Area Capabilities
Structure I/O PDBx/mmCIF, BinaryCIF, ModelCIF, legacy PDB, PQR, PDBQT
Structural model Atoms, residues, chains, models, identifiers, alternate conformations, assemblies
Query Structural selections and reusable queries
Geometry Distances, angles, transforms, alignment, internal coordinates
Spatial analysis Neighbor search, contacts, spatial indexing
Chemistry Element- and residue-aware structural chemistry
Crystallography Symmetry and biological assembly operations
Surfaces Molecular and solvent-related surface analysis
Validation Structural diagnostics and consistency checks
Comparison Alignment, RMSD, structural comparison
Trajectories Frame-oriented molecular trajectory analysis
Machine learning Structured scientific and ML-oriented export
Interoperability NumPy, Apache Arrow, native Rust
Interfaces Rust, Python, command line

Structural semantics

A molecular structure contains information that is easy to erase accidentally.

Consider an atom belonging to a residue with:

  • an author-assigned residue number;
  • a separate canonical identifier;
  • an insertion code;
  • multiple alternate conformations;
  • partial occupancy;
  • coordinates from one model;
  • biological assembly context.

Reducing that structure prematurely to:

x, y, z, element

can preserve its geometry while losing the information required to interpret it correctly.

MolFrame keeps structural context alongside coordinates:

Structure
├── coordinates
├── model
├── chain
├── residue
├── atom
├── altloc
├── occupancy
├── identifiers
├── assembly context
└── provenance

Selections and analyses therefore operate on a representation that still understands what the coordinates mean.

Explicit scientific results

Many structural analyses depend on choices that are often implicit:

  • Which model should be analyzed?
  • Which biological assembly?
  • Which alternate conformer?
  • Which identifier namespace?
  • What should happen when atoms are missing?
  • How much of the requested structure was actually analyzable?

MolFrame's analysis architecture is designed to make such decisions inspectable.

An enriched analysis result can conceptually carry:

Analysis<T>
├── value
├── coverage
├── ambiguity
├── diagnostics
└── provenance

This allows the value and the conditions under which it was produced to travel together.

In Python this is molframe.Analysis, returned by the governed analyses, and the decisions are an AnalysisPolicy you pass in:

import molframe

structure = molframe.read("1abc.pdb")
policy = molframe.AnalysisPolicy(altloc="highest_occupancy_per_residue", identifiers="label")

result = molframe.analysis.contacts(structure, 4.5, policy=policy)
result.status        # "complete" | "partial" | "ambiguous" | "indeterminate"
result.coverage      # used / intended atoms, missing, ambiguous
result.assumptions   # decisions made on your behalf
result.provenance    # deterministic JSON: version, policy, parameters
result.value         # the ContactTable

structure.select("chain B", policy=policy)  # the same policy decides what "chain" means

contacts, hydrogen_bonds, salt_bridges, validation.clashes and trajectory.rmsd return an Analysis; the hydrogen-bond and salt-bridge analyses need charges and roles from a Chemical Component Dictionary, supplied with molframe.chemistry.annotate(structure, "components.cif"), and say so when they are missing.

An analysis may also be indeterminate when the available structure does not support a scientifically defensible result.

Producing no answer is preferable to silently producing a misleading one.

Columnar by construction

MolFrame stores molecular information in a column-oriented representation rather than building the primary data model from individually allocated atom and residue objects.

This supports:

  • contiguous coordinate storage;
  • efficient scans and selections;
  • compact identifiers;
  • chunk-level statistics;
  • parallel kernels;
  • SIMD-friendly numeric operations;
  • direct NumPy views;
  • Arrow interoperability;
  • efficient serialization and transfer.

Hierarchical access remains available as a view over the same structure:

for chain in structure.chains:
    for residue in chain.residues:
        print(chain.label, residue.name)

The hierarchy is an interface over the molecular data, not a second independent copy of it.

File formats

PDBx/mmCIF

mmCIF is treated as a first-class structural format rather than immediately reduced to a legacy PDB-shaped schema.

MolFrame's CIF infrastructure is designed to preserve categories beyond the core atomic structure, including extension data that should survive round trips.

BinaryCIF

BinaryCIF provides compact binary encoding for PDBx data and maps into the same structural representation.

Legacy PDB

Legacy fixed-column PDB remains widely used and is supported directly.

Writers treat format limits explicitly. Data that cannot be safely represented should produce an error rather than silently truncating scientifically meaningful fields.

ModelCIF, PQR, and PDBQT

Specialized structure formats enter the same model so downstream algorithms do not require separate representations for each source.

Zero-copy Python interoperability

The Python API is a native interface to the Rust engine rather than a reimplementation of its computational kernels.

structure = molframe.read("1ubq.cif")

xyz = structure.coordinates

Coordinate buffers can be exposed directly to NumPy-compatible code.

Columnar annotations can be represented through Apache Arrow, enabling efficient exchange with scientific and analytical Python tools without reconstructing a hierarchy of Python objects.

MolFrame is designed to integrate with the Python scientific ecosystem rather than replace it.

Query and selection

A query is a short sentence that picks atoms: resname HEM, protein and chain A, byres (within 5 of resname HEM) and protein. The complete language, with every keyword, column and operator, is in the query language reference.

import molframe

structure = molframe.read("4hhb.cif")

heme = structure.select("resname HEM")         # 172 atoms
len(heme), heme.indices, heme.to_coordinates()

pocket = molframe.Query("byres (within 5 of resname HEM) and protein")
structure.select(pocket)                       # compile once, run many times
use molframe::{AnalysisPolicy, Query, QueryStructure};

let query = Query::compile("byres (within 5 of resname HEM) and protein")?;
let evaluation = structure.select_query(&query, &AnalysisPolicy::default())?;
You want Write
A kind of molecule protein, nucleic, water, ligand, polymer
Residues, chains, atoms resname HIS HEM, chain A B, name CA, element Fe
Residue numbers resid 87, resid 1:10
Wildcards name C*, resname H?S
A numeric condition bfactor > 50, occupancy < 1
Logic protein and not chain A, (chain A or chain C) and resid 1:5
Distance within 5 of resname HEM, around 5 resname HEM
Whole residues byres (within 5 of resname HEM)

A query that cannot run raises molframe.QueryError, which quotes the query, underlines the problem and says what to do. A query that runs but probably does not mean what it says (such as and and or mixed without parentheses) warns with molframe.QueryWarning.

Named queries

$name refers to another query, defined with QueryAliases. Resolving substitutes every name, so what runs is an ordinary query:

aliases = molframe.QueryAliases()
aliases.define("heme", molframe.Query("resname HEM"))
aliases.define("pocket", molframe.Query("byres (within 5 of $heme) and protein"))
structure.select(aliases.resolve(molframe.Query("$pocket")))

Definitions are live: redefining heme changes what $pocket resolves to. Text and the typed builder (molframe.sel.protein() & molframe.sel.chain("A")) compile to the same plan, whose fingerprint is its identity.

Geometry and spatial analysis

MolFrame provides reusable kernels for common structural operations including:

  • distances;
  • angles and dihedrals;
  • coordinate transforms;
  • centroids and extents;
  • radius of gyration;
  • structural alignment;
  • internal coordinates;
  • spatial indexing;
  • neighbor queries;
  • contact analysis.

Numeric kernels operate directly over the underlying coordinate representation whenever possible.

Structural comparison

Comparison workflows use the same molecular identifiers and structure model as ordinary analysis.

This supports operations such as:

mapping
alignment
superposition
RMSD
local comparison
sequence-aware correspondence

without first converting structures into an unrelated comparison-specific representation.

Validation

Parsing answers:

Can this file be interpreted?

Validation asks:

Does the interpreted structure make sense?

MolFrame separates these concerns.

Validation can report structural inconsistencies, suspicious geometry, incomplete data, representation problems, and other findings without conflating them with parser failure.

Diagnostics remain machine-readable so applications can decide how to handle them.

Trajectories

Trajectory support extends the structural model across coordinate frames without redefining molecular identity at every timestep.

This enables analyses over:

frame sequences
coordinate evolution
time-dependent measurements
structural comparison
aggregated trajectory statistics

while keeping topology and coordinate data appropriately separated.

Command line

Common operations are also available from the command line:

molframe info 1ubq.cif

molframe convert input.pdb output.cif

molframe validate structure.cif

molframe measure structure.cif

molframe rmsd model-a.cif model-b.cif

The CLI uses the same parsing and computational engine as the library APIs.

Performance

Performance claims should be reproducible.

MolFrame includes benchmark infrastructure for:

  • parsing;
  • structural access;
  • selections;
  • geometry;
  • spatial operations;
  • analysis;
  • serialization;
  • Python-boundary operations.

The architecture emphasizes properties that scale well:

contiguous data
low allocation pressure
parallel execution
SIMD-friendly kernels
zero-copy boundaries
memory mapping where appropriate
feature-gated dependencies

Specific benchmark numbers belong with their dataset, hardware, software revision, and methodology rather than as context-free claims in this README.

Benchmark sources live beside the subsystem they measure in each crate's benches/ directory; deterministic allocation and resident-memory cases live in crates/molframe-resource-bench.

Reciprocal crystallography

With the Rust crystal feature, CellTransform exposes reciprocal vectors (inverse ångström, without a 2π factor), reciprocal_spacing_squared and d_spacing. The origin has zero reciprocal length and infinite spacing. SymmetrySet::reflection_symmetry reports centricity, systematic absences and epsilon including centring, using exact rational translation phases. Missing operations and unrepresentable transformed indices are errors.

Python exposes the same calculations through molframe.crystal:

from molframe.crystal import UnitCell, SpaceGroup

cell = UnitCell([43.1, 51.7, 62.3], [73, 81, 67])
spacing = cell.d_spacing([2, -3, 5])
group = SpaceGroup(hall_number=6)  # Hall catalogue setting, not IT group number
constraints = group.reflection_symmetry([0, 1, 0])

ReflectionTable::miller_indices() now returns a borrowed exact-size iterator of row results, not an allocated vector. Shape errors are returned before iteration; missing/non-integral indices are errors at the corresponding row. Collect explicitly when owned indices are required. MTZ resolution calculation uses this iterator and the same reciprocal geometry.

Differential verification against local Gemmi 97c808222f468f8188f2ed87266e0d7c5a854ce2 matched all 530 Hall settings over indices [-4, 4]³ (386,370 reflections), plus 2,187 spacings in orthorhombic, triclinic and hexagonal cells. This covers these operations only, not general Gemmi feature parity or a speed comparison.

Structure factors

With the crystal feature, GaussianFormFactor::xray(element) gives the International Tables (Cromer–Mann) form factor for hydrogen to californium, and StructureFactorCalculator sums atoms over the complete space group with occupancy and isotropic or anisotropic displacement. A structure supplies all of that itself, including the space group a legacy PDB CRYST1 record names:

import numpy, molframe

structure = molframe.read("1orc.pdb")
hkl = numpy.array([[1, 2, 3], [0, 4, 0]], dtype=numpy.int32)
f = molframe.crystal.structure_factors(structure, hkl)   # complex128, one per row

Verified against Gemmi 0.7.5 on P 21 21 21, P 1 21 1 (anisotropic) and I 2 2 2: agreement to about 1e-5 relative, limited by Gemmi's single-precision coefficients. Anomalous dispersion, neutron and electron tables, and ions are not yet covered.

Resolution shells and normalized amplitudes follow Gemmi's Binner and calculate_amplitude_normalizers. The shells come in four spacings (equal_count, dstar, dstar2, dstar3); a normalizer is 1/(sqrt(epsilon) * rms) per reflection, where rms is the shell mean of F**2 / epsilon smoothed over neighbouring shells and interpolated in 1/d**2, so E = F * multiplier:

cell = molframe.crystal.UnitCell([31.5, 40.2, 52.7], [80.0, 101.3, 95.0])
group = molframe.crystal.SpaceGroup(1)                      # Hall number 1, P 1
bins = molframe.crystal.ResolutionBins(cell, hkl, bins=12, method="dstar3")
e = amplitudes * molframe.crystal.normalizers(cell, group, hkl, amplitudes, bins)

Dstar-spaced shells and the multipliers agree with Gemmi 0.7.5 to about 1e-15 relative in P 1 21 1, P 21 21 21, C 1 2 1 and P 1. Equal-count shells have the same limits, but a reflection whose 1/d**2 lies within an ulp of a limit can fall in the neighbouring shell, which moves other multipliers by about 1e-3.

crystal.reduce_cell brings a primitive cell to its Niggli setting (shortest edges, all angles acute or all obtuse) with Gruber normalization and the Krivy–Gruber steps, and returns the reduced cell with the change of basis that reaches it:

reduced = molframe.crystal.reduce_cell([8.9, 12.1, 57.2], [99.8, 79.5, 90.9])
reduced.lengths, reduced.angles, reduced.change_of_basis

On 400 random triclinic cells the reduced parameters agree with Gemmi 0.7.5 to 1e-14 relative and every change of basis is identical. Only primitive cells are reduced; a centred cell must be converted to its primitive setting first.

Rust features

The Rust facade is modular.

Applications can enable only the domains they require.

Feature areas include:

mmcif
bcif
modelcif
pdb

geometry
query
spatial
chemistry
embedded-tables
crystal

surface
analysis
validation
compare
trajectory
sequence
interop
audit
motif

The default configuration enables mmCIF and PDB only. Applications opt into analysis domains individually, and full is available for complete builds.

Project status

MolFrame is under active development and has not reached 1.0.

The project distinguishes three different properties:

Implemented
The capability exists.

Validated
The behavior has the appropriate deterministic, golden, differential, or scientific evidence.

Stable
The public contract is expected to remain backwards compatible.

A feature being implemented does not automatically imply that it has reached the other two stages.

Pre-1.0 releases may contain breaking API changes while these contracts are finalized.

Development

Build the complete Rust workspace:

cargo build --workspace

Run the test suite:

cargo test --workspace

The repository also contains project-specific verification tooling for formatting, linting, packaging, bindings, scientific fixtures, and reproducibility checks.

See CONTRIBUTING.md for the development workflow.

Citation

If MolFrame contributes to published research, please cite the software.

Machine-readable citation metadata is provided in CITATION.cff.

License

MolFrame is released under the MIT License.

The bundled reference data keeps the licence of its upstream source, carried beside the data it covers: mendeleev's MIT notice in crates/molframe-chem/data/LICENSE.mendeleev, and spglib's BSD-3-Clause notice in crates/molframe-xtal/data/LICENSE.spglib.

Metadata

Release files for molframe 0.6.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for molframe 0.6.3
File Size Uploaded
molframe-0.6.3.tar.gz 5.7 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for molframe 0.6.3
File
molframe-0.6.3-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
molframe-0.6.3-cp312-abi3-manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.28+ x86-64 Details
molframe-0.6.3-cp312-abi3-manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64 Details
molframe-0.6.3-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
molframe-0.6.3-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 64.4 MB

Release files / molframe-0.6.3.tar.gz

Download URL molframe-0.6.3.tar.gz
Size 5.7 MB
Tags Source
SHA-256 checksum
How to use checksums
ff5b2cc0a620c1cf5c6224878709ee9881f361230c5589b3e53ce69714e59e99
BLAKE2b-256 checksum
How to use checksums
0f96fa75f2e83f95ff3fd537f6c03bc2aa44947a24880f66af76406341bf624c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / molframe-0.6.3-cp312-abi3-win_amd64.whl

Download URL molframe-0.6.3-cp312-abi3-win_amd64.whl
Size 11.8 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
1efd4d62967454b9a225d13af0cb60859216e200d86c255cc72838234450d872
BLAKE2b-256 checksum
How to use checksums
dd7929cd9575cea49d8e2d94ad56aca19d375de88e0ee0bbd861ff4651e860bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / molframe-0.6.3-cp312-abi3-manylinux_2_28_x86_64.whl

Download URL molframe-0.6.3-cp312-abi3-manylinux_2_28_x86_64.whl
Size 12.5 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
ae14a9d43adda5109002c2fc7fa6f976542670be376da4faadcc7b93688c2ea8
BLAKE2b-256 checksum
How to use checksums
9e00d16dc520c4f3bb0493c3530841c2130fcc45c7dd0fca8d1cf6e4202c3e41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / molframe-0.6.3-cp312-abi3-manylinux_2_28_aarch64.whl

Download URL molframe-0.6.3-cp312-abi3-manylinux_2_28_aarch64.whl
Size 11.6 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
e90cb0ffc8e16b47b44dad31aaea4ca97df74d5373dae176e046dc3e8760488e
BLAKE2b-256 checksum
How to use checksums
85ac8e08226e55f1655b656d8521d1be9ef227e4874e4f04631115d236d5258b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / molframe-0.6.3-cp312-abi3-macosx_11_0_arm64.whl

Download URL molframe-0.6.3-cp312-abi3-macosx_11_0_arm64.whl
Size 10.8 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8b0776ae8ea34d8224010cf93cd11890196bde8891bc8df732b05ee2ed17df4b
BLAKE2b-256 checksum
How to use checksums
841f39bc8e151c4f0593b193048a0d133b2478e2e2df559c995b5b04cc897d19
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / molframe-0.6.3-cp312-abi3-macosx_10_12_x86_64.whl

Download URL molframe-0.6.3-cp312-abi3-macosx_10_12_x86_64.whl
Size 11.9 MB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
1c3a99184d4c4fd4643e446fb1f422154174ae371a58a6764e89da4a85d31afd
BLAKE2b-256 checksum
How to use checksums
b4157b4993891c4d440f41445abff944daa523bb806a0bba82a455bb3fc4163b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.4

6 release files

This release

0.6.3 This release

6 release files

0.6.2

6 release files

0.6.1

6 release files

0.6.0

6 release files

0.5.2

6 release files

0.5.1

6 release files

0.5.0

6 release files

0.4.0

6 release files

0.3.1

6 release files

0.3.0

6 release files

0.2.1

6 release files

0.2.0

6 release files

0.1.2

6 release files

0.1.1

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page