11# coding: utf-8
22from __future__ import unicode_literals
3+ from coreapi import Error , ErrorMessage
34import requests
45import itypes
56import json
89class BaseTransport (itypes .Object ):
910 schemes = None
1011
11- def transition (self , url , action = None , parameters = None ):
12+ def transition (self , link , params = None , session = None , link_ancestors = None ):
1213 raise NotImplementedError () # pragma: nocover
1314
1415
1516class HTTPTransport (BaseTransport ):
1617 schemes = ['http' , 'https' ]
1718
18- def transition (self , url , action = None , params = None ):
19- from coreapi import get_default_session
20- session = get_default_session ()
19+ def transition (self , link , params = None , session = None , link_ancestors = None ):
20+ if session is None :
21+ from coreapi import get_default_session
22+ session = get_default_session ()
2123
24+ response = self .make_http_request (session , link .url , link .action , params )
25+ document = self .load_document (session , response )
26+
27+ if isinstance (document , Error ):
28+ raise ErrorMessage (document .messages )
29+
30+ if link_ancestors :
31+ document = self .handle_inline_replacements (document , link , link_ancestors )
32+
33+ return document
34+
35+ def make_http_request (self , session , url , action = None , params = None ):
2236 method = 'GET' if (action is None ) else action .upper ()
2337 accept = session .get_accept_header ()
2438
@@ -44,10 +58,24 @@ def transition(self, url, action=None, params=None):
4458 }
4559 }
4660
47- response = requests .request (method , url , ** opts )
61+ return requests .request (method , url , ** opts )
62+
63+ def load_document (self , session , response ):
4864 if not response .content :
4965 return None
50-
5166 content_type = response .headers .get ('content-type' )
5267 codec = session .negotiate_decoder (content_type )
53- return codec .load (response .content , base_url = url )
68+ return codec .load (response .content , base_url = response .url )
69+
70+ def handle_inline_replacements (self , document , link , link_ancestors ):
71+ transition_type = link .transition
72+ if not transition_type and link .action .lower () in ('put' , 'patch' , 'delete' ):
73+ transition_type = 'inline'
74+
75+ if transition_type == 'inline' :
76+ root = link_ancestors [0 ].document
77+ keys_to_link_parent = link_ancestors [- 1 ].keys
78+ if document is None :
79+ return root .delete_in (keys_to_link_parent )
80+ return root .set_in (keys_to_link_parent , document )
81+ return document
0 commit comments