前言
由于有个需求需要同时接受TCP服务器指令,NTP同步时钟,加上需要后台执行一些函数。Django的多线程或者说异步其实挺麻烦的(菜,没时间研究)。正好最近小学一波fastapi,就尝试着去编写。 本文为一个简单接口(增加、查找)进行演示,还请大家多多赐教。 2023.10.12 11:23 更新了修改和删除
FastAPI实战
1、环境配置
项目目录如下:
说明;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就看看到,服务启动了。
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可以用接口文档进行简单测试
增加修改和删除
在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)
效果为: