Building Mock APIs with Swagger
This step-by-step tutorial for constructing a mock API in Python using Swagger. In this article, we’ll step through the full process, from defining our API with Swagger to developing and testing a mock server. Whether you’re an experienced developer or just starting started, this article will show you how to construct Mock APIs with Swagger. The project entails developing basic Mock APIs with Swagger, building a mock server in Python, and testing it to replicate API behavior.
Basic Terminologies
Building Mock APIs with Swagger in Python
Using Swagger, we will build a “basic Todo API“, produce a Python server stub, implement mock server logic, and execute the application. To replicate API answers, mock data for todos will be utilized. Below is the step-by-step procedure to build mock APIs with Swagger:
Step 1: Installation
In this step, we will install all the dependencies that we will require to build Mock APIs with Swagger. These are:
Install the below dependencies using pip and the following command:
pip install flask-restful
pip install flasgger
Step 2: Project Structure
Folder Structure
|--->app.py
|--->swagger.yml
Step 3: Create Swagger Specification
The provided Swagger YAML file (swagger.yml) defines the API structure and is used by the Swagger instance to generate Swagger UI documentation for the API. In this code, a Swagger 2.0 specification defines a Todo API with CRUD operations. It includes endpoints for retrieving all todos, creating a new todo, and managing individual todos by ID through GET, PUT, and DELETE operations.
Python3
swagger: '2.0' info: title: Todo API description: Simple Todo API with CRUD operations version: '1.0' paths: / todos: get: summary: Get all todos responses: '200' : description: A list of todos post: summary: Create a new todo parameters: - name: todo in : body required: true schema: type : object properties: task: type : string description: The task for the new todo completed: type : boolean description: Whether the task is completed responses: '201' : description: Todo created successfully / todos / {todo_id}: parameters: - name: todo_id in : path required: true type : integer get: summary: Get a specific todo by ID responses: '200' : description: Todo details '404' : description: Todo not found put: summary: Update a specific todo by ID parameters: - name: todo in : body required: true schema: type : object properties: task: type : string description: The updated task completed: type : boolean description: Whether the task is completed responses: '200' : description: Todo updated successfully '404' : description: Todo not found delete: summary: Delete a specific todo by ID responses: '200' : description: Todo deleted successfully '404' : description: Todo not found |
Step 4: Implement Mock API Server Logic
In this Python code, a Flask application is created to implement a Todo API using Flask-Restful. The endpoints for managing todos are defined with GET, PUT, DELETE, POST methods, and Swagger is integrated for API documentation using the provided Swagger YAML template.
app.py
Python3
from flask import Flask, request from flask_restful import Api, Resource from flasgger import Swagger app = Flask(__name__) api = Api(app) swagger = Swagger(app, template_file = 'swagger.yml' ) todos = [] class TodoResource(Resource): def get( self , todo_id): todo = next ((t for t in todos if t[ 'id' ] = = todo_id), None ) if todo: return todo else : return { 'message' : 'Todo not found' }, 404 def put( self , todo_id): todo = next ((t for t in todos if t[ 'id' ] = = todo_id), None ) if todo: todo[ 'task' ] = request.json.get( 'task' , todo[ 'task' ]) todo[ 'completed' ] = request.json.get( 'completed' , todo[ 'completed' ]) return { 'message' : 'Todo updated successfully' } else : return { 'message' : 'Todo not found' }, 404 def delete( self , todo_id): global todos todos = [t for t in todos if t[ 'id' ] ! = todo_id] return { 'message' : 'Todo deleted successfully' } class TodoListResource(Resource): def get( self ): return { 'todos' : todos} def post( self ): new_todo = { 'id' : len (todos) + 1 , 'task' : request.json[ 'task' ], 'completed' : request.json.get( 'completed' , False ) } todos.append(new_todo) return { 'message' : 'Todo created successfully' }, 201 api.add_resource(TodoListResource, '/todos' ) api.add_resource(TodoResource, '/todos/<int:todo_id>' ) if __name__ = = '__main__' : app.run(debug = True ) |
Step By Step Explanation of this Code
Import Necessary Modules
Import necessary modules and libraries, including Flask for the web framework, request for handling HTTP requests, Api and Resource from Flask-RESTful for building REST APIs, and Swagger from flasgger for integrating Swagger UI. Initialize the Flask app, API, and Swagger.
Python3
from flask import Flask, request from flask_restful import Api, Resource from flasgger import Swagger app = Flask(__name__) api = Api(app) swagger = Swagger(app, template_file = 'swagger.yml' ) todos = [] |
TodoResource Class
Define a class for handling individual todos (TodoResource). Implement methods for handling GET (retrieve todo by ID), PUT (update todo by ID), and DELETE (delete todo by ID) operations. The methods use the global todos list to store todo items.
Python3
class TodoResource(Resource): def get( self , todo_id): todo = next ((t for t in todos if t[ 'id' ] = = todo_id), None ) if todo: return todo else : return { 'message' : 'Todo not found' }, 404 def put( self , todo_id): todo = next ((t for t in todos if t[ 'id' ] = = todo_id), None ) if todo: todo[ 'task' ] = request.json.get( 'task' , todo[ 'task' ]) todo[ 'completed' ] = request.json.get( 'completed' , todo[ 'completed' ]) return { 'message' : 'Todo updated successfully' } else : return { 'message' : 'Todo not found' }, 404 def delete( self , todo_id): global todos todos = [t for t in todos if t[ 'id' ] ! = todo_id] return { 'message' : 'Todo deleted successfully' } |
TodoListResource Class
Define a class for handling the list of todos (TodoListResource). Implement methods for handling GET (retrieve all todos) and POST (create a new todo) operations. The POST method adds a new todo to the todos list.
Python3
class TodoListResource(Resource): def get( self ): return { 'todos' : todos} def post( self ): new_todo = { 'id' : len (todos) + 1 , 'task' : request.json[ 'task' ], 'completed' : request.json.get( 'completed' , False ) } todos.append(new_todo) return { 'message' : 'Todo created successfully' }, 201 |
Resource Registration
Register the TodoListResource class to handle routes for listing and creating todos (‘/todos’) and the TodoResource class to handle routes for individual todos (‘/todos/<int:todo_id>’). Start the Flask application if the script is run directly.
Python3
api.add_resource(TodoListResource, '/todos' ) api.add_resource(TodoResource, '/todos/<int:todo_id>' ) if __name__ = = '__main__' : app.run(debug = True ) |
Step 5: Run the Mock Server:
Execute the Python script (python app.py). To execute the script, open a terminal and navigate to the project directory then run the command:
python app.py
Now, access Swagger UI at http://127.0.0.1:5000/apidocs/ to interact with the mock API.
http://127.0.0.1:5000/apidocs/
Output
Video Demonstration
Building Mock API Using Swagger Another Example
Below is the step-by-step procedure to build another mock APIs with Swagger in Python.
Note: We are using same file structure as above.
Folder Structure
|--->books.py
|--->swagger_books.yml
Step 1: Create Swagger Specification (swagger_books.yml)
In this code, a Swagger 2.0 specification defines a simple Book API with CRUD operations, including endpoints for retrieving all books, creating a new book, and managing individual books by ID through GET, PUT, and DELETE operations. The API documentation is structured to include details about book title, author, and appropriate HTTP responses.
Python3
swagger: '2.0' info: title: Book API description: Simple Book API with CRUD operations version: '1.0' paths: / books: get: summary: Get all books responses: '200' : description: A list of books post: summary: Create a new book parameters: - name: book in : body required: true schema: type : object properties: title: type : string description: The title of the book author: type : string description: The author of the book responses: '201' : description: Book created successfully / books / {book_id}: parameters: - name: book_id in : path required: true type : integer get: summary: Get a specific book by ID responses: '200' : description: Book details '404' : description: Book not found put: summary: Update a specific book by ID parameters: - name: book in : body required: true schema: type : object properties: title: type : string description: The updated title author: type : string description: The updated author responses: '200' : description: Book updated successfully '404' : description: Book not found delete: summary: Delete a specific book by ID responses: '200' : description: Book deleted successfully '404' : description: Book not found |
Step 2: Write Python Script
In this Python code, a Flask application with Flask-Restful is implemented to create a Book API. Endpoints for managing books include GET, PUT, DELETE, and POST methods, with Swagger used for API documentation based on the provided Swagger YAML template (‘swagger_books.yml’). The code defines resources for book details, supports CRUD operations, and runs a development server when executed.
books.py
Python3
from flask import Flask, request from flask_restful import Api, Resource from flasgger import Swagger app = Flask(__name__) api = Api(app) swagger = Swagger(app, template_file = 'swagger_books.yml' ) books = [] class BookResource(Resource): def get( self , book_id): book = next ((b for b in books if b[ 'id' ] = = book_id), None ) if book: return book else : return { 'message' : 'Book not found' }, 404 def put( self , book_id): book = next ((b for b in books if b[ 'id' ] = = book_id), None ) if book: book[ 'title' ] = request.json.get( 'title' , book[ 'title' ]) book[ 'author' ] = request.json.get( 'author' , book[ 'author' ]) return { 'message' : 'Book updated successfully' } else : return { 'message' : 'Book not found' }, 404 def delete( self , book_id): global books books = [b for b in books if b[ 'id' ] ! = book_id] return { 'message' : 'Book deleted successfully' } class BookListResource(Resource): def get( self ): return { 'books' : books} def post( self ): new_book = { 'id' : len (books) + 1 , 'title' : request.json[ 'title' ], 'author' : request.json[ 'author' ] } books.append(new_book) return { 'message' : 'Book created successfully' }, 201 api.add_resource(BookListResource, '/books' ) api.add_resource(BookResource, '/books/<int:book_id>' ) if __name__ = = '__main__' : app.run(debug = True ) |
Step 5: Run the Mock Server
Execute the Python script (python app.py). To execute the script, open a terminal and navigate to the project directory then run the command:
python books.py
Now, access Swagger UI at http://127.0.0.1:5000/apidocs/ to interact with the mock API.
http://127.0.0.1:5000/apidocs/
Contact Us