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

star2014 picture star2014 · Jul 4, 2014 · Viewed 8.7k times · Source

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.

Answer

mata picture mata · Jul 5, 2014

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.