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/'
    r = requests.post(url, headers=token, json=body)

    if r.status_code == 201:
        return r.json()['result']
        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
             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?

  • Indeed, please share the full traceback
    – etrimaille
    Commented Feb 10, 2023 at 17:56
  • I have now added the full traceback of the error message Commented Feb 10, 2023 at 18:19
  • 1
    The error message does not say that body IS a QVariant but that body CONTAINS some QVariant as values. These QVariant probably comes from NULL values in your qgis feature. You need to sanitize your dict before trying to serialize it to JSON.
    – YoLecomte
    Commented Feb 10, 2023 at 20:37

1 Answer 1


Actually I found the problem. The 'body' dictionary had keys whose values were 'NULL'. After removing those, the code runs as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.