I created a PyQGIS plug in that creates loops over the features on a layer to create the body of an API post request. However, when I try to run that API call I get an error telling me the json parameter is not a "dict" but rather a QVariant. Here is my code:
def createFeatures(body, token):
if not isinstance(token, dict):
token = {'token':token, "content-type": "application/json"}
url = f'https://fibermap.vetro.io/v2/features/'
print(type(body))
r = requests.post(url, headers=token, json=body)
if r.status_code == 201:
return r.json()['result']
else:
msg = r.json()['message']
msg = f"Failed at creating new features\n\n{msg}\n"
qgis_popup(msg,f"Error {r.status_code}","Critical")
The part I find perplexing is that if the print statement returns <class 'dict'>
. Yet the next line gives me the following error:
WARNING Traceback (most recent call last):
File "C:/Users/RafaelC/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\qgis_to_vetro\qgis_to_vetro.py", line 378, in run
new_features = createFeatures(body_create, vetroToken)
File "C:/Users/RafaelC/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\qgis_to_vetro\VetroAPI.py", line 314, in createFeatures
r = requests.post(url, headers=token, json=body)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\requests\api.py", line 119, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\requests\sessions.py", line 516, in request
prep = self.prepare_request(req)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\requests\sessions.py", line 459, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\requests\models.py", line 317, in prepare
self.prepare_body(data, files, json)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\requests\models.py", line 467, in prepare_body
body = complexjson.dumps(json)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\simplejson\__init__.py", line 382, in dumps
return _default_encoder.encode(obj)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\simplejson\encoder.py", line 296, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\simplejson\encoder.py", line 378, in iterencode
return _iterencode(o, 0)
File "C:\PROGRA~1\QGIS3~1.16\apps\Python37\lib\site-packages\simplejson\encoder.py", line 273, in default
o.__class__.__name__)
TypeError: Object of type QVariant is not JSON serializable
Moreover, even if I try to use say print(json.dumps(body,indent=4))
I get the same error. I am using QGIS3.16.
Does anyone know what could be happening here?
Best Answer
Actually I found the problem. The 'body' dictionary had keys whose values were 'NULL'. After removing those, the code runs as expected.