FastApi快速搭建api指北

248 阅读4分钟

前言

由于有个需求需要同时接受TCP服务器指令,NTP同步时钟,加上需要后台执行一些函数。Django的多线程或者说异步其实挺麻烦的(菜,没时间研究)。正好最近小学一波fastapi,就尝试着去编写。 本文为一个简单接口(增加、查找)进行演示,还请大家多多赐教。 2023.10.12 11:23 更新了修改和删除

FastAPI实战

1、环境配置

项目目录如下:

4029532676.png 说明;run.py(启动项目、配置fastapi) crud.py(对数据库的操作) database.py(在fastapi下创建和配置数据) main.py(业务和接口) models.py(创建表(ORM)) schemas.py(响应体)

安装以下环境

fastapi == 0.63.0 uvicorn == 0.13.2

在run.py加入以下代码

import uvicorn
from fastapi import FastAPI

app = FastAPI(
    title='FastAPI FC Player',
    description='花车音乐播放系统API接口文档',
    version='0.0.1',
    docs_url='/docs',
    redoc_url='/redoc'
)

if __name__ == '__main__':
    uvicorn.run('run:app', host='0.0.0.0', port=8000, reload=True, workers=3)

这个时候运行run.py文件,在浏览器输入http://0.0.0.0:8000/docs就看看到,服务启动了。

3659611216.png

2、数据库配置

安装包 SQLAlchemy==1.3.22 在database.py中输入

# 在fastapi下创建和配置数据
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = 'sqlite:///./fcplayer.sqlite3'  # 这里使用的sqllite fcplayer为表名
# SQLALCHEMY_DATABASE_URL = "postgresql://username:password@host:port/database_name"  # MySQL或PostgreSQL的连接方法

# 创建数据库引擎
engine = create_engine(
    # echo=True表示引擎将用repr()函数记录所有语句及其参数列表到日志
    # 由于SQLAlchemy是多线程,指定check_same_thread=False来让建立的对象任意线程都可使用。这个参数只在用SQLite数据库时设置
    SQLALCHEMY_DATABASE_URL, encoding='utf-8', echo=True, connect_args={'check_same_thread': False}
)
# 在SQLAlchemy中,CRUD都是通过会话(session)进行的,所以我们必须要先创建会话,每一个SessionLocal实例就是一个数据库session
# flush()是指发送数据库语句到数据库,但数据库不一定执行写入磁盘;commit()是指提交事务,将变更保存到数据库文件
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, expire_on_commit=True)

# 创建基本映射类
Base = declarative_base(bind=engine, name='Base')

3、SQLAlchemy开发模型类

orm来创建数据库,类似于django的model中操作

教程:

Python3+SQLAlchemy+Sqlite3实现ORM教程 www.cnblogs.com/jiangxiaobo…

SQLAlchemy基础知识 Autoflush和Autocommit zhuanlan.zhihu.com/p/48994990 (这边以信息表为例)在models.py中输入

# 创建表(ORM)
from sqlalchemy import Column, String, Integer, Date, DateTime, ForeignKey, func, Boolean
from sqlalchemy.orm import relationship
from .database import Base


# 配置消息表
class Msg(Base):
    __tablename__ = 'message'
    id = Column(Integer, primary_key=True, autoincrement=True)
    info = Column(String(100), nullable=False, comment='信息')
    created_time = Column(DateTime, server_default=func.now(), comment='创建时间')

    __mapper_args__ = {"order_by": id.desc()}

    def __repr__(self):
        return f'{self.id}_{self.info}_{self.created_time}'

4、使用Pydantic建立与模型类对应的数据格式类

在schemas.py中增加

# 响应体
from pydantic import BaseModel
from datetime import datetime

# 消息表操作
class CreateMsg(BaseModel):
    info: str


class ReadMsg(CreateMsg):
    id: int
    created_time = datetime

    class Config:
        orm_mode = True


完成响应体的编写

编写curd的操作

在crud.py中加入

from pydantic import BaseModel
from datetime import datetime


class CreateMsg(BaseModel):
    info: str


class ReadMsg(CreateMsg):
    id: int
    created_time = datetime

    class Config:
        orm_mode = True

完成接口的编写

在main.py中加入:

from fastapi import APIRouter, Depends, HTTPException

from sqlalchemy.orm import Session

from FC import crud, schemas
from FC.database import engine, Base, SessionLocal

application = APIRouter()

Base.metadata.create_all(bind=engine)


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


@application.post("/create_msg", response_model=schemas.ReadMsg)
def create_msg(info: schemas.CreateMsg, db: Session = Depends(get_db)):
    return crud.create_msg(db=db, msg=info)


@application.get("/get_msg/{msg_id}", response_model=schemas.ReadMsg)
def get_msg(msg_id: int, db: Session = Depends(get_db)):
    db_msg = crud.get_msg(db=db, msg_id=msg_id)
    if db_msg is None:
        raise HTTPException(status_code=404, detail="msg not found")
    return db_msg

现在我们msg——api的增加和查找接口写好了

application还需要添加到run.py中

现在fc的__init__.py中加入

from .main import application

对run.py进行修改

import uvicorn
from fastapi import FastAPI
from FC import application

app = FastAPI(
    title='FastAPI FC Player',
    description='花车音乐播放系统API接口文档',
    version='0.0.1',
    docs_url='/docs',
    redoc_url='/redoc'
)

app.include_router(application, prefix='/FC', tags=['花车播放系统API'])

if __name__ == '__main__':
    uvicorn.run('run:app', host='0.0.0.0', port=8000, reload=True, workers=3)

测试下

用浏览器打开:http://localhost:8000/docs 就可以看到我们的接口啦 对post get可以用接口文档进行简单测试

3150755040.png

增加修改和删除

在schemas.py新增

class UpdateMsg(CreateMsg):
    class Config:
        orm_mode = True

在crud.py中新增

def update_msg(db: Session, msg_id: int, msg: schemas.UpdateMsg):
    db_msg = db.query(Msg).filter(Msg.id == msg_id).first()
    if not db_msg:
        raise HTTPException(status_code=404, detail="Msg not found")
    db_msg.info = msg.info
    db.commit()
    db.refresh(db_msg)
    return db_msg

def delete_msg(db: Session, msg_id: int):
    msg = db.query(Msg).filter(Msg.id == msg_id).first()
    if not msg:
        raise HTTPException(status_code=404, detail="Msg not found")
    db.delete(msg)
    db.commit()
    return msg

在main.py中新增

@application.put("/update_msg/{msg_id}")
def update_msg(msg_id: int, msg: schemas.UpdateMsg, db: Session = Depends(get_db)):
    return crud.update_msg(db=db, msg_id=msg_id, msg=msg)


@application.delete("/delete_msg/{msg_id}")
def delete_msg(msg_id: int, db: Session = Depends(get_db)):
    return crud.delete_msg(db=db, msg_id=msg_id)

效果为:

image.png