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.
Community moderators have prevented the ability to post new answers.
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)
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.