1818
1919
2020class ApiClient (object ):
21- def __init__ (self , config = None ):
22- # type: (Config) -> None
21+ def __init__ (self , config , base_path ):
22+ # type: (Config, str) -> None
23+
24+ # Assign base URL
25+ self ._base_path = base_path
2326
2427 # Assign passed config or globally configured instance
2528 self ._config = config or Config .get_instance ()
2629
27- # Assert data
28- if not isinstance (self .config , Config ):
29- raise ValueError ('A valid Config object is required to create an ApiClient' )
30+ @property
31+ def base_path (self ):
32+ # type: () -> str
33+ return self ._base_path
3034
3135 @property
3236 def config (self ):
@@ -43,8 +47,47 @@ def headers(self):
4347 'Content-Type' : 'application/json' ,
4448 }
4549
50+ def get_url (self , path = '' ):
51+ # type: (str) -> str
52+ return self ._urljoin (self .config .api_url , self .base_path , path )
53+
54+ @function_log
55+ def get (self , path = '' , params = None , ** kwargs ):
56+ kwargs = self ._fix_request_kwargs (kwargs , path , params = params )
57+ response = requests .get (** kwargs )
58+ return self ._check_response (response )
59+
60+ @function_log
61+ def post (self , path = '' , data = None , json = None , ** kwargs ):
62+ kwargs = self ._fix_request_kwargs (kwargs , path , data = data , json = json )
63+ response = requests .post (** kwargs )
64+ return self ._check_response (response )
65+
66+ @function_log
67+ def put (self , path = '' , data = None , ** kwargs ):
68+ kwargs = self ._fix_request_kwargs (kwargs , path , data = data )
69+ response = requests .put (** kwargs )
70+ return self ._check_response (response )
71+
72+ def _fix_request_kwargs (self , prev_kwargs , path , ** kwargs ):
73+ # type: (Dict[str, Any], str, Dict[str, Any]) -> Dict[str, Any]
74+ """ Set correct kwargs for requests """
75+ fixed_kwargs = prev_kwargs .copy ()
76+ fixed_kwargs .update (kwargs )
77+ if 'get_url' not in fixed_kwargs :
78+ fixed_kwargs ['get_url' ] = self .get_url (path )
79+ if 'headers' not in fixed_kwargs :
80+ fixed_kwargs ['headers' ] = self .headers
81+ return fixed_kwargs
82+
4683 @staticmethod
47- def check_response (response ):
84+ def _urljoin (* args ):
85+ return functools .reduce (
86+ lambda a , b : compat .urljoin (a + ('' if a .endswith ('/' ) else '/' ), b ),
87+ args )
88+
89+ @staticmethod
90+ def _check_response (response ):
4891 # type: (requests.Response) -> str
4992 if not hasattr (response , 'content' ):
5093 raise AttributeError (
@@ -59,47 +102,30 @@ def check_response(response):
59102
60103 return response .content
61104
62- @function_log
63- def get (self , url , params = None , ** kwargs ):
64- if 'headers' not in kwargs :
65- kwargs ['headers' ] = self .headers
66- response = requests .get (url , params , ** kwargs )
67- return self .check_response (response )
68-
69- @function_log
70- def post (self , url , data = None , json = None , ** kwargs ):
71- if 'headers' not in kwargs :
72- kwargs ['headers' ] = self .headers
73- response = requests .post (url , data , json , ** kwargs )
74- return self .check_response (response )
75-
76- @function_log
77- def put (self , url , data = None , ** kwargs ):
78- if 'headers' not in kwargs :
79- kwargs ['headers' ] = self .headers
80- response = requests .put (url , data , ** kwargs )
81- return self .check_response (response )
82-
83105
84106class BaseResource (object ):
85107 resource = None # type: str
86108 limit = 100 # type: int
87- api = None # type: ApiClient
88109 schema = BaseSchema () # type: marshmallow.Schema
89110
90111 def __init__ (self , config = None ):
91- # Assign passed config or globally configured instance
92- self ._config = config or Config .get_instance ()
93-
94- # Assert data
112+ # Set api
95113 if not self .__class__ .resource :
96- raise AttributeError ('Resource name not specified in class {}' .format (
97- self .__class__ .__name__ ) + '. Add an attribute `resource` name of the resource' )
114+ raise AttributeError ('Resource name not specified in class {}. '
115+ .format (self .__class__ .__name__ ) +
116+ 'Add an attribute `resource` name of the resource' )
117+ self ._api = ApiClient (config , self .__class__ .resource )
118+
119+ # Set passed config or globally configured instance
120+ self ._config = config or Config .get_instance ()
98121 if not isinstance (self .config , Config ):
99122 raise ValueError ('A valid Config object must be passed or globally configured '
100123 'to create a ' + type (self ).__name__ )
101- if not BaseResource .api :
102- BaseResource .api = ApiClient (config )
124+
125+ @property
126+ def api (self ):
127+ # type: () -> ApiClient
128+ return self ._api
103129
104130 @property
105131 def config (self ):
@@ -111,13 +137,9 @@ def list(self):
111137 # type: () -> List[Any]
112138 filters = self .build_filter ()
113139 logger .info ('Get list request by filter - {}' .format (filters ))
114- response = self .api .get (url = self . url , params = filters )
140+ response = self .api .get (params = filters )
115141 return self ._load_schema (response )
116142
117- @property
118- def url (self ):
119- return self .urljoin (self .config .api_url , self .resource )
120-
121143 def build_filter (self ):
122144 # type: () -> Dict[str, Any]
123145 res_filter = {}
@@ -127,17 +149,11 @@ def build_filter(self):
127149
128150 def get (self , pk ):
129151 # type: (str) -> Any
130- response = self .api .get (url = self . urljoin ( self . url , pk ) )
152+ response = self .api .get (path = pk )
131153 objects = self ._load_schema (response )
132154 if isinstance (objects , list ) and len (objects ) > 0 :
133155 return objects [0 ]
134156
135- @staticmethod
136- def urljoin (* args ):
137- return functools .reduce (
138- lambda a , b : compat .urljoin (a + ('' if a .endswith ('/' ) else '/' ), b ),
139- args )
140-
141157 def _load_schema (self , response , many = None ):
142158 # type: (str, bool) -> Union[List[Any], Any]
143159 objects , error = self .schema .loads (response , many )
0 commit comments