首页 > 其他分享 >My First CRUD App With Fast API

My First CRUD App With Fast API

时间:2023-06-10 18:11:26浏览次数:51  
标签:database App py CRUD Fast will session our id


Image by author

It’s the day before my fast API live stream. I decided to create a guide for the stream and turn it into a blog post. So, here it is.

Stream structure:

  • Fast API vs Django
  • Installation
  • Create First APP & Route
  • Swagger UI
  • Path Parameters
  • POST, PUT & DELETE Requests
  • Database & Models
  • CRUD with new database

Fast API vs. Django

A lot of you may know me as the Django guy. After all, my channel is littered with Django projects and courses. This last week I took a trip to Lake Shasta which is in northern California, and like always, I got bored with having too much free time on my hands so I decided to learn something new.

I’ve been asked over and over what my opinion was on the new framework and how it compares to Django, and up until now, I kept quiet because, well, I didn't know much about it.

After a week, I still don't know much about it, but I have learned how to create a simple CRUD app and have started forming my opinion. To be honest this opinion is not locked in and is subject to change as I work with fast API more and more.

Here’s my conclusion as of 5/22/2022. Django is still the more powerful framework and will be my go-to. Fast API is pretty cool though. One area where fast API really stood out for me was the support for ASYNC and not having to constantly serialize my data. Honestly, I hate having to serialize data just to render out a simple object or list.

Fast API was fast and easy to set up but you end up paying for it later. This is why I don't like lightweight frameworks like Flask and Fast API typically. Django gives me an easy-to-configure database, ORM, Authentication and so much more.

OK, enough with my opinions. Let's get started with the guide.

Installation

I should probably already assume this, but if you don't already, make sure you have Python installed on your machine. Fast API requires Python 3.6 and up.

Once you have Python installed, Fast API can be installed with a simple pip command

pip install fastapi

Create First APP and Route

Let’s start by creating a simple app and route that returns back a list of items as JSON data.

To create your first project, simply create a new folder somewhere on your computer. I’m adding this to my desktop and calling it myapi.

Open this folder with the text editor of your choice (VS Code for me) and create a file called main.py. This will be the main file that ties our app together.

myapi
main.py

Inside of the main.py file, start by importing the FastAPI class, setting up the app variable, and creating your first route. Here’s the code to do that:

#main.py
from fastapi import FastAPIapp = FastAPI()@app.get("/")
def getItems():
return ['Item 1', 'Item 2', 'Item 3']

Now, to see this output, let's install uvicorn which is an ASGI server.

pip install uvicorn

Now to run the server make sure you are in the projects root directory and run the following command:

uvicorn main:app --reload#Output
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.

main is the file name, app is the name of our app variable and — reload will restart our server anytime we make a change to the code and should only be used in development.

FastAPI Output List as JSON Data

Swagger UI

Fast API provides an interactive API that’s brought to us by swagger UI. I’ll save myself from explaining swagger UI and instead will provide a link if you want to check it out, but trust me, it’s pretty cool.

To see it in action, add /docs# to the end of the URL we set for our first route.

http://127.0.0.1:8000/docs#

This will give you a cool UI to work with so you can interact with your API and get more information than just some data. This will list out all your routes as you add them.

To test things out, click on the route that is currently available and then click “try it out” and then “execute.”

Now, you will see your data formatted like so:

Before moving on to the next section let’s create an object that will represent our database. We will eventually start working with an SQLite database but this will make things easier to start with before we advance later.

Create this object just above our first route:

and render the items out in the first route:

Path Parameters

Next, I want to create some dynamic routes to retrieve a particular object from my database. To do this we will create a new route with a path parameter and then specify the type of parameter we need in our view function.

This is actually very simple using the following code:

@app.get("/{id}")
def getItem(id:int):
return fakeDatabase[id]

This route will expect an integer as a path parameter for the id value. We will then take that parameter and query the item that has that particular id. When testing, make sure you are using ids that exist in your database.

Here’s the output:

POST, PUT and DELETE Requests

Time to send some POSTPUT, and DELETE requests so we can modify our fake database.

Just to recap, a POST request is for adding data, a PUT request is typically for Updating data and a DELETE request is for, well, deleting data.

Starting with our POST request for adding new items to our database, we have a few ways of doing this so I’ll test out three options.

Here is the route we need to create. I’ll break it down below.

#Option # 1
@app.post("/")
def addItem(task:str):
newId = len(fakeDatabase.keys()) + 1
fakeDatabase[newId] = {"task":task}
return fakeDatabase

