Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: <built-in function id> is not JSON serializable

I'm trying to make a connection to this website "android-review.googlesource.com" through "httplib.HTTPSConnection" which actually is Gerrit (a tool for reviewing code), Gerrit API provides an interface to JSON formatted review data. I need to gather JSON data then. You can find more information about Gerrit here: https://gerritreview.googlesource.com/Documentation/rest-api.html

Let me explain a bit about source code. There is a function called "GetRequestOrCached" which saves data in a file for cache usage and another function "MakeRequest" which creates a connection to website and return the response. But error is related to the part which json.dumps is used for a request (req) which request is a dictionary.

This is the error:

TypeError: <built-in function id> is not JSON serializable

This is the code:

import socket, sys
import httplib
import pyodbc
import json
import types
import datetime
import urllib2
import os
import logging
import re, time

def GetRequestOrCached( url, method, data, filename):

  path = os.path.join("json", filename)
  if not os.path.exists(path):
    data = MakeRequest(url, method, data)
    time.sleep(1)
    data = data.replace(")]}'", "")
    f = open(path, "w")
    f.write(data)
    f.close()
    return open(path).read()

def MakeRequest(url, method, data, port=443):
  successful = False
  while not successful:
    try:
      conn = httplib.HTTPSConnection("android-review.googlesource.com", port)
      headers = {"Accept": "application/json,application/jsonrequest",
        "Content-Type": "application/json; charset=UTF-8",
        "Content-Length": len(data)}
      conn.request(method, url, data, headers)
      conn.set_debuglevel(1)
      successful = True
    except socket.error as err:
        # this means a socket timeout
      if err.errno != 10060:
        raise(err)
      else:
        print err.errno, str(err)
        print "sleep for 1 minute before retrying"
        time.sleep(60)

  resp = conn.getresponse()
  if resp.status != 200:
    raise GerritDataException("Got status code %d for request to %s" % (resp.status, url))
  return resp.read()
#-------------------------------------------------
filename = "%d-ChangeDetails.json"
url = "/gerrit_ui/rpc/ChangeDetailService"
req = {"jsonrpc" : "2.0", 
  "method": "changeDetail",
  "params": [{"id": id}],
  "id": 44
      }
data = GetRequestOrCached(url, "POST", json.dumps(req), filename)
print json.loads(data)

This line causes the error "data = GetRequestOrCached(url, "POST", json.dumps(req), filename)". I will appreciate if the one who fixes the error also check to see if the response from website is an error or a correct response.

like image 462
star2014 Avatar asked Feb 13 '23 14:02

star2014


2 Answers

The error message says it all - you have the id function inside your req dictionary:

req = {"jsonrpc" : "2.0", 
  "method": "changeDetail",
  "params": [{"id": id}],
#                    ^- here
  "id": 44
}

Functions are not json serializable, so that's why you get the error.

On a side note - if you wanted to pass a variable instead, you've not initialized it before using it. Avoid using names of builtins as variable names (like id, int, ...) to avoid this kind of problem.

like image 123
mata Avatar answered Feb 15 '23 11:02

mata


You probably forgot to assign to the variable named id before using it when assigning to req.

Because you didn't assign to it, the builtin function named id is picked up, and passed on, to be json-ized. Since it is a function, it cannot be json-ized.

If the same had happened with a name which doesn't happen to be a builtin, you would have got:

UnboundLocalError: local variable referenced before assignment
like image 39
shx2 Avatar answered Feb 15 '23 11:02

shx2