Python Post to Bills using Pycurl

Hello again,

After working my way around Curl to successfully POST a Bill I have now
moved a step further to automate the process and have started using Python
with Pycurl to authenticate through OAuth and then POST the desired fields
to Freeagent.

The script I have put together so far can successfully GET data from the
API but I am struggling to POST. The script is below (populated with dummy
data) and please forgive and obviously/newbie mistakes, im new to Python!

import time
import pycurl
import urllib
import urllib.request
import urllib.parse
import json
import oauthlib as oauth
import io
from io import BytesIO
buf = io.BytesIO()
billdata = (’{“Bill”:{“due-on”: “2013-08-20”,“contact”: “https:
//api.sandbox.freeagent.com/v2/contacts/1835/","reference”:
“Python”,“total_value”: “150000.0”,“category”: “https:
//api.sandbox.freeagent.com/v2/categories/285/","dated-on”:
“2013-07-20”,“sales-tax-rate”: “20.0”}}’)

data = json.dumps(billdata)
def getUserData():

  •    c = pycurl.Curl()*
    
  •    c.setopt(pycurl.URL, "https://api.sandbox.freeagent.com/v2/bills")*
    
  •    c.setopt(pycurl.HTTPHEADER, [*
    
  •        'Authorization: Bearer %s' % str('xxxxxxxxxxxxxxxxxxxxxxxxx'),*
    
  •        'Accept: application/json',*
    
  •        'Content-Type : application/json'*
    
  •        ])*
    
  •    c.setopt(pycurl.POST, 1)*
    
  •    c.setopt(pycurl.POSTFIELDS,data)*
    
  •    c.setopt(pycurl.WRITEFUNCTION, buf.write)*
    
  •    c.perform()*
    

getUserData()
print (buf.getvalue())
buf.close

This is what is printed after executing the script:

b"

500 Internal Server Error

If you are the
administrator of this website, then please read this web application’s log
file and/or the web server’s log file to find out what went
wrong."

If anyone can help and point out where im going wrong that would be greatly
appreciated.

Regards,
Karl

Hi,

Thanks very much for the pointers. I’ll give it a try on Monday and let you know how it goes.

Thanks again for the help.

Karl

Hi Karl,

I can see a couple of errors with your script which is causing the API to
reject it. The first one is in your Content-Type header declaration,
there’s an extra space before the colon, which is leading the server to
ignore the header. The correct header string should be “Content-Type:
application/json”.

The second issue is you’re storing a string representation of the JSON data
you wish to send in the ‘billdata’ variable, then you’re also escaping it
with the json library and storing that into the ‘data’ variable. I would
suggest either using a python dictionary for ‘billdata’ and leaving the
json escaping in place, or just commenting out the 'data = …` line and
leaving ‘billdata’ containing a string representation of the JSON. (And
update your pycurl.POSTFIELDS line to use billdata directly if you comment
out the ‘data =’ line of course!)

And lastly I just noticed in the JSON, you’ve specified the top level key
as “Bill”. The API is case-sensitive with data, so you’ll need to change
that to “bill” before it’ll work.

Hope that helps! :slight_smile:
Caius