What you will see in the docs UI is the following:

app.post — We are specifying the HTTP request type for this route as a post request.

/ — This is the same route as getItemsaddItems will handle all post requests sent here while getItems will handle all get requests.

Function parameters — In the function we specify that we are expecting a task in the request body and the data type must be a string.

When we explicitly specify the parameters needed this will be reflected in the docs UI as a form field as the image above shows. Pretty neat, huh?

Now, let's say we need to send multiple values in the request body. We can add each field as a parameter to the function but this can get pretty messy.

Just imagine something like this:

addItem(“task”:str, “priority”:”str”, “rank”:int, ..........)

This can go on forever and get messy!

So instead, we will use pydantic to design our data scheme and simply pass in an object that will specify the data needed. This will make things much cleaner.

To do this, we will first install pydantic, then create a new file called schemas.py and add the following code:

pip install pydantic

Create schemas.py file

myapi
main.py
schemas.py

schemas.py

from pydantic import BaseModelclass Item(BaseModel):
task: str

We will then import our schema into our main.py file and update our addItem route to look like so.

from fastapi import FastAPI
import schemas…………#Option # 2
@app.post("/")
def addItem(item:schemas.Item):
newId = len(fakeDatabase.keys()) + 1
fakeDatabase[newId] = {"task":item.task}
return fakeDatabase

Your doc’s UI should look something like this:

OK, so options 1 and 2 work great but some of you may not know what data you want to send over right away, or maybe you just want to access the entire request body sent over and extract each item as you please. I’ll show you how to do this as option 3.

Again, we will modify the addItem route, but this time we need to import Body from Fast API in main.py

from fastapi import FastAPI, Body

Next, we will use the Body class and add it as a parameter in our route. Once we add it as a parameter, we can then access the request body as a dictionary and extract the value of the task.

#Option #3
@app.post("/")
def addItem(body = Body()):
newId = len(fakeDatabase.keys()) + 1
fakeDatabase[newId] = {"task":body['task']}
return fakeDatabase

And that’s it!

The downside to this approach is that you won’t have your fields specified in the docs UI. All you will see is a string value so you will have to create the entire request body yourself. Honestly, it’s not much of an issue since you typically have to create the request body in the front end anyways but it’s something to consider. Also, make sure that you are using double quotes and not single quotes. This will ensure that the string is able to be parsed on the receiving end.

Updating Data

In main.py, let's add the following route for updating data:

@app.put("/{id}")
def updateItem(id:int, item:schemas.Item):
fakeDatabase[id]['task'] = item.task
return fakeDatabase

We are using the same URL path as getItem, but this route will specifically handle the put request. You can use one of the three options we used for the post request. In my example, I decided to go with the pydantic route (option 2).

Deleting Data

Let’s add one more route, this one will process delete requests sent to /{id}. The only parameter we need is the id since all we are doing is finding the item we need and removing it from the database.

@app.delete("/{id}")
def deleteItem(id:int):
del fakeDatabase[id]
return fakeDatabase

Database and Models

All right, so we’re done with our placeholder database. It’s time to make a real connection and build out our models file. In this example, we will use SQLite as our DB.

pip install sqlalchemy

We’ll start by adding a database.py file to establish a connection and then add the following code inside of the new file.

myapi
main.py
schemas.py
database.py

database.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker#Create sqlite engine instance
engine = create_engine("sqlite:///todo.db")#Create declaritive base meta instance
Base = declarative_base()#Create session local class for session maker
SessionLocal = sessionmaker(bind=engine, expire_on_commit=False)

Once we have our database connection configured, we’ll want to create our database models to represent our db tables.

myapi
main.py
schemas.py
database.py
models.py

models.py

from sqlalchemy import Column, Integer, String
from database import Baseclass Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True)
task = Column(String(256))

Now, let's initiate our database in main.py so we can start using it.

https://gist.github.com/BetterProgramming/83edee29166269f0e622f81ca85e6a1f

Working with our database

OK, let's make our first database query.

Let's update our getItems view to query all the items in our database like so:

@app.get("/")
def getItems(session: Session = Depends(get_session)):
items = session.query(models.Item).all()
return items

This will return back all the items as a JSON list. At this point, we don’t have any items, so let's change that by updating our addItem view.

@app.post("/")
def addItem(item:schemas.Item, session = Depends(get_session)):
item = models.Item(task = item.task)
session.add(item)
session.commit()
session.refresh(item)
return item

Now to retrieve a single item.

