发布到API时无效的JSON对象 - Python

时间:2015-10-08 21:50:31

标签: python json api

我使用Blockchain.info's API发送多笔付款。我相信我拥有应有的一切,但是当我运行代码时,我得到以下错误:RuntimeError:错误:无效的收件人JSON。请确保url编码并查阅文档。可以在此处找到文档:https://blockchain.info/api/blockchain_wallet_api

我正在使用的Python library可以在此处找到:https://github.com/p4u/blockchain.py/blob/master/blockchain.py

关于这个问题的唯一其他帖子是由图书馆的原始创建者发布的,他说问题是金额不能是小数,但我的不是。可以在这里找到邮件:https://bitcointalk.org/index.php?topic=600870.0 < / p>

这是我的代码:

from __future__ import print_function
from itertools import islice, imap
import csv, requests, json, math
from collections import defaultdict
import requests
import urllib
import json
from os.path import expanduser
import configparser


class Wallet: 
    guid        = 'g'
    isAccount   = 0
    isKey       = 0
    password1   = 'x'
    password2   = 'y'
    url         = ''

def __init__(self, guid = 'g', password1 = 'x', password2 = 'y'):

    if guid.count('-') > 0:
        self.isAccount = 1
        if password1 == '': # wallet guid's contain - 
            raise ValueError('No password with guid.')
    else:
        self.isKey = 1

    self.guid = guid
    self.url = 'https://blockchain.info/merchant/' + guid + '/'

    self.password1 = password1
    self.password2 = password2

    r = requests.get('http://api.blockcypher.com/v1/btc/main/addrs/A/balance')
    balance = r.json()['balance']

    with open("Entries#x1.csv") as f,open("winningnumbers.csv") as nums:
        nums = set(imap(str.rstrip, nums))
        r = csv.reader(f)
        results = defaultdict(list)
        for row in r:
            results[sum(n in nums for n in islice(row, 1, None))].append(row[0])

    self.number_matched_0 = results[0]
    self.number_matched_1 = results[1]
    self.number_matched_2 = results[2]
    self.number_matched_3 = results[3]
    self.number_matched_4 = results[4]
    self.number_matched_5 = results[5]

    self.number_matched_5_json = json.dumps(self.number_matched_5, sort_keys = True, indent = 4)

    print(self.number_matched_5_json)

    if len(self.number_matched_3) == 0:
        print('Nobody matched 3 numbers')
    else:
        self.tx_amount_3 = int((balance*0.001)/ len(self.number_matched_3))

    if len(self.number_matched_4) == 0:
        print('Nobody matched 4 numbers')
    else:
        self.tx_amount_4 = int((balance*0.1)/ len(self.number_matched_4))

    if len(self.number_matched_5) == 0:
        print('Nobody matched 3 numbers')
    else:
        self.tx_amount_5 = int((balance*0.4)/ len(self.number_matched_5))

    self.d = {el: self.tx_amount_5 for el in json.loads(self.number_matched_5_json)}
    print(self.d)

    self.d_url_enc = urllib.urlencode(self.d)

def Call(self, method, data = {}):
    if self.password1 != '':
        data['password'] = self.password1 
    if self.password2 != '':
        data['second_password'] = self.password2

    response = requests.post(self.url + method,params=data)

    json = response.json()
    if 'error' in json:
        raise RuntimeError('ERROR: ' + json['error'])

    return json

def SendPayment(self, toaddr, amount, fromaddr = 'A', shared = 0, fee = 0.0001, note = True):
    data = {}
    data['to'] = toaddr
    data['amount'] = self.tx_amount_5
    data['fee'] = fee
    data['recipients'] = self.d_url_enc

    if fromaddr:
        data['from'] = fromaddr

    if shared:
        data['shared'] = 'true'

    if note:
        data['note'] = 'n'

    response = self.Call('payment',data)

def SendManyPayment(self, fromaddr = True, shared = False, fee = 0.0001, note = True):
    data = {}
    recipients = self.d_url_enc
    data['recipients'] = recipients.__str__().replace("'",'"')
    data['fee'] = str(fee)
    if fromaddr:
        data['from'] = 'A'
    if shared:
        data['shared'] = 'true'
    else:
        data['shared'] = 'false'
    if note:
        data['note'] = 'n'
    response = self.Call('sendmany',data)

    return response

print(Wallet().SendManyPayment())


Complete runtime error: Traceback (most recent call last):
  File "D:\Documents\B\Code\A\jsontest.py", line 125, in <module>
    print(Wallet().SendManyPayment())
  File "D:\Documents\B\Code\A\jsontest.py", line 121, in SendManyPayment
    response = self.Call('sendmany',data)
  File "D:\Documents\B\Code\A\jsontest.py", line 86, in Call
    raise RuntimeError('ERROR: ' + json['error'])
RuntimeError: ERROR: Invalid Recipients JSON. Please make sure it is url encoded and consult the docs.

1 个答案:

答案 0 :(得分:1)

data['recipients']功能中包含SendManyPayment()的内容是什么?看起来您正在尝试进行一些手动编码,而不是使用json.dumps(recipients)

文档说它应该是这样的:

{
    "1JzSZFs2DQke2B3S4pBxaNaMzzVZaG4Cqh": 100000000,
    "12Cf6nCcRtKERh9cQm3Z29c9MWvQuFSxvT": 1500000000,
    "1dice6YgEVBf88erBFra9BHf6ZMoyvG88": 200000000
}

尝试发送许多:

def SendManyPayment(self, fromaddr = True, shared = False, fee = 0.0001, note = True):
    data = {}
    recipients = self.d_url_enc
    # recipients should be a json string FIRST!
    data['recipients'] = json.dumps(recipients)
    data['fee'] = str(fee)
    if fromaddr:
        data['from'] = 'A'
    if shared:
        data['shared'] = 'true'
    else:
        data['shared'] = 'false'
    if note:
        data['note'] = 'n'
    response = self.Call('sendmany',data)

    return response