D
darran
I'm struggling with using urllib2 to access the Harvest time-tracking
web service (http://www.getharvest.com/api). GET is working fine.
POST is giving me a problem. Here is an example that creates a new
time-tracking entry using curl.
$ curl http://subdomain.harvestapp.com/daily/add -H 'Accept:
application/xml' \
-H 'Content-Type: application/xml' \
-u myusername:mypassword \
-d '<request><notes>testing API</notes><hours>3.5</
hours><project_id>65750</project_id><task_id>79702</
task_id><spent_at>Thu, 13 Sep 2007</spent_at></request>'
Here's a selection of info from running the above with --verbose
output:
* About to connect() to edmstudio.harvestapp.com port 80
Notice that 1) it is a POST, and 2) the data is going across as an
unencoded (xml) string. Now here is my attempt to achieve this with
python's urllib2:
entry = "<request><notes>testing API</notes><hours>3.5</
hours><project_id>65750</project_id><task_id>79702</
task_id><spent_at>Thu, 13 Sep 2007</spent_at></request>"
import urllib2
import base64
opener = urllib2.build_opener()
opener.addheaders = [
('Content-Type', 'application/xml'),
('Accept', 'application/xml'),
('Authorization', 'Basic %s' \
% base64.encodestring('%s:%s' % (myusername, mypassword)))]
# this GET works just fine - proof that authentication is correct
req = urllib2.Request(url='http://subdomain.harvestapp.com/daily')
response = opener.open(req)
print response.read()
# this POST (same data as the above curl example) fails with an
internal server error (500)
req = urllib2.Request(url='http://subdomain.harvestapp.com/daily/add',
data=entry)
response = opener.open(req)
print response.read()
I'm stumped. As always, any help is much appreciated.
web service (http://www.getharvest.com/api). GET is working fine.
POST is giving me a problem. Here is an example that creates a new
time-tracking entry using curl.
$ curl http://subdomain.harvestapp.com/daily/add -H 'Accept:
application/xml' \
-H 'Content-Type: application/xml' \
-u myusername:mypassword \
-d '<request><notes>testing API</notes><hours>3.5</
hours><project_id>65750</project_id><task_id>79702</
task_id><spent_at>Thu, 13 Sep 2007</spent_at></request>'
Here's a selection of info from running the above with --verbose
output:
* About to connect() to edmstudio.harvestapp.com port 80
POST /daily/add HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/xml
Content-Type: application/xml
Content-Length: 154
<request><notes>testing API</notes><hours>3.5</hours><project_id>65750</project_id><task_id>79702</task_id><spent_at>Thu, 13 Sep 2007</spent_at></request>HTTP/1.1 201 Created
Notice that 1) it is a POST, and 2) the data is going across as an
unencoded (xml) string. Now here is my attempt to achieve this with
python's urllib2:
entry = "<request><notes>testing API</notes><hours>3.5</
hours><project_id>65750</project_id><task_id>79702</
task_id><spent_at>Thu, 13 Sep 2007</spent_at></request>"
import urllib2
import base64
opener = urllib2.build_opener()
opener.addheaders = [
('Content-Type', 'application/xml'),
('Accept', 'application/xml'),
('Authorization', 'Basic %s' \
% base64.encodestring('%s:%s' % (myusername, mypassword)))]
# this GET works just fine - proof that authentication is correct
req = urllib2.Request(url='http://subdomain.harvestapp.com/daily')
response = opener.open(req)
print response.read()
# this POST (same data as the above curl example) fails with an
internal server error (500)
req = urllib2.Request(url='http://subdomain.harvestapp.com/daily/add',
data=entry)
response = opener.open(req)
print response.read()
I'm stumped. As always, any help is much appreciated.