import requests


def censusvar(src, year, var):
	"""Download information on a list of variables from Census API.

	Args:
		src (str): Census data source: 'acs1' for ACS 1-year estimates, 'acs5' for ACS 5-year estimates, 'acs3' for
			ACS 3-year estimates, 'acsse' for ACS 1-year supplemental estimates, 'sf1' for SF1 data.
		year (int): Year of data.
		var (list of str): Names of Census variable.

	Returns:
		dict: Dictionary with keys 'concept' (overall concept the variable falls under), 'label' (variable label),
			and 'predicateType' (variable type).

	Examples::

		censusdata.censusvar('sf1', 2010, ['P0010001']) # Returns information on the variable P0010001 from the 2010 Census SF1.
	"""
	assert src == 'acs1' or src == 'acs3' or src == 'acs5' or src == 'acsse' or src == 'sf1'
	ret = dict()
	for v in var:
		if src == 'acsse' or src == 'sf1' or v[0] == 'B':
			tabletype = ''
		elif v[0] == 'S':
			tabletype = 'subject/'
		elif v[:2] == 'DP':
			tabletype = 'profile/'
		elif v[:2] == 'CP':
			tabletype = 'cprofile/'
		elif v[0] == 'C':
			tabletype = ''
		else:
			raise ValueError(u'Unknown table type for variable {0}!'.format(v))
		if (src == 'acs1' or src == 'acs5' or src == 'acsse') and year >= 2010: presrc = 'acs/'
		elif src == 'acs3': presrc = 'acs/'
		elif src == 'sf1': presrc = 'dec/'
		else: presrc = ''
		r = requests.get('https://api.census.gov/data/{year}/{presrc}{src}/{tabletype}variables/{v}.json'.format(src=src, year=year, v=v, tabletype=tabletype, presrc=presrc))
		try:
			data = r.json()
		except:
			raise ValueError(u'Unexpected response (URL: {0.url}): {0.text} '.format(r))
		try:
			assert data['name'] == v
		except AssertionError:
			raise AssertionError(u'JSON variable information does not include key "name"', data)
		expectedKeys = ['group', 'label', 'limit', 'name',]
		try:
			assert [k for k in sorted(data.keys()) if k != 'attributes' and k != 'concept' and k != 'predicateType'] == expectedKeys
		except AssertionError:
			print(u'JSON variable information does not include expected keys ({0} and possibly attributes, concept, predicateType) or includes extra keys: '.format(expectedKeys), data)
		try: 
			ret[v] = [data.get('concept', ''), data['label'], data.get('predicateType', '')] # Concept, predicate type not provided for all years; default to empty if not provided
		except KeyError:
			raise KeyError(u'JSON variable information does not include expected keys: ', data)
	return ret