Skip to main content

An ICP Python Canister Development Kit for the Internet Computer

Project description

Basilisk

PyPI Local Tests IC Tests

An ICP Python Canister Development Kit and Application Framework. Write decentralized applications in Python efficiently on the Internet Computer.

Live demo: https://ic-basilisk.tech/.

Features

  • Based on CPython 3.13, compiled to WASM — deploy in seconds with a pre-built template, no Rust toolchain needed
  • Near-complete standard libraryos, json, re, math, datetime, hashlib, collections, networking stubs, and more. A few modules requiring native OS threads or sockets (e.g. threading, subprocess, socket) are not available

Built-in Application Framework:

  • Persistent storage — Rust-backed stable data structures (StableBTreeMap, StableBTreeSet, StableVec, StableLog, StableCell, StableMinHeap) powered by ic-stable-structures with tagged binary encoding — data persists across canister upgrades with no serialization step. Supports explicit type hints (nat8, int32, etc.) for compact, correctly-ordered keys and values
  • Filesystem — standard open() and os calls, automatically persisted to stable memory across upgrades
  • IC system APIsic.caller(), ic.time(), ic.canister_balance(), inter-canister calls, timers, and Candid types (Principal, Record, Variant, etc.)

Interactive shell, ORM, Schema Upgrade Checking, file transfer, task management, wallet, and more are provided by ic-basilisk-toolkit (pip install ic-basilisk-toolkit).

┌─────────────────────────────────────────────────────────┐
│                    Basilisk CDK                         │
├─────────────┬────────────┬──────────────────────────────┤
│ Filesystem  │ Storage    │ IC System APIs               │
│ POSIX-like  │ BTreeMap,  │ Timers, Inter-canister calls │
│ os/open()   │ Vec, Log,  │ Candid types, Lifecycle      │
│ auto-persist│ Cell, Heap │                              │
├─────────────┴────────────┴──────────────────────────────┤
│        MemoryManager (ic-stable-structures)             │
├─────────────────────────────────────────────────────────┤
│           CPython 3.13 (compiled to WASM)               │
├─────────────────────────────────────────────────────────┤
│              Internet Computer (ICP)                    │
└─────────────────────────────────────────────────────────┘

Quick Start

Prerequisites

  • dfx (IC SDK)
  • Python 3.10+

Install

pip install ic-basilisk

Create and deploy

# 1. Scaffold a new project
basilisk new my_project
cd my_project

# 2. Start the local replica and deploy
dfx start --background
dfx deploy

# 3. Call your canister
dfx canister call my_project greet '("World")'
# ("Hello, World! The counter is at 0.")

Built-in AI/Agent Endpoints

Basilisk can auto-inject standardized __shell__ and __browse__ endpoints into your canister at build time. Enable them with a single line:

__basilisk_features__ = ["shell", "browse"]

__shell__ — full Python execution (controller-only @update):

dfx canister call my_canister __shell__ '("print(1 + 1)")'
# ("2\n")

__browse__ — read-only data introspection (public @query, instant, free):

# Discover data schema
dfx canister call my_canister __browse__ '("{\"action\": \"schema\"}")'

# Read keys from a stable map (paginated, default limit=100)
dfx canister call my_canister __browse__ '("{\"action\": \"keys\", \"map\": \"users\"}")'

# Get a specific value
dfx canister call my_canister __browse__ '("{\"action\": \"get\", \"map\": \"users\", \"key\": \"alice\"}")'

Both endpoints can be overridden with custom implementations (e.g. custom guards, filtered data access). If you define __shell__ or __browse__ yourself, the compiler uses yours instead of the default.

CPython vs RustPython

CPython 3.13 RustPython
Build time ~seconds (template) ~60-120s (Cargo build)
Wasm size ~5.3 MB ~26 MB
Python compatibility Full (reference implementation) Partial (~3.10)

Cross-Language Benchmark

Pure-compute benchmarks comparing Rust, Motoko, and CPython on identical algorithms. Measured via ic0.performance_counter on a PocketIC replica. On the IC, 1 instruction ≈ 1 cycle of compute cost. Lower is better. These numbers exclude the fixed per-call fee (~590K cycles for updates, ~260K for queries) and memory/storage costs.

