bitcoinrpc


Namebitcoinrpc JSON
Version 0.7.0 PyPI version JSON
download
home_pagehttps://github.com/bibajz/bitcoin-python-async-rpc
SummaryLightweight Bitcoin JSON-RPC Python asynchronous client
upload_time2024-02-11 23:31:49
maintainer
docs_urlNone
authorLibor Martinek
requires_python>=3.7
licenseMIT
keywords bitcoin async json-rpc
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # bitcoin-python-async-rpc
Lightweight Bitcoin async JSON-RPC Python client.

Serves as a tiny layer between an application and a Bitcoin daemon, its primary usage
is querying the current state of Bitcoin blockchain, network stats, transactions...

If you want complete Bitcoin experience in Python, consult
[python-bitcoinlib](https://github.com/petertodd/python-bitcoinlib).

## Installation
```bash
$ pip install bitcoinrpc
```

## Supported methods
Here is a list of supported methods, divided by their categories. Should you need
method not implemented, wrap the call in `BitcoinRPC.acall(<your_method>, ...)` coroutine.

### Blockchain

|   Method   |   Supported?     |
|------------|:----------------:|
| `getbestblockhash` | ✔ |
| `getblock` | ✔ |
| `getblockchaininfo` | ✔ |
| `getblockcount` | ✔ |
| `getblockhash` | ✔ |
| `getblockheader` | ✔ |
| `getblockstats` | ✔ |
| `getchaintips` | ✔ |
| `getdifficulty` | ✔ |
| `getmempoolinfo` | ✔ |
| `getnetworkhashps` | ✔ |

### Mining

|   Method   |   Supported?     |
|------------|:----------------:|
| `getmininginfo` | ✔ |

### Network

|   Method   |   Supported?     |
|------------|:----------------:|
| `getconnectioncount` | ✔ |
| `getnetworkinfo` | ✔ |

### Raw transactions

|   Method   |   Supported?     |
|------------|:----------------:|
| `analyzepsbt` | ✔ |
| `combinepsbt` | ✔ |
| `decodepsbt` | ✔ |
| `finalizepsbt` | ✔ |
| `getrawtransaction` | ✔ |
| `joinpsbts` | ✔ |
| `utxoupdatepsbt` | ✔ |

### Wallet

|   Method   |   Supported?     |
|------------|:----------------:|
| `walletprocesspsbt` | ✔ |

## Usage
Minimal illustration (assuming Python 3.8+, where you can run `async` code in console)

```
$ python -m asyncio
>>> import asyncio
>>>
>>> from bitcoinrpc import BitcoinRPC
>>> rpc = BitcoinRPC.from_config("http://localhost:18443", ("rpc_user", "rpc_passwd"))
>>> await rpc.getconnectioncount()
10
>>> await rpc.aclose()  # Clean-up resource
```

You can also use the `BitcoinRPC` as an asynchronous context manager, which does
all the resource clean-up automatically, as the following example shows:

```python
$ cat btc_rpc_minimal.py
import asyncio

from bitcoinrpc import BitcoinRPC


async def main():
    async with BitcoinRPC.from_config("http://localhost:18443", ("rpc_user", "rpc_password")) as rpc:
        print(await rpc.getconnectioncount())


if __name__ == "__main__":
    asyncio.run(main())
```

Running this script yields:
```
$ python btc_rpc_minimal.py
10
```

If you want customize the underlying `httpx.AsyncClient`, you can instantiate the `BitcoinRPC` with one.
Consider the following script, where the client is configured to log every HTTP request before it is sent
out over the wire:

```python
$ cat btc_custom_client.py
import asyncio

import httpx

from bitcoinrpc import BitcoinRPC


async def log_request(request: httpx.Request) -> None:
    print(request.content)


async def main() -> None:
    client = httpx.AsyncClient(auth=("rpc_user", "rpc_password"), event_hooks={"request": [log_request]})
    async with BitcoinRPC(url="http://localhost:18443", client=client) as rpc:
        print(await rpc.getconnectioncount())


if __name__ == "__main__":
    asyncio.run(main())
```

Running this script yields:

```
$ python btc_custom_client.py 
b'{"jsonrpc":"2.0","id":1,"method":"getconnectioncount","params":[]}'
0
```

## Testing

A `Containerfile` is provided as a means to build an OCI image of a Bitcoin `regtest` node.
Build the image (`podman` is used, but `docker` should be fine too):

```
$ podman build \
  -f Containerfile \
  --build-arg BTC_VERSION=v24.1 \
  -t bitcoin-regtest:v24.1 \
  -t bitcoin-regtest:latest \
  .
```

and run it afterwards:

```
$ podman run \
  --rm \
  -it \
  --mount=type=bind,src=./tests/bitcoin-regtest.conf,target=/home/rpc/.bitcoin/bitcoin.conf \
  -p 127.0.0.1:18443:18443 \
  --name bitcoin-regtest \
  localhost/bitcoin-regtest:v24.1
```

which will expose the Bitcoin `regtest` node on port 18443, accesible from localhost only, with RPC user/password `rpc_user/rpc_password`.

After you are done testing, stop the container via:

```
$ podman stop bitcoin-regtest
```

---

If you want to test against a different version of Bitcoin node, pass a different [tag](https://github.com/bitcoin/bitcoin/tags) in the build stage:

```
$ podman build \
  -f Containerfile \
  --build-arg BTC_VERSION=v25.0 \
  -t bitcoin-regtest:v25.0 \
  -t bitcoin-regtest:latest \
  .
```

---

Different settings of the Bitcoin node may be passed via mounting your custom configuration file, or optionally as "arguments" to `podman run`:


```
$ podman run \
  --rm \
  -it \
  --mount=type=bind,src=<path/to/your/config_file>,target=/home/rpc/.bitcoin/bitcoin.conf \
  -p 127.0.0.1:18443:18443 \
  --name bitcoin-regtest \
  localhost/bitcoin-regtest:v24.1 <your> <args> ...
```

---

Please, keep in mind that Bitcoin node compiled in the image is intended for testing & debugging purposes only! It may serve you as an inspiration for building
your own, production-ready Bitcoin node, but its intended usage is testing!

---

For testing this library, install `tox` (preferably, in a fresh virtual environment).

Afterwards, coding-style is enforced by running:

```
(your-venv-with-tox) $ tox run -e linters
```

and tests corresponding are run (this example uses Python3.11)

```
(your-venv-with-tox) $ tox run -e py311
```

If you do not want to run tests marked as `"integration"`, which denote those requiring the bitcoin regtest node to run, you can filter them out by:

```
(your-venv-with-tox) $ tox run -e py311 -- -m 'not integration'
```


## Changelog

- **2024/02/12 - 0.7.0**: More robust handling of JSON-RPC 2.0 specification (thanks https://github.com/joxerx !)
  * **Breaking change**: change the handling of responses with non-2xx status codes in 'BitcoinRPC.acall'.
    Previously, said errors would be raised directly via the `httpx.Response.raise_for_status` method.
    Now, `httpx.Response.raise_for_status` is used only when the server
    returns an empty response, which may happen due to for example bad
    authentication. In all other cases, defer the decision whether RPC
    call was a success or a failure to the inspection of return JSON.
- **2023/06/04 - 0.6.1**: Add RPC methods, mainly concerned with PSBTs
- **2023/06/01 - 0.6.0**:
  * `BitcoinRPC` is now instantiated with a `httpx.AsyncClient` directly and an optional `counter` argument, which is a callable that may be used for distinguishing
    the JSON-RPC requests. Old-style instantiation, with `url` and optional user/password tuple, is kept within `BitcoinRPC.from_config` method.

- **2021/12/28 - 0.5.0** change the signature of `BitcoinRPC` from `host, port, ...` to `url, ...`, delegating the creation of the node url to the caller.

## License
MIT

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/bibajz/bitcoin-python-async-rpc",
    "name": "bitcoinrpc",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "bitcoin async json-rpc",
    "author": "Libor Martinek",
    "author_email": "libasmartinek@protonmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cb/88/25548ce0099c1425fd01b607b3adf2a9705bd4dc127024854d748a34f9b3/bitcoinrpc-0.7.0.tar.gz",
    "platform": null,
    "description": "# bitcoin-python-async-rpc\nLightweight Bitcoin async JSON-RPC Python client.\n\nServes as a tiny layer between an application and a Bitcoin daemon, its primary usage\nis querying the current state of Bitcoin blockchain, network stats, transactions...\n\nIf you want complete Bitcoin experience in Python, consult\n[python-bitcoinlib](https://github.com/petertodd/python-bitcoinlib).\n\n## Installation\n```bash\n$ pip install bitcoinrpc\n```\n\n## Supported methods\nHere is a list of supported methods, divided by their categories. Should you need\nmethod not implemented, wrap the call in `BitcoinRPC.acall(<your_method>, ...)` coroutine.\n\n### Blockchain\n\n|   Method   |   Supported?     |\n|------------|:----------------:|\n| `getbestblockhash` | \u2714 |\n| `getblock` | \u2714 |\n| `getblockchaininfo` | \u2714 |\n| `getblockcount` | \u2714 |\n| `getblockhash` | \u2714 |\n| `getblockheader` | \u2714 |\n| `getblockstats` | \u2714 |\n| `getchaintips` | \u2714 |\n| `getdifficulty` | \u2714 |\n| `getmempoolinfo` | \u2714 |\n| `getnetworkhashps` | \u2714 |\n\n### Mining\n\n|   Method   |   Supported?     |\n|------------|:----------------:|\n| `getmininginfo` | \u2714 |\n\n### Network\n\n|   Method   |   Supported?     |\n|------------|:----------------:|\n| `getconnectioncount` | \u2714 |\n| `getnetworkinfo` | \u2714 |\n\n### Raw transactions\n\n|   Method   |   Supported?     |\n|------------|:----------------:|\n| `analyzepsbt` | \u2714 |\n| `combinepsbt` | \u2714 |\n| `decodepsbt` | \u2714 |\n| `finalizepsbt` | \u2714 |\n| `getrawtransaction` | \u2714 |\n| `joinpsbts` | \u2714 |\n| `utxoupdatepsbt` | \u2714 |\n\n### Wallet\n\n|   Method   |   Supported?     |\n|------------|:----------------:|\n| `walletprocesspsbt` | \u2714 |\n\n## Usage\nMinimal illustration (assuming Python 3.8+, where you can run `async` code in console)\n\n```\n$ python -m asyncio\n>>> import asyncio\n>>>\n>>> from bitcoinrpc import BitcoinRPC\n>>> rpc = BitcoinRPC.from_config(\"http://localhost:18443\", (\"rpc_user\", \"rpc_passwd\"))\n>>> await rpc.getconnectioncount()\n10\n>>> await rpc.aclose()  # Clean-up resource\n```\n\nYou can also use the `BitcoinRPC` as an asynchronous context manager, which does\nall the resource clean-up automatically, as the following example shows:\n\n```python\n$ cat btc_rpc_minimal.py\nimport asyncio\n\nfrom bitcoinrpc import BitcoinRPC\n\n\nasync def main():\n    async with BitcoinRPC.from_config(\"http://localhost:18443\", (\"rpc_user\", \"rpc_password\")) as rpc:\n        print(await rpc.getconnectioncount())\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\nRunning this script yields:\n```\n$ python btc_rpc_minimal.py\n10\n```\n\nIf you want customize the underlying `httpx.AsyncClient`, you can instantiate the `BitcoinRPC` with one.\nConsider the following script, where the client is configured to log every HTTP request before it is sent\nout over the wire:\n\n```python\n$ cat btc_custom_client.py\nimport asyncio\n\nimport httpx\n\nfrom bitcoinrpc import BitcoinRPC\n\n\nasync def log_request(request: httpx.Request) -> None:\n    print(request.content)\n\n\nasync def main() -> None:\n    client = httpx.AsyncClient(auth=(\"rpc_user\", \"rpc_password\"), event_hooks={\"request\": [log_request]})\n    async with BitcoinRPC(url=\"http://localhost:18443\", client=client) as rpc:\n        print(await rpc.getconnectioncount())\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\nRunning this script yields:\n\n```\n$ python btc_custom_client.py \nb'{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getconnectioncount\",\"params\":[]}'\n0\n```\n\n## Testing\n\nA `Containerfile` is provided as a means to build an OCI image of a Bitcoin `regtest` node.\nBuild the image (`podman` is used, but `docker` should be fine too):\n\n```\n$ podman build \\\n  -f Containerfile \\\n  --build-arg BTC_VERSION=v24.1 \\\n  -t bitcoin-regtest:v24.1 \\\n  -t bitcoin-regtest:latest \\\n  .\n```\n\nand run it afterwards:\n\n```\n$ podman run \\\n  --rm \\\n  -it \\\n  --mount=type=bind,src=./tests/bitcoin-regtest.conf,target=/home/rpc/.bitcoin/bitcoin.conf \\\n  -p 127.0.0.1:18443:18443 \\\n  --name bitcoin-regtest \\\n  localhost/bitcoin-regtest:v24.1\n```\n\nwhich will expose the Bitcoin `regtest` node on port 18443, accesible from localhost only, with RPC user/password `rpc_user/rpc_password`.\n\nAfter you are done testing, stop the container via:\n\n```\n$ podman stop bitcoin-regtest\n```\n\n---\n\nIf you want to test against a different version of Bitcoin node, pass a different [tag](https://github.com/bitcoin/bitcoin/tags) in the build stage:\n\n```\n$ podman build \\\n  -f Containerfile \\\n  --build-arg BTC_VERSION=v25.0 \\\n  -t bitcoin-regtest:v25.0 \\\n  -t bitcoin-regtest:latest \\\n  .\n```\n\n---\n\nDifferent settings of the Bitcoin node may be passed via mounting your custom configuration file, or optionally as \"arguments\" to `podman run`:\n\n\n```\n$ podman run \\\n  --rm \\\n  -it \\\n  --mount=type=bind,src=<path/to/your/config_file>,target=/home/rpc/.bitcoin/bitcoin.conf \\\n  -p 127.0.0.1:18443:18443 \\\n  --name bitcoin-regtest \\\n  localhost/bitcoin-regtest:v24.1 <your> <args> ...\n```\n\n---\n\nPlease, keep in mind that Bitcoin node compiled in the image is intended for testing & debugging purposes only! It may serve you as an inspiration for building\nyour own, production-ready Bitcoin node, but its intended usage is testing!\n\n---\n\nFor testing this library, install `tox` (preferably, in a fresh virtual environment).\n\nAfterwards, coding-style is enforced by running:\n\n```\n(your-venv-with-tox) $ tox run -e linters\n```\n\nand tests corresponding are run (this example uses Python3.11)\n\n```\n(your-venv-with-tox) $ tox run -e py311\n```\n\nIf you do not want to run tests marked as `\"integration\"`, which denote those requiring the bitcoin regtest node to run, you can filter them out by:\n\n```\n(your-venv-with-tox) $ tox run -e py311 -- -m 'not integration'\n```\n\n\n## Changelog\n\n- **2024/02/12 - 0.7.0**: More robust handling of JSON-RPC 2.0 specification (thanks https://github.com/joxerx !)\n  * **Breaking change**: change the handling of responses with non-2xx status codes in 'BitcoinRPC.acall'.\n    Previously, said errors would be raised directly via the `httpx.Response.raise_for_status` method.\n    Now, `httpx.Response.raise_for_status` is used only when the server\n    returns an empty response, which may happen due to for example bad\n    authentication. In all other cases, defer the decision whether RPC\n    call was a success or a failure to the inspection of return JSON.\n- **2023/06/04 - 0.6.1**: Add RPC methods, mainly concerned with PSBTs\n- **2023/06/01 - 0.6.0**:\n  * `BitcoinRPC` is now instantiated with a `httpx.AsyncClient` directly and an optional `counter` argument, which is a callable that may be used for distinguishing\n    the JSON-RPC requests. Old-style instantiation, with `url` and optional user/password tuple, is kept within `BitcoinRPC.from_config` method.\n\n- **2021/12/28 - 0.5.0** change the signature of `BitcoinRPC` from `host, port, ...` to `url, ...`, delegating the creation of the node url to the caller.\n\n## License\nMIT\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Lightweight Bitcoin JSON-RPC Python asynchronous client",
    "version": "0.7.0",
    "project_urls": {
        "Homepage": "https://github.com/bibajz/bitcoin-python-async-rpc"
    },
    "split_keywords": [
        "bitcoin",
        "async",
        "json-rpc"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "19500172bc2f4e1fc147d21c21daf30fccdc25a12c88504e34daad2ac885746d",
                "md5": "83863d840177b37ed5397f58ac59acc5",
                "sha256": "69629756e33f9cd27c85bb2834b80f9d55536eee6373894b13e05480665a9dd8"
            },
            "downloads": -1,
            "filename": "bitcoinrpc-0.7.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "83863d840177b37ed5397f58ac59acc5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 11490,
            "upload_time": "2024-02-11T23:31:47",
            "upload_time_iso_8601": "2024-02-11T23:31:47.338264Z",
            "url": "https://files.pythonhosted.org/packages/19/50/0172bc2f4e1fc147d21c21daf30fccdc25a12c88504e34daad2ac885746d/bitcoinrpc-0.7.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cb8825548ce0099c1425fd01b607b3adf2a9705bd4dc127024854d748a34f9b3",
                "md5": "fb51677fc339a572a0d5923c92590b67",
                "sha256": "9c166adfb167f31d78470523869a8b2aea619d32e2fa71dcd5f83296c5f63c53"
            },
            "downloads": -1,
            "filename": "bitcoinrpc-0.7.0.tar.gz",
            "has_sig": false,
            "md5_digest": "fb51677fc339a572a0d5923c92590b67",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 14515,
            "upload_time": "2024-02-11T23:31:49",
            "upload_time_iso_8601": "2024-02-11T23:31:49.242569Z",
            "url": "https://files.pythonhosted.org/packages/cb/88/25548ce0099c1425fd01b607b3adf2a9705bd4dc127024854d748a34f9b3/bitcoinrpc-0.7.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-11 23:31:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "bibajz",
    "github_project": "bitcoin-python-async-rpc",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "tox": true,
    "lcname": "bitcoinrpc"
}
        
Elapsed time: 0.17962s