python requests.put() fails when urllib3 http.request('PUT', ...) succeeds. What gives? -


i trying hit atlassian confluence rest api using python requests.

i've called api, when call put update confluence page, returns 200, didn't update page.

i used chrome::yarc verify api working (which was). after while trying debug it, reverted try using urllib3, worked fine.

i'd use requests, can't life of me figure 1 out after hours , hours of trying debug, google, etc.

i'm running mac/python3:

$ uname -a darwin mylaptop.local 16.7.0 darwin kernel version 16.7.0: thu jun 15 17:36:27 pdt 2017; root:xnu-3789.70.16~2/release_x86_64 x86_64 $ python3 --version python 3.6.1 

here's code shows 3 ways i'm trying (two requests , 1 urllib3):

def update(self, spacekey, pagetitle, newcontent, contenttype='storage'):     if contenttype not in ('storage', 'wiki', 'plain'):         raise valueerror("invalid contenttype={}".format(contenttype))      # current page info     self._refreshpage(spacekey, pagetitle) # retrieve before update it.     orig_version = self.version      # content same requested content. nothing     if self.wiki == newcontent:         return      data_dict = {         'type' : 'page',         'version' : {'number' : self.version + 1},         'body'  : {             contenttype : {                 'representation' : contenttype,                 'value' : str(newcontent)             }         }     }     data_json = json.dumps(data_dict).encode('utf-8')      put = 'urllib3' #for until figure out why requests.put() doesn't work     enable_http_logging()     if put == 'requests':         r = self._cs.api.content(self.id).put(json=data_dict)         r.raise_for_status()     elif put == 'urllib3':         urllib3.disable_warnings() # know, can quit whining now!!!         headers = { 'content-type' : 'application/json;charset=utf-8' }         auth_header = urllib3.util.make_headers(basic_auth=":".join(self._cs.session.auth))         headers = {**headers, **auth_header}         http = urllib3.poolmanager()         r = http.request('put', str(self._cs.api.content(self.id)), body=data_json, headers=headers)     else:         raise valueerror("huh? unknown put type: {}".format(put))     enable_http_logging(false)      # verify page updated     self._refreshpage(spacekey, pagetitle) # check changes     if self.version != orig_version + 1:         raise runtimeerror("page not updated. still @ version {}".format(self.version))     if self.wiki != newcontent:         raise runtimeerror("page version updated, not content.") 

any great.

update 1: adding request dump

-----------start----------- put http://confluence.myco.com/rest/api/content/101904815 user-agent: python-requests/2.18.4 accept-encoding: gzip, deflate accept: */* connection: keep-alive content-length: 141 content-type: application/json authorization: basic <auth-token-here>==  b'{"type": "page", "version": {"number": 17}, "body": {"storage": {"representation": "storage", "value": "new body here version  version 17"}}}' 

requests never went put (bug???)

what you're observing requests behaving consistently web browsers: reacting http 302 redirect request.

from wikipedia:

the user agent (e.g. web browser) invited response code make second, otherwise identical, request new url specified in location field.

(...)

many web browsers implemented code in manner violated standard, changing request type of new request get, regardless of type employed in original request (e.g. post)

(...)

as consequence, update of rfc 2616 changes definition allow user agents rewrite post get.

so behaviour consistent rfc 2616. don't think can of 2 libraries behaves "more correctly".


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -