Skip to main content

Fast Generalized Linear Models with a Rust backend - statsmodels compatible

Project description

RustyStats 🦀📊

CI PyPI Rust License: AGPL-3.0

High-performance Generalized Linear Models with a Rust backend and Python API

Codebase Documentation: pricingfrontier.github.io/rustystats/

Features

  • Dict-First API - Programmatic model building ideal for automated workflows and agents
  • Fast - Parallel Rust backend for high-throughput fitting
  • Memory Efficient - Low memory footprint at scale
  • Stable - Step-halving IRLS, warm starts for robust convergence
  • Splines - B-splines and natural splines with auto-tuned smoothing and monotonicity
  • Target Encoding - Ordered target encoding for high-cardinality categoricals
  • Regularisation - Ridge, Lasso, and Elastic Net via coordinate descent
  • Lasso Credibility - Shrink toward a prior model instead of zero (CAS Monograph 13)
  • Validation - Design matrix checks with fix suggestions before fitting
  • Complete - 8 families, robust SEs, full diagnostics, VIF, partial dependence
  • Minimal - Only numpy and polars required

Installation

uv add rustystats

Quick Start

import rustystats as rs
import polars as pl

# Load data
data = pl.read_parquet("insurance.parquet")

# Fit a Poisson GLM for claim frequency
result = rs.glm_dict(
    response="ClaimCount",
    terms={
        "VehAge": {"type": "linear"},
        "VehPower": {"type": "linear"},
        "Area": {"type": "categorical"},
        "Region": {"type": "categorical"},
    },
    data=data,
    family="poisson",
    exposure="Exposure",
).fit()

# View results
print(result.summary())

Families & Links

Family Default Link Use Case
gaussian identity Linear regression
poisson log Claim frequency
binomial logit Binary outcomes
gamma log Claim severity
tweedie log Pure premium (var_power=1.5)
quasipoisson log Overdispersed counts
quasibinomial logit Overdispersed binary
negbinomial log Overdispersed counts (requires theta= or theta="estimate")

Dict-Based API

API built for programmatic model building.

result = rs.glm_dict(
    response="ClaimCount",
    terms={
        "VehAge": {"type": "bs", "monotonicity": "increasing"},  # Monotonic (auto-tuned)
        "DrivAge": {"type": "bs"},                               # Penalized smooth (default)
        "Income": {"type": "bs", "df": 5},                       # Fixed 5 df
        "BonusMalus": {"type": "linear", "monotonicity": "increasing"},  # Constrained coefficient
        "Region": {"type": "categorical"},
        "Brand": {"type": "target_encoding"},
        "Age2": {"type": "expression", "expr": "DrivAge**2"},
    },
    interactions=[
        {
            "VehAge": {"type": "linear"}, 
            "Region": {"type": "categorical"}, 
            "include_main": True
        },
    ],
    data=data,
    family="poisson",
    exposure="Exposure",
    seed=42,
).fit(regularization="elastic_net")

Multinomial Choice

Use multinomial_dict for mutually exclusive class outcomes such as insurance product-tier conversion.

result = rs.multinomial_dict(
    response="PurchasedTier",
    terms={
        "DriverAge": {"type": "bs"},
        "VehicleValue": {"type": "linear"},
        "Channel": {"type": "categorical"},
    },
    alternative_terms={
        "price": {
            "columns": {
                "basic": "price_basic",
                "standard": "price_standard",
                "premium": "price_premium",
            },
            "coefficient": "generic",
            "transform": "log",
        }
    },
    data=quotes,
    classes=["none", "basic", "standard", "premium"],
    reference="none",
).fit()

probs = result.predict_proba(new_quotes)
mix = result.tier_mix(new_quotes)
scenario = result.scenario(new_quotes, changes={"price_premium": 1.03})

