Tutorial: Restful API with Flask
Overview
In this tutorial, you can create a RESTful API using Flask and the PyMongo driver. This API will manage a collection of cocktail recipes, demonstrating key concepts such as data transformation, validation, pagination, and error handling.
Prerequisites
Ensure you have the following components installed and set up before you start this tutorial:
Tutorial
You can find the completed sample app for this tutorial in the Rewrite it in Rust - Flask Cocktail API GitHub repository.
Set-up
Create a new directory for your project and set up a virtual environment:
mkdir flask_mongo_api cd flask_mongo_api python3 -m venv venv source venv/bin/activate # On Windows, use `venv\Scripts\activate`
Install the necessary dependencies:
pip install Flask pymongo pydantic
Create a file named app.py
and add the following code:
from flask import Flask, jsonify, request from pymongo import MongoClient from pydantic import BaseModel, ValidationError from typing import List, Optional app = Flask(__name__) # MongoDB connection client = MongoClient("your_connection_string") db = client['cocktail_recipes'] collection = db['recipes'] class Recipe(BaseModel): name: str ingredients: List[str] instructions: str category: Optional[str] = None def get_recipes(): recipes = list(collection.find()) for recipe in recipes: recipe['_id'] = str(recipe['_id']) return jsonify(recipes) def add_recipe(): try: recipe_data = Recipe.parse_obj(request.json) collection.insert_one(recipe_data.dict()) return jsonify({"message": "Recipe added successfully"}), 201 except ValidationError as e: return jsonify(e.errors()), 400 if __name__ == '__main__': app.run(debug=True)
Step 2: Run Your Application
Execute the following command to start your Flask application:
python app.py
Your API will be accessible at http://127.0.0.1:5000.
Step 3: Testing the API
You can test your API using tools like Postman or curl.
GET /recipes: Fetch all recipes
curl http://127.0.0.1:5000/recipes POST /recipes: Add a new recipe
curl -X POST -H "Content-Type: application/json" \ -d '{"name": "Mojito", "ingredients": ["Rum", "Mint", "Sugar", "Lime"], "instructions": "Muddle mint leaves, add rum, sugar, and lime juice. Serve over ice."}' \ http://127.0.0.1:5000/recipes
Step 4: Implementing Pagination
To handle large datasets efficiently, implement pagination in your GET endpoint:
def get_recipes(): page = int(request.args.get('page', 1)) per_page = int(request.args.get('per_page', 10)) skip = (page - 1) * per_page recipes = list(collection.find().skip(skip).limit(per_page)) for recipe in recipes: recipe['_id'] = str(recipe['_id']) return jsonify(recipes)
Access paginated results by appending query parameters:
curl "http://127.0.0.1:5000/recipes?page=2&per_page=5"
Step 5: Error Handling
Enhance your application with custom error handling:
def bad_request(error): return jsonify({"error": "Bad Request", "message": error.description}), 400 def not_found(error): return jsonify({"error": "Not Found", "message": error.description}), 404 def internal_error(error): return jsonify({"error": "Internal Server Error", "message": error.description}), 500
These handlers provide meaningful error messages and appropriate HTTP status codes.
You've now built a RESTful API using Flask and MongoDB, incorporating essential features like data validation, pagination, and error handling. This foundation can be expanded with additional functionalities such as authentication, advanced querying, and deployment strategies.
For further reading and advanced topics, explore the MongoDB Developer Center and the Flask Documentation.
More resources
If you're new to these technologies, consider reviewing the following resources:
Think Python
Python & MongoDB Quickstart Series
Flask Tutorial
Pydantic Documentation