PyQGIS Plugins – Issue with Converting Dictionary to QVariant

dictionarypyqgisqgis-plugins

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.

Related Question