The multinomial path supports shared covariates, row/class weights, availability masks, class-specific utility offsets, ridge/lasso/elastic-net regularization with CV, multinomial target encoding, automatic smooth penalties for shared bs/ns main effects, summaries, pricing-grade diagnostics, wide-format alternative-specific covariates, price-change scenarios, vector-intercept calibration, utility-level monotonicity for shared linear/expression/fixed-df bs terms, Level-1 PMML/ONNX export for shared design-matrix scoring, and pickle serialization. Smooth monotone splines, target-encoded or alternative-specific monotonicity, exposure, symmetric reference-invariant ridge, and richer PMML/ONNX export for target-encoded, alternative-specific, availability, or offset models are reserved for later native support and fail explicitly where applicable.

See examples/tier_conversion_multinomial.py for a complete train/holdout workflow with availability, held-out log loss, alternative-specific price and richness terms, vector-intercept calibration, and premium price scenarios.

Term Types

Type Parameters Description
linear monotonicity (optional) Raw continuous variable
categorical levels (optional) Dummy encoding
bs df or k, knots, boundary_knots, degree=3, monotonicity B-spline (default: penalized smooth, k=10)
ns df or k, knots, boundary_knots Natural spline (default: penalized smooth, k=10)
target_encoding prior_weight=1 Regularized target encoding
expression expr, monotonicity (optional) Arbitrary expression (like I())

Interactions

Each interaction is a dict with variable specs. Use include_main to also add main effects.

interactions=[
    # Standard interaction: product terms (main effects + interaction)
    {
        "DrivAge": {"type": "bs", "df": 5}, 
        "Brand": {"type": "target_encoding"},
        "include_main": True
    },
    # Categorical × continuous (interaction only)
    {
        "VehAge": {"type": "linear"}, 
        "Region": {"type": "categorical"}, 
        "include_main": False
    },
    # TE interaction: combined target encoding TE(Brand:Region)
    {
        "Brand": {"type": "categorical"},
        "Region": {"type": "categorical"},
        "target_encoding": True,
        "prior_weight": 1.0,  # optional
    },
    # FE interaction: combined frequency encoding FE(Brand:Region)
    {
        "Brand": {"type": "categorical"},
        "Region": {"type": "categorical"},
        "frequency_encoding": True,
    },
]
Flag Effect
(none) Standard product terms (cat×cat, cat×cont, etc.)
target_encoding: True Combined TE encoding: TE(var1:var2)
frequency_encoding: True Combined FE encoding: FE(var1:var2)

Splines

# Default: penalized smooth with automatic tuning via GCV
result = rs.glm_dict(
    response="ClaimNb",
    terms={
        "Age": {"type": "bs"},           # B-spline (auto-tuned)
        "VehPower": {"type": "ns"},      # Natural spline (auto-tuned)
        "Region": {"type": "categorical"},
    },
    data=data, family="poisson", exposure="Exposure",
).fit()

# Fixed degrees of freedom (no penalty)
result = rs.glm_dict(
    response="ClaimNb",
    terms={
        "Age": {"type": "bs", "df": 5},       # Fixed 5 df
        "VehPower": {"type": "ns", "df": 4},  # Fixed 4 df
        "Region": {"type": "categorical"},
    },
    data=data, family="poisson", exposure="Exposure",
).fit()

Spline parameters:

  • No parameters → penalized smooth with automatic tuning (k=10)
  • df=5 → fixed 5 degrees of freedom
  • k=15 → penalized smooth with 15 basis functions
  • knots=[2.0, 5.0, 8.0] → explicit interior knot positions (mutually exclusive with df/k)
  • boundary_knots=(0.0, 10.0) → custom boundary knots (optional, defaults to data range)
  • monotonicity="increasing" or "decreasing" → constrained effect (bs only)

When to use each type:

  • B-splines (bs): Standard choice, more flexible at boundaries, supports monotonicity
  • Natural splines (ns): Better extrapolation, linear beyond boundaries

Monotonic Splines

Constrain the fitted curve to be monotonically increasing or decreasing. Essential when business logic dictates a monotonic relationship.

# Monotonically increasing effect (e.g., age → risk)
result = rs.glm_dict(
    response="ClaimNb",
    terms={
        "Age": {"type": "bs", "monotonicity": "increasing"},
        "Region": {"type": "categorical"},
    },
    data=data, family="poisson", exposure="Exposure",
).fit()

