Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore Python API Development Fundamentals Develop a full stack web application

Python API Development Fundamentals Develop a full stack web application

Published by Willington Island, 2021-06-26 18:00:04

Description: Python_API_Development_Fundamentals_Develop_a_full_stack_web_application

Search

Read the Text Version

Figure 7.16: Checking the uploaded image in the path 13. Get the recip e back and confirm that the cover_url attribute is p op ulated. Now, click on the Collections tab and select the GET Recipe request. Then, ty p e http://localhost:5000/recipes/5 into the URL field. You may rep lace the recip e ID, that is, 5, with any ID that is ap p rop riate. Then, click the S end button. The result can be seen in the following screenshot: Figure 7.17: Getting the recipe backand confirming that the cover_url attribute is populated Congratulations! We have tested the recip e cover image up load function. It works great! 8: Pagination, Searching, and Ordering Activity 13: Implementing Pagination on the User-Specific Recipe Retrieval API

S olution 1. M odify the code in the get_all_by_user method under models/recipe.py, as follows: @classmethod def get_all_by _user(cls, user_id, p age, p er_p age, visibility ='p ublic'): query = cls.query.filter_by (user_id=user_id) if visibility == 'p ublic': query = cls.query.filter_by (user_id=user_id, is_p ublish=True) elif visibility == 'p rivate': query = cls.query.filter_by (user_id=user_id, is_p ublish=False) return query.order_by (desc(cls.created_at)).p aginate(p age=p age, p er_p age=p er_p age) 2. Imp ort RecipePaginationS chema into resources/user.py: from schemas.recip e imp ort Recip eSchema, Recip ePaginationSchema 3. Declare the recipe_pagination_schema attribute in resources/user.py: recip e_p agination_schema = Recip ePaginationSchema() 4. Here, we've added the @user_kwargs decorator to UserRecipeListResource.get. It takes a few p arameters, including page, per_page, and visibility: class UserRecip eListResource(Resource): @jwt_op tional @use_kwargs({'p age': fields.Int(missing=1), 'p er_p age': fields.Int(missing=10), 'visibility ': fields.Str(missing='p ublic')}) 5. M odify the UserRecipeListResource.get method in resources/user.py: def get(self, username, p age, p er_p age, visibility ): user = User.get_by _username(username=username) if user is None: return {'message': 'User not found'}, HTTPStatus.NOT_FOUND current_user = get_jwt_identity () if current_user == user.id and visibility in ['all', 'p rivate']: p ass else: visibility = 'p ublic'

p aginated_recip es = Recip e.get_all_by _user(user_id=user.id, p age=p age, p er_p age=p er_p age, visibility =visibility ) return recip e_p agination_schema.dump (p aginated_recip es).data, HTTPStatus.OK The Recipe.get_all_by_user method gets the p aginated recip es by a p articular author, and then lets recipe_pagination_schema serialize the p aginated object and return it. Activity 14: Testing Pagination on the User-Specific Recipe RetrievalAPI S olution 1. Get all the recip es under John using Postman, p age by p age, with a p age size of two. First, click on the UserRecipeList request. 2. Ty p e http://localhost:5000/{username}/recipes into the Request URL. The {username} here should be the same as the one we inserted in the p revious exercise. In our case, it will be john. 3. Select the Params tab and p ut in the key -value p air (per_page, 2). 4. Send the request. The result is shown in the following screenshot: Figure 8.9: Getting all the recipes under John using Postman In the details of the recip e, we can see that there are links with the URLs of the first, last, and next p ages. We can't see the prev p age here because we are on the first p age. There is a total of four p ages, and we have two records p er p age. We can also see the sorted recip e details in the HTTP resp onse. 5. Click the next URL in links to query for the next two records in Postman with the request URL p op ulated (http://localhost:5000/users/john/recipes?per_page=2&page=2). Then, we just need to click on S end to send the request. The result is shown in the following screenshot:

Figure 8.10: Q uerying for the next two records in Postman with the request URL populated From the result, we can see that there are links to the first, last, next, and prev p ages. We can also see that we are currently on p age two. All the recip e data is there as well. Activity 15: Searching for Recipes with Specific Ingredients S olution 1. First, in models/recipe.py, add the ingredients attribute to the Recipe model: ingredients = db.Column(db.String(1000)) 2. Run the following command to generate a database migration scrip t: flask db migrate You will see that a new column called recipe.ingredients has been detected: INFO [alembic.autogenerate.comp are] Detected added column 'recip e.ingredients' Generating /TrainingBy Packt/Py thon-API-Develop ment-Fundamentals/smilecook/migrations/versions/0876058ed87e_.p y ... done 3. Check the content in /migrations/versions/0876058ed87e_.py, which is the database migration scrip t that was generated in the p revious step : \"\"\"emp ty message Revision ID: 0876058ed87e

Revises: 91c7dc71b826 Create Date: 2019-10-24 15:05:10.936752 \"\"\" from alembic imp ort op imp ort sqlalchemy as sa # revision identifiers, used by Alembic. revision = '0876058ed87e' down_revision = '91c7dc71b826' branch_labels = None dep ends_on = None def up grade(): # ### commands auto generated by Alembic - p lease adjust! ### op .add_column('recip e', sa.Column('ingredients', sa.String(length=1000), nullable=True)) # ### end Alembic commands ### def downgrade(): # ### commands auto-generated by Alembic - p lease adjust! ### op .drop _column('recip e', 'ingredients') # ### end Alembic commands ### Here, we can see that two functions have been generated in the scrip t. The upgrade function is used to add the new column, ingredients, to the recip e table, whereas the downgrade function is used to remove the ingredients column so that it goes back to its original state. 4. Run the following flask db upgrade command to up date the database schema: flask db up grade You will see the following outp ut: INFO [alembic.runtime.migration] Context imp l PostgresqlImp l. INFO [alembic.runtime.migration] Will assume transactional DDL. INFO [alembic.runtime.migration] Running up grade 91c7dc71b826 -> 0876058ed87e, emp ty message 5. In schemas/recipe.py, add the ingredients attribute to RecipeS chema: ingredients = fields.String(validate=[validate.Length(max=1000)]) 6. M odify the RecipeResource.patch method in resources/recipe.py to be able to up date ingredients: recip e.ingredients = data.get('ingredients') or recip e.ingredients

