Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Flask REST API Resourceful Blueprints Status Codes

samar shah
samar shah
2,701 Points

stuck!!

cannot for the life of me figure out what I am doing wrong here, very confused, any help would be much appreciated. Thanks

resources/recipes.py
from flask import Blueprint, abort, url_for

from flask.ext.restful import Resource, Api, reqparse, inputs, marshal, marshal_with, fields

import models

recipe_fields = {
    'name': fields.String
}


def get_recipe_or_404(id):
    try:
        recipe = models.Recipe.get(models.Recipe.id==id)
    except models.Recipe.DoesNotExist:
        abort(404)
    else:
        return recipe


class RecipeList(Resource):
    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument(
            'name',
            required=True,
            location=['form', 'json']
        )
        super().__init__()

    def get(self):
        return [marshal(recipe, recipe_fields) for recipe in models.Recipe.select()]

    @marshal_with(recipe_fields)
    def post(self):
        args = self.reqparse.parse_args()
        recipe = models.Recipe.create(**args)
        return (recipe, 201, {
            'Location': url_for('resources.recipes.recipe', id=recipe.id)
        })


class Recipe(Resource):
    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument(
            'name',
            required=True,
            location=['form', 'json']
        )
        super().__init__()

    @marshal_with(recipe_fields)
    def get(self, id):
        return get_recipe_or_404(id)

    @marshal_with(recipe_fields)
    def put(self, id):
        recipe = get_recipe_or_404(id)
        args = self.reqparse.parse_args()
        query = models.Recipe.update(**args).where(models.Recipe.id==id)
        query.execute()
        return (get_recipe_or_404(id), 200, {
            'Location': url_for('resources.recipes.recipe', id=recipe.id)
        })

    def delete(self, id):
        recipe = get_recipe_or_404(id)
        query = models.Recipe.delete().where(models.Recipe.id==id)
        query.execute()
        return ('', 204, {'location': url_for('resources.RecipeList')})

recipes_api = Blueprint('resources.recipes', __name__)
api = Api(recipes_api)
api.add_resource(RecipeList, '/api/v1/recipes', endpoint='recipes')
api.add_resource(Recipe, '/api/v1/recipes/<int:id>', endpoint='recipe')

1 Answer

Rohald van Merode
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Rohald van Merode
Treehouse Staff

Hey samar shah 👋

You'll want to have a look at value you're passing to the Location-header, currently you're setting it to resources.RecipeList but this is not an available endpoint.

On the second to last line the endpoint for the RecipeList resource is set to recipes. You'll therefor want to adjust the Location header to point to 'resources.recipes.recipes. After making that adjustment your code should pass as expected 😄

    return ('', 204, {'Location': url_for('resources.recipes.recipes')})

Hope this helps! 🙂

samar shah
samar shah
2,701 Points

I see, thank you for the response! really appreciated.