@app.get("/{id}")
def getItem(id:int, session: Session = Depends(get_session)):
item = session.query(models.Item).get(id)
return item

And to update an item.S

@app.put("/{id}")
def updateItem(id:int, item:schemas.Item, session = Depends(get_session)):
itemObject = session.query(models.Item).get(id)
itemObject.task = item.task
session.commit()
return itemObject

Lastly, to delete an item.

@app.delete("/{id}")
def deleteItem(id:int, session = Depends(get_session)):
itemObject = session.query(models.Item).get(id)
session.delete(itemObject)
session.commit()
session.close()
return 'Item was deleted'

OK, that’s it!

 

You can find the full code on GitHub or watch the stream recording here: https://www.youtube.com/watch?v=FOZNYBu8u18

标签:database,App,py,CRUD,Fast,will,session,our,id
From: https://www.cnblogs.com/weifeng1463/p/17471706.html

相关文章

  • uniapp-黑马优选学习01
    01.IDE使用HBuilderX02.scss/sass插件安装:为了方便样式的编写   地址: https://ext.dcloud.net.cn/plugin?name=compile-node-sass03.快捷键方案的设置、IDE主题色的设置、基本设置(ctlr加alt加逗号 :  ctrl+alt+, )    >>其它基本......
  • application.properties
    server.port=8080spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3307/teachmanger?useSSL=falsespring.datasource.username=rootspring.datasource.password=123456spring.datasource.type=com.alibaba.dru......
  • mapper层
    AnswerMapper.xml<?xmlversion="1.0"encoding="utf-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="co......
  • 靳宇灵 | FastAdmin数据库开发规则
    这里提供的是数据库表字段规则在你创建表时使用,当按如下的规则进行字段命名、类型设置和备注时使用phpthinkcrud-t表名生成CRUD时会自动生成对应的控制器、模型、视图、JS等。根据字段类型类型备注类型说明int整型自动生成type为number的文本框,步长为1enum枚举型自动生成单选下......
  • Vue启动报错:This usually happens because your environment has changed since runni
    Thisusuallyhappensbecauseyourenvironmenthaschangedsincerunning`npminstall`问题根本:这通常是因为运行NPM安装后环境发生了变化。运行“NPM重建节点SASS——强制”来为当前环境构建绑定。 如何解决:此时运行按照提示执行npmrebuildnode-sass命令,(如若不行,......
  • imessages数据检测,imessages过蓝检测,用applescript检测手机号码是否注册imessage实
    一、检测iMessage发送数据的2种方式:1.人工筛选,将要验证的号码输出到文件中,以逗号分隔。再将文件中的号码粘贴到iMessage客户端的地址栏,iMessage客户端会自动逐个检验该号码是否为iMessage账号,检验速度视网速而定。红色表示不是iMessage账号,蓝色表示iMessage账号。2.编写脚本控制......
  • 每日打卡app
    项目介绍:项目背景:石家庄铁道大学软件工程系从本学期开始要求21级学生每日打卡总结,特委托石家庄铁道大学给力21软件有限公司进行开发。第一阶段目标:1、用户注册:用户注册信息包括用户ID(学号)、用户名(姓名),手机号码,用户单位(班级),用户班级四项基本信息,用户第一次注册后,用户姓名不用每......
  • 图文详解丨iOS App上架全流程及审核避坑指南
    到了2021年,虽然网上也有大牛写过很多IOSApp上架流程资料,但随着苹果发布机制的微调有些已经过时了。我就趁着这次刚刚发布成功的鲜活经验,记录下来,做一下补充。1、首先得注册AppleDeveloper的开发者账号,最后如果要上架苹果商店,这个账号是要交年费的,核算下来大概600多元人民币。......
  • 图文详解丨iOS App上架全流程及审核避坑指南
    图文详解丨iOSApp上架全流程及审核避坑指南到了2021年,虽然网上也有大牛写过很多IOSApp上架流程资料,但随着苹果发布机制的微调有些已经过时了。我就趁着这次刚刚发布成功的鲜活经验,记录下来,做一下补充。1、首先得注册AppleDeveloper的开发者账号,最后如果要上架苹果商店,这个账......
  • iOS App的打包和上架流程
    ​   转载:iOSApp的打包和上架流程-掘金1.创建账号苹果开发者账号几种开发者账号类型个人开发者账号费用:99美元/年(688.00元)协作人数:仅限开发者自己不需要填写公司的邓百氏编码(D-U-N-SNumber)支持账号下的app上线AppStore需要创建AppleID公司开发者账号:......