背景

  • 前面讲了可以自定义 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 请求对象的更多相关文章

  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# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

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

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

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

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

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

随机推荐

  1. java基本数据类型和包装类之间的转换(装箱,拆箱)

    1.装箱:把基本数据类型转换成包装类 1.1自动装箱 int t1=2; Integer t2 =t1; 1.2手动装箱 Integer t3 = new Integer(t1); 2.拆箱:把包装类 ...

  2. 从eclipse转idea不适记录【持续更新】

    使用eclipse和idea时,快捷键对比 从一些最扎心的开始: 关于print一类的打印输出:System.out.println()补全 idea中可以sout.souf.serr:分别对应out ...

  3. tomcat中修改Web站点的默认根目录

    转自:http://blog.csdn.net/wzqcongcong/article/details/6387907 想把Tomcat的默认网站根目录修改成自己指定的目录,比如:F:/MyWeb.这 ...

  4. windows安装trojan记录

    1.trojan 客户端安装教程 https://v2raytech.com/trojan-clients/ 2.chrome安装插件(crx文件)教程 https://www.jianshu.com ...

  5. go协程调度

    目录 前言 1. 线程池的缺陷 2.Goroutine 调度器 3.调度策略 3.1 队列轮转 3.2 系统调用 3.3 工作量窃取 4.GOMAXPROCS设置对性能的影响 参考 前言 Gorout ...

  6. vue 根据身份证计算出出生日期和判断性别

    //获取生日和性别     getBirth(idCard) {              var birthday = "";       if(idCard != null & ...

  7. 前后端数据交互(三)——ajax 封装及调用

    有很多框架已经将 ajax 封装,需要的时候只需要调用就好,比如 jquery 是最常用的.我们为什么还需要学习 ajax 的封装呢?首先加强我们对ajax的认识,其次如果只是因为ajax请求需要引入 ...

  8. K8S的部署方式

    K8S部署主要有两种方式:

  9. 优化技术专题-线程间的高性能消息框架-深入浅出Disruptor的使用和原理

    前提概要 简单回顾 jdk 里的队列: 阻塞队列: ArrayBlockingQueue主要通过:数组(Object[])+ 计数器(count)+ ReetrantLock的Condition (n ...

  10. Python - 基本数据处理函数round()、int()、floor()、ceil()

    前言 对每位程序员来说,在编程过程中数据处理是不可避免的,很多时候都需要根据需求把获取到的数据进行处理,取整则是最基本的数据处理.取整的方式则包括向下取整.四舍五入.向上取整等等.下面就来看看在Pyt ...