{"id":4607,"date":"2022-08-19T07:50:06","date_gmt":"2022-08-19T14:50:06","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=4607"},"modified":"2022-09-19T05:09:04","modified_gmt":"2022-09-19T12:09:04","slug":"azure-cosmos-db-python-and-fastapi","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/azure-cosmos-db-python-and-fastapi\/","title":{"rendered":"Write a Python data layer with Azure Cosmos DB and FastAPI"},"content":{"rendered":"<p style=\"text-align: left;\">In this article, we will demonstrate how to build a data layer in Python for <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/introduction\" target=\"_blank\" rel=\"noopener\">Azure Cosmos DB<\/a> using <a href=\"https:\/\/fastapi.tiangolo.com\/\">FastAPI,<\/a> a web framework for building and testing Python APIs.<\/p>\n<p style=\"text-align: left;\">To demonstrate this, we will leverage the <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql\/create-sql-api-python\" target=\"_blank\" rel=\"noopener\">To Do App Quickstart in our docs.<\/a> This app shows simple CRUD operations (<em>insert, update, list and delete<\/em>) using a simple data model for a To-Do item consisting of <em>id, name, description,<\/em> and <em>isComplete <\/em>fields. The application that we will create, will wrap these CRUD operations and expose them through a set of custom APIs (Application Programming Interfaces) using the FastAPI routing feature. We will then test our custom APIs in <a href=\"https:\/\/swagger.io\/\" target=\"_blank\" rel=\"noopener\">Swagger<\/a> UI that comes pre-packaged with FastAPI.<\/p>\n<p style=\"text-align: left;\"><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Find complete code in Github<\/strong><\/p> The code related to this tutorial can be found in our <a href=\"https:\/\/github.com\/Azure-Samples\/azure-cosmos-db-with-fastapi\">Azure Cosmos DB With FastAPI Tutorial Repo<\/a>.<\/div><\/p>\n<p style=\"text-align: left;\">Here&#8217;s a complete list of steps we are going to follow to create and test our new backend data access layer.:<\/p>\n<ol style=\"text-align: left;\">\n<li>Create an Azure Cosmos DB account<\/li>\n<li>Setup the dev environment<\/li>\n<li>Creating .env file for credentials<\/li>\n<li>Connect to account, create database and container<\/li>\n<li>Define our ToDoItem data model<\/li>\n<li>Setup the API endpoint implementation<\/li>\n<li>Write our CRUD operations<\/li>\n<li>Register the API endpoints with FastAPI<\/li>\n<li>Test the endpoints<\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 1 \u2013 Create an Azure Cosmos DB account<\/h2>\n<p style=\"text-align: left;\">In a new web browser window or tab, navigate to the Azure portal (<a href=\"https:\/\/portal.azure.com\" target=\"_blank\" rel=\"noopener\">portal.azure.com<\/a>).<\/p>\n<ol style=\"text-align: left;\">\n<li>Sign-in into the <a href=\"https:\/\/portal.azure.com\">Azure Portal<\/a> using the credentials associated with your subscription.<\/li>\n<li>Select Create a resource, search for Azure Cosmos DB, and then create a new Azure Cosmos DB SQL API account resource with the following settings, leaving all remaining settings to their default values:\n<table class=\" alignleft\" style=\"height: 175px; width: 90.639%; margin-left: 40px;\">\n<tbody>\n<tr style=\"height: 29px;\">\n<td style=\"width: 148.25px; height: 29px;\"><strong>Setting<\/strong><\/td>\n<td style=\"width: 436.344px; height: 29px;\"><strong>Value<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 29px;\">\n<td style=\"width: 148.25px; height: 29px;\"><em>Subscription<\/em><\/td>\n<td style=\"width: 436.344px; height: 29px;\"><em>Your existing Azure subscription<\/em><\/td>\n<\/tr>\n<tr style=\"height: 29px;\">\n<td style=\"width: 148.25px; height: 29px;\"><em>Resource group<\/em><\/td>\n<td style=\"width: 436.344px; height: 29px;\"><em>Select an existing or create a new resource group<\/em><\/td>\n<\/tr>\n<tr style=\"height: 29px;\">\n<td style=\"width: 148.25px; height: 29px;\"><em>Account Name<\/em><\/td>\n<td style=\"width: 436.344px; height: 29px;\"><em>Enter a globally unique account name<\/em><\/td>\n<\/tr>\n<tr style=\"height: 29px;\">\n<td style=\"width: 148.25px; height: 29px;\"><em>Location<\/em><\/td>\n<td style=\"width: 436.344px; height: 29px;\"><em>Choose any available region<\/em><\/td>\n<\/tr>\n<tr style=\"height: 29px;\">\n<td style=\"width: 148.25px; height: 29px;\"><em>Capacity mode<\/em><\/td>\n<td style=\"width: 436.344px; height: 29px;\"><em>Serverless<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Below is a screenshot showing these settings in the Azure Portal, click Review+Create and follow subsequent process.<\/p>\n<p><figure id=\"attachment_4631\" aria-labelledby=\"figcaption_attachment_4631\" class=\"wp-caption aligncenter\" ><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/Step-2-scaled.jpg\"><img decoding=\"async\" class=\" wp-image-4631\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/Step-2-scaled.jpg\" alt=\"Image Step 2\" width=\"611\" height=\"446\" \/><\/a><figcaption id=\"figcaption_attachment_4631\" class=\"wp-caption-text\">Azure Cosmos DB Account configuration<\/figcaption><\/figure><\/p>\n<p>&nbsp;<\/li>\n<li><span style=\"font-size: 1rem;\">Wait for the deployment task to <\/span><span style=\"font-size: 1rem;\"><span style=\"font-size: 1rem;\">complete before continuing with further steps.\n<\/span><\/span><a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/Step-7-scaled.jpg\"><img decoding=\"async\" class=\"wp-image-4636 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/Step-7-scaled.jpg\" alt=\"Image Step 7\" width=\"608\" height=\"418\" \/><\/a><\/li>\n<li>Go to the newly created Azure Cosmos DB account resource and navigate to the Keys pane.<\/li>\n<li>The &#8220;Keys&#8221; section contains the connection details and credentials necessary to connect to the account from the SDK. Specifically:\n<ul>\n<li>Record the value of the <strong>UR<\/strong>I field. You will use this endpoint value later in this exercise.<\/li>\n<li>Record the value of the <strong>PRIMARY KEY<\/strong> field. You will use this key value later in this exercise.\n<a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/Step-10-scaled.jpg\"><img decoding=\"async\" class=\"alignnone wp-image-4689\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/Step-10-scaled.jpg\" alt=\"Image Step 10\" width=\"601\" height=\"441\" \/><\/a><\/li>\n<\/ul>\n<\/li>\n<li>Close your web browser window or tab.<\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 2 \u2013 Setup the dev environment<\/h2>\n<p style=\"text-align: left;\">For this application, you can use any terminal for executing your python and other commands. We&#8217;ve used VS Code as our editor here, but any editor works here. We will install FastAPI and Azure Cosmos DB Python SDK library following the steps below:<\/p>\n<ol style=\"text-align: left;\">\n<li>If Python is already installed, confirm it is version 3.6 or higher by executing <code>python \u2013version<\/code> in the Terminal. If not the correct version or if not installed, <a href=\"https:\/\/www.python.org\/downloads\/\" target=\"_blank\" rel=\"noopener\">install Python 3.6+ version<\/a>, then execute <code>python \u2013version<\/code> to verify correct installation.<\/li>\n<li>Installing the remaining python libraries\n<ol>\n<li><strong>Fast API<\/strong> \u2013 Use <code>pip install fastapi<\/code> to install Fast API<\/li>\n<li><strong>Uvicorn<\/strong> \u2013 Uvicorn is an ASGI web server implementation for Python. Use the command <code>pip install fastapi uvicorn <\/code> to install uvicorn<\/li>\n<li><strong>Dotenv<\/strong> &#8211; Python-dotenv reads key-value pairs from a .env file and can set them as environment variables. Use <code>pip install python-dotenv <\/code> to install dotenv library<\/li>\n<li><strong>Aiohttp<\/strong> &#8211; Asynchronous HTTP Client\/Server for asyncio and Python.. Use <code>pip install aiohttp\u00a0<\/code> to install aiohttp library<\/li>\n<li><strong>Azure Cosmos DB python client<\/strong> \u2013 Use <code>pip install azure-cosmos<\/code> to install azure-cosmos-db python client library.<\/li>\n<\/ol>\n<\/li>\n<li>You&#8217;ll need an editor to write code. We will use <a href=\"https:\/\/code.visualstudio.com\/download\" target=\"_blank\" rel=\"noopener\">Visual Studio Code (VS Code)<\/a> but you can use any code editor you&#8217;re comfortable with for writing Python.<\/li>\n<li>Create a directory to store our code and related assets. For example, <code>cosmos-fast<\/code>. Then navigate to it in your terminal.<\/li>\n<li>Open a terminal<\/li>\n<li>Use <code>cd &lt;<em>path to cosmos-fast<\/em>&gt;<\/code> to navigate to cosmos-fast directory in the terminal\/command prompt e.g., <code>cd \"C:\\Cosmos\\python-todo\\cosmos-fast\"<\/code><\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 3 \u2013 Creating .env file for credentials<\/h2>\n<p style=\"text-align: left;\">To execute CRUD operations, we need to connect to the Azure Cosmos DB account and create a database and collection for our ToDo app. To connect to Azure Cosmos DB, we need the URI and PRIMARY KEY from Step 1. Follow the below steps:<\/p>\n<ol style=\"text-align: left;\">\n<li>Create and open a file <code>.env<\/code> in the Code Editor<\/li>\n<li>Write your Azure Cosmos DB URI and KEY values to the <code>.env<\/code> file and save it\n<a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/uri-and-key.png\"><img decoding=\"async\" class=\"alignnone wp-image-4650\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/uri-and-key-300x74.png\" alt=\"Image uri and key\" width=\"555\" height=\"137\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/uri-and-key-300x74.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/uri-and-key.png 480w\" sizes=\"(max-width: 555px) 100vw, 555px\" \/><\/a><\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 4 \u2013 Connect to Azure Cosmos DB, create database and container<\/h2>\n<p style=\"text-align: left;\">To connect to our Azure Cosmos DB account, use the credentials stored in the <code>.env<\/code> file. In the below snippet, we read the URI and KEY using the dotenv library and use these to instantiate the Azure Cosmos DB client during the app start. The Azure Cosmos DB async client is a part of the <code>azure.cosmos.aio<\/code> package. We will also import <code>PartitionKey<\/code> and <code>exceptions<\/code> from the <code>azure.cosmos<\/code> package. FastAPI will be used to handle the app startup event when the app loads on the server and later it would be used for request routing. Follow the steps below:<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ul style=\"text-align: left;\">\n<li>Create <code>main.py<\/code> file and open it in the Code Editor.<\/li>\n<li>Add the necessary imports at the top of the <code>main.py<\/code> file as shown below:\n<code><\/code><\/p>\n<pre class=\"prettyprint\">from fastapi import FastAPI\r\nfrom dotenv import dotenv_values\r\nfrom azure.cosmos.aio import CosmosClient\r\nfrom azure.cosmos import PartitionKey, exceptions<code>\r\n<\/code><\/pre>\n<\/li>\n<li>Load the credentials in config variable, instantiate FastAPI, and define the Database and Container name.\n<pre class=\"prettyprint\">config = dotenv_values(\".env\")\r\napp = FastAPI()\r\nDATABASE_NAME = \"todo-db\"\r\nCONTAINER_NAME = \"todo-items\"<\/pre>\n<\/li>\n<li>Connect to the Azure Cosmos DB account by instantiating the Cosmos Client during the app startup event, store a reference to the database and container in the app object to use them later, and then close the client connection.\n<pre class=\"prettyprint\">@app.on_event(\"startup\")\r\nasync def startup_db_client():\r\n \u00a0 \u00a0 app.cosmos_client = CosmosClient(config[\"URI\"], credential = config[\"KEY\"])\r\n \u00a0 \u00a0 await get_or_create_db(DATABASE_NAME)\r\n \u00a0 \u00a0 await get_or_create_container(CONTAINER_NAME)<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul style=\"text-align: left;\">\n<li>Define the async <code>get_or_create_db<\/code> and <code>get_or_create_container<\/code> functions to fetch\/create the database and the container.\n<pre class=\"prettyprint\">async def get_or_create_db(db_name):\r\n    try:\r\n        app.database  = app.cosmos_client.get_database_client(db_name)\r\n        return await app.database.read()\r\n    except exceptions.CosmosResourceNotFoundError:\r\n        print(\"Creating database\")\r\n        return await app.cosmos_client.create_database(db_name)\r\n     \r\nasync def get_or_create_container(container_name):\r\n    try:        \r\n        app.todo_items_container = app.database.get_container_client(container_name)\r\n        return await app.todo_items_container.read()   \r\n    except exceptions.CosmosResourceNotFoundError:\r\n        print(\"Creating container with id as partition key\")\r\n        return await app.database.create_container(id=container_name, partition_key=PartitionKey(path=\"\/id\"))\r\n    except exceptions.CosmosHttpResponseError:\r\n        raise<\/pre>\n<p><strong style=\"font-size: 1rem;\"><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Important Note On Partition Key<\/strong><\/p>In the above snippet, please make a special note of the term &#8216;Partition Key\u2019. <a href=\"https:\/\/docs.microsoft.comazure\/cosmos-db\/partitioning-overview\" target=\"_blank\" rel=\"noopener\">Partition Key is an important concept in Azure Cosmos DB<\/a>, and a good <a href=\"https:\/\/youtu.be\/QLgK8yhKd5U\" target=\"_blank\" rel=\"noopener\">understanding of partition key best practices<\/a> can help you in better data modelling for optimum utilization of your requests budget while minimizing throttling.<\/div><\/strong><\/li>\n<li>Launch a new terminal window and navigate to the cosmos-fast directory by using the cd command<\/li>\n<li>Now start the server that will execute your python script using the uvicorn web server by typing the below command in the Terminal\n<pre class=\"prettyprint\">uvicorn main:app --reload<\/pre>\n<\/li>\n<li>Notice the output, you must see the \u201cCreating Database\u201d message when you run it for the first time<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2 style=\"text-align: left;\">Step 5 \u2013 Define our ToDoItem data model<\/h2>\n<p style=\"text-align: left;\">Next, define the data model for our To-Do items. It is recommended to define and use the models to make sure that we can validate that we would be storing the correct form of data in our database. FastAPI handles a lot of the tasks under the hood and takes care of data validation, mapping data types, generating API documentation, etc.<\/p>\n<p style=\"text-align: left;\">For our use case, each Todo item will have an Id (Azure Cosmos DB requires us to provide a unique id for each item that we create), name, description, and isComplete field. id, name, and description are string datatypes. isComplete is a boolean datatype. This is our model below:<\/p>\n<ol style=\"text-align: left;\">\n<li>Create a <code>models.py<\/code> file and open it in your Code Editor.<\/li>\n<li>In <code>models.py<\/code>, add required imports\n<pre class=\"prettyprint\">from pydantic import BaseModel\r\nfrom typing import Optional<\/pre>\n<\/li>\n<li>Define the ToDoItem Class\n<pre class=\"prettyprint\">class ToDoItem(BaseModel):\r\n    id : str \r\n    name : Optional[str]\r\n    description : Optional[str]\r\n    is_complete : Optional[bool]<\/pre>\n<\/li>\n<li>Save the <code>models.py<\/code> file. At this point, the models.py file would look like the file below:\n<a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/models.png\"><img decoding=\"async\" class=\" wp-image-4663 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/models-300x215.png\" alt=\"Image models\" width=\"348\" height=\"262\" \/><\/a><\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 6 \u2013 Setup the API endpoint implementation<\/h2>\n<p style=\"text-align: left;\">Now it is time to write functions to create ToDo items in our container, fetch a list of all the ToDo items, update an existing item, and delete an item. When we make create, delete, update, fetch, or other requests from the application frontend, we need to expose the respective functions through some API endpoints so that the frontend can call these functions that are hosted on our servers.<\/p>\n<p style=\"text-align: left;\">To implement the API endpoints, we will create another file <code>routes.py<\/code> and later import it in <code>main.py<\/code>. We will make use of the <code>APIRouter<\/code> component of the FastAPI for implementing the routes. Follow the steps below:<\/p>\n<ol style=\"text-align: left;\">\n<li>Create <code>routes.py<\/code> file in the same folder as the <code>main.py<\/code>, and open it in the Code Editor.<\/li>\n<li>In the <code>routes.py<\/code> file, add the following imports\n<pre class=\"prettyprint\">from fastapi import APIRouter, Request\r\nfrom fastapi.encoders import jsonable_encoder\r\nfrom typing import List<\/pre>\n<\/li>\n<li>Now, we also need to import our <code>ToDoItem model<\/code> defined in\u2008<code>models.py<\/code>\u00a0file as we would use the <code>ToDoItem model<\/code> in our requests and responses. Add the below line to import from models\n<pre class=\"prettyprint\">from models import ToDoItem<\/pre>\n<\/li>\n<li>We also need to instantiate <code>APIRouter()<\/code> from FastAPI to define the paths to access the defined functions. Add the below line to instantiate APIRouter:\n<pre class=\"prettyprint\">router = APIRouter()<\/pre>\n<\/li>\n<li>Save the file and move on to the next step where we discuss various endpoints.<\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 7 \u2013 API endpoint implementation<\/h2>\n<p style=\"text-align: left;\">Next, we will implement the four different API endpoints around the four CRUD operations mentioned earlier. This includes a POST request to CREATE a Todo item, a GET request to FETCH a list of all Todo items, a PATCH request to update a Todo item, and a DELETE request to delete a ToDoItem. These operations will also implement json_encoder. Json_encoder converts the ToDoItem object to a json dict.<\/p>\n<p style=\"text-align: left;\">So let us start by creating an endpoint to insert a ToDo item into our container.<\/p>\n<h3 style=\"text-align: left;\">Step 7.1 \u2013 POST request to insert one ToDoItem<\/h3>\n<p style=\"text-align: left;\">Copy and add the code below into your <code>routes.py<\/code> file.<\/p>\n<pre class=\"prettyprint\">@router.post(\"\/insert\", response_model=ToDoItem)\r\nasync def create_todo(request: Request, todo_item: ToDoItem):\r\n    todo_item = jsonable_encoder(todo_item)\r\n    new_todo = await request.app.todo_items_container.create_item(todo_item)\r\n    return new_todo<\/pre>\n<p style=\"text-align: left;\">Now let us understand it line by line.<\/p>\n<ol style=\"text-align: left;\">\n<li>The parameters inside the <code>router.post<\/code> bracket define the path at which the function is hosted, and the model to deserialize the resonse into.<\/li>\n<li>Inside <code>create_todo<\/code> function, we use the jsonable_encoder function to convert the <code>todo_item<\/code> object into a json dictionary as the Azure Cosmos DB client library allows only json objects in <code>create_item<\/code>.<\/li>\n<li>Next, we call the <code>create_item<\/code> function on our container in which we want to insert the ToDoItem.<\/li>\n<li>A successful <code>create_item<\/code> returns the newly created item which is then passed as the function&#8217;s return value as <code>new_todo<\/code>.<\/li>\n<li>Since we are using the Azure Cosmos DB Python Async SDK and we need to <code>await<\/code> on the <code>create_item<\/code>, the create_todo method must be declared as <code>async<\/code>.<\/li>\n<\/ol>\n<h3 style=\"text-align: left;\">Step 7.2 \u2013 GET Request to fetch a list of all ToDo Items<\/h3>\n<p style=\"text-align: left;\">We will use the <code>read_all_items<\/code> function from the Azure Cosmos DB Python client library to get a list of all the ToDo items.\u00a0Define function and expose it through a GET request as below:<\/p>\n<pre class=\"prettyprint\">@router.get(\"\/listall\", response_description=\"List of all To-do items\", response_model=List[ToDoItem])\r\nasync def list_todos(request: Request):\r\n    todos = [todo async for todo in request.app.todo_items_container.read_all_items()]\r\n    return todos<\/pre>\n<h3 style=\"text-align: left;\">Step 7.3 \u2013 Delete an Item<\/h3>\n<p style=\"text-align: left;\">Delete an item by specifying the id and the partition key. Define the delete function below that take id and partition key as the parameters. Define the function as below:<\/p>\n<pre class=\"prettyprint\">@router.delete(\"\/delete\")\r\nasync def delete_todo(request: Request, item_id: str, pk: str):\r\n     await request.app.todo_items_container.delete_item(item_id, partition_key=pk)\r\n<\/pre>\n<h3 style=\"text-align: left;\">Step 7.4 \u2013 Update an item<\/h3>\n<p style=\"text-align: left;\">Update an item by passing the id and the item to be updated. Updates can be done on all properties except the partition key. In this case, that is id, which needs to be passed in order to update the correct item. In our example, we will use the same ToDoItem class to get the update fields in the request body. We will first read the item, update our properties, then call <code>replace_item<\/code> to replace the existing item with the modified item. Define the function as below:<\/p>\n<pre class=\"prettyprint\">@router.put(\"\/update\", response_model = ToDoItem, )\r\nasync def replace_todo(request: Request, item_with_update:ToDoItem):\r\n    ````\r\n    Update an item. Id (which is also the PartitionKey in this case) values should reference the item to be updated:\r\n\r\n    - **id**: [Mandatory] Old Item ID\r\n    - **name**: [Optional] The new name.\r\n    - **description**: [Optional] The new description\r\n    - **isComplete**: [Optional] boolean  flag to mark a Todo complete or incomplete\r\n    ````\r\n    existing_item = await request.app.todo_items_container.read_item(item_with_update.id,partition_key = item_with_update.id)\r\n    existing_item_dict = jsonable_encoder(existing_item)\r\n    update_dict = jsonable_encoder(item_with_update)\r\n    for (k) in update_dict.keys():\r\n        if update_dict[k]:\r\n            existing_item_dict[k] = update_dict[k]\r\n    updatedItem = await request.app.todo_items_container.replace_item(item_with_update.id, existing_item_dict)    \r\n    return updatedItem\r\n<\/pre>\n<p style=\"text-align: left;\">Save the file.<\/p>\n<h2 style=\"text-align: left;\">Step 8 \u2013 Register the API endpoints with FastAPI<\/h2>\n<p style=\"text-align: left;\">Next, register the routes for our API endpoints for our CRUD operations in <code>main.py<\/code> so the requests are routed to the correct paths.<\/p>\n<p style=\"text-align: left;\">In the <code>main.py<\/code> file,<\/p>\n<ol style=\"text-align: left;\">\n<li>Add router import\n<pre class=\"prettyprint\">from routes import router as todo_router<\/pre>\n<\/li>\n<li>Add below line to include router\n<code>app.include_router(todo_router, tags=[\u201ctodos\u201d], prefix=\u201d\/todos\u201d)\n<\/code><\/li>\n<li>Save the file<\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Step 9 \u2013 Test the endpoints<\/h2>\n<p style=\"text-align: left;\">FastAPI automatically generates your API documentation and lets you test it. Follow the below steps:<\/p>\n<ol style=\"text-align: left;\">\n<li>In your browser, go to <a href=\"http:\/\/localhost:8000\/docs\">http:\/\/localhost:8000\/docs<\/a><\/li>\n<li>You will see all your endpoints listed there as shown in the picture below:\n<a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/fastApi.png\"><img decoding=\"async\" class=\"alignnone wp-image-4682\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/fastApi.png\" alt=\"Image fastApi\" width=\"654\" height=\"385\" \/><\/a><\/li>\n<li>Start testing the API endpoint by creating a ToDo Item.\n<ul>\n<li>Expand the Create Todo in the FastAPI page and click on Try It Out\n<a href=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/fastApiTry.png\"><img decoding=\"async\" class=\"alignnone wp-image-4683\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2022\/08\/fastApiTry.png\" alt=\"Image fastApiTry\" width=\"614\" height=\"357\" \/><\/a><\/li>\n<li>Replace the \u201cRequest Body\u201d content with the below JSON.\n<pre class=\"prettyprint\">{ \u00a0 \r\n  \u201cid\u201d: \u201cunique-item-id-1\u201d, \u00a0 \r\n  \u201cname\u201d: \u201cTo Do Title 1\u201d, \u00a0\r\n  \u201cdescription\u201d: \u201cJust a description of the todo\u201d, \r\n\u00a0 \u201cisComplete\u201d: false \r\n}<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<li>Click on Execute and observe the response.<\/li>\n<li>Just as we created an item, we can test the Delete, Update, and List operations by providing the required parameters and executing.<\/li>\n<li>Keep in mind that you cannot modify the id field for any item as it is the Partition Key.<\/li>\n<\/ol>\n<h2 style=\"text-align: left;\">Conclusion<\/h2>\n<p style=\"text-align: left;\">This post demonstrated how to create a python web app backend using Azure Cosmos DB Python SDK and FastAPI. We created API endpoints to expose database CRUD operations, which can in turn be used by an application&#8217;s frontend or other services. We also tested our API endpoints by using the built-in features of FastAPI. This article touched upon the basic concepts that will help you get started. In the subsequent articles, we will cover additional and advanced concepts, including best practices for making the most of the Azure Cosmos DB.<\/p>\n<h5 id=\"about-azure-cosmos-db\"><a href=\"https:\/\/azure.microsoft.com\/services\/cosmos-db\/#overview\" target=\"_blank\" rel=\"noopener\">About Azure Cosmos DB<\/a><i class=\"fabric-icon fabric-icon--Link\" aria-hidden=\"true\"><\/i><\/h5>\n<p>Azure Cosmos DB is a fast and scalable cloud database for modern app development.\u00a0<a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/optimize-dev-test\" target=\"_blank\" rel=\"noopener\">See how to get started, dev\/test, and run small production workloads free.<\/a><\/p>\n<p class=\"\">Get product updates, ask questions, and learn more about Azure Cosmos DB by following us on\u00a0<a href=\"https:\/\/www.linkedin.com\/company\/azure-cosmos-db\/\" target=\"_blank\" rel=\"noopener\">LinkedIn<\/a>,\u00a0<a href=\"http:\/\/www.youtube.com\/AzureCosmosDB\" target=\"_blank\" rel=\"noopener\">YouTube<\/a>, and\u00a0<a href=\"https:\/\/twitter.com\/azurecosmosdb\" target=\"_blank\" rel=\"noopener\">Twitter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will demonstrate how to build a data layer in Python for Azure Cosmos DB using FastAPI, a web framework for building and testing Python APIs. To demonstrate this, we will leverage the To Do App Quickstart in our docs. This app shows simple CRUD operations (insert, update, list and delete) using [&hellip;]<\/p>\n","protected":false},"author":97419,"featured_media":4702,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14,1217,19],"tags":[1825],"class_list":["post-4607","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-core-sql-api","category-python-sdk","category-tips-and-tricks","tag-fastapi"],"acf":[],"blog_post_summary":"<p>In this article, we will demonstrate how to build a data layer in Python for Azure Cosmos DB using FastAPI, a web framework for building and testing Python APIs. To demonstrate this, we will leverage the To Do App Quickstart in our docs. This app shows simple CRUD operations (insert, update, list and delete) using [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/4607","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/97419"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=4607"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/4607\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/4702"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=4607"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=4607"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=4607"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}