Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Flask REST API Resourceful Blueprints Status Codes

Stephen Falck
Stephen Falck
7,558 Points

what is wrong with the code here? it keeps saying every aspect of the delete function is wrong

Bummer: DELETE method returned a body. The body should be empty; Didn't find a Location header with the correct URL; DELETE method didn't have a 204 status code

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.recipes.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

Steven Parker
Steven Parker
210,468 Points

You're really close! And I actually did the same thing on my first attempt. But then I changed "resources.recipes.recipelist" to "resources.recipes.recipes" and it passed.