Skip to main content

<object-storage-proxy ⚡> Yet Another Object Storage Proxy

Project description

CI PyPI version PyPI downloads License: MIT Rust edition

object-storage-proxy

A fast, in-process reverse proxy for AWS S3 and IBM Cloud Object Storage, built on Cloudflare's pingora. It exposes a Python interface so you can plug in your own credential fetching, request signing, and authorization logic without touching the Rust core.

Note: This project is under active development. APIs may change before 1.0.

Why

Object storage backends like IBM COS assign one endpoint and one set of credentials per storage instance, which may contain many buckets. Managing credentials and endpoints across instances becomes cumbersome, especially when clients expect a single uniform endpoint.

This proxy solves that by:

  1. Translating path-style requests (http://proxy/bucket/key) to virtual-hosted-style (https://bucket.s3.region.host/key) on the way out.
  2. Re-signing requests with the correct backend credentials, so clients only need one keypair pointed at the proxy.
  3. Calling your Python functions for credential lookup and request authorization, with TTL-based caching.

Request lifecycle

Request stages

Features

  • Compatible with any AWS S3-compatible client: aws-cli, boto3, polars, spark, datafusion, presto, trino, ...
  • Decouples frontend authentication (what the client sends) from backend authentication (what the storage expects).
  • Python callables for credential fetching, HMAC key lookup, and per-request authorization.
  • TTL-based credential and authorization caching.
  • HTTP and HTTPS frontends (HTTPS supports HTTP/2).
  • Configurable thread count and per-URL request counting.
  • Presigned URL support with configurable max-usage limiting.

Installation

pip install object-storage-proxy

Or install from source (requires Rust stable and uv):

git clone https://github.com/opensourceworks-org/object-storage-proxy.git
cd object-storage-proxy
uv run maturin develop --release

See BUILD.md for full build instructions including Nix and Taskfile usage.

Quick start

1. Configure your AWS client

~/.aws/config:

[profile osp]
region = eu-west-3
output = json
services = osp-services
s3 =
    addressing_style = path

[services osp-services]
s3 =
  endpoint_url = http://localhost:6190

~/.aws/credentials:

[osp]
aws_access_key_id = MYCLIENTID
aws_secret_access_key = myclientsecret

The aws_access_key_id is passed as the token argument to your Python callables. It can be any identifier meaningful to your auth system: an internal client ID, an OAuth2 subject, etc.

2. Write your server script

import json
import os
from object_storage_proxy import ProxyServerConfig, start_server

def fetch_credentials(token: str, bucket: str) -> str:
    # Return either an IBM COS API key string, or a JSON string:
    # '{"access_key": "...", "secret_key": "..."}'
    return json.dumps({
        "access_key": os.environ["BACKEND_ACCESS_KEY"],
        "secret_key": os.environ["BACKEND_SECRET_KEY"],
    })

def lookup_secret(access_key: str) -> str | None:
    # Called to verify incoming HMAC signatures.
    return os.getenv("MYCLIENTSECRET") if access_key == "MYCLIENTID" else None

def authorize(token: str, bucket: str, request: dict) -> bool:
    # Return True to allow, False to deny.
    return True

cos_map = {
    "my-bucket": {
        "host": "s3.eu-de.cloud-object-storage.appdomain.cloud",
        "region": "eu-de",
        "port": 443,
        "ttl": 300,
    },
}

config = ProxyServerConfig(
    cos_map=cos_map,
    bucket_creds_fetcher=fetch_credentials,
    hmac_fetcher=lookup_secret,
    validator=authorize,
    http_port=6190,
)

start_server(config)

3. Run it

uv run python my_server.py

4. Use it

aws s3 ls s3://my-bucket/ --profile osp
aws s3 cp file.txt s3://my-bucket/file.txt --profile osp

A fuller example with HTTPS, HMAC keystores, and IBM COS is in examples/minimal_server.py.

Configuration reference

ProxyServerConfig

Parameter Type Required Default Description
cos_map dict yes Bucket-to-backend mapping. See below.
hmac_keystore list[dict] no [] Static HMAC keypairs accepted on the frontend.
bucket_creds_fetcher callable(token, bucket) -> str no Called once per bucket to fetch backend credentials. Return an IBM COS API key string or {"access_key":...,"secret_key":...} JSON.
hmac_fetcher callable(access_key) -> str | None no Called per request to resolve a secret key from an access key, used to verify incoming signatures.
validator callable(token, bucket[, request]) -> bool no Called per request to authorize access. Cached by (token, bucket) for the bucket TTL.
http_port int one of http/https required HTTP listener port.
https_port int one of http/https required HTTPS listener port (HTTP/2 supported).
threads int no 1 Number of worker threads.
verify bool no None Disable TLS verification on upstream connections. Development only.
skip_signature_validation bool no False Skip verification of incoming request signatures. Development only.
max_presign_url_usage_attempts int no 3 Max times a presigned URL may be used before being rejected.
server_name str no "osp" Server name included in log output.

cos_map entries

Each key is the bucket name as the client addresses it. The value is a dict:

Field Required Description
host yes Backend hostname
port yes Backend port (typically 443)
region no AWS/COS region string
apikey no IBM COS IAM API key (mutually exclusive with access_key/secret_key)
access_key no Backend HMAC access key
secret_key no Backend HMAC secret key
ttl no Credential and auth cache TTL in seconds. Default 300. Set to 0 to disable.
addressing_style no "path" or "virtual" (default "virtual")
is_tls_enabled no Defaults to true when port is 443

Python callable signatures

# Fetch backend credentials for a bucket.
# token: the access key from the client's Authorization header.
# Return an IBM COS API key string, or JSON: '{"access_key":"...","secret_key":"..."}'
def fetch_credentials(token: str, bucket: str) -> str: ...

# Resolve the secret key for an access key (used to verify incoming signatures).
def lookup_secret(access_key: str) -> str | None: ...

# Authorize a request. request dict contains: method, path, query, headers.
def authorize(token: str, bucket: str, request: dict | None = None) -> bool: ...

HTTPS setup

Generate a self-signed certificate for local development:

openssl req -x509 -nodes -days 365 \
  -newkey rsa:4096 \
  -keyout key.pem \
  -out cert.pem \
  -config localhost.cnf

export TLS_CERT_PATH=/path/to/cert.pem
export TLS_KEY_PATH=/path/to/key.pem

Then pass https_port=8443 to ProxyServerConfig.

Environment variables

See .env.example for the full list. Key variables:

Variable Description
COS_API_KEY IBM COS IAM API key
AWS_ACCESS_KEY / AWS_SECRET_KEY AWS backend credentials
TLS_CERT_PATH / TLS_KEY_PATH Paths to TLS certificate and key
OSP_ENABLE_REQUEST_COUNTING Set to true to enable per-URL request counting
AWS_REQUEST_CHECKSUM_CALCULATION Set to WHEN_REQUIRED to avoid checksum errors with AWS CLI v2

Build targets

Pre-built wheels are published to PyPI for the following platforms:

Platform Architecture Libc Python
Linux (ubuntu-22.04) x86_64 glibc (manylinux) 3.x
Linux (ubuntu-22.04) aarch64 glibc (manylinux) 3.x
Linux (alpine 3.18) x86_64 musl (musllinux_1_2) 3.x
macOS (macos-14) aarch64 (Apple Silicon) 3.x
Source distribution any any 3.x

Windows builds are not currently active in CI. An sdist is always published so you can build from source on any platform with Rust stable installed.

Building from source

See BUILD.md.

Roadmap

  • Pass path and method to Python callbacks; cache by (token, bucket, path, method)
  • Expose pingora server and service configuration to Python
  • Spark streaming write support
  • AWS CLI checksum workaround (aws/aws-cli#9214)

Contributing

See CONTRIBUTING.md. Bug reports and feature requests go through GitHub Issues.

License

MIT

Project details


Release history Release notifications | RSS feed

Download files

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

Source Distribution

object_storage_proxy-0.5.0.tar.gz (1.4 MB view details)

Uploaded Source

Built Distributions

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

object_storage_proxy-0.5.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded PyPymanylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded PyPymanylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp314-cp314t-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp314-cp314-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

object_storage_proxy-0.5.0-cp314-cp314-macosx_11_0_arm64.whl (5.2 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

object_storage_proxy-0.5.0-cp313-cp313t-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp313-cp313-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

object_storage_proxy-0.5.0-cp313-cp313-macosx_11_0_arm64.whl (5.2 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

object_storage_proxy-0.5.0-cp312-cp312-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

object_storage_proxy-0.5.0-cp312-cp312-macosx_11_0_arm64.whl (5.2 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

object_storage_proxy-0.5.0-cp311-cp311-musllinux_1_2_x86_64.whl (7.8 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

object_storage_proxy-0.5.0-cp311-cp311-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

object_storage_proxy-0.5.0-cp311-cp311-macosx_11_0_arm64.whl (5.2 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

object_storage_proxy-0.5.0-cp310-cp310-manylinux_2_34_aarch64.whl (8.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ ARM64

object_storage_proxy-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

File details

Details for the file object_storage_proxy-0.5.0.tar.gz.

File metadata

  • Download URL: object_storage_proxy-0.5.0.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.13.3

File hashes

Hashes for object_storage_proxy-0.5.0.tar.gz
Algorithm Hash digest
SHA256 7b0d65e6fd4c0124e5ba1e3a3a941f2dc1b809d03f99f2ff115495d7f1837949
MD5 28af45f2bb4483803ef2c091a89c7da7
BLAKE2b-256 1c102d7756a8e3717e4db7d8003c7c24f8d11d4eeaa1b3064c288fc81fbfd8c5

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 2027433474ebeeab926804365c0ed248e3b886a15590efa7491ea2e1dc6c6e6a
MD5 5660282612199352527dba37928467f2
BLAKE2b-256 89b809afdcc524c7d91ca733f54c4caa38868c5b13ed0058ced1764fc444d949

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c8c5a9a69f1511952947cf78400c2ac2cb82d9db876316bd76cdc9a6edfb6138
MD5 e32ea33dad28898565ef8edbb12bf433
BLAKE2b-256 670575a5a34cc87a2069bf3adaa4030efb1ae6bbbccea2132cc3dc946405f5ed

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 46b4ef69dec5c15baa959d053fa508922bc6f44d5bf82f8e707787805891dbe2
MD5 0110b42dd044603b60a2f80fa5c123d8
BLAKE2b-256 c43bcb25c94baaeaab0b667e9afb654cf17a1d30629d0b00774fdbf1f588c983

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp314-cp314t-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp314-cp314t-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 7994c1526e0f2fbbd9e7f3f303f5160b9594de099853cd63a4354e2e85bffe31
MD5 e3e58cffbb3ec23fd93a8e73bdac27a7
BLAKE2b-256 12378fb511c85274e2b138493ff354e8f16d643d35c7e1bca3b7983dbdfe1c73

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp314-cp314-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp314-cp314-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 61a862a60b29bc605a56535a9b7f52659362e21125c45f2ac4d4163d7e2f4de8
MD5 383938fbba5ee0d295620c36a7e68914
BLAKE2b-256 44bb3ce102be03a2722cb2724712bb26c3c47db558dce5597fc5875c97a15add

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4376fe7157e8e059dc422b46cd9b4ce1a76972dcedbee6b2500e05d28464cfbe
MD5 624afa93d2e87e596434f42fa70248de
BLAKE2b-256 654972726dd633240b9f1df97d516f73a5b43c6c587f5a5be02d11b119a1e396

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a1fda72b2f96d42f154435ad5e9003b3a6e025f0d36f13066e86f48a7f03de0b
MD5 2f4bc8320580a46190aab97d9df7078f
BLAKE2b-256 771260b46fb25a1cb6ce04b53014741d333da3f88b00c0da1244b0646fa9beb9

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp313-cp313t-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp313-cp313t-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 3b9de289e08b7c9b7026a13bb8386447b43e15bf9001c05a6f327be4f8d44537
MD5 1ea18b808c089c4ed2ceb1ac1edb98b5
BLAKE2b-256 f63d19180d560cd63375f7d6fefa1782f316c7730c7a6cf1b70b7d0069f67055

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp313-cp313-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp313-cp313-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 d24c3ecdc64a76f3821b575baec24fe43d91470053fa65492f3ae310f2c96b52
MD5 d840bc679d89747a1a4efa67f13bd523
BLAKE2b-256 8f2e462865d54d9445a94daa48e99d0fccd484961eee06ec16c4d955524a0567

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 42053fb19e56bad79fced41d267d99e64e3b99a24a54e49fbf82028eb5d61096
MD5 46949e98e7d1f4bc25f54bc2ccbff057
BLAKE2b-256 723e66b329a032e7b1db2129439adf683592552b98a2bd70d8991a823ce2652e

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 577fdc8545d4a8696baf95a49b8a8dc1deeb572937a82d0d8ae014e9abf458a0
MD5 ed933983db550ae2f9ac9da418add8e8
BLAKE2b-256 d88d38681f38ae9362a926e44154e29ec13be241e8b58cf811c887a7ce951625

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp312-cp312-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp312-cp312-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 456464f72db8f22f2cb949f7a36ebefa5702471ac31c249e6bbf130808ed0252
MD5 0ab03a163ff8fb3edbadeaf48ebd0ca9
BLAKE2b-256 fb827f5cd8e674db3e6047697f40d02a61457151708de5245511d3f33bc1e488

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2315dc2b926fed717dff7277b94c5cc99bbb51c64ed11becda8f33ef3b5ea519
MD5 246b20ae0fe3656b3f71cc7ca852f534
BLAKE2b-256 5b165e834ca3b0edd55f22183159ccd8be3420f2c9e47b51c8ca73bfe324ebb2

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9053e9db5719583a00d3f68717e08d55966228a3bbb4339a427d83f8d05d0b6f
MD5 bf707f5b94596c418a1afed6eb2224e9
BLAKE2b-256 104de12614d4a6a9eea9ac2670b5dd552481eb4d169a06230ced26ea4097d1b9

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 598c443f850ec1f177b03a9db4cef5e70b84619cd8e4f95b80b09dcf16f37520
MD5 fbbe5f0cb0be1f683a2a3a62a9edb10e
BLAKE2b-256 084986dc6aaea2bf6510c7e1e534a7f294f4d95b8b9defcad57c32b67a214e65

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp311-cp311-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp311-cp311-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 21ef15305ce755284aba5c8148f07dc342e2535cf8cac4d7c8ec0a5401c9783c
MD5 4562a1db30cd91d502d3f000af0bb262
BLAKE2b-256 a97aba453c01d6b2f6febaf77ee7d1234d5fdd7cb15ab41e174fdc7a1a598a05

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 80957b46a6bfd1cb8b9269ebd87613a0ce78d009baa5638f1f8d058fe3fdf6a5
MD5 ed10d958743ea5ce205d8ec6b49434a1
BLAKE2b-256 4eb168a7baf3dc63a549fcbc37c57e8c282914ce42dcd243b075225ad46b2657

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7dbfad7a96f80d3926e8c9bdd1ef47def239796b525bbbfd14293ae3fb964c08
MD5 467bf80fdf65542d9bfa76224129c4d4
BLAKE2b-256 9346854864bca42414b5837d9476d3602513cd5bdb9a152856cec59d03a9c172

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp310-cp310-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp310-cp310-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 ac2cfffae05f7d715e1639c59620c8503605f9bb6d62f9fade1ca30f1c9638d4
MD5 da0ff3b9e432bdbdf626a09715b384aa
BLAKE2b-256 9bed3c5c427fbc6653ce195b9e14a92acd2fc86ffbb163b354188ae57b9dfd3d

See more details on using hashes here.

File details

Details for the file object_storage_proxy-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for object_storage_proxy-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 982c7545804d7bd9244a10fe3c0cf50cf3694180648867ac1a7c78f972a961c8
MD5 54df2977932336042979d9bdec0a5429
BLAKE2b-256 c1c22c22445338a1d74b10c9ffab452ecc382e9bf95d42af195d3f75edf7332f

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