Skip to main content

Run JavaScript with full browser APIs in Python, powered by V8

Project description

iv8 — Run JavaScript with a Full Browser Environment in Python

PyPI Python Platform GitHub

iv8 is a high-performance Python native extension built on the V8 engine. It implements browser APIs at the C++ level, providing highly controllable, high-fidelity BOM/DOM/CSSOM emulation with built-in API call chain monitoring and Chrome DevTools remote debugging. Run JavaScript that depends on a web environment directly in Python — no browser required.

Suitable for browser environment emulation, automated script execution, security research, JS engine testing, and more.

This repository is the Community Edition of iv8, offering a fully functional baseline browser environment emulation that covers the vast majority of everyday use cases.

iv8 also offers a Pro Edition, which adds a CSS layout engine (cascade, inheritance, box model layout), CSS animation and transition drivers, a protocol stack built by deep-trimming Chromium's network module (not a Cronet wrapper), multi-context Worker parallel execution, enhanced API semantic/timing/boundary alignment (covering more spec edge cases), and deep algorithmic optimizations for computation performance and memory footprint. The Community Edition continues to evolve, and mature Pro features will progressively be backported.

The Python–V8 interop layer draws on the design of STPyV8, with optimized design and implementation.


Key Highlights

Feature Description
C++ Native Browser APIs Pure C++ implementation of BOM / DOM / CSSOM / Events / Crypto / Canvas / WebGL and more, covering 70+ HTML elements, 25+ CSS rule types, 80+ event types
Streaming HTML Parser page.load aligns with browser navigation flow: HTML parsing → <script> pause & execute → stylesheet processing → DOMContentLoaded / load event dispatch
Programmable Event Loop Micro/macro-task tiered scheduling (aligned with HTML spec); sleep(5000) completes instantly in logical time mode
Browser Fingerprint Config Ships with Chrome/Windows default fingerprint (200+ fields); selectively override via environment, JS-side behavior matches real browsers
Multi-thread Parallelism Each Context owns a V8 Isolate; GIL released during execution; ~4.7x speedup measured with 8 threads
DevTools Remote Debugging Breakpoints, API access breakpoints, Elements / Application panels; built-in anti-debug protection (debugger; disabled)
API Monitoring Debug mode auto-records browser API access chains and JS built-in reflection paths to locate environment probing logic
Trusted Input Events Dispatches isTrusted=true mouse / pointer events (click / mousedown / pointerdown, etc.)
Function Disguise & Hook wrapNative disguises as [native code]; hookNative intercepts in-place at C++ layer, function identity unchanged

Architecture Overview

iv8 free System-level Runtime Model

Python enters the C++ Bridge through JSContext, each Context owns a dedicated v8::Isolate enabling true parallelism across multiple Python threads; within the isolate, the window scope and per-document runtime are mounted, with core capabilities including the page.load loading flow, event loop and time control, offline resource model, and trusted input; monitoring and debugging form an optional debug plane, activated only in debug / with_devtools() mode.

Quick Start

pip install iv8

Supports Python 3.8 – 3.14, Windows (x64), and Linux (x64). The Linux build is compiled to the manylinux standard and runs on CentOS, Ubuntu, Debian, Fedora, and other mainstream distributions.

import iv8

