fastapi(一)
废话不多说,直接上代码。
目录结构, 由于我也是刚开始学这个框架,只是了解了怎么注册蓝图,JWT的集成,数据库的集成,想了解更多,自行打开官方文档去详细阅读。fastapi官网文档链接
创建一个main.py文件, 我这个是添加了蓝图, 关键字:
- from fastapi import FastAPI
- from text import demo
- from wx import test_client
- from sql_conf import models, database
- models.Base.metadata.create_all(bind=database.engine)
- app = FastAPI()
- app.include_router(demo.router, prefix="/api")
- app.include_router(test_client.router, prefix="/wx")
- if __name__ == '__main__':
- import uvicorn
- uvicorn.run(
- app='main:app',
- host="0.0.0.0",
- port=8082,
- reload=True,
- debug=True
- )
auth.py用来jwt的校验和生成
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 3:25 下午
- import jwt
- from fastapi import HTTPException, Security, status
- from fastapi.security import HTTPAuthorizationCredentials, HTTPBasic
- from passlib.context import CryptContext
- from datetime import datetime, timedelta
- class AuthHandler():
- security = HTTPBasic()
- pwd_content = CryptContext(schemes=['bcrypt'], deprecated='auto')
- secret = 'SECRET'
- # 密码加密
- def get_password_has(self, password):
- return self.pwd_content.hash(password)
- # 密码校验
- def verify_password(self, plain_password, hashed_password):
- return self.pwd_content.verify(plain_password, hashed_password)
- # 生成token
- def encode_token(self, user_id):
- payload = {
- 'exp': datetime.utcnow() + timedelta(days=0, minutes=120),
- 'iat': datetime.utcnow(),
- 'sub': user_id
- }
- return str(jwt.encode(payload, self.secret, algorithm='HS256'))
- # token解码
- def decode_token(self, token):
- try:
- payload = jwt.decode(token, self.secret, algorithms=['HS256'])
- return payload['sub']
- except jwt.ExpiredSignatureError:
- raise HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED,
- detail="签名已过期"
- )
- except jwt.InvalidTokenError:
- raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='签名无效!')
- def auth_wrapper(self, oauth: HTTPAuthorizationCredentials = Security(security)):
- return self.decode_token(oauth.credentials)
wx,test两个目录,都是单独的一个app。
wx目录下的test_client.py
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 4:00 下午
- from fastapi import status, APIRouter, Depends, Path, Query
- from fastapi.responses import JSONResponse
- from sql_conf.database import SessionLocal
- from typing import Union, Any
- from sql_conf.models import User
- from sql_conf.crud import db_create
- from sqlalchemy.orm import Session
- from sql_conf.db_session import get_db
- from .data_model import UserItem, USerLgoin
- from auth import AuthHandler
- auth_middle = AuthHandler()
- router = APIRouter(
- tags=["wx"],
- responses={404: {"description": "未找到接口!"}}
- )
- @router.get('/')
- async def read_main(token_data: Union[str, Any] = Depends(auth_middle.decode_token),):
- content = {"msg": "hello wx"}
- return JSONResponse(status_code=status.HTTP_200_OK, content=content)
- @router.post('/create_user')
- async def create_user_info( Item: UserItem, db: Session = Depends(get_db)):
- result = {'code': 0, "message": ""}
- request_dict = Item.dict()
- login = request_dict.get('login')
- email = request_dict.get('email')
- pwd = request_dict.get("hashed_password")
- if not login:
- return JSONResponse(status_code=status.HTTP_201_CREATED, content={"code": 201, "msg": '请输入账号!'})
- has_pwd = auth_middle.get_password_has(pwd)
- save_user_info = {
- 'email': email,
- 'login': login,
- 'hashed_password': has_pwd
- }
- comiit_user = db_create(db=db, payload=save_user_info)
- if comiit_user:
- result['code'] = 200
- result['message'] = '注册成功!'
- else:
- result['code'] = 201
- result['message'] = '注册失败!'
- return JSONResponse(status_code=status.HTTP_200_OK, content=result)
- @router.post('/login_user')
- async def user_login(Data: USerLgoin, db: Session=Depends(get_db)):
- result = {}
- user_dict = Data.dict()
- user_name = user_dict.get('username')
- pwd = user_dict.get('password')
- filter_data = db.query(User).filter_by(login=user_name).first()
- version_pwd = auth_middle.verify_password(plain_password=pwd, hashed_password=filter_data.hashed_password)
- print(version_pwd)
- if version_pwd:
- token = auth_middle.encode_token(user_id=filter_data.id)
- print(token)
- result['code'] = 200
- result['msg'] = '登录成功!'
- result['token'] = token
- else:
- result['code'] = 201
- result['msg'] = '登录失败!'
- return JSONResponse(status_code=status.HTTP_200_OK, content=result)
- @router.get('/get_user/', summary="获取用户信息")
- async def get_user_info(token_data: Union[str, Any] = Depends(auth_middle.decode_token), db: Session = Depends(get_db)):
- result = {}
- filter_user = db.query(User).filter_by(id=int(token_data)).first()
- if filter_user:
- result['code'] = 200
- result['message'] = '用户信息'
- result['userinfo'] = {
- 'login': filter_user.login,
- 'email': filter_user.email,
- 'pwd': filter_user.hashed_password
- }
- else:
- result['code'] = 201
- result['message'] = "未获取到用户信息!"
- return JSONResponse(status_code=status.HTTP_200_OK, content=result)
data_model.py 用来创建数据模型
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 4:02 下午
- from pydantic import BaseModel
- class UserItem(BaseModel):
- login: str
- email: str
- hashed_password: str
- class USerLgoin(BaseModel):
- username: str
- password: str
text目录demo.py文件
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 3:48 下午
- from typing import Optional
- from fastapi import FastAPI, Body, status, APIRouter
- from pydantic import BaseModel
- from fastapi.responses import JSONResponse
- router = APIRouter(
- tags=["items"],
- responses={404: {"description": "Not found"}}
- )
- class Item(BaseModel):
- name: str
- price: float
- is_offer: Optional[bool] = None
- @router.get('/')
- def index():
- content = {"hello": "world"}
- return JSONResponse(status_code=status.HTTP_200_OK, content=content)
- @router.get("/items/{item_id}")
- def read_item(item_id: int, q: Optional[str] = None):
- return {'itrm_id': item_id, "q": q}
- @router.put("/items/{item_id}")
- def update_item(item_id: int, item: Item):
- print(item_id)
- print(item)
- return {"item_name": item.name, "item_id": item_id}
sql_conf目录用于配置数据库
创建 crud.py, database.py, db_session.py, models.py
crud.py 数据库的增删改查
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 4:52 下午
- from sql_conf import models
- from sqlalchemy.orm import Session
- def db_create(db: Session, payload):
- try:
- db_user = models.User(**payload)
- db.add(db_user)
- db.flush()
- db.commit()
- return db_user
- except Exception as e:
- print("错误: {}".format(e))
数据库的连接 databases.py
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 4:52 下午
- from sqlalchemy import create_engine
- from sqlalchemy.ext.declarative import declarative_base
- from sqlalchemy.orm import sessionmaker
- db_conf = {
- 'user': 'user',
- 'password': '密码',
- 'host': 'ip',
- 'port': '3306',
- 'name': 'demo'
- }
- # 数据库访问地址
- SQLALCHEMY_DATABASE_URL = "mysql+pymysql://{user}:{password}@{host}:{port}/{name}".format(
- user=db_conf['user'],
- password=db_conf['password'],
- host=db_conf['host'],
- port=db_conf['port'],
- name=db_conf['name']
- )
- # 启动引擎
- engine = create_engine(
- SQLALCHEMY_DATABASE_URL
- )
- # 创建会话
- SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
- # 数据模型基类
- Base = declarative_base()
models.py创建模型
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 4:52 下午
- from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
- from sqlalchemy.orm import relationship
- from .database import Base
- class User(Base):
- __tablename__ = "users"
- id = Column(Integer, primary_key=True, index=True)
- login = Column(String(length=60), index=True)
- email = Column(String(length=255), unique=True, index=True, )
- hashed_password = Column(String(length=255))
- is_active = Column(Boolean, default=True)
db_session.py 数据库会话信息
- #! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # Eamil: 1922878025@qq.com
- # @Author: Wyc
- # @Time: 2:59 下午
- from .database import SessionLocal
- def get_db():
- db = ""
- try:
- db = SessionLocal()
- yield db
- finally:
- db.close()
fastapi(一)的更多相关文章
- FastAPI框架
目录 FastAPI框架 安装 基本使用 模版渲染 安装jinja2 基本使用 form表单数据交互 基本数据 文件交互 静态文件配置 FastAPI框架 该框架的速度(天然支持异步)比一般的djan ...
- FastAPI 快速搭建一个REST API 服务
最近正好在看好的接口文档方便的工具, 突然看到这个, 试了一下确实挺方便 快速示例 from fastapi import FastAPI from pydantic import BaseModel ...
- 三分钟了解 Python3 的异步 Web 框架 FastAPI
快速编码,功能完善.从启动到部署,实例详解异步 py3 框架选择 FastAPI 的原因. FastAPI 介绍 FastAPI 与其它 Python-Web 框架的区别 在 FastAPI 之前,P ...
- FastAPI框架入门 基本使用, 模版渲染, form表单数据交互, 上传文件, 静态文件配置
安装 pip install fastapi[all] pip install unicorn 基本使用(不能同时支持,get, post方法等要分开写) from fastapi import Fa ...
- python fastApi实战项目 - 爱投票管理系统(一)
一.闲来无事,在工作之余自己研究了一下python的异步框架 - fastapi,并写包括 1.部门管理 2.角色管理 3.用户管理 4.菜单管理 5.登录日志 6.操作日志 六个基础功能模块,演示链 ...
- fastapi+vue搭建免费代理IP网站部署至heroku
说明 最近需要用到一些HTTP的代理,用于爬虫去爬取信息,搜索了一些网站,貌似现在这类提供免费代理IP的网站很多,刚好最近看了点vue的视频,弄个网站练练. 部署到heroku,预览地址:点击这里 F ...
- FastAPI学习: 个人博客的后端API
前言 学习FastAPI中把官方文档过了一遍,看了些大佬的文章,也借鉴(抄袭)了部分代码,写了一套个人博客的API,目前还比较简陋,统计的API基本没有,而且目前基本都停留在单表查询,所以含量不高,接 ...
- FastApi 进阶
前言 终于有了第一个使用 FastApi 编写的线上服务, 在开发的过程中还是遇到了些问题, 这里记录一下 正文 目录结构 我们知道, FastApi 的启动方式推荐使用 uvicorn, 其启动方式 ...
- FastApi学习(二)
前言 继续学习 此为第二篇, 还差些知识点就可以结束, 更多的比如用户的身份校验/ swagger 文档修改等以后会单独写 正文 使用枚举来限定参数 可以使用枚举的方式来限定参数为某几个值之内才通过 ...
- FastApi学习(一)
前言 学习不止 正文 介绍 FastApi是PythonWeb框架的'新晋干员',虽然年轻但是很能打 目前已有 12k start GitHub 官网 为什么说他能打呢?它内部使用了 Python 的 ...
随机推荐
- 大数据学习day39----数据仓库02------1. log4j 2. 父子maven工程(子spring项目的创建)3.项目开发(埋点日志预处理-json数据解析、清洗过滤、数据集成实现、uid回补)
1. log4j(具体见log4j文档) log4j是一个java系统中用于输出日志信息的工具.log4j可以将日志定义成多种级别:ERROR / WARN / INFO / DEBUG ...
- 大数据学习day14-----第三阶段-----scala02------1. 元组 2.类、对象、继承、特质 3.函数(必须掌握)
1. 元组 映射是K/V对偶的集合,对偶是元组的最简单的形式,元组可以装着多个不同类型的值 1.1 特点 元组相当于一个特殊的数组,其长度和内容都可变,并且数组中可以装任何类型的数据,其主要用处就是存 ...
- 【Reverse】每日必逆0x01
附件:https://files.buuoj.cn/files/7458c5c0ce999ac491df13cf7a7ed9f1/SimpleRev 题解 查壳 64位ELF文件,无壳 IDApro处 ...
- 【swift】CoreData Crash(崩溃)(Failed to call designated initializer on NSManagedObject class)
感谢另一篇博客:https://blog.csdn.net/devday/article/details/6577985 里面的图片和介绍,发现问题如他描述的一样,没有bundle 我的Xcode版本 ...
- Java8使用并行流(ParallelStream)注意事项
Java8并行流ParallelStream和Stream的区别就是支持并行执行,提高程序运行效率.但是如果使用不当可能会发生线程安全的问题.Demo如下: public static void co ...
- 【力扣】454. 四数相加 II
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单化,所有的 A ...
- 【HarmonyOS】【DevEco Studio】NOTE04:How to Jump to a Page(页面间的跳转)
页面创建与基本设置 创建页面 创建两个新页面,分别为AbilityPage1.AbilityPage2 设置页面基本内容 以AbilityPage1为例 导包 import com.example.m ...
- JAVA日志发展史
JAVA日志发展史 第一阶段 2001年以前,Java是没有日志库的,打印日志全凭System.out和System.err 缺点: 产生大量的IO操作同时在生产环境中无法合理的控制是否需要输出 输出 ...
- Linux中定时任务
目录 一.简介 二.crondtab file 三.crond命令的调试 四.精确到秒的任务计划 一.简介 定时任务在线测试网站 定时任务基本概念: (1).crond是一个daemon类程序,路径为 ...
- MySQL获取对应时间
一.查询当前时间包含年月日 SELECT CURDATE(); SELECT CURRENT_DATE(); 二.查询当前时间包含年月日时分秒 SELECT NOW(); SELECT SYSDATE ...