# Monotonically decreasing effect (e.g., vehicle value with age)
result = rs.glm_dict(
    response="ClaimAmt",
    terms={"VehAge": {"type": "bs", "df": 4, "monotonicity": "decreasing"}},
    data=data, family="gamma",
).fit()

Coefficient Constraints

Constrain coefficient signs using monotonicity on linear and expression terms.

result = rs.glm_dict(
    response="y",
    terms={
        "age": {"type": "linear", "monotonicity": "increasing"},  # β ≥ 0
        "age2": {"type": "expression", "expr": "age ** 2", "monotonicity": "decreasing"},  # β ≤ 0
        "income": {"type": "linear"},
    },
    data=data, family="poisson",
).fit()
Constraint Term Spec Effect
β ≥ 0 "monotonicity": "increasing" Positive effect
β ≤ 0 "monotonicity": "decreasing" Negative effect

Target Encoding

Ordered target encoding for high-cardinality categoricals.

# Dict API
result = rs.glm_dict(
    response="ClaimNb",
    terms={
        "Brand": {"type": "target_encoding"},
        "Model": {"type": "target_encoding", "prior_weight": 2.0},
        "Age": {"type": "linear"},
        "Region": {"type": "categorical"},
    },
    data=data, family="poisson", exposure="Exposure",
).fit()

# Sklearn-style API
encoder = rs.TargetEncoder(prior_weight=1.0, n_permutations=4)
train_encoded = encoder.fit_transform(train_categories, train_target)
test_encoded = encoder.transform(test_categories)

Key benefits:

  • No target leakage: Ordered target statistics
  • Regularization: Prior weight controls shrinkage toward global mean
  • High-cardinality: Single column instead of thousands of dummies
  • Exposure-aware: For frequency models with exposure="Exposure", automatically uses claim rate (ClaimCount/Exposure) instead of raw counts. Pre-RS-ACT-002 users with offset="Exposure" get the same behaviour via the legacy alias, but array offset= no longer feeds the encoder — pass exposure= explicitly for exposure-weighted target encoding.
  • Interactions: Use target_encoding: True in interactions to encode variable combinations

Expression Terms

result = rs.glm_dict(
    response="y",
    terms={
        "age": {"type": "linear"},
        "age2": {"type": "expression", "expr": "age ** 2"},
        "age3": {"type": "expression", "expr": "age ** 3"},
        "income_k": {"type": "expression", "expr": "income / 1000"},
        "bmi": {"type": "expression", "expr": "weight / (height ** 2)"},
    },
    data=data, family="gaussian",
).fit()

Supported operations: +, -, *, /, ** (power)


Regularization

CV-Based Regularization

# Just specify regularization type - cv=5 is automatic
result = rs.glm_dict(
    response="y",
    terms={"x1": {"type": "linear"}, "x2": {"type": "linear"}, "cat": {"type": "categorical"}},
    data=data,
    family="poisson",
).fit(regularization="ridge")  # "ridge", "lasso", or "elastic_net"

print(f"Selected alpha: {result.alpha}")
print(f"CV deviance: {result.cv_deviance}")

Options:

  • regularization: "ridge" (L2), "lasso" (L1), or "elastic_net" (mix)
  • selection: "min" (best fit) or "1se" (more conservative, default: "min")
  • cv: Number of folds (default: 5)
  • standardize: Internally standardize penalized columns before the penalty acts, reporting original-scale coefficients (default: True; set False for the legacy raw-scale penalty)

Explicit Alpha

# Skip CV, use specific alpha
result = rs.glm_dict(response="y", terms={"x1": {"type": "linear"}, "x2": {"type": "linear"}}, data=data).fit(alpha=0.1, l1_ratio=0.0)  # Ridge
result = rs.glm_dict(response="y", terms={"x1": {"type": "linear"}, "x2": {"type": "linear"}}, data=data).fit(alpha=0.1, l1_ratio=1.0)  # Lasso
result = rs.glm_dict(response="y", terms={"x1": {"type": "linear"}, "x2": {"type": "linear"}}, data=data).fit(alpha=0.1, l1_ratio=0.5)  # Elastic Net

Lasso Credibility