with iv8.JSContext() as ctx:
    # Execute JavaScript
    print(ctx.eval("1 + 2"))  # 3

    # Browser APIs work out of the box
    print(ctx.eval("navigator.userAgent"))   # Mozilla/5.0 ...
    print(ctx.eval("navigator.webdriver"))   # False

    # Load an HTML page (streaming parse + script execution + event dispatch)
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body><div id="app">Hello</div></body></html>'
        });
    """)
    print(ctx.eval("document.getElementById('app').textContent"))  # "Hello"

Performance Characteristics

The following data was measured on Intel Core i7-14700 / Windows 10 / Python 3.11; results may vary on different hardware.

Dimension Metric Data
Speed JSContext create + eval + destroy ~3.3 ms / call
Simple eval throughput (1+1) ~950,000 ops/s
Browser API calls (navigator / DOM / crypto) 340,000 – 570,000 ops/s
Real webpage DOM parse (Wikipedia JavaScript article, ~440 KB) ~7 ms / page (incl. Context create+destroy ~11.5 ms, serial ~86 pages/s)
Memory First load (import iv8 + 1st Context) +15 MB
Per-round peak increment (batch loop) ~9 MB
100-round long-run cumulative drift +2 MB
Multi-thread Speedup (2 / 4 / 8 threads) 1.86x / 3.26x / 4.71x

Memory figures are iv8 marginal increments (excluding the Python interpreter itself). Multi-thread test uses compute-intensive JS (200K sin/cos loop iterations); real-world scenarios (executing hundreds of KB of obfuscated JS) typically show better speedup. For GIL release mechanism, Context creation overhead, and page.load vs innerHTML guidance, see the Best Practices section below.


Browser API Compatibility

iv8 provides an extensive browser API emulation layer on top of the V8 engine, covering the following web standards (some are interface-level stubs):

Category Coverage
DOM & HTML Document, Element, Node inheritance chain, 70+ HTML element interfaces, ShadowRoot, MutationObserver, Range, Custom Elements, etc.
SVG SVGElement inheritance chain with 50+ SVG element interfaces, SVGAnimated* series
CSS & CSSOM CSSStyleSheet, 25+ CSSRule subclasses, CSSStyleDeclaration, CSS Typed OM (CSSUnitValue / CSSMath*), Highlight API
Event System EventTarget / Event inheritance chain, 80+ event types (UI / Mouse / Pointer / Keyboard / Touch / Drag / Clipboard / Animation, etc.)
Window & Navigator Window, Location, History, Navigator, Screen, Performance API, Navigation API
Network XMLHttpRequest, Fetch API (Request / Response / Headers), Streams, WebSocket, WebTransport, Beacon. XHR / fetch responses injected via add_resource, giving users full control over real request details (proxy / TLS fingerprint / cookie pool)
Encoding & File TextEncoder / Decoder, Blob, File, FileReader, URL / URLSearchParams, File System Access
Storage localStorage, sessionStorage, CookieStore, IndexedDB, Storage Buckets
Crypto crypto.getRandomValues, SubtleCrypto (AES-GCM / AES-CBC / RSA-OAEP / RSA-PSS / ECDH / ECDSA / HMAC / HKDF / PBKDF2 / digest algorithms, etc.)
Canvas & Graphics Canvas 2D, WebGL / WebGL2 (30+ extensions, parameters from environment.webgl.*), WebGPU, OffscreenCanvas
Media HTMLMediaElement, Web Audio API (20+ AudioNode subclasses), MediaStream, WebRTC, WebCodecs
Timers & Scheduling setTimeout / setInterval / requestAnimationFrame / requestIdleCallback, Scheduler API
Web Animations Animation, KeyframeEffect, DocumentTimeline, ScrollTimeline, ViewTimeline
Geometry DOMPoint, DOMRect, DOMQuad, DOMMatrix and ReadOnly variants
Performance PerformanceTiming, PerformanceResourceTiming, PerformanceObserver, MemoryInfo, etc.
Permissions & Security Permissions API, Credential Management, Trusted Types, CSP
Device APIs Clipboard, Notification, Geolocation, DeviceOrientation, Sensor API, BatteryManager
Communication MessagePort, Web MIDI, Presentation API
Workers Worker / SharedWorker / ServiceWorker / Worklet

Feature Details

1. JavaScript Execution & Type Conversion

Built on the modern V8 engine with full ES6+ syntax support (class, modules, Promise, async/await, optional chaining, private fields, top-level await, etc.). Return values are automatically converted to Python types.

with iv8.JSContext() as ctx:
    # Primitive types auto-convert
    print(ctx.eval("42"))                    # int: 42
    print(ctx.eval("'hello'"))               # str: "hello"
    print(ctx.eval("[1, 2, 3]"))             # list: [1, 2, 3]

    # to_py=True recursively converts complex nested objects
    data = ctx.eval("({name: 'test', items: [1,2,3]})", to_py=True)
    print(data['items'])  # [1, 2, 3]

    # Full ES6+ support
    ctx.eval("""
        const { name, scores } = { name: 'Alice', scores: [90, 85, 92] };
        var avg = scores.reduce((a, b) => a + b, 0) / scores.length;
    """)
    print(ctx.eval("avg"))  # 89

2. Browser Environment & Fingerprint Configuration

iv8 ships with a complete Chrome desktop / Windows baseline fingerprint (200+ fields) — ready to use without passing environment. Use the environment dict to selectively override fingerprint fields; unspecified fields retain their defaults. The exposed browser version is determined by navigator.userAgent / navigator.userAgentData fields, freely overridable by users — built-in defaults serve only as out-of-the-box fallbacks and do not constitute a commitment to a specific Chrome version.

with iv8.JSContext(environment={
    "navigator": {
        "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
        "platform": "Win32",
        "language": "zh-CN",
        "languages": ["zh-CN", "en-US"],
        "hardwareConcurrency": 8,
        "deviceMemory": 8,
    },
    "screen": {
        "width": 1920, "height": 1080, "colorDepth": 24,
    },
    "location": {
        "href": "https://example.com/page",
    },
    "webgl": {
        "vendor": "Google Inc. (NVIDIA)",
        "renderer": "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060)",
    },
}) as ctx:
    print(ctx.eval("navigator.userAgent"))
    print(ctx.eval("navigator.hardwareConcurrency"))  # 8
    print(ctx.eval("screen.width"))                    # 1920

View all configurable fields: get_defaults() returns all supported paths and their default values, making it easy to discover the full override surface:

for path, value in sorted(iv8.JSContext.get_defaults().items()):
    print(f"{path} = {value!r}")
# navigator.userAgent = 'Mozilla/5.0 ...'
# screen.width = 1920
# window.devicePixelRatio = 1.0
# ...

3. DOM Manipulation & Page Loading

Full DOM engine with HTML streaming parse, element creation, and node manipulation.

Two ways to load HTML:

  • page.load(snapshot) — Streaming load aligned with key browser navigation stages: parse HTML by chunk, pause on <script> for execution (including external resources from the bundle), process <style> and <link> stylesheets, dispatch DOMContentLoaded / load events, sync document.URL / location.href. Best for scenarios requiring script execution, lifecycle events, or simulating a real page load.

  • document.documentElement.innerHTML — Direct assignment that only builds the DOM tree — no script execution, no event dispatch, no URL synchronization. Lower overhead, ideal for simple scenarios where only the DOM structure is needed (e.g., parsing HTML, extracting data).

page.load(snapshot) parameters:

Field Type Required Description
baseURL string Yes Page URL, synced to document.URL and location.href
html string Yes HTML source
resources Object No External resource mapping (URL → content); <script src> / <link href> in HTML and runtime XHR / fetch all match against this
headers Object/Array No Main document response headers (CSP, Set-Cookie, etc.)

resources format: Keyed by URL; values support shorthand and full format:

resources: {
    // Shorthand: value is the content string directly
    'https://example.com/lib.js': 'var LIB = true;',

    // Full format: specify HTTP status, response headers, body
    'https://example.com/app.js': {
        body: 'var APP = true;',
        status: 200,
        headers: [['content-type', 'application/javascript']],
    }
}
with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><head><script src="/app.js"></script></head><body></body></html>',
            resources: {
                'https://example.com/app.js': { body: 'window.APP_LOADED = true;' }
            }
        });
    """)
    print(ctx.eval("window.APP_LOADED"))  # True

4. Event Loop & Timer Control

Implements micro-task / macro-task two-phase scheduling (aligned with HTML spec event loop), with macro-tasks prioritized by level and fine-grained time control APIs.

  • Macro-tasks: setTimeout, setInterval, requestAnimationFrame, XHR/fetch callbacks, etc.
  • Micro-tasks: Promise.then/catch/finally, queueMicrotask, MutationObserver callbacks, etc.
with iv8.JSContext(time_mode="logical") as ctx:
    ctx.eval("""
        var log = [];
        setTimeout(() => log.push('macro-100'), 100);
        setTimeout(() => log.push('macro-200'), 200);
        Promise.resolve().then(() => log.push('micro'));
        queueMicrotask(() => log.push('micro-2'));
    """)

    ctx.eval("window.__iv8__.eventLoop.advance(250)")
    print(ctx.eval("log"))
    # ['micro', 'micro-2', 'macro-100', 'macro-200']

Event loop control methods:

Method Description
advance(total, step?) Advance virtual time frame-by-frame (default step ~16.67ms), simulating rAF rhythm
sleep(ms?, max?) Advance virtual time by ms milliseconds, draining the task queue in chronological order
tick(ms?) Advance ms milliseconds and run one event loop iteration
drain(max?) Drain all due tasks without advancing time
drainMicrotasks() Drain only the micro-task queue
drainTimers() Process only due timer callbacks
setAutoAdvanceStep(ms) Set the auto-increment step for performance.now() (default 0.001ms)
setDateAdvanceStep(ms) Set the auto-increment step for Date.now() (default 1ms)

