shelterapi.py 5.16 KB
Newer Older
Aron Gergely's avatar
Aron Gergely committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    #! /usr/bin/env python
#-*- coding: utf-8 -*-

# ***** BEGIN LICENSE BLOCK *****

#
#
# ***** END LICENSE BLOCK *****

__author__ = ""
__version__ = ""
__date__ = ""
__revision__ = ""
__copyright__ = ""
__license__ = ""

17 18 19
#from bootstrap import db
from bootstrap import db
from sqlalchemy.sql import func
20
from flask import Blueprint, jsonify, request
Aron Gergely's avatar
Aron Gergely committed
21
from collections import defaultdict
22
from web.models import Shelter, Attribute, Property, Value, Association
23

Aron Gergely's avatar
Aron Gergely committed
24 25 26
api_bp = Blueprint('api for shelter', __name__, url_prefix='/api/v0.1')

def tree():
27
    return defaultdict(tree)
28 29

def queryfactory(model,join=False,filt=False,value=False):
30
	
31 32 33 34 35 36
	#helper functions to construct queries
	def filter_or(obj,attrib,val):
		"""Construct filtering method (OR)"""
		list(val)
		if len(val) == 1:
			return obj.filter(attrib == val[0])
37
		else: 
38 39 40 41 42 43 44 45 46 47
			return obj.filter(attrib.in_(val))
	
	def filter_and(obj,attrib,val):
		"""Construct filtering methods recursively (AND)"""
		list(val)
		if len(val) == 1:
			return obj.filter(attrib == val[0])
		else: 
			return filter_and(obj.filter(attrib == val[len(val)-1]),attrib, val[0:len(val)-1])

48
#subquery = queryfactory(Property,Attribute,Attribute.name,attr)
49 50

	if join and not filt:
51
		return model.query.join(join)
52
	elif filt and join:
53
		return filter_or(model.query.join(join),filt,value)
54
	elif filt and not join:
55
		return filter_or(model.in_(value))
56 57
	else:
		return "error"
58 59 60 61 62 63 64 65 66

@api_bp.route('/', methods=['GET'])
def apimessage():
    message = tree()
    message["API version"] = 0.1
    message["Message"] = "This is the development API"
    return jsonify(message)

@api_bp.route('/attributes/<attribute_name>', methods=['GET'])
67
def getattributes(attribute_name, safetext=False):
68 69 70
    """Returns available values for a given attribute name, separated by semicolons"""
    result= tree()
    
71
    attributes = Attribute.query.filter(Attribute.uniqueid==attribute_name).\
72
                                first().associated_values
73 74
   
    result[attribute_name] = ";".join([attribute.name for attribute in attributes])
75
    return jsonify(result)
Aron Gergely's avatar
Aron Gergely committed
76 77 78

@api_bp.route('/shelters', methods=['GET'])
def allshelters():
79
    """Returns all shelters and their properties"""
Aron Gergely's avatar
Aron Gergely committed
80
    result = tree()
81
    
82 83
    ## attribute parameter listening
    if request.args.getlist('attribute'):
84 85
    	attr = request.args.getlist('attribute')
    
86
    	subquery = queryfactory(Property,Attribute,Attribute.uniqueid,attr).subquery()
87 88
    	shelter_properties = Property.query.filter(Property.shelter_id==subquery.c.shelter_id).all()
    else:
89 90 91 92 93 94
    	shelter_properties = db.session.query(Property.shelter_id,Attribute.name,func.string_agg(Value.name,"';'").label("value"))\
    		.join(Attribute)\
    		.join(Association,Property.id==Association.property_id)\
    		.join(Value, Association.value_id==Value.id)\
    		.group_by(Property.shelter_id, Attribute.name)
    	print(shelter_properties)
95
    
96
    ## value parameter listening
97
    if request.args.getlist('attribute') and request.args.getlist('value'):
98
    	valu = request.args.getlist('value')
99
    
100
    	subquery = Property.query.filter(Property.attribute.has(Attribute.uniqueid.in_(attr)), Property.values.any(Value.name.in_(valu))).subquery()
101
    	shelter_properties = Property.query.filter(Property.shelter_id==subquery.c.shelter_id).all()
102

103
    ## format parameter listening and populate defaultict	
104
    if request.args.get('format') == 'prettytext':
105 106 107 108
    	for shelter_property in shelter_properties:
    		result[shelter_property.shelter_id][shelter_property.attribute.name] = shelter_property.get_values_as_string()
    else:
    	for shelter_property in shelter_properties:
109
    		result[shelter_property.shelter_id][shelter_property.name] = shelter_property.value
Aron Gergely's avatar
Aron Gergely committed
110 111
    return jsonify(result)

112

Aron Gergely's avatar
Aron Gergely committed
113
@api_bp.route('/shelters/<int:shelter_id>', methods=['GET'])
114 115
def shelters(shelter_id):
    """Returns specific shelter with its properties"""
Aron Gergely's avatar
Aron Gergely committed
116 117
    result = tree()
    shelter_properties  = Property.query.filter(Property.shelter_id==shelter_id)
118
    for shelter_property in shelter_properties:
119 120
    	result[shelter_property.shelter_id][shelter_property.attribute.uniqueid] = shelter_property.get_values_as_string()
    
Aron Gergely's avatar
Aron Gergely committed
121 122
    return jsonify(result)

123 124 125 126 127 128
@api_bp.route('/shelters/<attribute_name>', methods=['GET'])
@api_bp.route('/shelters/<attribute_name>/<attribute_value>', methods=['GET'])
def attributes(attribute_name, attribute_value=''):
    """Returns all shelters which match a specific attribute name or attribute name + value"""
    result = tree()
    if not attribute_value:
129
    	shelter_properties = Property.query.filter(Property.attribute.has(uniqueid=attribute_name))
130
    else:
131
    	shelter_properties = Property.query.filter(Property.attribute.has(uniqueid=attribute_name), Property.values.any(name=attribute_value))
132 133
    
    for shelter_property in shelter_properties:
134
    	result[shelter_property.shelter_id][shelter_property.attribute.uniqueid] = shelter_property.get_values_as_string()
135
   
136
    return jsonify(result)
137

138 139 140 141
#shelter_properties = Property.query.join(Property.category).filter(Property.category.has(name="Identification"))
#for shelter_property in shelter_properties:
#    	result[shelter_property.shelter_id][shelter_property.attribute.name] = shelter_property.get_values_as_string()
#    return jsonify(result)
142