@C-B-Elite ,
Would you be able to push out a v2.2.0 with the already merged updates?
I have many projects that still use ic-py, and I would be able to upgrade them after that.
@C-B-Elite ,
Would you be able to push out a v2.2.0 with the already merged updates?
I have many projects that still use ic-py, and I would be able to upgrade them after that.
Hi, I just got back from vacation.
I’m back to work now, and I’m planning to release a new version this week (likely Friday–Saturday), which will include your PR.
By the way, over the next month, I’m also expecting a larger upgrade. The main focus will be updating the current endpoints (v2 is already outdated), which may introduce some underlying code changes. It will also include a few security-related features that were not previously supported.
Thanks for your attention and support!
Does canister http-outcall in pocket-ic support?
At the moment, icp-py-core doesn’t have support for pocket-ic (and there’s no short-term plan to implement it). As far as I remember, pocket-ic is able to simulate \canister HTTP outcalls.
We’re excited to announce the release of icp-py-core v2.1.1, which fixes an important bug in the Candid DID parser that affected Motoko-generated DID files.
The Candid DID parser now correctly handles service definitions that use type references, a pattern commonly generated by Motoko canisters.
Previously broken pattern (now fixed):
type MyService = service {
hello: () -> (text);
};
service : () -> MyService
This pattern is valid Candid syntax and is frequently used in Motoko-generated DID files, but the parser was failing to parse it correctly.
Support for service : () -> TypeName pattern
Support for nested type references
Support for type references with initialization arguments
Comprehensive test coverage added
pip install --upgrade icp-py-core
GitHub Repository: GitHub - eliezhao/icp-py-core: Python Agent Library for the DFINITY Internet Computer
PyPI Package: Client Challenge
Full Changelog: icp-py-core/CHANGELOG.md at master · eliezhao/icp-py-core · GitHub
Thanks to @icppWorld for reporting this issue and providing detailed analysis.
I’m excited to announce the release of ICP-PY-CORE v2.2.1, a significant update that brings structured error handling, HTTP/2 support, and enhanced certificate verification capabilities to the Python SDK for the Internet Computer.
pip install icp-py-core==2.2.1
PyPI: icp-py-core · PyPI
GitHub: GitHub - eliezhao/icp-py-core: Python Agent Library for the DFINITY Internet Computer
v2.2.1 introduces a comprehensive error handling system with 11 specialized error classes, making it easier to handle different types of failures:
from icp_core import (
TransportError, # HTTP/network errors
ReplicaReject, # Canister rejections
SecurityError, # Base for security errors
SignatureVerificationFailed,
CertificateVerificationError,
# ... and more
)
try:
result = agent.update("canister-id", "method", args)
except ReplicaReject as e:
print(f"Rejected: {e.reject_code} - {e.reject_message}")
except TransportError as e:
print(f"Network error: {e.url}")
except SecurityError as e:
print(f"Security issue: {e}")
Benefits:
HTTP/2 is now enabled by default in all async methods, providing:
No code changes required - it’s automatically enabled!
v2.2.1 now uses the latest Boundary Node API endpoints for optimal performance and compatibility:
/api/v3/canister/.../read_state and /api/v3/subnet/.../read_state)/api/v4/canister/.../call) with proper delegation verificationThese updates ensure you’re using the most current and efficient endpoints available on the Internet Computer.
Added support for the v4 API’s sharded canister_ranges structure:
[canister_ranges, subnet_id, shard_label]lookup_tree and list_paths methods for shard navigationread_state operationsClient methods now raise TransportError for network issuesAgent methods raise structured errors (ReplicaReject, SecurityError, etc.)__cause__ attribute preservation/api/v3/canister/.../read_state and /api/v3/subnet/.../read_state)/api/v4/canister/.../call)check_delegation logic for proper delegation verification with v4 endpointsIf you’re currently catching generic Exception, consider catching specific error types:
# Before
try:
result = agent.update("canister-id", "method", args)
except Exception as e:
# Generic handling
pass
# After (recommended)
try:
result = agent.update("canister-id", "method", args)
except ReplicaReject as e:
# Handle canister rejections
handle_rejection(e)
except TransportError as e:
# Handle network issues
handle_network_error(e)
except SecurityError as e:
# Handle security issues
handle_security_error(e)
Error classes are now available from icp_core:
from icp_core import TransportError, ReplicaReject, SecurityError
No code changes required - HTTP/2 is automatically enabled for async methods.
The endpoint updates are transparent - no code changes required. The library automatically uses:
Happy coding with ICP-PY-CORE! ![]()
The Rust extension ic-candid-parser is still at v0.1.0 on PyPI, which predates the fix for the pattern.
Would you be able to push out a new release for that ic-candid-parser package as well?
I issued a bug report too at Bug: VarT service reference fix not published to PyPI · Issue #10 · eliezhao/icp-py-core · GitHub
Thank you!
I’ll check it and update it soon.
I’ve released version v2.2.1, which fixes this issue. Thank you for the feedback — my local environment was affected by the development setup, so I didn’t notice this problem earlier.
@icpp
Everything now works. Thanks for the quick action.
I am pleased to preview the next release of icp-py-core. This update adds configurable timeouts, optional replica-signed query verification, automatic Candid (.did) fetching from canisters, and async-friendly Canister methods.
Release timeline: I expect this update to be released in 1–2 weeks. During this period I will collect feedback and issues for version 2.2.1; any fixes will be included in the next release.
Development of the above features is complete. Further testing is in progress on the feature/verify-replica-query-signature-and-canister-timeout branch.
Query timeout
DEFAULT_QUERY_TIMEOUT_SEC).timeout argument on Agent.query(), Agent.query_async(), and the underlying query endpoint helpers.TimeoutWaitingForResponse exception (with timeout_seconds and optional request_id), so you can handle timeouts consistently.Update (canister call) timeout
DEFAULT_POLL_TIMEOUT_SECS).timeout parameter and TimeoutWaitingForResponse behavior for Agent.update() and Agent.update_async().All timeouts are configurable; when not set, the defaults above apply.
Replica-signed query verification
When the boundary node returns replica-signed query responses (with signatures), you can optionally verify them before trusting the result.
How to use
verify_query_signatures=True when creating the Agent, or pass it per call to Agent.query() / Agent.query_async().False.What is verified
\x0Bic-response + request ID and response fields).QuerySignatureVerificationFailed, MissingSignature, TooManySignatures, plus existing certificate/node-key errors for easier debugging.Auto-fetch Candid (DID)
You no longer need to manually provide a .did file for every canister.
The Canister class can fetch the Candid interface from the Internet Computer when you don’t pass a local definition.
How it works
Canister(agent, canister_id, candid_str=None, auto_fetch_candid=True)
candid_str is provided, it is used as today.candid_str is not provided and auto_fetch_candid=True (default), the client:
candid:service (no controller rights required).candid (requires controller or appropriate permissions).ValueError is raised, asking you to ensure the canister exposes Candid metadata or to pass candid_str (or set auto_fetch_candid=False and provide candid_str later).Backward compatibility
candid_str or setting auto_fetch_candid=False keeps the previous behavior (no fetch, manual DID only).Async variants for every canister method
For each method defined in the canister’s Candid interface, the library now exposes an async variant: <method_name>_async (e.g. get_async, set_async).
Usage
await canister.get_async() (or your method name) instead of calling the sync version inside an async context.Example
examples/simple_counter_example_async.py demonstrates async query and update with the Canister wrapper (e.g. get_async, set_async) and aligns with async usage common in other IC agent libraries.I hope these changes make icp-py-core more robust, secure, and convenient for both sync and async workflows. Feedback and issues are welcome on the repository.
Looking forward to these updates. Especially the auto-pull of did files and the ability to set the timeout are really nice and important ![]()
Hi @C-B-Elite ,
I managed to replace yet another dfx subprocess with an icp-py-core call using the canister interface, but it included a long duration call and the resulting timeout exposed a few bugs.
They’re fixed in this PR: Fix/read state and v4 polling by icppWorld · Pull Request #13 · eliezhao/icp-py-core · GitHub
Let me know how that looks. With these changes, my long duration call is working great.
Thank you for your feedback. Since we updated the endpoint, some issues may have surfaced that were outside my expectations.
It looks like the next release will need to be brought forward. I’m planning to publish a new version this weekend that includes a fix for this bug along with the new features.
I have released icp-py-core v2.3.0 with new features and bug fixes. Upgrade with:
pip install --upgrade icp-py-core
Configurable timeouts
Query and update calls now have configurable timeouts (defaults: 30s for queries, 60s for update polling). On timeout the library raises TimeoutWaitingForResponse.
# Override per call
result = agent.query(canister_id, "method", arg, timeout=10)
result = await agent.query_async(canister_id, "method", arg, timeout=10)
agent.update(canister_id, "method", arg, timeout=90)
Optional query response signature verification
You can verify replica-signed query responses (opt-in, default off). Uses Ed25519 and subnet node public keys (fetched and cached as needed).
agent = Agent(url, verify_query_signatures=True)
# or per call:
agent.query(canister_id, "method", arg, verify_query_signatures=True)
Auto-fetch Candid from canister
The Canister wrapper can fetch the service’s Candid interface from the IC when you don’t provide it (tries public candid:service, then private candid metadata).
canister = Canister(agent, canister_id) # no candid_str needed
canister.some_method(args)
Canister async methods
For each canister method, an async variant is available (e.g. get_async, set_async) with the same types and encoding as the sync methods.
result = await canister.get_async()
await canister.set_async(value)
Candid composite query support
Candid support for composite query is included.
Canister timeout passthrough
Canister high-level methods now pass the timeout argument through to the underlying query/update calls.
Since taking over the maintenance of the Python agent, I have completed all originally planned milestones along with every additional feature introduced afterward.
icp-py-core now delivers a comprehensive set of core functionalities and has resolved all previously identified security vulnerabilities from the ic-py audit.
Moving forward, maintenance will focus on staying aligned with the latest Internet Computer features, keeping endpoints up to date, optimizing performance, and addressing issues raised by the developer community.
Thank you for using icp-py-core — I remain committed to actively maintaining and improving this repository.
Thank you for getting icp-py-core in good shape. Things are working great and this package is critical for a lot of the things we do.
FYI, icp-py-core is an important enabler to make this application possible & secure.
It is python cli that has a locally managed wallet that can now verify the certificates of signed messages using the capabilities of icp-py-core.
Hey @C-B-Elite, can you look at this issue and fix it? We ran into the problem recently when using ic-py-core for preview deployments:
Thanks for opening this issue. I also ran into it.