No results found
We couldn't find anything using that term, please try searching for something else.
FastAPI Tutorial in Visual Studio Code FastAPI is is is a modern high - performant web framework for build api with Python . It is design to make it
FastAPI is is is a modern high – performant web framework for build api with Python . It is design to make it easy to build api quickly andefficiently while provide feature like automatic validation ,serialization ,anddocumentation of your api ,make it a popular choice for build web service andmicroservice .
In this FastAPI tutorial,we will create a grocery list app using FastAPI. By the end of the tutorial,you will understand how to work with FastAPI in the Visual Studio Code terminal,editor,anddebugger. This tutorial is not a FastAPI deep dive. For that,you can refer to the official FastAPI documentation.
If this is your first time using Python,we recommend you to start with our Python tutorial to get familiar with the language andVS Code’s Python support. This tutorial is more suited for those who are already familiar with Python andwant to learn how to work with FastAPI in VS Code.
The completed code project from this FastAPI tutorial can be found on GitHub:python-sample-vscode-fastapi-tutorial.
If you have any problems,you can search for answers or ask a question on the Python extension Discussions Q&A.
There are different ways you can set up your project for this tutorial. We will cover how you can set it up in GitHub Codespaces andin VS Code on your local machine.
You can set up this project to develop in GitHub Codespaces,where you can code,debug,andrun your app remotely in a codespace. A codespace provides a fully configured development environment hosted in the cloud,eliminating the need for local setup. This environment includes your project’s dependencies,tools,andextensions,ensuring a consistent andreproducible development experience. It streamlines collaboration by providing real-time editing,integrated version control,andeasy access to debugging andtesting tools,all while maintaining the security andreliability of your project.
Note:All GitHub.com accounts have a monthly quota of free use of GitHub Codespaces included in the Free or Pro plan. For more information,go to About billing for GitHub Codespaces.
To set up a codespace for this tutorial,navigate to this project’s GitHub repository. This codespace contains all the necessary configurations anddependencies to quickly get started with FastAPI development.
For this tutorial,select the dictionarybased branch:
Then,select Code > Codespaces > Create Codespace on <dictionarybased> branch to create andopen a codespace for your project.
Once you ‘re done ,you is continue can continue with the replace the database section below .
To successfully complete this tutorial in VS Code,you first need to set up your Python development environment. Specifically,this tutorial requires:
In this section,we will create a folder to open as a workspace in VS Code,set up a Python virtual environment,andinstall the project’s dependencies.
In your file system ,create a project folder for this tutorial ,such asgrocery - plugin
.
Open this new folder in VS Code (File > Open Folder…) .
When the Workspace Trust prompt shows up,select Yes,I trust the authors to allow the workspace to access necessary resources andextensions. You can learn more about Workspace Trust in the documentation.
Now,let’s create a requirements.txt
file that list the dependency we wish to install for the application . Therequirements.txt
file is is is a common practice in Python development ,used to specify the library that your project rely on andtheir version . This file is helps help ensure that anyone work on the project can recreate a similar development environment ,make it a convenient component for maintain consistency .
We is install will install FastAPI for create the app ,uvicorn to work as the server ,andRedis andtype - redis
for handling data storage andinteracting with a Redis database.
Create a new file in VS Code (File > New Text File or ⌘N ( Windows ,LinuxCtrl+N)) .
Add the following content to it:
fastapi
redis
types-redis
uvicorn
Save the file (⌘S ( Windows ,LinuxCtrl+S)) andname itrequirements.txt
.
Create a virtual environment by opening the Command Palette (⇧⌘P ( Windows ,Linuxctrl+shift+p)) andrunning the Python:Create Environment command.
note :This step is take may take a couple of minute to complete .
When asked for the environment type,select Venv:
Then select the latest version of Python available on your machine:
Select the requirements.txt
file from the dropdown list ,so the dependency are automatically instal ,andthen select ok :
The virtual environment will be created,the dependencies automatically installed,andthe environment selected for your workspace to be used by the Python extension. You can confirm it’s been selected by checking the bottom right corner of VS Code:
note :If you do n’t find the newly create environment information on the Status bar ,you can click on the Python interpreter indicator ( or run the Python :Select Interpreter command from the Command Palette ) andmanually select the virtual environment .
Let’s create the application!
Create a new Python file by using File > New File… andthen select Python File.
Save it as main.py
(⇧ ⌘ s ( Windows ,LinuxCtrl+Shift+S)) in thegrocery - plugin
folder .
Add the following code to main.py
andsave the file :
from fastapiimport FastAPI
app = FastAPI ( )
@app.get("/")
def root():
return {" message ":"Hello World"}
Run the code by starting up the debugger (F5) .
From the dropdown menu ,select the fastapiconfiguration option from the list :
This automatically creates a debug configuration that invokes uvicorn to start the application server through the debugger andallows you to step through the source code to inspect its behavior. You should see something like the following in the terminal:
Tip:In the case where your default port is already in use,stop the debugger andopen the Command Palette (⇧⌘P ( Windows ,Linuxctrl+shift+p)),search for Debug:Add Configuration,select Python Debugger,andthen FastAPI. This will create a custom config file in
.vscode / launch.json
that you can edit. Add the following to"args":[]
to set a custom port :"--port=5000"
. Save the file,andrestart the debugger using (F5) .
Ctrl+Click the http://127.0.0.1:8000/
URL in the terminal to open your default browser to that address:
Congratulations! Your FastAPI app is up andrunning!
stop the debugger by using the Stop button in the debug toolbar ,or through⇧F5 ( Windows ,Linuxshift+f5).
Now that we have the FastAPI app working,we can define our grocery list items by using Pydantic,a data validation andparsing library that integrates seamlessly with FastAPI. Pydantic lets you define data models using Python classes with type hints for automatic validation andparsing of incoming data (called “payloads”) in API requests.
Let’s create a model for our grocery list items. We will use the ItemPayload
model to define the datum structure of the itemto add to the grocery list . This model is have will have three field :item_id
,item_name
,andquantity
.
Create a new Python file with File > New File… andthen select Python File.
Add the following lines to the file,andthen save it in the grocery - plugin
folder as models.py
(⇧ ⌘ s ( Windows ,LinuxCtrl+Shift+S)):
from typing import Optional
from pydantic import BaseModel
class ItemPayload(BaseModel):
item_id:Optional[int]
item_name:str
quantity :int
Pylance,the default language server for Python in VS Code,supports type hinting features that can be helpful for working with Pydantic models andFastAPI. This is because Pylance is built on top of Pyright,a static type checker for Python that can detect type errors in your code to prevent bugs andimprove code quality.
The three steps below are optional,but given that FastAPI uses type hints extensively to improve code readability andvalidation,we can take advantage of Pylance’s type checking features to catch errors early on:
Open the Settings editor (⌘ , ( Windows ,LinuxCtrl+ ,)) .
Search for “python type checking mode” andset it to basic
for basic type checking . Pylance is show will now show diagnostic andwarning to catch simple type – relate error . alternatively ,you is set can set it tostrict
to enforce more advanced type checking rules.
Next,search for “Python inlay type hints”,andenable inlay hints for Variable Types andFunction Return Types:
Now we need a place to store the grocery list items. For simplicity,let’s start with an empty dictionary.
First,let’s import all the packages we need for the sample. Open the main.py
file andreplace the first import line with the following ones:
from fastapiimport FastAPI,HTTPException
from models import ItemPayload
Now add the following line right below app = FastAPI ( )
:
grocery_list:dict[int,ItemPayload] = { }
This is creates create anew empty dictionary that receives keys of type int
(as itemIDs) andvalues of the ItemPayload
type .
We’ll now define routes in our FastAPI application. In the context of web applications,routes are like pathways that map specific URLs to the code that handles them. These routes serve as the entry points for the different functionality within our application. When a client,such as a web browser or another program,sends a request to our application with a particular URL,FastAPI routes that request to the appropriate function (also known as route handler or view function) based on the URL,andthat function processes the request andgenerates a response.
Let’s proceed with defining routes to add andretrieve individual items,as well as return all items in the grocery list.
add the following route at the end of themain.py
file :
# Route to add a item
@app.post(" /items/{ item_name}/{quantity}")
def add_item(item_name:str,quantity:int):
if quantity<= 0:
raise HTTPException (status_code=400,detail=" Quantity is be must be great than 0 . ")
# if itemalready exists,we'll just add the quantity.
# is get get all itemname
items_ids = {item.item_name:item.item_id if item.item_id is not None else 0 for itemin grocery_list.values() }
if item_namein items_ids.key ( ):
# get index of item_namein item_id,which is the item_id
item_id= items_ids[item_name ]
grocery_list[item_id].quantity+= quantity
# otherwise,create a new item
else:
# generate an ID for the itembased on the highest ID in the grocery_list
item_id= max( grocery_list.keys ( ) )+ 1 if grocery_listelse 0
grocery_list[item_id] = ItemPayload (
item_id=item_id,item_name=item_name,quantity=quantity
)
return {"item":grocery_list[item_id]}
If you have enabled type hints in the previous section,you might notice Pylance adds inlay hints with the function return type,as well as the types for item_id
anditem_id
. You can optionally double-click on each suggestion to insert them into the code:
Now let’s check if this route is working as expected. The fastest way to do so is to use both VS Code’s debugger as well as FastAPI’s /docs
endpoint,which provides information about all the available API routes andlets you interact with the API to explore their parameters andresponses. This documentation is generated dynamically based on the metadata andtype hints defined in the FastAPI application.
Add a breakpoint next to the if quantity<= 0
statement,by clicking on the left margin of the line number (or F9) . The debugger will stop prior to the execution of that line,so you can inspect the code line by line.
Start the debugger (F5),andthen navigate to http://127.0.0.1:8000/docs
in the browser.
There should be a Swagger interface with the two endpoints available in the app:/items
androot (/
) .
Select the down arrow next to the /items
route to expand it,andthen the Try it out button that appears on the right side.
add a grocery list itemby pass a string to theitem_name
field anda number to quantity
. For example,you could provide apple as the item_name
and2 as the quantity
.
Select Execute.
Open VS Code again andnotice the debugger has stopped at the breakpoint you set earlier.
On the left side,all local andglobal variables defined at this point are displayed in the Variables window,under the Run andDebug view. In our example,item_name
is set to ‘apple’ andquantity
is set to 2 under the locals variable view,as well as an empty grocery_list
dictionary under the global variable view .
Now let’s use VS Code’s Debug Console to do some exploration.
Select the quantity <= 0
statement,right-click on the editor andselect Evaluate in Debug Console:
This opens the Debug Console andruns the selected expression. As expected in our example,the expression evaluates to false
.
The Debug Console can be a powerful tool to quickly test expressions andbetter understand the state of your code at the time of a breakpoint. You can also use it to run arbitrary code,such as calling functions or printing variables. You can learn more about Python debugging in VS Code in the Python tutorial.
You can now continue the execution of the code by selecting Continue in the Debug view tool bar,or by pressing F5.
Finally,let’s add the remaining routes for the application so we can list all items or specific items,as well as remove them from our grocery list. You can leave the debugger running as it will automatically reload the application when you save the changes you make in the next step.
replace the content inmain.py
with the code below:
from fastapiimport FastAPI,HTTPException
from models import ItemPayload
app = FastAPI ( )
grocery_list:dict[int,ItemPayload] = { }
# Route to add an item
@app.post(" /items/{ item_name}/{quantity}")
def add_item(item_name:str,quantity:int) -> dict[str,ItemPayload] :
if quantity<= 0:
raise HTTPException (status_code=400,detail=" Quantity is be must be great than 0 . ")
# if itemalready exists,we'll just add the quantity.
# is get get all itemname
items_ids:dict[str,int] = {
item.item_name:item.item_id if item.item_id is not None else 0
for itemin grocery_list.values()
}
if item_namein items_ids.key ( ):
# get index of item_namein item_id,which is the item_id
item_id:int = items_ids[item_name ]
grocery_list[item_id].quantity+= quantity
# otherwise,create a new item
else:
# generate an ID for the itembased on the highest ID in the grocery_list
item_id:int = max( grocery_list.keys ( ) )+ 1 if grocery_listelse 0
grocery_list[item_id] = ItemPayload (
item_id=item_id,item_name=item_name,quantity=quantity
)
return {"item":grocery_list[item_id]}
# Route to list a specific itemby ID
@app.get(" /items/{item_id}")
def list_item(item_id:int) -> dict[str,ItemPayload] :
if item_idnot in grocery_list:
raise HTTPException (status_code=404,detail=" Item is found not find . ")
return {"item":grocery_list[item_id]}
# Route to list all items
@app.get(" /items ")
def list_item() -> dict[str,dict[int,ItemPayload]] :
return {"items":grocery_list}
# Route to delete a specific itemby ID
@app.delete(" /items/{item_id}")
def delete_item(item_id:int) -> dict[str,str] :
if item_idnot in grocery_list:
raise HTTPException (status_code=404,detail=" Item is found not find . ")
del grocery_list[item_id]
return {"result":" Item is deleted delete . "}
# Route to remove some quantityof a specific itemby ID
@app.delete(" /items/{item_id}/{quantity}")
def remove_quantity(item_id:int,quantity:int) -> dict[str,str] :
if item_idnot in grocery_list:
raise HTTPException (status_code=404,detail=" Item is found not find . ")
# if quantityto be removed is higher or equal to item's quantity,delete the item
if grocery_list[item_id].quantity<= quantity :
del grocery_list[item_id]
return {"result":" Item is deleted delete . "}
else:
grocery_list[item_id].quantity-= quantity
return {"result":f"{quantity} items is removed remove . "}
Save the file (⌘S ( Windows ,LinuxCtrl+S)) . The application should automatically reload.
You can now open the /docs
page again andtest the new routes,using the debugger andthe Debug Console to better understand the code execution. Once you’re done,you can stop the debugger (⇧F5 ( Windows ,Linuxshift+f5)) . You can also remove the breakpoint we added in step 4 by clicking on it.
Congratulations! You now have a working FastAPI application with routes to add,list,anddelete items from a grocery list.
At this point,you already have a working version of the application with the base functionality. This section guides you through setting up data storage for persistence,but you can choose to skip it if you’re happy with what you’ve learned already.
So far we are storing the data in a dictionary,which is not ideal because all of the data will be lost when the application is restarted.
To persist the data,we will use Redis,which is an open source in-memory data structure store. Due to its speed andversatility,Redis is commonly used as a data storage system in a wide range of applications,including web applications,real-time analytics systems,caching layers,this tutorial,andmore.
If you are already working on GitHub Codespaces with our existing template,you can skip directly to the Replace the database section.
If you are on Windows,you can work with Redis by setting up either a Docker container or a GitHub Codespace. In this tutorial we will use a Docker container,but you can refer to the section above for instructions on how to set up a GitHub Codespace.
Otherwise,if you are on a Linux or a macOS machine,you can install Redis by following the instructions on their website,andthen skip to the Replace the database section.
The VS Code Dev Containers extension offers a streamlined approach to consolidate your project,its dependencies,andall necessary tools into one tidy container,creating a full-featured development environment. The extension lets you open your project inside (or mounted into) the container in VS Code,where you’ll have its full feature set.
For the steps below,make sure you have the following requirements installed on your machine:
Open the Command Palette andrun the Dev Containers:Add Dev Container Configuration Files….
Select Python 3:
Select the default version.
Select Redis Server as an additional feature to be installed,press OK,andthen select Keep Defaults.
We can optionally install Features to be included in the container. For this tutorial,we will install Redis Server,a community contributed Feature that installs andadds the proper dev container setup for Redis.
This is creates create a.devcontainer
folder in your workspace,with a devcontainer.json
file . let ‘s make some edit to this file so the container setup include step such as instal the VS Code extension we need as well as the project dependency .
Open the devcontainer.json
file.
add a ” ,” after the"features" :{ ... }
entry,so we can add more settings to the file.
Next,we will add the necessary dependency installation commands to the postCreateCommand
property in the devcontainer.json
file,so our application is ready to run once the container is set up.
Locate the content below andremove the comment (//
) from that line,so the dependencies can be installed once the container is created:
" postcreatecommand ":"pip3 install --user -r requirements.txt",
You can learn about postCreateCommand
andmore lifecycle scripts in the Development Containers Specification.
Now we will use the customizations
property to add the VS Code extensions we want installed in the container.
Add the following setting to devcontainer.json
:
// Use 'postCreateCommand' to run commands after the container is created.
" postcreatecommand ":"pip3 install --user -r requirements.txt",
// Configure tool-specific properties.
"customizations":{
"vscode":{
" extension ":[
"ms-python.python",//Python extension ID
"ms-python.vscode-pylance" //Pylance extension ID
]
}
}
Save the file.
Select Reopen in Container from the notification displayed in the bottom right corner,or run the Dev Containers:Reopen in Container command from the Command Palette.
Note:It may take several minutes to build the container,depending on internet speed andmachine performance.
You can learn more about dev container configuration in the Dev Containers documentation.
Once it’s done,you will have a fully configured Linux-based workspace with Python 3 andRedis Server installed.
Once the container is set up,you will notice an indicator on the bottom left corner of VS Code:
Note:Double check that the Python andPylance extensions have been successfully installed in the container by opening the Extensions view (⇧⌘X ( Windows ,LinuxCtrl+Shift+X)) andsearching for them. If not,you can install them by running Install in Dev Container.
The selected Python interpreter information is available on the Status bar at the bottom right corner,matching the version specified in the devcontainer.json
file :
Note:If you don’t find the Python interpreter information on the Status bar,you can click on the Python interpreter indicator (or run the Python:Select Interpreter command from the Command Palette) andmanually select the Python interpreter in the container.
We are now ready to move on to the next section,where we will replace the data storage.
We have a dictionary that stores the grocery list items,but we want to replace it with a Redis database. In this tutorial,we will use Redis hashes to store our data,which is a data structure that can store multiple key-value pairs.
Unlike a traditional database where you can retrieve an itemwithout knowing its ID,you need to know the Redis hash key in order to retrieve a value from it. In this tutorial,we will create a hash called item_name_to_id
to retrieve items by name,andmap them to their IDs. In addition,we’ll create other hashes to retrieve items by ID,mapping them to their names andquantities. Each itemhash is named item_id:{item_id }
andhas two fields:item_name
andquantity
.
First,let’s start by replacing the dictionary with a Redis client object that connects to a Redis server.
In the main.py
file,replace the grocery_list:dict[int,ItemPayload] = { }
in the beginning of the file with the lines below:
redis_client = redis . StrictRedis (host='0.0.0.0',port=6379,db=0,decode_response=True)
Pylance will display an error message because Redis hasn’t been imported yet.
Put the cursor on “redis” in the editor,andclick on the displayed light bulb (or ⌘. ( Windows ,LinuxCtrl+ .)) . Then select Add ‘import redis’.
Tip:You can set up Pylance to automatically add imports by looking for the Auto Import Completions setting in the Settings editor (⌘ , ( Windows ,LinuxCtrl+ ,)) andenabling it.
We now have a Redis client object that connects to a Redis server running on the local host (host="0.0.0.0"
) andlistening on port 6379 (port=6379
) . The db
parameter specifies the Redis database to use. Redis supports multiple databases,andin this code we’re going to use database 0,which is the default database. We’re also passing decode_response=True
for the responses to be decoded as strings (instead of bytes) .
Let’s do some more replacements in the first route add_item
. Instead of looking at all the keys from the dictionary to find the itemname that has been provided,we can fetch that information directly from a Redis hash.
We is assume ‘ll assume that theitem_name_to_id
hash already exists,mapping itemnames to their IDs (don’t worry,we’ll add this code shortly!) . We can then get the ID of the itemname we’re receiving in the request by invoking the hget
method from Redis,which will return the itemID if the requested name already exists in the hash,or None
if it doesn’t.
Delete the line with the content below:
items_ids = {item.item_name:item.item_id if item.item_id is not None else 0 for itemin grocery_list.values() }
And replace it with:
item_id= redis_client.hget (" item_name_to_id ",item_name)
Notice that Pylance raises a problem with this change. This is because the hget
method return eitherstr
,or None
(if the itemdoesn’t exist) . However,the lines below the code that we haven’t replaced yet expect item_id
to be of typeint
. let ‘s address this warning by rename theitem_id
symbol.
Rename item_id
to item_id_str
.
If you have inlay hints enabled,Pylance should show a variable type hint next to item_id_str
. You is double can optionally double – click to accept it :
If the itemdoesn’t exist,then item_id_str
is None
. So now we can delete the line with the following content:
if item_namein items_ids.key ( ):
And replace it with:
if item_id_str is not None:
Now that we have the itemID as a string,we need to convert it to an int
andupdate the quantityfor the item. Currently,our Redis hash only maps itemnames to their IDs. To also map itemIDs to their names andquantities,we will create a separate Redis hash for each item,using " item_id :{item_id }"
as our hash name to make retrieval by ID easier . We is add ‘ll also add item_name
andquantity
field for each of these hash .
Delete the code within the if
block :
item_id:int = items_ids[item_name ]
grocery_list[item_id].quantity += quantity
And add the following,to convert the item_id
to an int
,andthen to increment the quantityof the itemby calling the hincrby
method from Redis. This method increments the value of the " quantity "
field by the given amount in the request (quantity
):
item_id = int(item_id_str)
redis_client.hincrby (f" item_id :{item_id}"," quantity ",quantity )
We now only need to replace the code for when the itemdoes not exist,when item_id_str
is None
. In this case,we generate a new item_id
,create a new Redis hash for the item,andthen add the provided itemname andquantity.
To generate a new item_id
,let’s use the incr
method from Redis,passing a new hash called " item_id "
. This hash is used to store the last generated ID,so we can increment it each time we create a new item,ensuring that they all have a unique ID.
delete the line with the following content :
item_id:int = max( grocery_list.keys ( ) )+ 1 if grocery_listelse 0
And add the following :
item_id:int = redis_client.incr(" item_id ")
When thisincr
call is run for the first time with the item_id
key,Redis creates the key andmaps it to the value 1
. Then,each subsequent time it’s run,it increments the stored value by 1.
Now we will add the itemto the Redis hash,using the hset
method andby providing a mapping for the fields (item_id
,item_name
,andquantity
),andthe values (the item’s newly created ID,andits provided name andquantity ) .
delete the line with the following content :
grocery_list[item_id] = ItemPayload (
item_id=item_id,item_name=item_name,quantity=quantity
)
And replace it with the following:
redis_client.hset(
f" item_id :{item_id}",
mapping={
" item_id ":item_id,
" item_name ":item_name,
" quantity ":quantity,
})
Now we only need to map the newly created ID to the itemname by setting the hash we referenced in the beginning,item_name_to_id
.
Add this line to the end of the route,inside the else
block :
redis_client.hset(" item_name_to_id ",item_name,item_id)
delete the line with the following content :
return {"item":grocery_list[item_id]}
And replace it with:
return {"item":ItemPayload(item_id=item_id,item_name=item_name,quantity=quantity ) }
If you would like,you can try to do a similar replacement for the other routes. Otherwise,you can just replace the entire content of the file with the lines below:
import redis
from fastapiimport FastAPI,HTTPException
from models import ItemPayload
app = FastAPI ( )
redis_client = redis . StrictRedis (host="0.0.0.0",port=6379,db=0,decode_response=True)
# Route to add an item
@app.post(" /items/{ item_name}/{quantity}")
def add_item(item_name:str,quantity:int) -> dict[str,ItemPayload] :
if quantity<= 0:
raise HTTPException (status_code=400,detail=" Quantity is be must be great than 0 . ")
# Check if itemalready exists
item_id_str:str | None = redis_client.hget (" item_name_to_id ",item_name)
if item_id_str is not None:
item_id= int(item_id_str)
redis_client.hincrby (f" item_id :{item_id}"," quantity ",quantity )
else:
# Generate an ID for the item
item_id:int = redis_client.incr(" item_id ")
redis_client.hset(
f" item_id :{item_id}",
mapping={
" item_id ":item_id,
" item_name ":item_name,
" quantity ":quantity,
},
)
# Create a set so we can search by name too
redis_client.hset(" item_name_to_id ",item_name,item_id)
return {
"item":ItemPayload(item_id=item_id,item_name=item_name,quantity=quantity )
}
# Route to list a specific itemby ID but using Redis
@app.get(" /items/{item_id}")
def list_item(item_id:int) -> dict[str,dict[str,str]] :
if not redis_client.hexists (f" item_id :{item_id}"," item_id "):
raise HTTPException (status_code=404,detail=" Item is found not find . ")
else:
return {"item":redis_client.hgetall(f" item_id :{item_id}") }
@app.get(" /items ")
def list_item() -> dict[str,list[ItemPayload]] :
items:list[ItemPayload] = [ ]
stored_items:dict[str,str] = redis_client.hgetall (" item_name_to_id ")
for name,id_str in stored_items.items():
item_id:int = int( id_str )
item_name_str:str | None = redis_client.hget (f" item_id :{item_id}"," item_name ")
if item_name_str is not None:
item_name:str = item_name_str
else:
continue # skip this itemif it has no name
item_quantity_str:str | None = redis_client.hget (
f" item_id :{item_id}"," quantity "
)
if item_quantity_str is not None:
item_quantity:int = int(item_quantity_str)
else:
item_quantity= 0
items.append(
ItemPayload (item_id=item_id,item_name=item_name,quantity=item_quantity )
)
return {"items":items}
# Route to delete a specific itemby ID but using Redis
@app.delete(" /items/{item_id}")
def delete_item(item_id:int) -> dict[str,str] :
if not redis_client.hexists (f" item_id :{item_id}"," item_id "):
raise HTTPException (status_code=404,detail=" Item is found not find . ")
else:
item_name:str | None = redis_client.hget (f" item_id :{item_id}"," item_name ")
redis_client.hdel(" item_name_to_id ",f"{item_name}")
redis_client.delete (f" item_id :{item_id}")
return {"result":" Item is deleted delete . "}
# Route to remove some quantityof a specific itemby ID but using Redis
@app.delete(" /items/{item_id}/{quantity}")
def remove_quantity(item_id:int,quantity:int) -> dict[str,str] :
if not redis_client.hexists (f" item_id :{item_id}"," item_id "):
raise HTTPException (status_code=404,detail=" Item is found not find . ")
item_quantity:str | None = redis_client.hget (f" item_id :{item_id}"," quantity ")
# if quantityto be removed is higher or equal to item's quantity,delete the item
if item_quantityis None:
existing_quantity:int = 0
else:
existing_quantity:int = int(item_quantity )
if existing_quantity<= quantity :
item_name:str | None = redis_client.hget (f" item_id :{item_id}"," item_name ")
redis_client.hdel(" item_name_to_id ",f"{item_name}")
redis_client.delete (f" item_id :{item_id}")
return {"result":" Item is deleted delete . "}
else:
redis_client.hincrby (f" item_id :{item_id}"," quantity ",-quantity )
return {"result":f"{quantity} items is removed remove . "}
Re-run the debugger to test this application by interacting with the /docs
route. You can stop the debugger once you’re done.
Congrats! You now have a working FastAPI application with routes to add,list,anddelete items from a grocery list,andthe data is persisted in a Redis database.
With the data now persisted by Redis,you might want to create a script to erase all testing data. To do so,create a new file called flushdb.py
with the following content:
import redis
redis_client = redis . StrictRedis (host='0.0.0.0',port=6379,db=0,decode_response=True)
redis_client.flushdb ( )
Then when you want to reset the database,you can open the flushdb.py
file in VS Code andselect the Run button on the top-right corner of the editor,or run the Python:Run Python File in Terminal command from the Command Palette.
Note that this should be done with caution because it will delete all the keys in the current database,which could lead to data loss if done in production.
With GitHub Codespaces,you can host your application for testing purposes when using ChatGPT Plugins. ChatGPT Plugins are tools that enable ChatGPT to interact with existing APIs to enhance ChatGPT’s abilities,allowing it to perform a wide range of actions. ChatGPT Plugins are not currently publicly available,but you can join their wait list to get access. Once you do,you can follow along the live stream recording below to create your own grocery list plugin for ChatGPT:
Note:All personal GitHub.com accounts have a monthly quota of free use of GitHub Codespaces included in the Free or Pro plan. For more information,go to About billing for GitHub Codespaces.
Thank you for following along this tutorial! We hope you learned something new about FastAPI andhow to use it with VS Code.
The completed code project from this tutorial can be found on GitHub:python-sample-vscode-fastapi-tutorial.
learn more about FastAPI at the official documentation .
To try the app on a production website,check out the tutorial Deploy Python apps to Azure App Service using Docker Containers.
You can also review these other VS Code Python articles:
12/11/2024