FastAPI(54)- 详解 Request 请求对象

时间:2021-08-07 13:25:31

背景

  • 前面讲了可以自定义 Response,那么这里就讲下请求对象 Request
  • 可以通过 Request 来获取一些数据

获取请求基础信息

@app.get("/base")
async def get_base(*, request: Request):
res = {
# 客户端连接的 host
"host": request.client.host,
# 客户端连接的端口号
"port": request.client.port,
# 请求方法
"method": request.method,
# 请求路径
"base_url": request.base_url,
# request headers
"headers": request.headers,
# request cookies
"cookies": request.cookies
}
return res

请求结果

{
"host": "127.0.0.1",
"port": 54364,
"method": "GET",
"base_url": {
"_url": "http://127.0.0.1:8080/"
},
"headers": {
"host": "127.0.0.1:8080",
"connection": "keep-alive",
"sec-ch-ua": "\"Chromium\";v=\"94\", \"Google Chrome\";v=\"94\", \";Not A Brand\";v=\"99\"",
"accept": "application/json",
"sec-ch-ua-mobile": "?0",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-site": "same-origin",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "http://127.0.0.1:8080/docs",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6",
"cookie": "test_token=tokenABC"
},
"cookies": {
"test_token": "tokenABC"
}
}

可以看到 port 并不是 8080

request.url 对象

from fastapi import Query

@app.get("/url/{item_id}")
async def get_url(*,
item_id: str,
name: str = Query(...),
request: Request):
res = {
# 请求 url
"url": request.url,
# 总的组成
"components": request.url.components,
# 请求协议
"scheme": request.url.scheme,
# 请求 host
"hostname": request.url.hostname,
# 请求端口
"url_port": request.url.port,
# 请求 path
"path": request.url.path,
# 请求查询参数
"query": request.url.query,
"fragment": request.url.fragment,
"password": request.url.password
}
return res

请求结果

{
"url": {
"_url": "http://127.0.0.1:8080/url/123?name=456",
"_components": [
"http",
"127.0.0.1:8080",
"/url/123",
"name=456",
""
]
},
"components": [
"http",
"127.0.0.1:8080",
"/url/123",
"name=456",
""
],
"scheme": "http",
"hostname": "127.0.0.1",
"url_port": 8080,
"path": "/url/123",
"query": "name=456",
"fragment": "",
"password": null
}

request.url 是一个对象(URL 类),得到的是一个字典

获取路径参数、查询参数

@app.get("/query_path/{item_id}")
async def get_all(*,
item_id: str,
name: str = Query(...),
request: Request):
res = {
# 获取路径参数
"path_params": request.path_params,
"item_id": request.path_params.get("item_id"),
# 获取查询参数
"query_params": request.query_params,
"name": request.query_params["name"]
}
return res

请求结果

{
"path_params": {
"item_id": "123"
},
"item_id": "123",
"query_params": {
"name": "小菠萝"
},
"name": "小菠萝"
}

path_params、query_params返回的都是字典格式的数据

获取表单数据

@app.post("/form")
async def get_form(*,
username: str = Form(...),
oassword: str = Form(...),
request: Request):
res = {
# 获取表单数据
"form": await request.form()
}
return res

请求结果

{
"form": {
"username": "name",
"oassword": "***"
}
}

获取 Request Body

class Item(BaseModel):
id: str
title: str @app.post("/body")
async def get_body(item: Item, request: Request):
res = {
# 获取 Request Body
"body": await request.json(),
"body_bytes": await request.body()
}
return res

请求结果

{
"body": {
"id": "string",
"title": "string"
},
"body_bytes": "{\n \"id\": \"string\",\n \"title\": \"string\"\n}"
}

.body() 返回值类型是 bytes

获取 Request 存储的附加信息

async def dep_state(request: Request):
# 给 request 存储附加数据
request.state.db = "Mysql+pymysql//username" @app.post("/state/", dependencies=[Depends(dep_state)])
async def get_state(request: Request):
res = {
"state": request.state,
"db": request.state.db
}
return res

请求结果

{
"state": {
"_state": {
"db": "Mysql+pymysql//username"
}
},
"db": "Mysql+pymysql//username"
}

获取文件上传信息

from fastapi import UploadFile, File, Form

@app.post("/file")
async def get_file(*,
file: UploadFile = File(...),
name: str = Form(...),
request: Request):
form_data = await request.form()
res = {
# 表单数据
"form": form_data,
# 文件对象 UploadFile
"file": form_data.get("file"),
# 文件名
"filename": form_data.get("file").filename,
# 文件类型
"content_type": form_data.get("file").content_type,
# 文件内容
"file_content": await form_data.get("file").read()
}
return res

请求结果

{
"form": {
"file": {
"filename": "test.txt",
"content_type": "text/plain",
"file": {}
},
"name": "表单name!!"
},
"file": {
"filename": "test.txt",
"content_type": "text/plain",
"file": {}
},
"filename": "test.txt",
"content_type": "text/plain",
"file_content": "hello world"
}

UploadFile 对象

  • form_data.get("file") 返回的是一个 starlette.datastructures.UploadFile 对象
  • filename、content_type 是对象实例属性
  • .read() 是实例方法,读取文件