Shrink model coefficients toward a prior model (complement of credibility) instead of toward zero. Based on the methodology in CAS Monograph 13 (Holmes & Casotto, 2025).

When lasso zeroes a coefficient, the prediction for that term falls back to the complement rather than vanishing — making regularized models directly usable as rating plans.

# 1. Fit a countrywide (prior) model
cw_result = rs.glm_dict(
    response="ClaimCount",
    terms={"VehAge": {"type": "bs"}, "DrivAge": {"type": "bs"}},
    data=countrywide_data,
    family="poisson",
    exposure="Exposure",
).fit()

# 2. Fit a state model with lasso, shrinking toward countrywide rates
state_result = rs.glm_dict(
    response="ClaimCount",
    terms={
        "VehAge": {"type": "bs"},
        "DrivAge": {"type": "bs"},
        "Region": {"type": "categorical"},
    },
    data=state_data,
    family="poisson",
    exposure="Exposure",
    complement="countrywide_rate",  # Column with prior rates (response scale)
).fit(regularization="lasso")

# 3. Inspect which terms the data supports vs. trusts the complement
print(state_result.summary())            # Shows "Lasso Credibility Results"
print(state_result.credibility_summary())  # Deviation from complement per term

Complement sources:

  • str — column name in the DataFrame (rates for log-link, probabilities for logit)
  • np.ndarray — array of prior values on the response scale
  • GLMModel — fitted model; predictions are computed automatically

Works with all families/links, splines, categoricals, interactions, and target encoding.


Design Matrix Validation

# Check for issues before fitting
model = rs.glm_dict(
    response="y",
    terms={"x": {"type": "ns", "df": 4}, "cat": {"type": "categorical"}},
    data=data, family="poisson",
)
results = model.validate()  # Prints diagnostics

if not results['valid']:
    print("Issues:", results['suggestions'])

# Validation runs automatically on fit failure with helpful suggestions

Checks performed:

  • Rank deficiency (linearly dependent columns)
  • High multicollinearity (condition number)
  • Zero variance columns
  • NaN/Inf values
  • Highly correlated column pairs (>0.999)

Model Diagnostics

# Compute all diagnostics at once
diagnostics = result.diagnostics(
    train_data=data,
    categorical_factors=["Region", "VehBrand", "Area"],  # Including non-fitted
    continuous_factors=["Age", "Income", "VehPower"],    # Including non-fitted
)

# Export as compact JSON (optimized for LLM consumption)
json_str = diagnostics.to_json()

# Pre-fit data exploration (no model needed)
exploration = rs.explore_data(
    data=data,
    response="ClaimNb",
    categorical_factors=["Region", "VehBrand", "Area"],
    continuous_factors=["Age", "VehPower", "Income"],
    exposure="Exposure",
    family="poisson",
    detect_interactions=True,
)

Diagnostic Features:

  • Calibration: Overall A/E ratio, calibration by decile with CIs, Hosmer-Lemeshow test
  • Discrimination: Gini coefficient, AUC, KS statistic, lift metrics
  • Factor Diagnostics: A/E by level/bin for ALL factors (fitted and non-fitted)
  • VIF/Multicollinearity: Variance inflation factors for design matrix columns
  • Partial Dependence: Effect plots with shape detection and recommendations
  • Overfitting Detection: Compare train vs test metrics when test data provided
  • Interaction Detection: Greedy residual-based detection of potential interactions
  • Warnings: Auto-generated alerts for high dispersion, poor calibration, missing factors
  • Base Model Comparison: Compare new model against existing/benchmark predictions

Diagnostics JSON Shape

The diagnostics.to_json() output includes:

