Unable to POST transactions (Error 400) [Python noob]

Hey! It's my first time working with Python and REST, and I seem to be stuck when trying to send a POST request back to the server. I've done a ton of googling but I just can't find something that works

I'm currently only sending transactions one at a time (Still need to optimize that..), to the URL: 

https://api.youneedabudget.com/v1/budgets/<budget_id>/transactions/bulk?access_token=<token>

 

This is the json data I'm trying to POST

{'transactions':
  [
    {
      u'import_id': None,
      'account_id': u'<account_id>',
      u'deleted': False,
      'payee_id': '',
      'memo': u'Source: Test',
      u'transfer_transaction_id': None,
      u'date': u'2018-11-19',
      u'cleared': u'uncleared',
      u'payee_name': u'TestPayee',
      'account_name': u'TestAccount',
      'category_name': 'To be Budgeted',
      u'flag_color': None,
      u'approved': True,
      u'subtransactions': [],
      'id': '',
      u'transfer_account_id': None,
      'amount': 22334,
      'category_id': ''
    }
  ]
}

I'm not sure why some items have the u' prefix, those are the ones I haven't touched.

My script replaces the account name/id, payee name, category name/id, amount. Even if I specify the category_id it doesn't work.

This is the code snippet that gives me the 400 error:

url = 'https://api.youneedabudget.com/v1/budgets/' + targetbudget + '/transactions/bulk?access_token=' + str(getAPIKey())
data = {'transactions':[transactiondata]}
data = urllib.urlencode(data)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req) # 400?

I have tried adding a Content-Type: application/json header without luck, and also tried using the requests module.


My entire script can be found here: https://github.com/sondregronas/YNAB-Shared-Categories

I'm not sure if its very readable, I will get around to optimizing/cleaning it later..

Thanks!

3replies Oldest first
  • Oldest first
  • Newest first
  • Active threads
  • Popular
    • George
    • Developer
    • george_ynab
    • 7 mths ago
    • Reported - view

    Sondre G , what does `response` look like in your code snippet? It should be a JSON object that provides detail on the error. Something along the lines of:

     

    {
      "error": {
        "id": "400",
        "name": "bad_request",
        "detail": "<validation errors>"
      }
    }

    That error response detail should point you in the right direction. I suspect the problem is the JSON data you're POST'ing. Try removing the `u` prefixes in your JSON data. At least in the JSON keys. I'm not familiar with Python so I'm not really sure what's going on with those `u`s. 

    Reply Like
      • Sondre G
      • Media Producer
      • Silver_Mask.2
      • 7 mths ago
      • Reported - view

      George Sorry I didn't seem to read how to extract the complete error message correctly:

      {
        "error":
        {
          "id":"400",
          "name":"bad_request",
          "detail":"transactions this field is required."
        }
      }

      The transactions is part of the data so not sure what I did wrong

      Tried removing everything with a u' prefix without any luck.

      Reply Like
    • Sondre G
    • Media Producer
    • Silver_Mask.2
    • 7 mths ago
    • 1
    • Reported - view

    After some more digging I found out that there's an issue with urllib2 in older versions of python (I'm using 2.7.13), in that it doesn't know how to calculate Content-Length..

     

    Solved it by doing:

    data = json.dumps({'transactions':[transactiondata]})
    clen = len(data)
    req = urllib2.Request(url, data, {'Content-Type': 'application/json', 'Content-Length': clen})
    try:
      response = urllib2.urlopen(req)
    except urllib2.HTTPError as e:
      print e.code
      print e.read()
    print response.read()
    Reply Like 1
Like Follow
  • 7 mths agoLast active
  • 3Replies
  • 155Views
  • 1 Following