UploadFile 的其他异步方法

和 Python 普通的文件对象方法一样,只不过都是 async 异步的

  • write
  • read
  • seek
  • close

FastAPI(54)- 详解 Request 请求对象

FastAPI(54)- 详解 Request 请求对象的更多相关文章

  1. TOMCAT原理详解及请求过程(转载)

    转自https://www.cnblogs.com/hggen/p/6264475.html TOMCAT原理详解及请求过程 Tomcat: Tomcat是一个JSP/Servlet容器.其作为Ser ...

  2. 详解SpringMVC请求的时候是如何找到正确的Controller

    详解SpringMVC请求的时候是如何找到正确的Controller[附带源码分析] 目录 前言 源码分析 重要接口介绍 SpringMVC初始化的时候做了什么 HandlerExecutionCha ...

  3. Java精通并发-自旋对于synchronized关键字的底层意义与价值分析以及互斥锁属性详解与Monitor对象特性解说【纯理论】

    自旋对于synchronized关键字的底层意义与价值分析: 对于synchronized关键字的底层意义和价值分析,下面用纯理论的方式来对它进行阐述,自旋这个概念就会应运而生,还是很重要的,下面阐述 ...

  4. Servlet的学习之Request请求对象(3)

    本篇接上一篇,将Servlet中的HttpServletRequest对象获取RequestDispatcher对象后能进行的[转发]forward功能和[包含]include功能介绍完. 首先来看R ...

  5. Servlet的学习之Request请求对象(2)

    在上一篇<Servlet的学习(十)>中介绍了HttpServletRequest请求对象的一些常用方法,而从这篇起开始介绍和学习HttpServletRequest的常用功能. 使用Ht ...

  6. JSP内置九个对象Request请求对象

    jsp内置对象是什么呢? 例如Java语言使用一个对象之前需要实例化(也就是所说的new一个对象),创建对象这个过程有点麻烦,所以在jsp中提供了一些内置对象,用来实现很多jsp应用.在使用内置对象时 ...

  7. c&num; 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c&num; dynamic动态类型和匿名类 详解C&num; 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C&num;中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

  8. opa gatekeeper笔记:AdmissionReview input&period;request请求对象结构

    官方:https://v1-17.docs.kubernetes.io/zh/docs/reference/access-authn-authz/extensible-admission-contro ...

  9. ASP&period;NET 运行时详解 揭开请求过程神秘面纱

    对于ASP.NET开发,排在前五的话题离不开请求生命周期.像什么Cache.身份认证.Role管理.Routing映射,微软到底在请求过程中干了哪些隐秘的事,现在是时候揭晓了.抛开乌云见晴天,接下来就 ...

随机推荐

  1. html局部打印

    html页面局部打印的小栗子 只要修改点击打印的按钮和打印的div区域的id就行啦 <!DOCTYPE html> <html> <head> <title& ...

  2. Apache运行python cgi程序

    Apache运行python cgi程序 环境 win10 x64 专业版 Apache2.4 python 2.7 Apache安装和配置 Apache服务器的安装请自行搜索.在Apache2.4中 ...

  3. Dr&period;Kong的艺术品

    题目 Dr.Kong设计了一件艺术品,该艺术品由N个构件堆叠而成,N个构件从高到低按层编号依次为1,2,……,N.艺术品展出后,引起了强烈的反映.Dr.Kong观察到,人们尤其对作品的高端部分评价甚多 ...

  4. Hacker(九)----黑客攻防前准备1

    黑客在入侵Internet中其他电脑之前,需要做一系列准备工作,包括在电脑中安装虚拟机.准备常用的工具软件及掌握常用的攻击方法. 一.在计算机中搭建虚拟环境 无论时攻击还是训练,黑客都不会拿实体计算机 ...

  5. ElasticSearch入门(3) —— head插件

    #### 安装ES head插件 具体请参考github地址:https://github.com/mobz/elasticsearch-head 使用 安装Install # 在线安装head插件 ...

  6. hibernate状态转换关系图【原】

    hibernate状态转换 其它参考 简单理解Hibernate三种状态的概念及互相转化 简单的Hibernate入门介绍

  7. vue工具知识

    1.访问数据自动格式化 Google jsonview插件(已用) 2.字体图标库. https://icomoon.io/  上传svg可生成字体图标

  8. word之常用功能

    0.word区域:标题栏.快速访问工具栏.功能区.功能按钮.导航窗口.编辑区.水平垂直滑动条.状态栏 1.更改office主题.文件---帐户---office主题.(传统白色.浅灰色.深灰色) 2. ...

  9. 第一部分:开发前的准备-第八章 Android SDK与源码下载

    第8章 Android SDK与源码下载 如果你是新下载的SDK,请阅读一下步骤了解如何设置SDK.如果你已经下载使用过SDK,那么你应该使用AVD Manager,来更新即可. 下面是构建Andro ...

  10. SpringBoot-整合多数据源

    整合多数据源 这里有两种,分包数据源和注解数据源,这里讲分包数据源 配置文件中新增两个数据源 spring.datasource.test1.driverClassName = com.mysql.j ...