{
  "model_summary": {
    "formula": "...", "family": "poisson", "link": "log",
    "n_obs": 2000, "n_params": 6, "df_resid": 1994,
    "converged": true, "iterations": 5,
    "scale": 1.0,
    "scale_pearson": 1.0148,
    "null_deviance": 1408.77,
    "robust_se_type": "HC1"
  },
  "train_test": {
    "train": {
      "n_obs": 2000, "deviance": 2118.42,
      "log_likelihood": -1059.21,
      "aic": 2130.42, "bic": 2162.70,
      "gini": 0.3241, "auc": 0.6621, "ae_ratio": 1.0
    }
  },
  "coefficient_summary": [
    {
      "feature": "Age", "estimate": 0.00996,
      "std_error": 0.00339, "z_value": 2.941,
      "p_value": 0.0033, "significant": true,
      "conf_int": [0.003318, 0.01659],
      "relativity": 1.01, "relativity_ci": [1.0033, 1.0167],
      "robust_std_error": 0.003378, "robust_z_value": 2.947,
      "robust_p_value": 0.0032, "robust_significant": true
    }
  ]
}
  • BIC (train_test.train.bic): Bayesian Information Criterion alongside AIC
  • Scale (model_summary.scale): Deviance-based dispersion parameter
  • Scale Pearson (model_summary.scale_pearson): Pearson-based dispersion estimate
  • Null Deviance (model_summary.null_deviance): Intercept-only model deviance
  • Confidence Intervals (coefficient_summary[].conf_int): 95% CI [lower, upper]
  • Robust SEs (coefficient_summary[].robust_*): HC1 sandwich estimators for each coefficient
  • Robust SE Type (model_summary.robust_se_type): Present only when robust SEs were computed

Robust SE fields are null when store_design_matrix=False (lean mode) or for deserialized models.

Comparing Against a Base Model

Compare your new model against predictions from an existing model (e.g., current production model):

# Add base model predictions to your data
data = data.with_columns(pl.lit(old_model_predictions).alias("base_pred"))

# Run diagnostics with base_predictions
diagnostics = result.diagnostics(
    train_data=data,
    categorical_factors=["Region", "VehBrand"],
    continuous_factors=["Age", "VehPower"],
    base_predictions="base_pred",  # Column name with base model predictions
)

# Access comparison results
bc = diagnostics.base_predictions_comparison

# Side-by-side metrics
print(f"Model loss: {bc.model_metrics.loss}, Base loss: {bc.base_metrics.loss}")
print(f"Model Gini: {bc.model_metrics.gini}, Base Gini: {bc.base_metrics.gini}")

# Improvement metrics (positive = new model is better)
print(f"Loss improvement: {bc.loss_improvement_pct}%")
print(f"Gini improvement: {bc.gini_improvement}")
print(f"AUC improvement: {bc.auc_improvement}")

# Decile analysis sorted by model/base prediction ratio
for d in bc.model_vs_base_deciles:
    print(f"Decile {d.decile}: actual={d.actual:.4f}, "
          f"model={d.model_predicted:.4f}, base={d.base_predicted:.4f}")

The comparison includes:

  • Side-by-side metrics: Loss (mean deviance), Gini, AUC, A/E ratio for both models
  • Improvement metrics: loss_improvement_pct, gini_improvement, auc_improvement
  • Decile analysis: Data sorted by model/base ratio, showing where the new model diverges
  • Calibration comparison: Count of deciles where each model has better A/E

Calibration Primitives

Explicit calibration tools for assessing and adjusting model balance, kept separate from the GLM coefficients so the underlying fit stays untouched.

# Standalone summary on arrays (overall A/E, per-bin, optional per-factor)
summary = rs.calibration_summary(
    y, mu,
    exposure=exposure,
    weights=weights,         # optional; weighted Σwy/Σwμ
    by={"Region": region},   # optional per-factor breakdown
    n_bins=10,
    ranking="auto",          # rate-rank when exposure is present
    min_exposure=10.0,       # flag low-exposure cells as suppressed
)

# From a fitted GLM (response/exposure resolved automatically)
result.calibration_summary(data, by="Region")

# Multiplicative or monotone calibration objects (opt-in, serialized separately)
cal = result.fit_calibration(holdout, method="global")     # GlobalCalibration
iso = result.fit_calibration(holdout, method="isotonic")   # IsotonicCalibration
calibrated_pred = cal.predict(result.predict(new_data))

# Log-link intercept relevel — same factor c = Σ(w·y)/Σ(w·μ), updates only the
# intercept. Every other coefficient is bit-identical, relativities preserved.
releveled = result.relevel(holdout)
assert all(releveled.params[1:] == result.params[1:])