7. M odify the Recipe.get_all_published method in models/recipe.py so that it gets all the p ublished recip es that it can through the ingredients: return cls.query.filter(or_(cls.name.ilike(key word), cls.descrip tion.ilike(key word), cls.ingredients.ilike(key word)), cls.is_p ublish.is_(True)).\\ order_by (sort_logic).p aginate(p age=p age, p er_p age=p er_p age) 8. Right-click on it to run the ap p lication. Flask will then start up and run on localhost (127.0.0.1) at p ort 5000: Figure 8.11: Running Flaskon the localhost 9. Log in to a user account and create two recip es by running the following httpie command in the Py Charm console. The {token} p laceholder should be rep laced with the access token: http POST localhost:5000/recip es \"Authorization: Bearer {token}\" name=\"Sweet Potato Casserole\" descrip tion=\"This is a lovely Sweet Potato Casserole\" num_of_servings=12 cook_time=60 ingredients=\"4 cup s sweet p otato, 1/2 cup white sugar, 2 eggs, 1/2 cup milk\" directions=\"This is how y ou make it\" http POST localhost:5000/recip es \"Authorization: Bearer {token}\" name=\"Pesto Pizza\" descrip tion=\"This is a lovely Pesto Pizza\" num_of_servings=6 cook_time=20 ingredients=\"1 p re-baked p izza crust, 1/2 cup p esto, 1 rip e tomato\" directions=\"This is how y ou make it\" 10. Publish these two recip es by using the following httpie command: http PUT localhost:5000/recip es/14/p ublish \"Authorization: Bearer {token}\" http PUT localhost:5000/recip es/15/p ublish \"Authorization: Bearer {token}\" 11. Search for recip es that contain the eggs string in the name, descrip tion, or ingredients. Click on the RecipeList request and select the Params tab. Then, insert the first key -value p air (q, eggs) and send the request. The result is shown in the following screenshot:

Figure 8.12: Searching for the eggs ingredient by sending a request From the p receding search result, we can see that there is a recip e with eggs in the ingredients. 9: Building More Features Activity 16: Getting Cache Data after Updating Recipe Details S olution 1. Get all the recip e data back, click on RecipeList and send the request. The result is shown in the following screenshot:

Figure 9.15: Get the recipe data backand send the request 2. Log in to y our account, click on the Collections tab and select the POS T Token request. Then, send the request. The result is shown in the following screenshot: Figure 9.16: Select the POST Token request and send it 3. M odify a recip e record using the PATCH method. First, select the PATCH Recipe request. 4. Now select the Headers tab and modify Bearer {token}; the token should be the access token.

5. Select the Body tab and modify num_of_servings to 5, and cook_time to 50: { \"num_of_servings\": 5, \"cook_time\": 50 } 6. Send the request. The result is shown in the following screenshot: Figure 9.17: Modifying a recipe record using the PATCH method 7. Get all the recip e data back again, click on RecipeList. 8. Send the request. The result is shown in the following screenshot:

Figure 9.18: Get all the recipe data backagain We can see that when we get all the recip e details again, the details are not up dated, which will cause the user to see the wrong information. Activity 17: Adding Multiple Rate-Limit Restrictions S olution 1. In resources/user.py, imp ort limiter from extensions: from extensions imp ort image_set, limiter 2. In UserRecipeListResource, p ut the limiter.limit function in the decorators attribute: class UserRecip eListResource (Resource): decorators = [limiter.limit('3/minute;30/hour;300/day ', methods=['GET'], error_message='Too M any Requests')] 3. Comment out the whitelist in app.py: # @limiter.request_filter # def ip _whitelist(): # return request.remote_addr == '127.0.0.1' In Py Charm, to comment out a line of code, if y ou are using M ac, y ou can use Command + /, and if y ou are using Windows, y ou can use Ctrl + /. 4. When we are done, click Run to start the Flask ap p lication; then, we are ready to test it:

Figure 9.19: Starting the Flaskapplication 5. Get all the recip es for a user and check the rate limit information in the resp onse header. First, click on UserRecipeList and send the request. 6. Then, select the Header tab in Response. The result is shown in the following screenshot: Figure 9.20: Checking the rate limit information in the response header In the HTTP resp onse, we can see that the rate limit for this endp oint is three, while we only have two remaining request quotas. The limit is going to be reset in 60 seconds. 10: Deployment Activity 18: Changing access_token to a Variable in Postman S olution 1. Perform user login and get the access token. Use the POS T Token request to get the access token. You should see the following out p ut :

Figure 10.29: Performing user login to get an access token 2. Click Manage environments in the top right-hand corner in Postman. Create the access_token variable. The value is the access token we obtained in the p revious step . Then, click Update:

Figure 10.30: Adding more environment variables in Postman 3. Select the GET User request. In the Headers tab, change the Authorization value to Bearer {{access_token}}, which is the environment variable we added in the p revious step , and then send the request. You should see the following outp ut: Figure 10.31: Using more environment variables in Postman


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook