Security and risk analysis tool for AI projects (AI-BOM).
Project description
AI-BOM Inspector
Offline-first SBOM + AI supply-chain risk and license scanner. Privacy posture: default is --offline (no network calls) unless you opt into --online. Local-first; optional enrichment (OSV/HF/Shadow-UEFI) can be enabled explicitly. Fully offline supported. The "AI" is transparent rules + heuristics with a deterministic executive summary that runs offline; teams can still layer in their own LLM if desired.
Architecture at a glance
graph TD
A["CLI / API"] --> B["Manifest & SBOM parsers"]
A --> C["Model metadata loaders"]
B --> D["Risk engine"]
C --> D
D --> E["Report renderers<br/>(JSON, Markdown, HTML, CycloneDX, SPDX)"]
E --> F["CI gates<br/>(fail-on-score, diff)"]
The scanner defaults to local-only analysis: it ingests manifests/SBOMs, can layer in optional OSV/Hugging Face lookups, and emits reports that CI can enforce. Network enrichment (OSV, Hugging Face, Shadow-UEFI-Intel metadata) only occurs when you deliberately pass --online and enable the relevant feature flag.
Repository layout
ai-bom-inspector/
crates/
core/ # parsing, normalization, scoring (Rust extension)
licenses/ # license rules, SPDX mapping
advisories/ # CVE ingestion adapters (OSV/NVD/etc)
report/ # JSON/MD/SARIF outputs + diff support
src/ # Python package (aibom_inspector)
policies/
examples/
default.yml
strict.yml
oss-friendly.yml
schemas/
policy.schema.json
report.schema.json
integrations/
github-action/ # composite action wrapper for CI
pre-commit/ # reusable hook definition
docs/
QUICKSTART.md
POLICY.md
SCORING.md
FAQ.md
.github/
workflows/
ci.yml
scan-pr.yml # runs on PR and posts summary
tests/
README.md
What it does
- Parse dependency manifests across Python (
requirements.txt,pyproject.toml), JavaScript (package.json/package-lock.json), Go (go.mod), and Java (pom.xml) - Ingest existing SBOMs (
--sbom-file) and export CycloneDX or SPDX alongside AI-BOM extensions - Gather AI model metadata from JSON or explicit Hugging Face IDs and auto-discover model references (OpenAI/Anthropic calls,
from_pretrainedloads, pipeline configs) directly from your repo - Apply heuristics for pins, stale models, license posture (permissive vs copyleft vs proprietary vs unknown), and optional CVE lookups via OSV
- Surface AI model lineage, training data provenance, license ambiguity, and model risk profiles so AI-BOM metadata is front-and-center for governance reviews
- Inspect model artifacts (safetensors/pickle checkpoints) for poisoned weights or unsafe globals and compute hashes for reputation checks
- Cross-check models against local vulnerability/advisory feeds, training source fingerprints, and map findings to STRIDE + MITRE ATLAS categories
- Emit JSON, Markdown, HTML, CycloneDX, or SPDX reports with risk breakdowns driven by explainable heuristics plus a deterministic, offline AI summary (optionally replaceable by your own LLM if desired)
- Optionally pull firmware research context from Shadow-UEFI-Intel when
--online --enable-shadow-uefi-intelis used - Maintain evidence chain-of-custody with attestations, audit logs, and integrity checks so governance teams can trace decisions end-to-end
- Provide score explainability artifacts (policy version, intel versions, weight breakdowns, temporal multipliers) to make risk outcomes audit-ready
- Require org context (asset criticality, data sensitivity, environment) so scores cannot be generated without enterprise context
The default reports only use deterministic heuristics; the "AI summary" field is generated offline from the scan findings so teams get an executive-ready summary without hosted inference.
Network behavior
- Global posture:
--offlineis the default and hard-blocks every remote call. Expect[OFFLINE_MODE]/[CVE_LOOKUP_SKIPPED]annotations in reports when enrichment is skipped. - Opt-in enrichment: add
--onlineto allow outbound calls, then enable specific feeds (e.g.,--with-cves,--model-id,--enable-shadow-uefi-intel) to choose what actually dials out. - Local-only hardening: pass
--local-only(or keep--safe-modeenabled) to enforce zero outbound fetches even if--onlineis set. - Endpoints and payloads:
| Endpoint | When it fires | Data sent | How to disable |
|---|---|---|---|
https://api.osv.dev/v1/query (or OSV_API_URL) |
--online and --with-cves |
JSON body containing package.name, package.ecosystem, and version for each dependency |
Default offline; omit --with-cves; keep --offline; or point OSV_API_URL to an internal mirror |
https://huggingface.co/api/models/<id> (or huggingface_hub SDK) |
--online with --model-id or models whose source is huggingface |
Model identifier only; response cached locally | Default offline; avoid --online; or provide a fully populated models.json |
| GitHub API for Shadow-UEFI-Intel | --online and --enable-shadow-uefi-intel |
Repository metadata fetch; no project data sent | Default is disabled; leave --enable-shadow-uefi-intel off or keep --offline enabled |
Local model advisory/hash databases (model_vulnerability_db.json, model_hash_reputation.json) |
Always local unless you point to a custom URL | None (local JSON only) | Use defaults or pass --model-advisory-db / --model-hash-db |
| Future feeds | Any new integrations (documented as added) | Varies by feed | Default offline; disable the specific feature flag; or run with --offline |
Timeouts can be tuned via --osv-timeout, --shadow-uefi-timeout, or the OSV_API_TIMEOUT / SHADOW_UEFI_INTEL_TIMEOUT environment variables.
Installation
- Pinned release from GitHub (current canonical path):
pip install "aibom-inspector @ git+https://github.com/aibom-inspector/AI-BOM-Inspector.git@main" # Prefer a tagged release for CI: pip install "aibom-inspector @ git+https://github.com/aibom-inspector/AI-BOM-Inspector.git@v0.1.0"
- Editable dev install:
pip install -e .[dev]
- Wheels: the Rust extension ships as a wheel when you build from source—
python -m buildwill produce a.whlunderdist/for airgapped installs. - PyPI readiness: packaging metadata and wheels are production-ready for internal or public registries; use GitHub release pins above for stable CI installs or build a wheel locally for airgapped environments.
Build + SBOM generation
- Build a wheel for offline installs:
python -m build
- Generate a CycloneDX SBOM for this tool:
pip install cyclonedx-bom cyclonedx-py -o aibom-inspector-sbom.json
Getting started
-
Create a
models.jsonfile if you want to include model metadata (auto-discovery will still pull model IDs out of your code/configs when this is omitted). A ready-to-use sample lives inexamples/models.sample.json:[ {"id": "gpt2", "source": "huggingface", "license": "mit", "last_updated": "2024-01-01"}, {"id": "custom-embedder", "source": "private"} ]
-
Run the scanner (auto-detects dependency files when present):
aibom scan --models-file models.json --format html --output report.html
Run
aibom scan --helpfor the full list of options and supported formats.Network calls are off by default; add
--online(plus flags like--with-cvesor--model-id) if you want remote enrichment.
Who is this for?
- AppSec and security engineers who want CI/CD-friendly AI-BOMs without shipping code to a third party
- MLOps/platform teams who need model metadata (license, freshness, advisories) next to dependencies
- Builders who want tweakable, explainable rules instead of black-box scanners
Why this vs. Snyk & friends?
- Small, OSS, local-first: zero data leaves your laptop or CI box.
- AI-stack aware: treats models as first-class assets instead of opaque blobs.
- Customizable rules: heuristics are readable Python, not black-box policies.
- Offline gates + allowlists + model-as-asset scoring: enforce allowlisted model sources, run fully offline by default, and score models/dependencies together—capabilities that hosted scanners often treat as optional add-ons.
Examples
-
End-to-end demo (
examples/demo/): tiny app withrequirements.txt,pyproject.toml,package-lock.json,go.mod,models.json, and generatedaibom-report.json/md/html.- HTML report snapshot: open
examples/demo/aibom-report.html - Markdown rendering snapshot: see
examples/demo/aibom-report.md - Before/after hygiene comparison:
docs/screenshots/before-after.html
Small JSON excerpt (full file in
examples/demo/aibom-report.json):{ "stack_risk_score": 30, "risk_breakdown": {"unpinned_deps": 3, "unverified_sources": 0, "unknown_licenses": 1, "stale_models": 1}, "dependencies": [{"name": "urllib3", "issues": ["[KNOWN_VULN] CVE-2019-11324: CRLF injection when retrieving HTTP headers"]}], "models": [{"id": "gpt2", "issues": ["[STALE_MODEL] Model metadata is stale", "[MODEL_VULNERABILITY] Advisory feed match (model_vulnerability_db.json)"]}] }
- HTML report snapshot: open
-
Screenshots:
- HTML report: open
examples/demo/aibom-report.html - Markdown rendering: view
examples/demo/aibom-report.md - Before vs. after: open
docs/screenshots/before-after.html
- HTML report: open
-
Sample models file:
examples/models.sample.json -
Sample Markdown report:
examples/report.sample.md -
Example commands:
- Only dependency scan with autodetection:
aibom scan --format json
- Only dependency scan with autodetection:
-
Include models from a file:
aibom scan --models-file examples/models.sample.json --format markdown --output report.md -
Specify models inline:
aibom scan --online --model-id gpt2 --model-id meta-llama/Llama-3-8B --format html -
Enrich CVEs during the scan:
aibom scan --online --with-cves --format json -
Use local model advisory and hash feeds:
aibom scan --models-file models.json --model-advisory-db feeds/model_vulnerability_db.json --model-hash-db feeds/model_hash_reputation.json -
Apply training source fingerprints:
aibom scan --models-file models.json --training-source-db feeds/training_source_fingerprints.json -
Include non-Python manifests:
aibom scan --manifest package-lock.json --manifest go.mod --format json -
Import an SBOM:
aibom scan --sbom-file path/to/cyclonedx.json --format html --output merged-report.html -
Run fully offline (no OSV/HF calls):
aibom scan --format markdown -
Require inputs or fail fast:
aibom scan --require-input -
Export CycloneDX:
aibom scan --format cyclonedx --sbom-output aibom-cyclonedx.json -
Fail CI if health score < 70:
aibom scan --fail-on-score 70 --format html -
Inspect model weights directly (detect NaNs/LSB steganography):
aibom weights my_model.safetensors --json- Quick comparison of two runs:
aibom diff aibom-report-old.json aibom-report-new.json
- Quick comparison of two runs:
Highest-impact capabilities
See docs/HIGHEST_IMPACT_NEXT_MOVES.md for the capabilities that enable the end-to-end discover → enforce loop, policy-as-code UX, and GitHub-native SARIF outputs.
Enterprise trust baseline
See docs/ENTERPRISE_TRUST_BASELINE.md for the deal-maker controls around provenance/signing, artifact integrity, and dependency trust enforcement that enterprises expect in CI/CD rollouts.
Enterprise control plane
- Enterprise Control Plane: multi-tenant governance, evidence storage, and CI/CD enforcement.
- Enterprise roadmap: central policy server, org audit features, dashboards, and web UI milestones.
- Open-core boundary: commercial vs OSS separation and packaging.
- AI supply chain threat model: sales-ready threat taxonomy and control mapping.
- Deployment reference: SaaS/on-prem parity and isolation model.
- Policy engine deep dive: deterministic enforcement and explainability.
30-second sample report (before vs. after)
- Input SBOM: lightweight CycloneDX with a few Python and npm components plus a Hugging Face model ID.
- Before (messy state):
- Command:
aibom scan --sbom-file examples/demo/aibom-report.json --format markdown --output before.md --fail-on-score 70 - Top findings:
MISSING_PINfor multiple deps,UNKNOWN_LICENSEon the model,STALE_MODEL, demoKNOWN_VULNentry, andUNVERIFIED_SOURCE. - Outcome:
stack_risk_score≈ 50 and exit code 1 because it failed the--fail-on-score 70gate.
- Command:
- After (hardened state):
- Command:
aibom scan --sbom-file examples/demo/aibom-report.json --models-file examples/models.sample.json --format markdown --output after.md --fail-on-score 70 --online --with-cves - Top findings:
CVEhits (if any) plus minor governance nits; pins and licenses quiet down once manifests and model metadata are cleaned up. - Outcome:
stack_risk_scorein the high 80s and exit code 0, making it CI-safe.
- Command:
AI-BOM extensions
CycloneDX and SPDX exports include AI-BOM extension data (e.g., aibom:source, license category, risk score, and issues) alongside the standard SBOM fields. See docs/ai-bom-extensions.md for the JSON schema and how each extension maps into CycloneDX properties and SPDX summaries.
Standards alignment
- AI-BOM schema mapping:
schemas/report.schema.jsontracks the AI-BOM JSON conventions and is structured to align with the TAIBOM-style trust/attestation fields emerging in the community (e.g., explicit model source, license, provenance, and risk signals). - CycloneDX/SPDX bridges: the CycloneDX/SPDX exporters project
aibom:*properties into vendor-neutral fields so the output can slot into existing SBOM pipelines without custom parsers. - Reference-first posture: schema updates aim to follow the AI-BOM working drafts; additions are scoped so teams can diff their SBOMs against the schema and treat this project as a reference implementation rather than a one-off tool.
- Credibility pack:
docs/credibility-pack/ships SBOM slices, a repo list, and a scoreboard you can rerun to validate detection heuristics and false-positive rates.
Output formats at a glance
See docs/OUTPUTS.md for a side-by-side JSON, SARIF, and CycloneDX example plus guidance on when to use each.
Adoption defaults
- Gates to start with: fail CI on
--fail-on-score 70, require allowlisted model sources (--require-inputplus allowlist rules inpolicies/examples/*), and keep--offlineas the default posture. - CI vs. local: run
aibom scan --format json --output aibom-report.json --fail-on-score 70in CI, then publish CycloneDX/SPDX via--format cyclonedxor--format spdxfor downstream compliance jobs. Locally, add--format htmlor--format markdownfor readability and iterate with--diffagainst previous runs. - Policy cookbook: see
docs/POLICY_COOKBOOK.mdfor OSS-friendly, enterprise-strict, and regulated defaults that can be copied into your own policy file (HIPAA, SOC 2, ISO/IEC 42001 packs are inpolicies/examples/).
Configuration tips:
- OSV enrichment uses the public API by default; override with
--osv-urlorOSV_API_URLand adjust the HTTP timeout via--osv-timeoutorOSV_API_TIMEOUT. - Model risk databases can be swapped via
--model-advisory-db,--model-hash-db,--license-risk-db, and--training-source-dbwhen you want to point at internal mirrors or curated feeds.
Heuristics & Risk Signals
AI-BOM Inspector ships with lightweight, explainable checks that map to common AI supply-chain issues:
| Code | What it means | Severity |
|---|---|---|
MISSING_PIN |
Dependency version not pinned with ==/~= |
High |
LOOSE_PIN |
Dependency uses a range (>=, <=, etc.) |
Medium |
UNSTABLE_VERSION |
Pre-1.0 releases that may churn | Medium |
KNOWN_VULN / CVE |
Known vulnerable versions (built-in heuristics + optional OSV lookup; recommends safer versions when known) | High |
LICENSE_RISK |
Copyleft / reciprocal terms detected for a model | Medium |
MODEL_LICENSE_RESTRICTED |
Restricted or custom model license detected (OpenRAIL, research-only, etc.) | Medium |
PROPRIETARY_AI_RISK |
Proprietary model license may limit auditability or reuse | Medium |
UNKNOWN_LICENSE |
Model or SBOM component lacks license metadata | High |
STALE_MODEL |
Model metadata older than ~9 months | Medium |
UNVERIFIED_SOURCE |
Non-standard model source value | Medium |
MODEL_VULNERABILITY |
Model flagged by a vulnerability/advisory feed | High |
MODEL_HASH_MALICIOUS |
Model hash matches a malicious fingerprint | High |
MODEL_WEIGHT_ANOMALY |
Safetensors inspection detected poisoned/steganographic weights | High |
PICKLE_DANGEROUS_GLOBALS |
Pickle checkpoint references dangerous globals | High |
MODEL_LINEAGE_RISK |
Base model lineage contains license or vulnerability risk | Medium |
MODEL_LINEAGE_UNKNOWN |
Base model lineage not present in scan context | Medium |
FINE_TUNE_INHERITANCE_RISK |
Fine-tune inherits high-risk findings from base model | High |
DATASET_CONTAMINATION_RISK |
Training sources suggest contamination or policy exposure | High |
TRAINING_SOURCE_RISK |
Training source requires additional governance review | Medium |
SUPPLY_CHAIN_ANOMALY |
Model hash mismatch or artifact integrity anomaly detected | High |
MODEL_HASH_INVALID |
Declared model hash is not a valid SHA256 fingerprint | Medium |
MODEL_HASH_MISSING |
Model artifacts present without declared hashes | Medium |
OFFLINE_MODE / CVE_LOOKUP_SKIPPED |
Scan ran offline or without network dependencies; no remote enrichment performed | Low |
METADATA_UNAVAILABLE |
Model registry/API could not be reached; metadata reused from cache with a warning | Low |
INVALID_SBOM |
SBOM could not be parsed; flagged as an issue instead of crashing the scan | Medium |
The report shows a stack_risk_score (0–100, higher is healthier) and a risk_breakdown capturing unpinned deps, unverified sources, unknown licenses, stale models, and CVE hits. Tune the scoring with --risk-max-score, per-severity --risk-penalty-* flags, and governance/CVE penalties so teams can calibrate what “red” means for them. Conceptually, this is a health score: penalties are subtracted from the maximum, so --fail-on-score 70 means “fail if health drops below 70/100.”
How the risk score is computed
- Start from
risk_settings.max_score(default 100) and subtract penalties instead of adding danger points. - Every dependency/model issue subtracts
risk_settings.penalty_for(severity)(default high=8, medium=4, low=2). - Governance penalties subtract an extra
governance_penaltyfor each unpinned dependency and unverified model source; CVE hits subtractcve_penaltyto emphasize known exploit paths. - Active exploitation flags override baseline scoring with
active_exploitation_penalty, ensuring live exploitation signals dominate baseline severity math. - The resulting value is clamped between 0–
max_score, giving you a “health score” you can fail CI on via--fail-on-score.
Recommended scoring policy
- Start conservative: gate on
--fail-on-score 70while teams pilot the tool; after triage, ratchet up to 80 once noisy signals are addressed. - Respond by signal type:
MISSING_PIN/LOOSE_PIN: add explicit==pins (or~=if you must) and commit lockfiles.UNKNOWN_LICENSE/LICENSE_RISK: annotate licenses inmodels.jsonand prefer permissive alternatives when available.STALE_MODEL: update to a fresher model release or document a waiver inmodels.json.KNOWN_VULN/CVE: upgrade to the suggested safe version; if blocked, add a comment in your SBOM or pin to a patched fork.UNVERIFIED_SOURCE: source models from trusted registries (Hugging Face, internal artifactory) and record provenance.OFFLINE_MODE/CVE_LOOKUP_SKIPPED: rerun with network access before shipping to ensure enrichment isn’t missing critical advisories.
Assumptions and known limitations
- Offline mode trades fidelity for privacy: metadata/CVE lookups are skipped; issues are marked with
OFFLINE_MODE/CVE_LOOKUP_SKIPPEDso reviewers know enrichment was suppressed. - SBOM trust but verify: malformed SBOMs are surfaced as
INVALID_SBOMissues and ignored otherwise; well-formed CycloneDX/SPDX inputs are merged into the dependency set. - Model metadata freshness depends on registries: network failures are tolerated and recorded as
METADATA_UNAVAILABLE, but license/freshness signals may be stale until the registry is reachable again. - Weight inspection is heuristic: the safetensors scanner samples bits and looks for NaNs/Inf/LSB bias; unusual dtypes or truncated files raise clear errors instead of silently passing.
Threat taxonomy + MITRE ATLAS mapping
AI-BOM Inspector attaches explicit AI threat categories and STRIDE classifications to model findings. Mappings are surfaced in the report framework section and can be tailored via a local taxonomy file:
- Default taxonomy:
src/aibom_inspector/data/ai_threat_taxonomy.json - Override:
aibom scan --threat-taxonomy-db path/to/ai_threat_taxonomy.json - MITRE ATLAS controls appear alongside NIST AI RMF, ISO/IEC 42001, OWASP LLM Top 10, SOC 2, and EU AI Act mappings.
See
docs/THREAT_TAXONOMY.mdfor the default taxonomy and extension guidance.
Model risk databases
Model risk intelligence is local-first. You can ship curated JSON feeds in-repo or pull them from internal mirrors:
- Model vulnerability DB:
model_vulnerability_db.json(use--model-advisory-dbto override) - Model hash reputation DB:
model_hash_reputation.json(use--model-hash-dbto override) - License risk DB:
license_risk_db.json(use--license-risk-dbto override) - Training source fingerprints:
training_source_fingerprints.json(use--training-source-dbto override)
Before vs. after hardening
| Scenario | Risk score | Signals |
|---|---|---|
| Messy AI stack | 48/100 | Unpinned package-lock.json, unknown model license, stale model metadata |
| Hardened AI stack | 88/100 | All deps pinned, permissive licenses, fresh model metadata, no advisories |
Example: scanning a real project
aibom scan --requirements requirements.txt --models-file models.json --with-cves --format html --output report.html \
--risk-penalty-high 10 --risk-penalty-medium 5 --risk-penalty-low 2
Pair it with aibom diff report-old.json report-new.json to highlight PR drift, or run in CI with --fail-on-score 70.
Performance & scale signals
Baseline timings below were captured on the included demo project to give teams a starting point. Re-run in your own CI to capture local baselines:
| Scenario | Command | Result |
|---|---|---|
| Demo project scan | PYTHONPATH=src python -m aibom_inspector.cli scan --requirements examples/demo/requirements.txt --pyproject examples/demo/pyproject.toml --manifest examples/demo/package-lock.json --manifest examples/demo/go.mod --models-file examples/demo/models.json --format json --output /tmp/aibom-report.json |
2.16s real (container, Python 3.10.19) |
Use /usr/bin/time -p or your CI timing metrics to capture project-specific numbers (dependency count, model count, and total runtime).
Testing and CI
- Run unit tests:
pytest - GitHub Action:
.github/workflows/scan-pr.ymluses the bundled composite action to scan PRs and post a risk comment. - One-command SARIF + Markdown upload (offline by default; pair with
--online --with-cveswhen you want CVEs):name: AI-BOM Inspector on: [pull_request] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install AI-BOM Inspector run: pip install aibom-inspector - name: Scan AI stack and emit SARIF + Markdown run: >- aibom scan --format sarif --output aibom-report.sarif --markdown-output aibom-report.md --fail-on-score 75 --require-input - name: Upload SARIF to GitHub Security uses: github/codeql-action/upload-sarif@v3 with: sarif_file: aibom-report.sarif - name: Upload Markdown artifact uses: actions/upload-artifact@v4 with: name: aibom-report path: aibom-report.md
- CI guardrails: keep
--offlineunless you need enrichments; when allowed, add--online --with-cvesto the scan step and adjust allowlists accordingly.
Releases and distribution
- Tagged releases: we cut signed Git tags for CLI milestones; package metadata lives in
pyproject.tomland tracks the changelog. - PyPI: publishing is planned under the
aibom-inspectorname; until then, install from source (pip install -e .[dev]) or lock to a tag tarball. - Versioning: semantic-ish—patch releases for heuristics/docs, minor bumps when report schemas or exit codes change.
Security, governance, and contributions
- See
SECURITY.mdfor how to report vulnerabilities. - See
CODE_OF_CONDUCT.mdfor community standards. - See
CONTRIBUTING.mdfor development conventions and how to propose changes. CHANGELOG.mdtracks notable updates.
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
Built Distribution
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 aibom_inspector-0.1.1.tar.gz.
File metadata
- Download URL: aibom_inspector-0.1.1.tar.gz
- Upload date:
- Size: 103.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
722fbfa9168824674feb320f6b69afa236ae1551ccf19dce0efe418ccdef62e2
|
|
| MD5 |
055be2deda7315a6d6d636be626b8fe3
|
|
| BLAKE2b-256 |
18216472233f672de189cfe1235680a7e6f8aa589699800d2d2e77b103e83f22
|
File details
Details for the file aibom_inspector-0.1.1-py3-none-any.whl.
File metadata
- Download URL: aibom_inspector-0.1.1-py3-none-any.whl
- Upload date:
- Size: 98.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbee38af248e90490f14264a33f6ae2c60c892b71f94f0f942f228d81764a38b
|
|
| MD5 |
731d8a26c4014105e83d62bff583407b
|
|
| BLAKE2b-256 |
3230d9e3fc74e239cba76a0f7bc0208143c4359b731448e59fb979ff37e2e97c
|