Calibration is never applied silently to result.predict(). Calibration objects are separate, serializable (to_dict/from_dict), and not folded into GLM coefficients. Fitting calibration on the same rows used to fit the model overstates calibration quality — prefer a held-out fold.


Per-Prediction Contributions

Decompose each row's prediction into per-term contributions for trace explainability:

result = rs.glm_dict(
    response="sale_flag",
    terms={"diff_to_market": {"type": "ns", "df": 10}},
    data=train,
    family="binomial",
).fit()

rows = result.predict_contributions(new_data)
print(rows[0])
# {
#   "family": "binomial", "link": "logit",
#   "output_space": "linear_predictor", "prediction_space": "response",
#   "base_value": 0.0417,
#   "sum_contributions": -1.4280,
#   "prediction_from_contributions": -1.3863,   # eta
#   "prediction_value": 0.2000,                  # mu = inverse_link(eta)
#   "contributions": [
#       {"term": "diff_to_market", "term_type": "ns",
#        "feature_value": -25.0, "contribution": -1.4280, "rank": 1}
#   ]
# }

Key properties:

  • base_value + sum(contributions) == linear predictor (validated to 1e-9 by default)
  • inverse_link(linear predictor) == predict() (also validated)
  • Spline bases, categorical dummies, target/frequency encoding columns, and interaction tensor products are grouped back to their source term; the ladder shows factor-level rows, not basis-level rows
  • Offset is an explicit row (term_type="offset", contribution = log(Exposure) for log-link)
  • For complement-of-credibility models, base_value is per-row = link(complement[row]), and the intercept appears as a contribution row representing the deviation

Options:

  • group_terms=False: expand multi-column terms into one row per design column
  • include_design_columns=True: keep grouped rows but attach a per-column breakdown
  • return_format="dataframe": long-format pl.DataFrame (faster for batch scoring)
  • validate=False, atol, rtol: control the additivity check

Model Serialization

Save and load fitted models for later use:

# Fit and save
model_bytes = result.to_bytes()

with open("model.bin", "wb") as f:
    f.write(model_bytes)

# Load later
with open("model.bin", "rb") as f:
    loaded = rs.GLMModel.from_bytes(f.read())

# Predict with loaded model
predictions = loaded.predict(new_data)

What's preserved:

  • Coefficients and feature names
  • Categorical encoding levels
  • Spline knot positions
  • Target encoding statistics
  • Formula, family, link function
  • Complement of credibility specification

Compact storage: Only prediction-essential state is stored (~KB, not MB).


Model Export (PMML & ONNX)

Export fitted models to standard formats for deployment — no extra dependencies required. PMML uses stdlib XML; ONNX protobuf serialization is implemented from scratch in Rust.

PMML

# Export to PMML 4.4 XML
pmml_xml = result.to_pmml()
result.to_pmml(path="model.pmml")

# Load & predict (consumer side)
# uv add pypmml
from pypmml import Model
pmml_model = Model.fromFile("model.pmml")

new_data = pl.DataFrame({"VehAge": [3, 5, 1], "Area": ["C", "A", "B"]})
preds = pmml_model.predict(new_data.to_dict(as_series=False))

ONNX

# Export — "scoring" requires pre-built design matrix, "full" embeds preprocessing
result.to_onnx(path="model.onnx", mode="scoring")
result.to_onnx(path="model_full.onnx", mode="full")

# Predict (consumer side)
# uv add onnxruntime
import onnxruntime as ort
session = ort.InferenceSession("model_full.onnx")
preds = session.run(None, {"input": raw_features})[0]

For MultinomialModel, PMML/ONNX export is currently Level-1 scoring only: the consumer supplies the pre-built shared design matrix without the intercept column. Multinomial mode="full", target encoding, alternative terms, availability masks, and class-specific offsets fail closed with validation errors. | Size | Smaller | Larger |


Dependencies

Rust

  • ndarray, nalgebra - Linear algebra
  • rayon - Parallel iterators (multi-threading)
  • statrs - Statistical distributions
  • pyo3 - Python bindings

Python

  • numpy - Array operations (required)
  • polars - DataFrame support (required)

License

AGPL-3.0

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

rustystats-0.8.12.tar.gz (650.4 kB view details)

Uploaded Source

Built Distributions

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

rustystats-0.8.12-cp313-cp313-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.13Windows x86-64

rustystats-0.8.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

rustystats-0.8.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

rustystats-0.8.12-cp313-cp313-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

rustystats-0.8.12-cp313-cp313-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

rustystats-0.8.12-cp312-cp312-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.12Windows x86-64

rustystats-0.8.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rustystats-0.8.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

rustystats-0.8.12-cp312-cp312-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rustystats-0.8.12-cp312-cp312-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

rustystats-0.8.12-cp311-cp311-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.11Windows x86-64

rustystats-0.8.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

rustystats-0.8.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

rustystats-0.8.12-cp311-cp311-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

rustystats-0.8.12-cp311-cp311-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

rustystats-0.8.12-cp310-cp310-win_amd64.whl (1.7 MB view details)

Uploaded CPython 3.10Windows x86-64

rustystats-0.8.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

rustystats-0.8.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

rustystats-0.8.12-cp310-cp310-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

rustystats-0.8.12-cp310-cp310-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

Details for the file rustystats-0.8.12.tar.gz.

File metadata

  • Download URL: rustystats-0.8.12.tar.gz
  • Upload date:
  • Size: 650.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustystats-0.8.12.tar.gz