Benchmark Rust Motoko CPython vs Rust (CPython)
noop (call overhead) 13,686 3,299 15,592 1.1x
increment (state mutation) 12,827 3,411 15,159 1.2x
fibonacci(25) (iterative) 12,750 5,713 36,553 2.9x
fibonacci_recursive(20) 373,953 2,050,048 29,617,193 79.2x
sum_to(10000) (arithmetic loop) 272,761 513,314 12,767,523 46.8x
ackermann(3,6) (deep recursion) 3,285,678 15,225,081 284,158,839 86.5x
method_overhead (total prelude) 12,334 2,863 10,172 0.8x

Full CI logs: All backends

Python-Specific Benchmark (CPython vs RustPython)

These benchmarks use language-specific data structures (Python dict, list, str) so they only compare CPython against RustPython — not against Rust/Motoko, which have fundamentally different standard libraries.

Benchmark CPython RustPython RustPython / CPython
string_ops (100 concatenations) 275,375 2,135,202 7.8x
list_ops (500 append + sort) 602,711 5,819,267 9.7x
dict_ops (500 inserts + lookups) 3,407,101 23,087,720 6.8x

CPython is 6–10x faster than RustPython across the board, with the gap largest for recursive function calls and list operations.

Run it yourself: trigger the Benchmark workflow from the Actions tab — select cpython, rust, motoko, or all as the backend, and local or ic as the network.

The benchmark sources are in benchmarks/counter/ (CPython), benchmarks/counter_rust/ (Rust), and benchmarks/counter_motoko/ (Motoko).

Projects Using Basilisk

  • Realms — Governance Operating System for building and deploying governance systems on the Internet Computer

Using Basilisk? Open a PR to add your project here.

Why "Basilisk"?

Basilisk fountain in Basel, Switzerland
A basilisk fountain in Basel, Switzerland — where this project was written.

This project was written in Basel, Switzerland — a city guarded by basilisks since the Middle Ages. In European mythology, the basilisk is the king of serpents — part rooster, part snake — making it a fitting patron for a Python framework.

According to local legend, a basilisk once dwelt beneath Basel's streets, turning to stone anyone who dared look upon it. The citizens, unable to defeat it by force, outwitted the creature with a mirror: confronted with its own reflection, the basilisk was petrified by its own gaze. Impressed by the creature's power, the people of Basel didn't destroy it — they adopted it. To this day, basilisk statues stand watch over the city's fountains, their water said to carry a faint enchantment of protection.

In the shadow of the Tower of the Bank for International Settlements — where the world's central banks convene to shape global finance — a basilisk fountain stands watch. It is here, at the crossroads of ancient myth and modern power, that we chose to unleash the dormant power of Python onto the Internet Computer.

The fountains still flow in Basel. And now, so does Python on the IC. Great power requires great responsibility. Handle with care.

Disclaimer

Basilisk may have unknown security vulnerabilities due to the following:

  • Limited or no production deployments on the IC
  • No extensive automated property tests
  • No independent security reviews/audits

Security

See SECURITY.md.

Documentation

For detailed architecture notes, see CPYTHON_MIGRATION_NOTES.md.

Discussion

Feel free to open issues.

License

See LICENSE.

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

ic_basilisk-0.13.2.tar.gz (335.1 kB view details)

Uploaded Source

Built Distribution

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

ic_basilisk-0.13.2-py3-none-any.whl (345.7 kB view details)

Uploaded Python 3

File details

Details for the file ic_basilisk-0.13.2.tar.gz.

File metadata

  • Download URL: ic_basilisk-0.13.2.tar.gz
  • Upload date:
  • Size: 335.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for ic_basilisk-0.13.2.tar.gz
Algorithm Hash digest
SHA256 b38ee3f6206fbaa8e48069eec25c2eea3c69480b33f08eaf9f4383b5d54aa94e
MD5 aa7c16e3064be68bb45182c4b26778ce
BLAKE2b-256 f2bfddf918cbc545115ca90f18af1281a977119061b779588106f479cf81bb97

See more details on using hashes here.

File details

Details for the file ic_basilisk-0.13.2-py3-none-any.whl.

File metadata

  • Download URL: ic_basilisk-0.13.2-py3-none-any.whl
  • Upload date:
  • Size: 345.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for ic_basilisk-0.13.2-py3-none-any.whl
Algorithm Hash digest
SHA256 bd2fe9552a701e48736ab08f11b7cc19ee644f3b09c6d46b47fedeffad8debfa
MD5 a3deb8eb9688e5d272ad0916028ccd89
BLAKE2b-256 1503dcb389a2eac931c3e2f57f6266c113e0a90d78de2b48aaba21f698b313a6

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