Time modes:

Mode Description Use Case
logical (default) Pure logical advancement; sleep(5000) completes instantly Automation, fast execution
system Anchored to system time; Date.now() reflects real elapsed time during JS execution Time-sensitive scenarios (PoW, time-delta checks)

5. Network Request Interception

add_resource() and the resources parameter of page.load write into the same offline resource bundle. During HTML parsing, <script src> / <link href> / CSS @import, as well as runtime XHR / fetch, all match against this bundle. netLog automatically records all XHR / fetch / navigation requests initiated from the JS side, enabling analysis of the target JS network behavior.

with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body></body></html>'
        });
    """)

    # XHR requests are automatically captured by netLog
    ctx.eval("""
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.example.com/data', false);
        xhr.send();
    """)
    print(ctx.eval("xhr.status"))  # 200

    entries = ctx.eval("window.__iv8__.netLog.entries", to_py=True)
    for entry in entries:
        print(f"  {entry.get('method', '')} {entry.get('url', '')}")

Collaborating with real HTTP requests: iv8's network APIs do not send HTTP requests directly; instead they match responses from the offline bundle. This design gives users full control over the network layer (proxy, TLS fingerprint, cookie pool, etc., are all determined by the user's HTTP client). Typical workflow: JS initiates request → pause event loop → Python sends real HTTP request → inject response → resume event loop.

import requests

with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body></body></html>'
        });
    """)

    # JS initiates an async XHR
    ctx.eval("""
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.example.com/data');
        xhr.onload = function() { window._result = xhr.responseText; };
        xhr.send();
    """)

    # Python sends the real request and injects the response into the offline bundle
    resp = requests.get("https://api.example.com/data")
    ctx.add_resource(
        url="https://api.example.com/data",
        body=resp.text,
        status=resp.status_code,
        headers=dict(resp.headers),
    )

    # Resume the event loop — the XHR callback will match the just-injected resource
    ctx.eval("window.__iv8__.eventLoop.drain()")
    print(ctx.eval("window._result"))

6. Monitoring & Debugging

Runtime modes:

Mode Description
prod (default) Zero monitoring overhead, suitable for production use
debug Enables API call chain tracing, reflection interceptor monitoring, and DevTools debugging

API monitoring in debug mode: Automatically records all monitored browser API property reads/writes, method calls, and constructor calls (high-frequency built-in types like Math / JSON / Array / typed arrays are silenced by default to reduce noise; adjustable via ignore_apis). Also instruments JS built-in reflection paths (Object.keys / getOwnPropertyDescriptor / defineProperty, Reflect.ownKeys / get / has, Function.prototype.toString, JSON.parse / stringify, etc.), recording the target JS environment probing chain.

DevTools debugging: Built-in Chrome DevTools Protocol (CDP) support.

