async-substrate-interface


Nameasync-substrate-interface JSON
Version 1.5.5 PyPI version JSON
download
home_pageNone
SummaryAsyncio library for interacting with substrate. Mostly API-compatible with py-substrate-interface
upload_time2025-10-06 18:36:33
maintainerLatent Holdings
docs_urlNone
authorOpentensor Foundation
requires_python<3.14,>=3.9
licenseMIT License Copyright (c) 2025 Opentensor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords substrate development bittensor
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Async Substrate Interface
This project provides an asynchronous interface for interacting with [Substrate](https://substrate.io/)-based blockchains. It is based on the [py-substrate-interface](https://github.com/polkascan/py-substrate-interface) project.

Additionally, this project uses [bt-decode](https://github.com/opentensor/bt-decode) instead of [py-scale-codec](https://github.com/polkascan/py-scale-codec) for faster [SCALE](https://docs.substrate.io/reference/scale-codec/) decoding.

## Installation

To install the package, use the following command:

```bash
pip install async-substrate-interface
```

## Usage

Here are examples of how to use the sync and async inferfaces:

```python
from async_substrate_interface import SubstrateInterface

def main():
    substrate = SubstrateInterface(
        url="wss://rpc.polkadot.io"
    )
    with substrate:
        result = substrate.query(
            module='System',
            storage_function='Account',
            params=['5CZs3T15Ky4jch1sUpSFwkUbYEnsCfe1WCY51fH3SPV6NFnf']
        )

        print(result)

main()
```

```python
import asyncio
from async_substrate_interface import AsyncSubstrateInterface

async def main():
    substrate = AsyncSubstrateInterface(
        url="wss://rpc.polkadot.io"
    )
    async with substrate:
        result = await substrate.query(
            module='System',
            storage_function='Account',
            params=['5CZs3T15Ky4jch1sUpSFwkUbYEnsCfe1WCY51fH3SPV6NFnf']
        )

        print(result)

asyncio.run(main())
```

### Caching
There are a few different cache types used in this library to improve the performance overall. The one with which
you are probably familiar is the typical `functools.lru_cache` used in `sync_substrate.SubstrateInterface`.

By default, it uses a max cache size of 512 for smaller returns, and 16 for larger ones. These cache sizes are 
user-configurable using the respective env vars, `SUBSTRATE_CACHE_METHOD_SIZE` and `SUBSTRATE_RUNTIME_CACHE_SIZE`.

They are applied only on methods whose results cannot change — such as the block hash for a given block number 
(small, 512 default), or the runtime for a given runtime version (large, 16 default).

Additionally, in `AsyncSubstrateInterface`, because of its asynchronous nature, we developed our own asyncio-friendly 
LRU caches. The primary one is the `CachedFetcher` which wraps the same methods as `functools.lru_cache` does in 
`SubstrateInterface`, but the key difference here is that each request is assigned a future that is returned when the 
initial request completes. So, if you were to do:

```python
bn = 5000
bh1, bh2 = await asyncio.gather(
    asi.get_block_hash(bn),
    asi.get_block_hash(bn)
)
```
it would actually only make one single network call, and return the result to both requests. Like `SubstrateInterface`,
it also takes the `SUBSTRATE_CACHE_METHOD_SIZE` and `SUBSTRATE_RUNTIME_CACHE_SIZE` vars to set cache size.

The third and final caching mechanism we use is `async_substrate_interface.async_substrate.DiskCachedAsyncSubstrateInterface`,
which functions the same as the normal `AsyncSubstrateInterface`, but that also saves this cache to the disk, so the cache
is preserved between runs. This is product for a fairly nice use-case (such as `btcli`). As you may call different networks
with entirely different results, this cache is keyed by the uri supplied at instantiation of the `DiskCachedAsyncSubstrateInterface`
object, so `DiskCachedAsyncSubstrateInterface(network_1)` and `DiskCachedAsyncSubstrateInterface(network_2)` will not share
the same on-disk cache.

As with the other two caches, this also takes `SUBSTRATE_CACHE_METHOD_SIZE` and `SUBSTRATE_RUNTIME_CACHE_SIZE` env vars.


### ENV VARS
The following environment variables are used within async-substrate-interface
 - NO_CACHE (default 0): if set to 1, when using the DiskCachedAsyncSubstrateInterface class, no persistent on-disk cache will be stored, instead using only in-memory cache.
 - CACHE_LOCATION (default `~/.cache/async-substrate-interface`): this determines the location for the cache file, if using DiskCachedAsyncSubstrateInterface
 - SUBSTRATE_CACHE_METHOD_SIZE (default 512): the cache size (either in-memory or on-disk) of the smaller return-size methods (see the Caching section for more info)
 - SUBSTRATE_RUNTIME_CACHE_SIZE (default 16): the cache size (either in-memory or on-disk) of the larger return-size methods (see the Caching section for more info)


## Contributing

Contributions are welcome! Please open an issue or submit a pull request to the `staging` branch.

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Contact

For any questions or inquiries, please join the Bittensor Development Discord server: [Church of Rao](https://discord.gg/XC7ucQmq2Q).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "async-substrate-interface",
    "maintainer": "Latent Holdings",
    "docs_url": null,
    "requires_python": "<3.14,>=3.9",
    "maintainer_email": "BD Himes <b@latent.to>",
    "keywords": "substrate, development, bittensor",
    "author": "Opentensor Foundation",
    "author_email": "BD Himes <b@latent.to>",
    "download_url": "https://files.pythonhosted.org/packages/88/05/869c05493ae0c19058e69921504fa46b5f1fe433863c34f262bc8c71d886/async_substrate_interface-1.5.5.tar.gz",
    "platform": null,
    "description": "# Async Substrate Interface\nThis project provides an asynchronous interface for interacting with [Substrate](https://substrate.io/)-based blockchains. It is based on the [py-substrate-interface](https://github.com/polkascan/py-substrate-interface) project.\n\nAdditionally, this project uses [bt-decode](https://github.com/opentensor/bt-decode) instead of [py-scale-codec](https://github.com/polkascan/py-scale-codec) for faster [SCALE](https://docs.substrate.io/reference/scale-codec/) decoding.\n\n## Installation\n\nTo install the package, use the following command:\n\n```bash\npip install async-substrate-interface\n```\n\n## Usage\n\nHere are examples of how to use the sync and async inferfaces:\n\n```python\nfrom async_substrate_interface import SubstrateInterface\n\ndef main():\n    substrate = SubstrateInterface(\n        url=\"wss://rpc.polkadot.io\"\n    )\n    with substrate:\n        result = substrate.query(\n            module='System',\n            storage_function='Account',\n            params=['5CZs3T15Ky4jch1sUpSFwkUbYEnsCfe1WCY51fH3SPV6NFnf']\n        )\n\n        print(result)\n\nmain()\n```\n\n```python\nimport asyncio\nfrom async_substrate_interface import AsyncSubstrateInterface\n\nasync def main():\n    substrate = AsyncSubstrateInterface(\n        url=\"wss://rpc.polkadot.io\"\n    )\n    async with substrate:\n        result = await substrate.query(\n            module='System',\n            storage_function='Account',\n            params=['5CZs3T15Ky4jch1sUpSFwkUbYEnsCfe1WCY51fH3SPV6NFnf']\n        )\n\n        print(result)\n\nasyncio.run(main())\n```\n\n### Caching\nThere are a few different cache types used in this library to improve the performance overall. The one with which\nyou are probably familiar is the typical `functools.lru_cache` used in `sync_substrate.SubstrateInterface`.\n\nBy default, it uses a max cache size of 512 for smaller returns, and 16 for larger ones. These cache sizes are \nuser-configurable using the respective env vars, `SUBSTRATE_CACHE_METHOD_SIZE` and `SUBSTRATE_RUNTIME_CACHE_SIZE`.\n\nThey are applied only on methods whose results cannot change \u2014 such as the block hash for a given block number \n(small, 512 default), or the runtime for a given runtime version (large, 16 default).\n\nAdditionally, in `AsyncSubstrateInterface`, because of its asynchronous nature, we developed our own asyncio-friendly \nLRU caches. The primary one is the `CachedFetcher` which wraps the same methods as `functools.lru_cache` does in \n`SubstrateInterface`, but the key difference here is that each request is assigned a future that is returned when the \ninitial request completes. So, if you were to do:\n\n```python\nbn = 5000\nbh1, bh2 = await asyncio.gather(\n    asi.get_block_hash(bn),\n    asi.get_block_hash(bn)\n)\n```\nit would actually only make one single network call, and return the result to both requests. Like `SubstrateInterface`,\nit also takes the `SUBSTRATE_CACHE_METHOD_SIZE` and `SUBSTRATE_RUNTIME_CACHE_SIZE` vars to set cache size.\n\nThe third and final caching mechanism we use is `async_substrate_interface.async_substrate.DiskCachedAsyncSubstrateInterface`,\nwhich functions the same as the normal `AsyncSubstrateInterface`, but that also saves this cache to the disk, so the cache\nis preserved between runs. This is product for a fairly nice use-case (such as `btcli`). As you may call different networks\nwith entirely different results, this cache is keyed by the uri supplied at instantiation of the `DiskCachedAsyncSubstrateInterface`\nobject, so `DiskCachedAsyncSubstrateInterface(network_1)` and `DiskCachedAsyncSubstrateInterface(network_2)` will not share\nthe same on-disk cache.\n\nAs with the other two caches, this also takes `SUBSTRATE_CACHE_METHOD_SIZE` and `SUBSTRATE_RUNTIME_CACHE_SIZE` env vars.\n\n\n### ENV VARS\nThe following environment variables are used within async-substrate-interface\n - NO_CACHE (default 0): if set to 1, when using the DiskCachedAsyncSubstrateInterface class, no persistent on-disk cache will be stored, instead using only in-memory cache.\n - CACHE_LOCATION (default `~/.cache/async-substrate-interface`): this determines the location for the cache file, if using DiskCachedAsyncSubstrateInterface\n - SUBSTRATE_CACHE_METHOD_SIZE (default 512): the cache size (either in-memory or on-disk) of the smaller return-size methods (see the Caching section for more info)\n - SUBSTRATE_RUNTIME_CACHE_SIZE (default 16): the cache size (either in-memory or on-disk) of the larger return-size methods (see the Caching section for more info)\n\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request to the `staging` branch.\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n## Contact\n\nFor any questions or inquiries, please join the Bittensor Development Discord server: [Church of Rao](https://discord.gg/XC7ucQmq2Q).\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2025 Opentensor\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.\n        ",
    "summary": "Asyncio library for interacting with substrate. Mostly API-compatible with py-substrate-interface",
    "version": "1.5.5",
    "project_urls": {
        "Repository": "https://github.com/opentensor/async-substrate-interface/"
    },
    "split_keywords": [
        "substrate",
        " development",
        " bittensor"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0c017c4359b2f95f30c121a04e3cc9cd8b0b6e2dddb2ce7067aa03ff33b3ec8a",
                "md5": "48e45d1836797ca68374d888caf41ead",
                "sha256": "13fb3d928706dc350df4b45207b642798386b3455f86d62a11f42f3c122cb790"
            },
            "downloads": -1,
            "filename": "async_substrate_interface-1.5.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "48e45d1836797ca68374d888caf41ead",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<3.14,>=3.9",
            "size": 85172,
            "upload_time": "2025-10-06T18:36:31",
            "upload_time_iso_8601": "2025-10-06T18:36:31.932316Z",
            "url": "https://files.pythonhosted.org/packages/0c/01/7c4359b2f95f30c121a04e3cc9cd8b0b6e2dddb2ce7067aa03ff33b3ec8a/async_substrate_interface-1.5.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8805869c05493ae0c19058e69921504fa46b5f1fe433863c34f262bc8c71d886",
                "md5": "adab8bbba5ca499b0bb7384da443d8b2",
                "sha256": "c0faa8d143244c4e9d1bf25bb15d886390e4cd4ad1d70762108602fb259d65e3"
            },
            "downloads": -1,
            "filename": "async_substrate_interface-1.5.5.tar.gz",
            "has_sig": false,
            "md5_digest": "adab8bbba5ca499b0bb7384da443d8b2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<3.14,>=3.9",
            "size": 81866,
            "upload_time": "2025-10-06T18:36:33",
            "upload_time_iso_8601": "2025-10-06T18:36:33.632068Z",
            "url": "https://files.pythonhosted.org/packages/88/05/869c05493ae0c19058e69921504fa46b5f1fe433863c34f262bc8c71d886/async_substrate_interface-1.5.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-06 18:36:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "opentensor",
    "github_project": "async-substrate-interface",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "async-substrate-interface"
}
        
Elapsed time: 1.57386s