Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

trivial python json request does not work

Arne Schirmacher January 6, 2015

I want to update a Confluence page via a python program, but I get a server error 500 and I can't figure out why this is the case.

I have tested all parameters using the curl command line from the Confluence REST API example page: https://developer.atlassian.com/display/CONFDEV/Confluence+REST+API+Examples#ConfluenceRESTAPIExamples-Updateapage

I have also verified that my python program sends exactly the same put request data as the curl version by logging all headers and data on the Confluence server.

See the Python code below and the output: It logs in to Confluence, saves the login cookie and uses the cookie value in the next GET requests which returns the server result code of 200 and a lot of data. This is proof that the login process and the cookie method works for the GET request.

However the following PUT request always returns the server result code 500.

update.py:

import sys
# import the standard JSON parser
import simplejson as json
from subprocess import Popen, PIPE
# import the REST library
from restful_lib import Connection

base_url = "https://mydomain.dom/confluence"
page_title = "new page"
space_key = "TEST"

conn = Connection(base_url)

# log in
response = conn.request_post("/login.action", args={'os_username':'myname', 'os_password':'mypassword'}, headers={'content-type':'application/json', 'accept':'application/json'})
cookie = response[u'headers']['set-cookie']

# GET request
response = conn.request_get("/rest/api/content", args={'title':page_title, 'spaceKey':space_key, 'expand':'version' }, headers={'content-type':'application/json', 'accept':'application/json', 'cookie':cookie })

status = response[u'headers']['status']
print 'status 1: ', status

#body = json.loads(response[u'body'])
#response[u'body'] = "(body)"
#json.dump(response, sys.stdout, sort_keys=True, indent=4 )
#print
#json.dump(body, sys.stdout, sort_keys=True, indent=4 )
#print

response = conn.request_put("/rest/api/content/20283425" , args={}, body='{"id":20283425,"type":"page","title":"new page","space":{"key":"TEST"},"body":{"storage":{"value":"<p>my new value</p>","representation":"storage"}},"version":{"number":9}}', headers={'content-type':'application/json', 'accept':'application/json', 'cookie':cookie})

status = response[u'headers']['status']
print 'status 2: ', status

body = json.loads(response[u'body'])
response[u'body'] = "(body)"
json.dump(response, sys.stdout, sort_keys=True, indent=4 )
print
json.dump(body, sys.stdout, sort_keys=True, indent=4 )
print

Results:

$ python update.py
status 1:  200
status 2:  500
{
    "body": "(body)",
    "headers": {
        "connection": "close",
        "content-type": "application/json",
        "date": "Tue, 06 Jan 2015 20:30:49 GMT",
        "status": "500",
        "transfer-encoding": "chunked",
        "x-asen": "SEN-123456",
        "x-ausername": "myname",
        "x-content-type-options": "nosniff",
        "x-pad": "avoid browser bug",
        "x-seraph-loginreason": "OK"
    }
}
{
    "message": "javax.ws.rs.WebApplicationException: null",
    "statusCode": 500
}

There is an exception in the server logs:

2015-01-07 04:53:21,695 ERROR [ajp-bio-9012-exec-238] [rest.api.model.ExceptionConverter] convertServiceException No status code found for exception, converting to internal server error :
 -- url: /confluence/rest/api/content/20283425 | userName: myusername
javax.ws.rs.WebApplicationException
        at com.sun.jersey.server.impl.uri.rules.TerminatingRule.accept(TerminatingRule.java:66)
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter$JerseyOsgiServletContainer.doFilter(RestDelegatingServletFilter.java:178)
        at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:795)
        at com.atlassian.plugins.rest.module.RestDelegatingServletFilter.doFilter(RestDelegatingServletFilter.java:73)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
        at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
        at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:77)
        at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:63)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
        at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
        at com.atlassian.labs.botkiller.BotKillerFilter.doFilter(BotKillerFilter.java:36)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
        at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
        at com.atlassian.plugins.rest.module.servlet.RestServletUtilsUpdaterFilter.doFilterInternal(RestServletUtilsUpdaterFilter.java:26)
        at com.atlassian.plugins.rest.module.servlet.RestServletUtilsUpdaterFilter.doFilter(RestServletUtilsUpdaterFilter.java:40)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
        at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
        at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:25)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
        at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)
        at com.atlassian.mywork.client.filter.ServingRequestsFilter.doFilter(ServingRequestsFilter.java:37)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:78)
        at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:42)
        at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter$1.doFilter(DelegatingPluginFilter.java:70)

Please advise.

2 answers

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Alex Medved _ConfiForms_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 6, 2015

Take a look at this thread, https://answers.atlassian.com/questions/312039

There is a JAVA example as well, if that helps https://bitbucket.org/jaysee00/confluence-rest-api-example/src/master/src/main/java/com/atlassian/api/examples/Main.java

 

But, basically, you have to add ancestors when you update your page (increase version number and put ancestors into the posted JSON)

 

Arne Schirmacher January 7, 2015

I tested the exact json string from the python code (the string from the body='...' assignment in the conn.request_put function call) with curl: {noformat} curl -u myname:mypassword -X PUT -H 'Content-Type: application/json' -d'{"id":20283425,"type":"page","title":"new page","space":{"key":"TEST"},"body":{"storage":{"value":"<p>my new value</p>","representation":"storage"}},"version":{"number":9}}' https://mydomain.dom/confluence/rest/api/content/20283425 {"id":"20283425","type":"page","title":"new page","space":{"id":11862018,"key":"TEST", ... (more response data) {noformat} and it worked just fine. The page was properly updated. This is proof that the json string itself is correct. The problem must be caused by something else, maybe how I am using the conn.request_put call.

0 votes
Joe Clark
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
January 6, 2015

If you look in the Confluence server-side log, you should see more information about the WebApplicationException - including a full stack trace and, most likely, the inner exception that caused it.

Arne Schirmacher January 6, 2015

I have updated my question to include the stack trace.

TAGS
AUG Leaders

Atlassian Community Events