rustai
Local, zero-cost research for local models. Search the open web, strip it down to the text that matters, and hand a small model a context window it can actually use — with no API key, no per-call billing, and no heavyweight Python crawler in the middle.
import rustai
result = rustai.research("how does BM25 handle document length", max_sources=5, max_tokens=2048)
print(result.markdown) # cited, deduplicated, ranked Markdown — ready to prompt
Why this exists
Retrieval for a local model is a data-cleaning problem wearing a search costume. The search itself is the easy part; what actually decides whether a 7B model answers well is how much of its 4k window you spent on cookie banners.
Hosted APIs solve this for a fee. Python crawler stacks solve it by pulling in a
browser-grade DOM, which is where the memory goes. rustai does it locally in
Rust:
| Hosted search API | Python crawler stack | rustai |
|
|---|---|---|---|
| Cost per query | metered | free | free |
| API key | required | — | none |
| Extraction | vendor's | yours to build | built in |
| Context compression | rarely | yours to build | built in |
| Scholarly sources | rarely | yours to build | built in |
| Peak RSS, 200 docs | n/a | +15.5 MB | +4.4 MB |
See Benchmarks for how those numbers were produced.
Try it in Colab
notebooks/colab_quickstart.ipynb runs the
whole pipeline in a browser — offline denoising, live collection, the search
providers, a benchmark against trafilatura, and a look at the TLS fingerprints.
notebooks/colab_oneshot.ipynb is the same
thing as a single cell: build, install, and a report covering denoising
accuracy, throughput, live fetches, every provider, and the pipeline end to end.
Until wheels are on PyPI, Colab has to build from source, and the BoringSSL
dependency makes that a 10–20 minute first run. Both notebooks cache the wheel
to Drive, so every session after the first installs in seconds. They install
clang and libclang-dev before building: BoringSSL's bindings run bindgen,
which needs libclang, and the Colab base image does not ship it.
Install
pip install rustai
Wheels are published for Linux, macOS and Windows on CPython 3.9+ (a single
abi3 wheel per platform). No Rust toolchain needed to install.
For the Rust crate (published as rustai-core, since rustai was taken on crates.io):
cargo add rustai-core
What it does, stage by stage
query ──▶ search router ──▶ fetcher ──▶ denoiser ──▶ slimmer ──▶ context
concurrent impersonated DOM heuristics BM25 + density
free providers + polite + Markdown + MMR dedupe
1. Search router — free providers, fused
| Kind | Providers |
|---|---|
| Web search | duckduckgo, searxng:<instance> |
| Reference | wikipedia, wikipedia:ko (any language edition) |
| Scholarly | arxiv, openalex, crossref |
| Sites you trust | rss:<feed>, sitemap:<sitemap.xml>, index:<front page> |
All keyless, all free, all queried concurrently; a provider that fails or rate-limits degrades the result set instead of failing the call.
The scholarly providers are not a nicety. A web search for a paper returns blog
posts about the paper; arXiv, OpenAlex and Crossref return the paper. OpenAlex
stores abstracts as an inverted index for licensing reasons, and rustai
reconstructs them, which makes its snippets the most informative of any provider
here. arXiv results always point at the abstract page, never the PDF, because a
PDF is not something this pipeline can read.
index: harvests an HTML listing page — a front page, an archive, a forum — for
the links it offers. A site with no feed and no sitemap is still collectable.
OpenAlex and Crossref run a faster "polite pool" for callers who identify
themselves — pass contact_email to use it.
Rankings are combined with reciprocal rank fusion, because provider scores
are not comparable to each other but ranks always are. URLs are canonicalised
first — www., tracking parameters, fragments and trailing slashes stripped —
so a page found by three providers counts once and ranks higher for it.
2. Fetcher — looks like a browser, behaves like a guest
Bot walls read your TLS ClientHello (JA3/JA4) and HTTP/2 SETTINGS frame, not
your User-Agent. rustai replays a real Chrome's via
wreq, so ordinary pages return ordinary
200s.
Being able to get in is not a licence to be rude, so robots.txt, Crawl-delay,
per-host spacing, a concurrency ceiling, capped bodies and backoff-on-retry are
all on by default. Legacy encodings (EUC-KR, Shift_JIS) are decoded properly
rather than assumed to be UTF-8.
When a site answers with Retry-After, that is honoured in place of the
backoff curve — a server's own number beats any we could invent — up to
max_retry_after, past which a delay is really a refusal.
For IP-reputation blocking, which fingerprinting cannot touch, pass proxies
and requests rotate round-robin across them. cookie_file persists the jar, so
a session — clearance cookies included — survives the process.
HTTP redirects are followed, and so are HTML-level ones: a stub page that
redirects through <meta refresh> or location.replace returns a perfectly
good 200 containing no content, which is how sites that canonicalise URLs in
the browser silently produce empty extractions elsewhere.
For the minority of pages that ship an empty shell and build the DOM in JavaScript, an opt-in headless Chrome fallback fires — but only after a cheap static fetch has demonstrably failed, since rendering costs ~100× a fetch.
3. Denoiser — find the article, drop the furniture
Three signals, in order:
- Structural priors —
<nav>,<footer>,<aside>,role="banner", and a class/id vocabulary that has been stable for a decade. - Link density — anchor text over total text. Navigation and "related posts" rails approach 1.0; prose approaches 0.
- Text-to-HTML ratio — visible characters over serialised markup bytes. Ad slots and widgets are almost pure markup.
Then a Readability-style content score picks the container holding the article, and the survivors are written as clean Markdown — headings, lists, fenced code, pipe tables, absolutised links.
The output is not one blob. It is a list of units, each carrying its own text, its Markdown, its heading breadcrumb and its token cost. That granularity is what makes the next stage possible.
Listing pages take a different path. A front page defeats article extraction
for the same reason navigation is boilerplate everywhere else — except here the
link density is the content. rustai detects that by measuring how much of the
page's prose belongs to a link, and returns an inventory instead: titles, URLs,
standfirsts and section headings, ready to fetch. article.kind tells you which
you got. On thirteen real pages spanning news front pages, aggregators, encyclopaedia
articles, papers, READMEs and specs, the classifier is 12 for 12; it costs about
1% of extraction time and index_mode="never" turns it off.
4. Slimmer — spend the context window deliberately
Given a question and a pile of articles, choose the units that best fill a budget:
- BM25 relevance at unit granularity, so you get the two paragraphs that answer the question rather than the page that contains them.
- Information density — content-word ratio, numeric ratio, type-token ratio, minus an explicit boilerplate penalty. This is what separates a dense factual paragraph from "In this article we will explore some of the things you need to know", which matches query terms perfectly and says nothing.
- MMR selection with an overlap-coefficient redundancy penalty, because three copies of the same syndicated paragraph is the most common way to waste a window.
Output is Markdown with source headers, URLs, heading breadcrumbs and […]
elision markers, under the token budget you set.
Usage
One call
import rustai
r = rustai.research("what changed in HTTP/3", max_sources=5, max_tokens=2048)
print(r.markdown) # the context
print(r.context.tokens) # what it actually cost
for src in r.context.sources:
print(src["url"], src["tokens"])
for stage, message in r.failures:
print("skipped:", stage, message) # nothing is swallowed silently
A reusable client
Sharing a client shares its connection pool, its robots.txt cache and its
per-host pacing state, so it is meaningfully faster than repeated one-shot calls.
client = rustai.Client(
providers=["duckduckgo", "wikipedia:en", "arxiv", "openalex"],
contact_email="you@example.com", # OpenAlex/Crossref polite pool
max_tokens=4096,
concurrency=24,
impersonate="chrome", # or "firefox", "safari", "random", "chrome_143", "none"
respect_robots=True,
proxies=["socks5://user:pass@host:1080"], # rotated round-robin
cookie_file="~/.cache/rustai/jar.json", # session survives the process
)
...
client.save_cookies() # write the jar back out
hits = client.search("rust async runtime") # list[SearchResult]
pages = client.fetch([h.url for h in hits[:5]]) # list[Page] — raw HTML
articles = client.read([h.url for h in hits[:5]]) # list[Article] — cleaned
result = client.research("rust async runtime") # the whole pipeline
Offline: clean HTML you already have
No network, no client, nothing to configure:
article = rustai.extract(html, url="https://example.com/post")
article.title # str | None
article.markdown # cleaned Markdown
article.text # plain text
article.tokens # estimated LLM tokens
article.stats.compression # e.g. 0.94 — how much was dropped
for unit in article.units:
print(unit.kind, unit.tokens, unit.heading_path, unit.text[:60])
For a batch, extract_many runs across every core and releases the GIL, so it
is roughly 4× the throughput of a loop over extract — and about 30× that of
trafilatura:
articles = rustai.extract_many(list_of_html) # 1:1 with the input
articles = rustai.extract_many(list_of_html, list_of_urls) # positional urls
Compress a set you assembled yourself
articles = client.read(my_urls)
ctx = rustai.slim("my question", articles, max_tokens=1024, max_tokens_per_source=400)
print(ctx.markdown)
max_tokens_per_source caps how much any single page can contribute, so one long
article cannot crowd out corroborating sources.
Listing pages
front = rustai.extract(html, "https://news.example/")
if front.kind == "index":
for link in front.links:
print(link.text, link.url, link.heading_path)
urls = [l.url for l in front.links]
articles = client.read(urls) # now go read them
Scholarly search
client = rustai.Client(
providers=["arxiv", "openalex", "crossref"],
contact_email="you@example.com",
)
for hit in client.search("sparse attention long context"):
print(hit.title)
print(" ", hit.url)
print(" ", hit.snippet[:120]) # authors (year). abstract…
Your own sites, without a search engine
client = rustai.Client(providers=[
"rss:https://blog.rust-lang.org/feed.xml",
"sitemap:https://doc.rust-lang.org/sitemap.xml",
])
Feeds and sitemaps are the highest-signal sources here — complete, ordered, and free of anyone else's ranking.
Utilities
rustai.count_tokens("some text") # budget estimate, CJK-aware
rustai.density("some text") # 0.0–1.0 information density
rustai.tokenize("한국어 텍스트") # the ranker's own tokens
rustai.canonical_url("https://www.x.com/a/?utm_source=b") # 'x.com/a'
rustai.parse_feed(xml) # list[dict]
rustai.parse_sitemap(xml) # {"urls": [...], "sitemaps": [...]}
Errors
Everything derives from rustai.RustaiError:
| Exception | Raised when |
|---|---|
NetworkError |
transport failure, timeout, oversized body |
HttpStatusError |
non-2xx response |
RobotsError |
robots.txt disallows the URL |
ExtractError |
the document could not be parsed |
ProviderError |
a search provider failed |
BrowserError |
headless fallback unavailable |
Batch calls (fetch, read) skip failures by default; pass
raise_on_error=True to get the first one instead. search returns partial
results by default; pass strict=True to raise when every provider fails.
Rust API
use rustai_core::pipeline::Pipeline;
# async fn run() -> rustai_core::Result<()> {
let pipeline = Pipeline::new()?;
let research = pipeline.research("what is BM25", 5).await;
println!("{}", research.context.markdown);
# Ok(()) }
Every stage is public and usable alone: rustai_core::search::Router,
rustai_core::http::Fetcher, rustai_core::parse::extract, rustai_core::rank::slim.
Cargo features
| Feature | Default | What it does |
|---|---|---|
impersonate |
✅ | Chrome TLS/JA3 + HTTP/2 fingerprint emulation |
python |
— | PyO3 bindings (enabled by maturin) |
browser |
— | headless-Chrome fallback via chromiumoxide |
nightly-simd |
— | SIMD tokenisation inside tl; requires a nightly toolchain |
Text scanning in this crate is SIMD-accelerated on stable regardless, via
memchr. The nightly-simd feature only affects tl's own HTML tokeniser,
which is gated on #![feature(portable_simd)] upstream.
Being a good citizen
This library makes it easy to hit other people's servers quickly, so the defaults lean conservative:
robots.txtis honoured for every content fetch, withCrawl-delayrespected.- Requests to one host are spaced 250 ms apart; total concurrency is capped.
- Response bodies are capped at 8 MB and aborted mid-stream past that.
- Retries back off exponentially rather than hammering a rate limit.
Search-provider endpoints you name explicitly (DuckDuckGo's HTML endpoint, a feed
URL) skip the robots.txt check, because a query is not a crawl and several of
those endpoints disallow the very path they exist to serve. Pages discovered
through them go through the normal checked path.
Impersonation exists so ordinary reading is not misclassified as abuse. It is not a licence to ignore a site's terms, and you are responsible for what you point this at.
Be clear-eyed about what it does. Measured against ten sites, the profiles
produce genuinely distinct JA3, JA3N and Akamai HTTP/2 fingerprints — but on
sites with real bot defences (Cloudflare Enterprise, PerimeterX) turning
impersonation on changed the outcome on none of them. Those blocks key on
datacenter IP reputation and behaviour, not on the ClientHello. A fingerprint is
necessary, not sufficient; proxies is the knob that addresses the rest, and
some sites you simply should not be scraping.
Benchmarks
Reproduce with:
python benches/corpus.py /tmp/rustai-corpus
cargo run --release --example bench -- /tmp/rustai-corpus # Rust only
python benches/benchmark.py # batch, vs bs4+lxml
RUSTAI_BENCH_STREAM=1 python benches/benchmark.py # streaming
The corpus is 200 synthetic article pages, 9.43 MB of HTML, ~46 KB each, shaped like real ones: heavy chrome, nested wrappers, ad slots, a sidebar, a script blob. Synthetic so the benchmark is deterministic and redistributable — the chrome-to-content ratio is what an extractor is tested on, not raw size.
Rust alone, streaming one document at a time (Apple M1, macOS 26.6, release build):
documents 200
input 9.43 MB
output 2.27 MB in 12000 units
compression 75.9%
throughput 638 docs/s, 30.1 MB/s
peak RSS 4.9 MiB
From Python (CPython 3.14):
| Engine | Throughput | vs trafilatura |
|---|---|---|
rustai.extract_many |
3,545 docs/s | 16.1× |
rustai.extract (loop) |
840 docs/s | 3.8× |
trafilatura |
220 docs/s | 1× |
Median of three runs. trafilatura is the fair comparison — it is the closest
equivalent, since it also produces structured Markdown — and both emit the same
2.27 MB of output from the same input. extract_many runs across the rayon pool
with the GIL released, which is where the further 4.2× comes from.
Peak process RSS, streaming one document at a time: rustai 39.3 MB against
bs4+lxml's 50.4 MB — +4.4 MB versus +15.5 MB over the 34.9 MB floor
of a CPython 3.14 interpreter holding the corpus.
Concurrent fetching, measured on 20 live URLs across many hosts: 1.7 pages/s serial versus 15.1 concurrent, an 8.7× speedup. Beyond that the bottleneck is the remote server, not this library.
"Marginal RSS" subtracts the 34.9 MB floor of a CPython 3.14 interpreter holding
the corpus, which both engines pay identically. Importing rustai itself costs
1.0 MB over a bare interpreter.
Caveats worth stating plainly. The bs4 baseline produces a flat string while
rustai produces structured Markdown units with metadata, so that row
understates rustai's work per document; the trafilatura row is the honest
comparison. And these are single-machine numbers on one synthetic corpus — run
the benchmark on your own pages before trusting them.
Development
cargo test # Rust unit tests, no network
cargo test --features browser # includes the headless fallback build
maturin develop --release # build and install into the active venv
pytest # Python tests
pytest -m network # the live-internet tests, off by default
License
Dual-licensed under MIT or Apache-2.0, at your option.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rustai-0.1.0.tar.gz.
File metadata
- Download URL: rustai-0.1.0.tar.gz
- Upload date:
- Size: 171.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6c00b632a05251db1e16418439e5c9c686becb488b96b2d0e0fd7f373d2d0bf
|
|
| MD5 |
df8cec7cd03ed981a36b93fa4cf3a1cd
|
|
| BLAKE2b-256 |
4267ba696cea33ca267900a5c4c9ea04d7c0060cc93453afcadcae20ceef0d3c
|
Provenance
The following attestation bundles were made for rustai-0.1.0.tar.gz:
Publisher:
release.yml on imhyensuk/rustai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustai-0.1.0.tar.gz -
Subject digest:
a6c00b632a05251db1e16418439e5c9c686becb488b96b2d0e0fd7f373d2d0bf - Sigstore transparency entry: 2719790941
- Sigstore integration time:
-
Permalink:
imhyensuk/rustai@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imhyensuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustai-0.1.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: rustai-0.1.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 4.4 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15a45d76525cb0b1ffc4d974d8222dcf6a9872c6e8da6a6022d1af2d49bc556c
|
|
| MD5 |
a813c5a3ad3c6e4b18c012aa5a13cf37
|
|
| BLAKE2b-256 |
c6b7ac0073784375d903b15f84b1ef814a102ea5a2252b1a750cdfccf88562fe
|
Provenance
The following attestation bundles were made for rustai-0.1.0-cp39-abi3-win_amd64.whl:
Publisher:
release.yml on imhyensuk/rustai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustai-0.1.0-cp39-abi3-win_amd64.whl -
Subject digest:
15a45d76525cb0b1ffc4d974d8222dcf6a9872c6e8da6a6022d1af2d49bc556c - Sigstore transparency entry: 2719793649
- Sigstore integration time:
-
Permalink:
imhyensuk/rustai@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imhyensuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustai-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rustai-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 4.4 MB
- Tags: CPython 3.9+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40413cf51b3e20a48d506da3d2f224dc32d8017722e86a2a0cd2c597d5b14ae4
|
|
| MD5 |
b238ce776fdaa918fea567553b7cecae
|
|
| BLAKE2b-256 |
57bc0023ec8e87d5a37db0a7b123a2ca5e014528155ca8480551fe6f9501d7a2
|
Provenance
The following attestation bundles were made for rustai-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl:
Publisher:
release.yml on imhyensuk/rustai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustai-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
40413cf51b3e20a48d506da3d2f224dc32d8017722e86a2a0cd2c597d5b14ae4 - Sigstore transparency entry: 2719792953
- Sigstore integration time:
-
Permalink:
imhyensuk/rustai@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imhyensuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustai-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: rustai-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 4.2 MB
- Tags: CPython 3.9+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afd70fa843f13d6e4a27a2c3d58424102e9ca01eb6bbe21cbcb3f108a6c62b10
|
|
| MD5 |
66c74b645f8645f8592e6d27223006ee
|
|
| BLAKE2b-256 |
a37511b906ee7151086116df70fe9afda4cc3438dfae5c4bd4fae2dc772df9a1
|
Provenance
The following attestation bundles were made for rustai-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl:
Publisher:
release.yml on imhyensuk/rustai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustai-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
afd70fa843f13d6e4a27a2c3d58424102e9ca01eb6bbe21cbcb3f108a6c62b10 - Sigstore transparency entry: 2719795851
- Sigstore integration time:
-
Permalink:
imhyensuk/rustai@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imhyensuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustai-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: rustai-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.9 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4049b0c2087af8c490dcb3140874840f85dcf2535df8dae2d81fead69c9f594f
|
|
| MD5 |
692cc8bd0748da69ab1f9dbb8017c5ed
|
|
| BLAKE2b-256 |
b6043160246770c26417df81216549e0f2c31ad9160790d9c36c9c949e923d17
|
Provenance
The following attestation bundles were made for rustai-0.1.0-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on imhyensuk/rustai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustai-0.1.0-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
4049b0c2087af8c490dcb3140874840f85dcf2535df8dae2d81fead69c9f594f - Sigstore transparency entry: 2719792026
- Sigstore integration time:
-
Permalink:
imhyensuk/rustai@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imhyensuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rustai-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: rustai-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 4.1 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
265fee14101b84653c6896f1533de88ffba547a1b515256d30cdde3cfd018c2b
|
|
| MD5 |
7ee6b62ef14f3ced9ba3c475f2710bfa
|
|
| BLAKE2b-256 |
5650fd5a0855444f410b680eae7b9eec952a77398e6747f2451cd1db9167f578
|
Provenance
The following attestation bundles were made for rustai-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on imhyensuk/rustai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rustai-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
265fee14101b84653c6896f1533de88ffba547a1b515256d30cdde3cfd018c2b - Sigstore transparency entry: 2719794912
- Sigstore integration time:
-
Permalink:
imhyensuk/rustai@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/imhyensuk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64d3b833ed8ead6089fb2374af436e2d4a5d47e8 -
Trigger Event:
push
-
Statement type: