Search code examples
pythoncurlpython-requestsrpcbitcoin

How do I allow for passage of function parameters into a cURL request using requests in Python


I'm trying to convert bitcoin RPC calls into functions to use in python, some of the RPC API calls have parameters such as the block height for the command getblockhash.

I have a function that works and returns the genesis block by passing [0] in the params keyword:

def getblockhash():
    headers = {
        'content-type': 'text/plain;',
    }
    data = '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockhash", "params": [0]}'
    response = requests.post('http://127.0.0.1:8332/', headers=headers, data=data,
                             auth=(USERNAME, PASSWORD))
    response = response.json()
    return response

I get this response:

{'result': '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f', 'error': None, 'id': 'curltest'}

I want to be able to pass a variable into this spot instead of hardcoding it such as:

def getblockhash(height):
    headers = {
        'content-type': 'text/plain;',
    }
    data = {"jsonrpc": "1.0", "id":"curltest", "method": "getblockhash", "params": [height]}
    data = str(data)
    response = requests.post('http://127.0.0.1:8332/', headers=headers, data=data,
                             auth=(USERNAME, PASSWORD))
    response = response.json()
    return response

I get this result:

"{'result': None, 'error': {'code': -32700, 'message': 'Parse error'}, 'id': None}"

I've tried testing various things and found that the error shows up when adding

data = str(data)

So how can I pass a function parameter into this without getting the parsing error?


Solution

  • You are directly posting the string representation of a dictionary to the server. However, the string representation of a dictionary is not valid JSON. Example:

    >>> example = {"hello": "world"}
    >>> str(example)
    "{'hello': 'world'}"
    

    Note that the key and value in the string representation are encapsulated by single quotes. However, JSON requires strings to be encapsulated by double quotes.

    Possible solutions are: use the json kwarg instead of data to let requests convert the dictionary to valid JSON, manually convert the dictionary to JSON data using the json module, or (as jordanm suggests in their comment) use a JSON-RPC module.