Skip to content Skip to sidebar Skip to footer

Two Variable Urls Using Flask-restful

This seems like something that would come up a lot, but I can't find any documentation on it. I'm writing an api and I want urls to look like this: '/api/v1.0/restaurant/Name&A

Solution 1:

This has nothing to do with the & ampersand nor with with using more than one URL parameter.

You can only use entries from the resto_fields output fields mapping in your endpoint; you don't have an address entry in your resto_fields mapping, but your restaurant endpoint requires it to build the URL.

Add an address field to your output fields, or use one of the existing fields in the route.

Solution 2:

This is not ideal, but it gets things working.

The problem was occurring when flask-restful was trying to create the uri for the resource during marshalling with resto_fields.

This wasn't a problem when the url only took name as a variable, but, once the url required name&address, a BuildError would get raised.

To workaround this problem I removed

'uri': fields.Url('restaurant')

from restos_fields, and constructed the uri after marshalling the resource and added it to the marshalled resource before returning it.

    resto = {'restaurant': marshal(restaurant, resto_fields)}

    resto['restaurant']['uri'] = '/api/v1.0/restaurant/{0}&{1}'.format(name, address)
    return resto

If anyone has a more elegant way of making this work I'd be eager to hear about it.

Solution 3:

Took me a while to figure this out, so a corrected answer...

@Martijn's answer is not quite correct for this case.

Correct is: You have to have the attributes required for the get method in your data dictionary (Not in the output fields).

So your code should work like this:

resto_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'street_address': fields.String,
    'address_locality': fields.String,
    'address_region': fields.String,
    ‘score’: fields.Float,
    'phone_number': fields.String,
    'uri': fields.Url('restaurant')
    }

def get(self, name, address):
    restaurant = session.query(Restaurant).filter_by(name=name).filter_by(address=address)

    # restaurant must have an 'address' field
    restaurant['address'] = ' '.join[restaurant['street_address'], restaurant['address_locality']]
    resto = {'restaurant': marshal(restaurant, resto_fields)}

    return resto

addresswill not be part of the generated response

Post a Comment for "Two Variable Urls Using Flask-restful"