Algorithm Hash digest
SHA256 f9fb9e70e93fdc2c38b90ea6508916fb9dddee317573811a5f193d2a0452e77c
MD5 067a91556b9f7c354dff5cea27dba013
BLAKE2b-256 eaad27391d690f9f3e5405cb57687c56325c073c4e644ddb8f5e83f2a9822728

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12.tar.gz:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 b25d9296bc34f8ef6348bc81842d1988a4440fd5097097aaf6c34c90d812b70c
MD5 97d9d6ccc35e7e906b23870f667fec0d
BLAKE2b-256 057699db947ea429552bfec78ee635870f3404bea6c5c68048bfb8355807b11c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp313-cp313-win_amd64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0ac6334962d43a6be2807e8d677a00ef98ed1848e44b2032b75249bffb20f4c2
MD5 c7b0f982b3ef291f1b9614cc3adf2b69
BLAKE2b-256 c47a7aea1f710aaec36890ecacd98fab1cab0b8ed6580905946b7476fa856265

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 70a9355bd9939bddf7d2c104bc2273dee158feb89850fde4542a16a585200158
MD5 549cea38ee36486e6a1327dcfb521efc
BLAKE2b-256 241570d21181a3035651a11f10a3f6fa2647739acd9a3658b183fd531f040b15

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9cbd54b359a414acb2f6a4c3e3ce4a418a75b743d0511401d94ecd653aa19f99
MD5 cf3f6bedc070581db7f04c2da9dfaa7b
BLAKE2b-256 e75e8df1c02b0eba9bd8e64363b62fe5e0bc6e0422590aa750f891e32c3ecca8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6d63d0c6beeaa95e1a54361f760e9f041a2ddfad1befbd5f8b8ae8b4f75ab6bd
MD5 093ac6f6e394691095192793a64413d3
BLAKE2b-256 846e8e00cebdc3386193b378b4c99f41738bf3404929c763e8707aefd2f6ca7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 97a0c07c8adc2551dc8b1c35ac95feb75fcc1e22e683695fa345658af0c19fd7
MD5 2e874091099ddfea06bafb8a732ce665
BLAKE2b-256 d8dfee773add8abf56f61fd3219c1b7fc24c0b8c92f0c7ed2974869172331096

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp312-cp312-win_amd64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7bf91031f0714a7eabd9c3d491fae5d85a2b029728eda357e98fd43de8d15742
MD5 9af9a551ca654ea51a259611d9fcd69c
BLAKE2b-256 228942e59845a464aaef6534b0aab24f796a565e38dea2ad05cdaea96e365518

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a412a2a273ce7b4dd7cb8f12d40c539fa1cf11c2f7f1821bc8a38c106e7cdb13
MD5 9035692bee515ce10155c406a68eaf1a
BLAKE2b-256 e90de0f8904ebf48a3d23000b5b33ae4126b57f44a8dadf21d9f483f2b8d1f81

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a28f499cc88bf8440b4887d48bb99ab92a9da0468c54eaf5e645d80c9c01ab13
MD5 08d1190b33ed38a20aa496fe621af302
BLAKE2b-256 b9b17d154ac331ecd19e58f827e756304fb43f92739c11ba33227ccfcd3fd76e

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 adad5ef01546def22c289a3886e07c0be05c2ee604479f5fd9cba595090afea7
MD5 c6aedd29d9524b87a07bf1e991b62f82
BLAKE2b-256 d04e6e8e03496f1ef28fd62ffd38b861c338f87c7adb4234fab3c79d3645dd81

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 7a958f7b5b8ce5c9f967e1e16a7d77ffd94113c46132a35443839680e4dfaf8e
MD5 02dafcbcb1987069059babac10982341
BLAKE2b-256 07a0c0455fcfc5d8bd0e744ae74777aa65733dd90230bead5ffa1de49db23314

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp311-cp311-win_amd64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b9a02156fc20c324975ade42184c3563309090d38c411207646727b0873d74af
MD5 994993ca4fbe272848d1fae24843be93
BLAKE2b-256 bbf3a852acd46aaeaafda08aef93ae8df89fb3eb26375dc5560fba6aae5de701

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7a002db74ba3d52cb4b9f7700a1625cbb8cf9c7b55b839d0e51b2e3fa2e5bdf5
MD5 4d64df207eae9283230ea9abe998c0e8
BLAKE2b-256 3d4369af79d570b8fe2354166aad3769d1deebf1d764db3008b3da529a18a7cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7eb4edb3450a071ce61f8d170daf157d7d68933caaa029056955d29db991ff17
MD5 1ff3615da6ca4ccdc868272a09bc98b2
BLAKE2b-256 f95b5227cb5d2a34893708c2c98b39f0d139fa5c6bf792a674736995448e9717

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d873bb291520b43d142c59d0b33c8c3e07de58bf8f86cfc0a442cca7577898e4
MD5 7a04b131eae74fbffc1b260fb026b0df
BLAKE2b-256 25c1cee0a52e3d71be5c2ef5b8bd555cc907a7b93f5dc911ff180e2bff80c463

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 f1c8356d82266c8c9d79a0ca3e85f967afffd9be441521495a668d4180d0828c
MD5 de4bd5dd2ac61768acaae7a4fcc2f69d
BLAKE2b-256 da829b92d3f2a2446fb6ba970851a802a199737696069f34d57fdbf8d278c0a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp310-cp310-win_amd64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0473ea9bc2686db838c7366fe24868183b90656ddf9c4a59ac6d145cf36e8c30
MD5 66055419f9d3c84f155304025d621eb0
BLAKE2b-256 25af5927d11377a52d06e2e12b1133fbb914edf559aaf840fa75d8035d437172

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2b3403ebaea3a6b80b8fe5795583a3103fcc74f555c9102a98b3937fa129b40c
MD5 86de8a2e1fbdc396fcacf921ea97fc2a
BLAKE2b-256 9ef0a3b5ae247e664478a4756219c67f76d358eabea3659749dd14fb3861f860

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 19578c735b67dad9a6301130ee8c59f36b97d224591cd3cc189da64309f0b4d1
MD5 17063c92e775bf500e5064c039211205
BLAKE2b-256 136b67bfa7412855000ed5c16792abee80480f0810d952de8bb318b0aef85d4c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustystats-0.8.12-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustystats-0.8.12-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1112700da6a2af5fb60c40c1862698c13c3cf1e57eee989f420ca2c3f375055d
MD5 943b4f5804d9d40561656c2f6cd81a21
BLAKE2b-256 37c0e8d5f7ae0413cdb5926263408ec22f2e0886a7e8c299b6445c667c4e6450

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustystats-0.8.12-cp310-cp310-macosx_10_12_x86_64.whl:

Publisher: release.yml on PricingFrontier/rustystats

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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