Anti-debug Protection & Replacement Tools:

  • debugger;vdebugger;: iv8 disables native debugger; statements (they won't trigger breakpoints) because target JS commonly exploits infinite debugger loops for anti-debugging. Use vdebugger; instead — its behavior is identical to standard debugger.
  • consolevconsole: Some anti-scraping JS detects the debugging environment through behavioral differences in the console API. After setting enable_console=False to disable standard console DevTools reporting, use vconsole.log() / vconsole.warn() etc. as replacements. vconsole output appears only in the DevTools Console panel and is completely invisible to target JS.
# Basic debugging
with iv8.JSContext(mode='debug').with_devtools(port=9229) as ctx:
    ctx.eval("vdebugger;")  # Pauses in Chrome DevTools

# API access breakpoints + covert debug channel
with iv8.JSContext(mode='debug').with_devtools(
    port=9229,
    watch_apis=["navigator.userAgent", "document.cookie", "canvas.toDataURL"],
    enable_console=False,
) as ctx:
    ctx.eval("let ua = navigator.userAgent;")  # Triggers breakpoint
    ctx.eval("vconsole.log('debug info', ua);")  # Only visible in DevTools

Supported DevTools features: Breakpoint debugging (vdebugger;), API access breakpoints (watch_apis), event listener breakpoints, XHR/Fetch URL breakpoints, DOM element structure inspection (Elements panel), Cookie / Storage inspection and editing (Application panel), step-through execution, variable inspection and modification.

7. Input Event Simulation

Dispatches trusted mouse / pointer events with isTrusted=true; capture → target → bubble chain and isTrusted semantics aligned with Chrome.

with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body><button id="btn">Click</button></body></html>'
        });

        var clicked = false;
        document.getElementById('btn').addEventListener('click', e => {
            clicked = e.isTrusted;  // true
        });

        window.__iv8__.input.dispatchMouseEvent({
            type: 'click',
            target: document.getElementById('btn'),
            clientX: 50, clientY: 25,
            button: 0, buttons: 0
        });
    """)
    print(ctx.eval("clicked"))  # True

8. Function Disguise & Hooking

with iv8.JSContext() as ctx:
    ctx.eval("""
        var myFunc = window.__iv8__.wrapNative(function(x) { return x * 2; }, 'myFunc');
    """)
    print(ctx.eval("myFunc.toString()"))     # "function myFunc() { [native code] }"
    print(ctx.eval("myFunc(21)"))            # 42

    # hookNative — Intercept API property access at the C++ layer in-place
    ctx.eval("window.__iv8__.hookNative('Window.window', function() { return this; })")

9. Python ↔ JS Interop

expose() exposes Python objects to the __iv8__.data namespace in JS, without polluting the window global scope. When JS calls an exposed Python function, the GIL is automatically acquired (blocking the current V8 execution and other Python threads), so exposed functions should be kept lightweight.

import requests

with iv8.JSContext() as ctx:
    # Method 1: Named expose
    ctx.expose(requests.get, "httpGet")
    # JS: __iv8__.data.httpGet("https://...")

    # Method 2: Auto-named (uses the function's __name__ attribute)
    def fetch_data(url):
        return requests.get(url).text
    ctx.expose(fetch_data)
    # JS: __iv8__.data.fetch_data("https://...")

    # Method 3: Keyword argument batch expose
    ctx.expose(get=requests.get, post=requests.post)
    # JS: __iv8__.data.get(...), __iv8__.data.post(...)

    # Expose non-function data (dicts, lists, etc.)
    ctx.expose({"token": "abc123", "debug": True}, "config")
    result = ctx.eval("__iv8__.data.config.token")  # "abc123"

Python API Reference

iv8.JSContext

Main entry class. Creates an independent V8 context with browser APIs.

Constructor parameters:

Parameter Type Default Description
mode str "prod" "prod" production mode / "debug" debug mode
environment dict None Browser fingerprint configuration (navigator / screen / location / webgl, etc.)
config dict None Framework behavior configuration (timezone, permissions.*, etc.; full paths via get_defaults())
ignore_apis list Built-in default APIs to exclude from monitoring logs
time_mode str "logical" "logical" logical time / "system" system time
js_api str "__iv8__" JS-side utility object mount name

Methods:

Method Description
eval(source, name="", line=-1, col=-1, to_py=False, devtools=True) Execute JS code; return value auto-converts to Python types
close(gc="none") Release the context. gc can be "low_memory" (or "v8" / True) / "aggressive" to trigger GC
add_resource(url, body, status=200, headers=None) Inject an offline HTTP response
with_devtools(port=9229, watch_apis=None, enable_console=True) Enable DevTools debugging
expose(obj, name?) / expose(**kwargs) Expose Python objects to the __iv8__.data namespace
get_defaults() Get all supported environment/config paths and their default values

Context manager usage (recommended):

with iv8.JSContext() as ctx:
    ctx.eval("...")
# Resources automatically released

JS-side Utility Object

When a context is created, iv8 mounts a utility object window.__iv8__ on the global scope (customizable via the js_api parameter). This object is designed to be "undetectable" (typeof window.__iv8__ === "undefined") and does not affect target JS behavior.

Utility Description
__iv8__.eventLoop.* Event loop control (advance / sleep / tick / drain, etc.)
__iv8__.page.load(snapshot) Stream-load an HTML document
__iv8__.input.dispatchMouseEvent(init) Dispatch trusted mouse events (isTrusted=true)
__iv8__.input.dispatchPointerEvent(init) Dispatch trusted pointer events
__iv8__.netLog.entries Captured network request log array
__iv8__.wrapNative(fn, name) Disguise a JS function as a native function
__iv8__.hookNative(api, hook) In-place hook an existing API
__iv8__.help() Print all available utilities and descriptions

Best Practices

GIL & Multi-threading

iv8 releases the Python GIL during V8 JavaScript execution, allowing multiple threads to truly execute JS code in parallel. When V8 calls back into Python (e.g., a function exposed via expose() is invoked by JS), the GIL is automatically reacquired.

Python eval() → Release GIL → V8 executes → (JS calls Python → Acquire GIL → Execute → Release GIL) → V8 returns → Acquire GIL → Return to Python

Each JSContext owns an independent V8 Isolate — no additional locking required for multi-threaded use:

import threading

def run_js(thread_id, environment):
    with iv8.JSContext(environment=environment) as ctx:
        ua = ctx.eval("navigator.userAgent")
        print(f"Thread {thread_id}: {ua}")

threads = []
for i in range(4):
    t = threading.Thread(target=run_js, args=(i, {
        "navigator": {"userAgent": f"ThreadBot/{i}"}
    }))
    threads.append(t)
    t.start()
for t in threads:
    t.join()

Since the GIL is released during V8 execution, multi-threading achieves near-multiprocess parallelism while avoiding the overhead of inter-process communication and memory copying. For scenarios requiring simultaneous execution of multiple JS environments (e.g., concurrently running scripts from different sites), prefer multi-threading.

Context Creation Overhead

JSContext creation (including an independent V8 Isolate + browser API surface) and destruction are lightweight — approximately 3ms per cycle (~300 ctx/s) in practice. There is no need to aggressively reuse contexts. Creating a fresh JSContext each time provides a clean environment state, avoiding side-effect contamination from previous executions.

page.load vs innerHTML

Approach Overhead Use Case
page.load(snapshot) Higher: streaming parse + script execution + event dispatch When full page lifecycle is needed (script execution, event triggering)
innerHTML = html Lower: builds DOM tree only When only DOM structure is needed (parsing HTML, extracting data)

If the target JS does not depend on DOMContentLoaded / load events or external script execution, using innerHTML assignment can significantly reduce overhead.


License

The iv8 Community Edition is distributed as pre-compiled binaries and is not open source.

  • Free for personal, educational, and non-commercial use
  • Reverse-engineering, decompilation, and disassembly are prohibited
  • Commercial use (integration into commercial products or services) requires a commercial license (Pro Edition)
  • Unauthorized redistribution is prohibited

See the LICENSE file for details.

Disclaimer

This project is intended solely for learning, research, security testing, and lawful automation purposes. Users must comply with the terms of service and robots policies of target websites, as well as all applicable laws and regulations. The author assumes no responsibility for any misuse.

For more real-world usage examples, see the examples/ directory.

Acknowledgments

  • STPyV8 — Design reference for the Python–V8 interop layer

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

iv8-0.1.2-cp314-cp314-win_amd64.whl (53.3 MB view details)

Uploaded CPython 3.14Windows x86-64

iv8-0.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (73.9 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

iv8-0.1.2-cp313-cp313-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.13Windows x86-64

iv8-0.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (73.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

iv8-0.1.2-cp312-cp312-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.12Windows x86-64

iv8-0.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (73.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

iv8-0.1.2-cp311-cp311-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.11Windows x86-64

iv8-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (74.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

iv8-0.1.2-cp310-cp310-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.10Windows x86-64

iv8-0.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (74.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

iv8-0.1.2-cp39-cp39-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.9Windows x86-64

iv8-0.1.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (74.0 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

iv8-0.1.2-cp38-cp38-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.8Windows x86-64

iv8-0.1.2-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (74.0 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64

File details

Details for the file iv8-0.1.2-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 53.3 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 0c4da3285ee1a0f78181305efc4f140332203f9b4eaba5ec191213aafa953545
MD5 af0a4e9b43119c16d3a0afe22bdf5703
BLAKE2b-256 0a63b987ed4695b7c4b339da9809643cb0baa2114cbc67c1ca63ec7c9e6ae4bc

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 ab5c9357e20ab7f2ad03f010afadb652859c2e888086a3fd3f2c6cd7a696bb66
MD5 2ffcd926f36a36841f5f458882d87b7d
BLAKE2b-256 e282447cb0d7a16d20aad54b902089c64ca44481c535df199a022912faa3fb2f

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 233e74f4b90aa3307bd1115cb6694076acca3e1e8a1fad5b6f77447986906426
MD5 2e379d13ee3d7c9e214c8ccef11598f6
BLAKE2b-256 92eb6b81ad1e2299c5f329d76c3ef034461868a02789f3cfac756fb225002ea9

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 de0fed9fc671a531794958a04aa5f7bc3764fc80e1c31515b186d02e96c330ad
MD5 2f470a6171b946a8097d19effb159929
BLAKE2b-256 2565f90c722f1f428c53573922a768318a9316e8f3a3cdb4fb31c64c13911d21

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 afccdf43112473b3589a63f750166464c3c835fe5923c2c97475b049c01898b5
MD5 14fded77fb44d5b2d774059ff68beafd
BLAKE2b-256 bffb996cca9ab0f49e30dac5e6a9cbdddc5b6aff99f3d60028a82ab6dd9d0135

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 643614577121f9be14569e4a9baa055ece16aa261e67c2a7fc72d5c781770d20
MD5 da52a575542ea197710147b99e2843f7
BLAKE2b-256 6a3a0455f137a25c0b69d33301c1db426a1eca321798e3a12e4a23178168eef0

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 fe03b2b1850cab38886e85aeaadbb61b127f2018dec9bc1b2d72eb79bf520cb1
MD5 579b182e9457b42e42cdd3225d49bdec
BLAKE2b-256 1496d2ade90caa93ce70fcf5d2391eb3cc1a4215ceb8140dd7d8963c8ff3abbc

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 239fa18bedaf961d5ad312792e53394b425c58d82135eb0892cf60dbb54beb13
MD5 5dbfd2e5e173fb806abcea08a43ba862
BLAKE2b-256 de29b8e6c3121b48e8c58692089af2d57836cd5c23e716b32e6df71d0194a693

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 accecebad77429e97f1a64335508e2eff304f90a3b819186e7c5054eef7e9ad9
MD5 ae63b3c1adb03a6fd67e8dc99d5cdf62
BLAKE2b-256 e475ab05ccf5cf26a6209933d77ce4ffb47581f45cd2772dacea52422861eee1

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 0f4c4eea7ea1629acb43d3356d5eb9182c1066155449d6823685c7f38b8a6f36
MD5 2ec48e64f4cfc1c70dfd018aeef7f1ec
BLAKE2b-256 75c554313cc79081519b4fb683f2664cb893a1b8b8f715562b3fe061f748416d

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 704fe82ccdbccd1dfbe272b1b14c24d68a33df772d33e1857f2287d50e86ae01
MD5 af6fb39dcbb901e93012fa1efb82c5a2
BLAKE2b-256 99163a82b7d5fa01fea39f448d4ff89cfd8b023b6123990abaac51534c5c09d4

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 ff182172ae20a86e074e880884e89d00a86325901c5bd84ca70d560a3c104e3d
MD5 db10a4dca47c4d5537d89d4caadd6e51
BLAKE2b-256 d7d23e1bb781772b3d96cae5064187d729c6ba047c372755a2021391b79ef7bc

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.2-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.2-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 f21802fca9a992bd97b5d06a6a7af95c042d99d1afa53c01d8b89b3fc283a402
MD5 df3d1fbbd4222c471e8dd42e72c391ba
BLAKE2b-256 bdc6cddb9cc3d18de5eb1f6bddd150a9fbafdc4e41eb842121bd612fc4b0ac8a

See more details on using hashes here.

File details

Details for the file iv8-0.1.2-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.2-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 b883e1899ca844f56eb6300d6bbdd05fdf1e239843a8805e1ab2102b6c2e2a79
MD5 057027522e3d2b3564642a419a92c101
BLAKE2b-256 329cad0168a1a9328a4be4042a655d2fe3682ed8318dbc627c25b04387ebb4cb

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