Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

FastAPI Tutorial – How to Develop, Test, and Deploy APIs

Welcome to the world of FastAPI, a sleek and high-performance web framework for constructing Python APIs. Don't worry if you're new to API programming – we'll start at the beginning. An API (Application Programming Interface) connects several software programs allowing them to converse and exchange information. APIs are essential in modern software development as they are an application's backend architecture.After reading this quick start guide, you will be able to develop a course administration API using FastAPI and MongoDB. The best part is that you will not only be writing APIs but also testing and containerizing the app.In this walkthrough project, we'll create a Python backend system using FastAPI, a fast web framework, and a MongoDB database for course information storage and retrieval. The system will allow users to access course details, view chapters, rate individual chapters, and aggregate ratings. The project is designed for Python developers with basic programming knowledge and some NoSQL knowledge. Familiarity with MongoDB, Docker, and PyTest is not required since I will be highlighting everything you need to know for the scope of this project. Here's what we are going to be building:FastAPI Backend: It will serve as the interface for handling API requests and responses. FastAPI is chosen for its ease of use, performance, and intuitive design.MongoDB Database: A NoSQL database to store course information. MongoDB's flexible schema allows us to store data in JSON-like documents, making it suitable for this project.Course Information: Users will be able to view various course details, such as course name, description, instructor, etc.Chapter Details: The system will provide information about the chapters in a course, including chapter names, descriptions, and any other relevant data.Chapter Rating: Users will have the ability to rate individual chapters. We will implement functionality to record and retrieve chapter ratings.Course Aggregated Rating: The system will calculate and display the aggregated Rating for each course based on the ratings of its chapters.This walkthrough shows how to set up a development environment, build a FastAPI backend, integrate MongoDB, define API endpoints, add chapter rating functionality, and compute aggregate course ratings. It covers fundamental project concepts as well as Python, MongoDB, and NoSQL databases. By the end, this useful backend system will manage chapter details, course information, and user ratings, serving as the basis for a complex and rewarding project.The goal is to create a system that processes course-related queries. The course information must then be retrieved from MongoDB depending on the request. Lastly, this answer data must be returned in a standard format (JSON).We'll begin with a script that reads the course information from courses.json. This data will be stored in the MongoDB instance. Once the data has been loaded, our API Code may connect to this database to allow for simple data retrieval.The interesting aspect is creating several endpoints with FastAPI. Our API will be able to:Additionally, for each course, we will aggregate all reviews, providing visitors with relevant information regarding course popularity and quality.This tutorial focuses on building a scalable, efficient, and user-friendly API. Once we've tested everything, we'll containerize the application using Docker. This will greatly simplify deployment, maintenance, and installation.Here are the sections of this tutorial:HTTP (Hypertext Transfer Protocol) methods specify the action to be taken on a resource. The following are the most often used API development methods:GET: Requests information from a server. When a client submits a GET request, it is requesting data from the server. POST: Sends data to the server for processing. When a client submits a POST request, it is often delivering data to the server to create or update a resource. PUT: Updates server data. When a client submits a PUT request, the resource indicated in the request is updated. DELETE: A client sending a DELETE request is asking for the removal of the specified resource.The client is often a front-end application that sends requests to the server, such as a web browser or a mobile app. The server, on the other hand, is the back-end application in charge of processing client requests and responding appropriately.A request is a communication delivered by the client to the server that specifies the intended action and any required data. The HTTP method, URL (Uniform Resource Locator), headers, and, in the case of POST or PUT requests, the data payload are all part of a request.After the server gets the request, it processes it and returns a response. The response is the message given back to the client by the server that contains the requested data or the outcome of the activity. A response generally comprises an HTTP status code indicating the success or failure of the request, as well as any data sent back to the client by the server.MongoDB is a type of NoSQL database. It is non-relational and saves information as collections and documents. Install MongoDB for your operating system from the official website. Now run the mongosh command for your terminal to verify if the installation was successful. Connect to the MongoDB server with MongoDB Compass. I recommend that you set up MongoDB by specifying settings such as port number, storage engine, authentication, and so forth. Now that the connection is established, the next step is to create a database or a "document". Call this database "courses". It will be empty for you currently. In just a minute we'll insert the documents using a Python script.You could insert records one by one, but it is best to use a JSON file to simplify that process. Download this file courses.json from GitHub. All course information is present in it (as a list of courses). Specifically, each course has the following structure:You will need a few Python packages for this project. Get them installed via the pip commands like so:Now, let's write a Python script to insert all this course data into the database so that we can start building API routes. Spin up your IDE, create a file called script.py, and make sure it is in the same directory as the courses.json file. This script populates a MongoDB database with the course information from the JSON file. It begins by connecting to the local MongoDB instance. It reads course data from a file called courses.json and creates a new field for course ratings. It then develops an index to speed up data retrieval. Lastly, the course data is added to the MongoDB collection. It's a straightforward script for managing course data in a database. On running the script, all records from the courses.json should have been inserted into the courses DB. Switch to MongoDB Compass to verify it. These API endpoints provide an efficient way to manage course information, retrieve course details, and allow user interactions for rating chapters. I recommend designing the API endpoints first along with the HTTP request type before writing the code. This acts as a good reference and provides clarity during the coding process.Okay, time to dive into the API code. Create a brand new Python file and call it main.py:The code imports essential modules and creates an active instance of the FastAPI class named app. It also establishes a connection to the local MongoDB database using the PyMongo library and the db variable now stores the connection reference to the courses document.Let's go over each of these endpoints in more detail now.This endpoint allows you to retrieve a list of all available courses. You can sort the courses based on different criteria, such as alphabetical order (based on the course title in ascending order), date (in descending order), or total course rating (in descending order). Also, we'll allow users to filter the courses based on their domain.This code defines an endpoint in the FastAPI application to retrieve a list of all available courses. The endpoint can be accessed using an HTTP GET request to the '/courses' URL.The @app.get() decorator is attached to the get_course function and it takes care of this.When a request is made to this endpoint, the code first calculates the total course rating by summing up the ratings of all the chapters in each course. It then updates the rating field of each course in the MongoDB database with the computed total and count of ratings.Next, the code determines the sorting mode based on the sort_by query parameter. If sort_by is set to date, the courses will be sorted by their creation date in descending order. If it is set to rating, the courses will be sorted by their total rating in descending order. Otherwise, the courses will be sorted alphabetically by their names in ascending order.If the optional domain query parameter is provided, the code will filter the courses based on the specified domain.Finally, the code queries the MongoDB database to retrieve the relevant course information, including the course name, creation date, description, domain, and rating. The courses are sorted according to the selected sorting mode and returned as a list.That was the code explanation, but what about the actual API response? Run the command below in your terminal from the current working directory: Uvicorn is an ASGI webserver. You can interact with API endpoints right on your local machine without any external server. On running the above command you should see a success message stating that the server has started. Fire up your browser and enter http://127.0.0.1:8000/courses in the URL bar. The output that you will see will be the JSON response directly from the server.Verify that the first object contains the following:Guess what? It is a list of all the courses that we stored in our database. Your front-end application may now iterate over all these items and present them in a fancy way to the user. That is the power of APIs.At this point, if you wish to see the documentation for your API do so by navigating to the http://127.0.0.1:8000/docs endpoint. This navigable API comes prepackages with FastAPI. How cool is that? Don't like the plain old look of the docs? Fret not, there is also a /redoc endpoint with a slightly fancier interface. Just navigate to http://127.0.0.1:8000/redoc and you will be greeted with this screen.You'll use this endpoint to get an overview of a specific course. Simply provide the course_id in the URL, and the API will return detailed information about that particular course.This code snippet searches the MongoDB database for the course with the specified course_ id and extracts the course information while leaving out the chapters field. If it cannot find the course, it throws an HTTPException with the status code 404. If it finds it, it tries to access the rating field and replaces it with its 'total' value to display the total rating. If not, the rating box is set to Not rated yet. Finally, without the chapters field, it returns the JSON response of the course information, including the total rating.Hitting this endpoint returns specific information about a chapter within a course. By specifying both the course_id and the chapter_id in the URL, you can access the details of that particular chapter.As you might expect, course_id is the course identity, and chapter id is the chapter identifier inside that course.When a request is made to this endpoint, the code first searches the MongoDB database for the course with the specified course id, ignoring the _id column in the response.If the course with the supplied course_id cannot be found in the database, the code throws an HTTPException with the status code 404, indicating that the course could not be located.The code then uses the GET function to retrieve the list of chapters for the course, setting the default value to an empty list if the 'chapters' field does not exist.Using the chapter_id provided in the request, the code then attempts to retrieve the exact chapter within the list of chapters. If the chapter id is not a valid integer or is out of range for the list of chapters, the code throws an HTTPException with the status code 404. This indicates that it could not locate the chapter.If it locates the chapter, the response contains information on the individual chapter within the course.This endpoint allows users to rate individual chapters within a course. You can provide a rating of 1 for a positive review or -1 for a negative review. The API aggregates all the ratings for each course, providing valuable feedback for future improvements.Up until now, we've mostly seen GET requests. But now let's see how you can send data to the server, validate it, and insert it in the application database. We have put in place an endpoint for users to rate each chapter within a course using an HTTP POST request to the /courses/course_id/chapter_id URL. Users can provide a rating value of 1 for a positive rating or -1 for a negative rating. The code queries the MongoDB database to find the course with the specified course_id, excluding the _id field.If it doesn't find the course, it raises an HTTP exception with a status code of 404. The code retrieves the list of chapters, setting the default value to an empty list. If the chapter_id is not a valid integer or is out of range, it raises an HTTPException with a status code of 404. If the chapter is found, the code updates its rating by incrementing the total rating value with the provided rating and incrementing the count value.If the chapter does not have an existing rating field, it creates one and initializes it with the provided rating and a count of 1. The updated rating is then updated in the database, and the updated chapter is returned as the response, providing feedback to the user about their rating for that chapter.To make a POST request, open the docs and click on the request highlighted in the above image. Then, click on "Try it out", fill in the post data, and press the Execute button right below. This sends the POST data to the server which is then validated. If all the submitted data is as expected, the server accepts and shows the 200 status code meaning that the operation was successful. The submitted data is now in the MongoDB document.That's a wrap on the API development part.As the complexity of modern web applications increases, so does the number of API endpoints and their interactions. In a dynamic e-commerce web app, there could be hundreds of endpoints, each supporting multiple HTTP request methods. And these endpoints might be intricately interconnected. Ensuring the proper functioning of all these endpoints after each development iteration becomes a formidable task for developers and QA teams. Here is where automated testing comes to the rescue.Create a file test_app.py in the same directory as courses.json and main.py:That sets up an automated testing environment. FastAPI Test Client simulates HTTP requests to the web app. With this, you can pretend to be a user, sending requests to your app and getting responses back, just like a real user would.We're using MongoDB Connection for course data storage, with MongoClient enabling interaction and data updates during tests.Test Database is a separate database for testing. It will not affect the actual course documents.With this configuration, you can now create test functions that send requests to your FastAPI app using the TestClient. You will interact with your MongoDB database during these tests, but don't worry—this is just the test database, so nothing important will be harmed.These test functions use TestClient to interact with the "/courses" endpoint of the FastAPI application. They check if the endpoint behaves as expected when different parameters, such as sorting and filtering by domain, are provided. The tests verify the status codes, data presence, sorting order, and domain filtering in the API responses, ensuring the functionality of the course endpoint is correct and reliable.Pay attention to the assert statements. The expected results are checked against actual results and it returns a True or False Boolean based on the this comparison. The objective is to get all the tests to pass by equalizing these values.The tests use TestClient to send queries to FastAPI's "/courses/course id" endpoint, retrieving course data from the MongoDB database using the db.courses.find_one function. Comparing API response data to database data can help you determine if the endpoint handles existing and non-existent course IDs.The tests anticipate the FastAPI application's "/courses/course id/chapter number" endpoint to provide chapter information for a certain course ID and number when they use the TestClient to make the request. We use assertions to determine if the answer includes the anticipated data or gives a "Not Found" response for a non-existent chapter. It validates that the correct API chapter was retrieved and handles existing and non-existent chapters.To test the rating capability, the test function specifies the course ID, chapter ID, and rating variables. It uses the TestClient's post method to submit a POST request to the "/courses/course id/chapter id" API, providing the course ID and chapter number in the URL and passing the rating variable as a query parameter. FastAPI mimics a user's activity to rate a certain chapter of a course. The response is successful with a 200 status code. JSON content is validated for "name" and "rating" keys, as well as "total" and "count" keys. The total rating and rating count are greater than 0, indicating users have rated the chapter. This verification makes sure that the rating addition endpoint works as intended, with the API returning the correct success code and expected information about the chapter, including its name and updated rating details.By running the pytest command, all the test functions in the test_app.py file will be executed, and you'll get feedback on whether the endpoints are functioning as expected or if any errors or regressions have occurred. This allows developers and QA teams to catch issues early in the development cycle and maintain the application's reliability and stability.As you can see in the image below, all the tests are passing. Good job! As you keep on adding more features and endpoints to the app, keep adding the associated tests in order to validate correctness. This is called Test Driven Development (TDD).By detecting regressions, integrating components, resolving errors, doing load and performance tests, and testing for security, endpoint testing verifies that an application's essential operations are right. All potential weaknesses and vulnerabilities are noted and tagged for inspection. Pytest helps you make sure that API endpoints work well together, and also helps you deal with failures and edge cases. It can manage numerous concurrent large requests in practical situations.You can put your application and all of its dependencies together into a single unit called a container. This is called containerization. It separates the application from the underlying system, which maintains consistency across different operating systems.Docker is a modern containerization technology that makes it easier to create, distribute, and execute containers. It enables developers to consistently and reproducibly build, ship, and execute apps without building from source.Get Docker installed from here: https://www.docker.com/get-started.Dockerizing Python programs helps you make sure that they run consistently across multiple computers, eliminating compatibility difficulties. It containerizes the software, its dependencies, and customizations, making it portable.In the same directory as other files, make a new file called Dockerfile. Note that it does not require any extension.Starting with the official Python 3.9 thin image, the Dockerfile defines the image's blueprint.It changes the working directory to /app, which is where the application code will be stored. This projects requirements are listed in the requirements.txt file, which was put into the container.The RUN command uses pip to install Python requirements. COPY moves the app's code from the host to the container's /app directory. CMD provides the command that will be executed when the container starts.In this case, it runs "uvicorn main:app" (the main.py FastAPI app) with host set to 0.0.0.0 and port 80.Build the Docker image in the same directory as the Dockerfile using: docker build -t my_python_app .Run the container in detached mode using the command docker run -d -p 80:80 my_python_app.Once you do this, you can view the status of the containers and the image from Docker Desktop.Find the container ID or name with docker ps. Stop the container using its ID or name: docker stop This walkthrough has only addressed development, testing, and containerization. Just note that post deployment container security, if neglected, introduces risks like vulnerabilities, misconfigurations, and attacks. You should ideally take advantage of a CNAPP to scan images, stick to best practises, and monitor running containers for protection.The takeaway is that Docker containerization allows bundling of Python scripts with dependencies, making them consistent and portable. The Dockerfile describes how the image should be created. Running the container after it has been constructed is as simple as issuing a single command. It's just as simple to put a stop to it. Docker makes it simple to manage Python application distribution.This tutorial was a quick start guide to help you leverage the power of FastAPI. We built a course administration API that efficiently handles queries related to courses. We did this by importing course data from a JSON file into MongoDB and then creating multiple endpoints for users to access course lists, overviews, chapter information, and user scores. We also added a review aggregation feature to demonstrate using HTTP POST and HTTP GET methods so that you can grab data as well as post data to the server. PyTest helped us handle automated testing, ensuring dependability and stability. We then containerized the application Docker, which simplifies deployment and maintenance. My Github Repository contains the complete code covered in this quick start walkthrough. Subscribe to my technical blog for technical cheat sheets and resources.Google Cloud Facilitator | FullStack Django Developer | Python Expert with a flair for Data Science and REST APIs | Sir Read-A-Lot. Also a cinephile and music aficionado. If you read this far, tweet to the author to show them you care. Tweet a thanks Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started freeCodeCamp is a donor-supported tax-exempt 501(c)(3) charity organization (United States Federal Tax Identification Number: 82-0779546)Our mission: to help people learn to code for free. We accomplish this by creating thousands of videos, articles, and interactive coding lessons - all freely available to the public. We also have thousands of freeCodeCamp study groups around the world.Donations to freeCodeCamp go toward our education initiatives, and help pay for servers, services, and staff. You can make a tax-deductible donation here.



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

FastAPI Tutorial – How to Develop, Test, and Deploy APIs

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×