@@ -200,24 +200,37 @@ def call_api_get(self, method, api_path=None, **kwargs):
200200 )
201201 )
202202
203- def call_api_post (self , method , files = None , use_json = None , ** kwargs ):
204- reduced_args = self .__reduce_kwargs (kwargs )
205- # Since pass is a reserved word in Python it has to be injected on the request dict
206- # Some methods use pass (users.register) and others password (users.create)
207- if "password" in reduced_args and method != "users.create" :
208- reduced_args ["pass" ] = reduced_args ["password" ]
209- del reduced_args ["password" ]
210- if use_json is None :
211- # see https://requests.readthedocs.io/en/master/user/quickstart/#more-complicated-post-requests
212- # > The json parameter is ignored if either data or files is passed.
213- # If files are sent, json should not be used
214- use_json = files is None
215- if use_json :
203+ def call_api_post (self , method , body = None , files = None , use_json = None , ** kwargs ):
204+ """Send a POST request to the API.
205+
206+ There are two modes of operation:
207+
208+ 1. **Raw body** — pass ``body`` directly. The value is serialized as-is
209+ via ``json=body``, which supports any JSON-serializable structure
210+ (lists, dicts, etc.). ``kwargs`` are ignored in this mode.
211+
212+ 2. **Keyword arguments** (default) — individual kwargs are collected
213+ into a dict and sent as the request payload. By default the payload
214+ is sent as JSON (``json=``), but when ``files`` are provided it
215+ falls back to form-encoded ``data=`` because requests ignores the
216+ ``json`` parameter when ``files`` is set. You can override this
217+ with ``use_json=True/False``.
218+
219+ :param method: API method path, appended to ``self.api_path``.
220+ :param body: A raw JSON-serializable payload (e.g. a list).
221+ When provided, ``kwargs``, ``files``, and ``use_json``
222+ are ignored.
223+ :param files: Files to upload (passed to ``requests``).
224+ :param use_json: Force JSON (True) or form-encoded (False) encoding.
225+ Defaults to JSON when no files are attached.
226+ """
227+ url = self .server_url + self .api_path + method
228+
229+ if body is not None :
216230 return json_or_error (
217231 self .session .post (
218- self .server_url + self .api_path + method ,
219- json = reduced_args ,
220- files = files ,
232+ url ,
233+ json = body ,
221234 headers = self .headers ,
222235 verify = self .ssl_verify ,
223236 cert = self .cert ,
@@ -226,10 +239,21 @@ def call_api_post(self, method, files=None, use_json=None, **kwargs):
226239 )
227240 )
228241
242+ reduced_args = self .__reduce_kwargs (kwargs )
243+
244+ # "pass" is a Python reserved word, but some endpoints (e.g.
245+ # users.register) expect it instead of "password".
246+ if "password" in reduced_args and method != "users.create" :
247+ reduced_args ["pass" ] = reduced_args .pop ("password" )
248+
249+ if use_json is None :
250+ use_json = files is None
251+
229252 return json_or_error (
230253 self .session .post (
231- self .server_url + self .api_path + method ,
232- data = reduced_args ,
254+ url ,
255+ json = reduced_args if use_json else None ,
256+ data = None if use_json else reduced_args ,
233257 files = files ,
234258 headers = self .headers ,
235259 verify = self .ssl_verify ,
0 commit comments