Team API returns 422 Client Error: Unprocessable Entity

Hi,

Can anyone help me understand why I am getting a 422 error when using Add Team Member API call from a Python script? The server is running Grafana 5.3.4.

This is the function I am using:

def grafana_add_team_member(args):
  team = grafana_get_team(args)
  rest_url = "http://%s:%s/api/%s/%s/members" % (args.host, args.port, "teams", team['teams'][0]['id'])

  print("URL: %s" % (rest_url))
  print("DATA: %s" % (args.data))

  try:
    r = requests.post(url=rest_url, auth=(args.user, args.password), verify=False, data=args.data)
    r_json = r.json()
    if r.status_code == 200:
      return(r_json)
    else:
      r.raise_for_status()
  except ValueError:
    raise Exception(r)
  except Exception:
    raise

And the output is this:

URL: http://grafana:3000/api/teams/9/members
DATA: {u'userId': 1}
error: the action 'add' for 'team_member' generated an error (422 Client Error: Unprocessable Entity for url: http://grafana:3000/api/teams/9/members).

I have double checked that there is a user with an ID of 1 and a group with an ID of 9, and that that group has no members.

I have another similar function for adding a team and that seems to work perfectly:

def grafana_add_team(args):
  rest_url = "http://%s:%s/api/%s" % (args.host, args.port, "teams")
  try:
    r = requests.post(url=rest_url, auth=(args.user, args.password), verify=False, data=args.data)
    r_json = r.json()
    if r.status_code == 200:
      return(r_json)
    else:
      r.raise_for_status()
  except ValueError:
    raise Exception(r)
  except Exception:
    raise

I have also been able to get and delete teams using python and the API; it is only adding group members that is causing a problem. I mention this because I believe it indicates that the Python code is correct and that there is some problem with the data I am using, but as far as I can see that matches what is given in the API docs.

I am aware that I have not defined headers for the call, but I haven’t defined them or needed them to create or delete teams.

Thanks in advance for any assistance.

r0tty

Maybe add header like example here

Content-Type: application/json

Hi,

Thanks for the fast reply. I have already experimented with headers without any success.

The first thing I did was to check the value of headers after the call, using this debug line:

  try:
    r = requests.post(url=rest_url, auth=(args.user, args.password), verify=False, data=args.data, headers=header)
    print("Headers: %s" % r.headers)
    r_json = r.json()

And that gave this output:

Headers: {'Date': 'Thu, 29 Nov 2018 12:36:33 GMT', 'Content-Length': '81', 'Content-Type': 'application/json; charset=utf-8'}

So, it is already correct, but I tried setting headers with this code anyway:

  header = {
    "Accept": "application/json",
    "Content-Type": "application/json"
  }
  print("URL: %s" % (rest_url))
  print("DATA: %s" % (args.data))
  try:
    r = requests.post(url=rest_url, auth=(args.user, args.password), verify=False, data=args.data, headers=header)
    print("Headers: %s" % r.headers)

But when I run that I get a 400 error:

URL: http://grafana:3000/api/teams/9/members
DATA: {u'userId': 1}
Headers: {'Date': 'Thu, 29 Nov 2018 12:37:41 GMT', 'Content-Length': '188', 'Content-Type': 'application/json; charset=utf-8'}
error: the action 'add' for 'team_member' generated an error (400 Client Error: Bad Request for url: http://grafana:3000/api/teams/9/members).

So, I think you’re probably right that this is something to do with headers, but what? :O)

r0tty

What does the u in the {u'userId': 1} mean?

Hi,

Ha! That question helped fix it thanks.

Python stores its dicts using Unicode (I believe). I didn’t think that would be an issue though because none of the other similar calls I have been making to Grafana have had a problem. However, in an attempt to prove that was not the issue I tried this, which worked:

def grafana_add_team_member(args):
  team = grafana_get_team(args)
  rest_url = "http://%s:%s/api/%s/%s/members" % (args.host, args.port, "teams", team['teams'][0]['id'])
  header = {
    "Accept": "application/json",
    "Content-Type": "application/json"
  }
  try:
    r = requests.post(url=rest_url, auth=(args.user, args.password), verify=False, data=json.dumps(args.data), headers=header)
    r_json = r.json()
    if r.status_code == 200:
      return(r_json)
    else:
      r.raise_for_status()
  except ValueError:
    raise Exception(r)
  except Exception:
    raise

Thanks very much for your help!