结语

受 社区生态,或者说官网的加载速度,想要靠官网文档系统学习,简直是噩梦。

嗯?突然想到了找镜像站。这个还可以

下面的内容是我看文档感兴趣的部分

嗯,我又可以了。才刚刚开始呢。

后面的内容都是我看文档按照自己感兴趣的地方,自己排的。可能顺序并不是特别适合您。

3 天后:嗯 我又有点不行了,一个问题困扰了半天。按照官方项目一摸一样却错误,大概是因为 sqlAlchemy delete 的生命周期问题。对于此现在能将就就将就吧,不要再小问题上纠结过多。

Dependencies 依赖,注入?

FastAPI有一个非常强大但直观的依赖注入系统。

它的设计使用起来非常简单,并使任何开发人员都可以非常轻松地将其他组件与FastAPI集成在一起

使用它的情况:

  • 有共享逻辑(一次又一次地使用相同的代码逻辑)。
  • 共享数据库连接。
  • 强制执行安全性,身份验证,角色要求等。...
  • 减少代码重复

Tips: 依赖是可以嵌套的。

简单的示例:

from typing import Optional
from fastapi import Depends, FastAPI

app = FastAPI()


async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

async def common_parameters(test: dict = Depends(common_parameters)):
  # 仅供示例无任何实际意义
  if not test[q]:
    test[q] = 'test'
  return test



@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters1)):
    # commons['q1'] = commons['q']
    return commons

# 字典 commons 接收的参数来自于 common_parameters 的返回值

想了一下再 common_parameters , 验证 用户的登录情况,登录返回 true. 没有登录直接再此函数内部处理。试一下?有了(路径操作修饰符的依赖性)[https://weng.cloud/fastapi/tutorial/dependencies/dependencies-in-path-operation-decorators/index.html] (如果有全局钩子更适合这种情况

什么可以作为依赖

依赖项应该是“可调用的”。

Python 中的“可调用”是 Python 可以像函数一样“调用”的任何东西。

因此,如果您有一个对象something(可能不是函数),并且可以像下面这样“调用”(执行)该对象:

something()

要么

something(some_argument, some_keyword_argument="foo")

那么它是一个“可调用的”。

使用类作为依赖

改写上面的

from typing import Optional

from fastapi import Depends, FastAPI

app = FastAPI()

class CommonQueryParams:
    def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit


@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
      # if commons.q:      
    return commons

注意CommonQueryParams在上面的代码中编写两次:

async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams))

在第二个参数, FastAPI 将提取声明的参数,而这正是 FastAPI 实际调用的参数。

在这种情况下,第一个CommonQueryParams ,对于FastAPI没有任何特殊含义。FastAPI 不会将其用于数据转换,验证等(因为它正在使用= Depends(CommonQueryParams)

您实际上可以只写:

commons = Depends(CommonQueryParams)

但是仍然鼓励声明类型,这样您的编辑器将知道将作为参数传递的内容commons的类型,然后可以帮助您完成代码,进行类型检查等

捷径

FastAPI 为这些情况提供了一个快捷方式,在这种情况下,依赖关系是一个类, FastAPI 将“调用”该类来创建该类本身的实例。

则最优解为:

commons: CommonQueryParams = Depends()

Dependencies in path operation decorators 路径操作符的依赖项

  • 在某些情况下,您并不真正需要路径操作函数中的依赖项的返回值。
  • 或者该依赖项不返回值, 但是你仍然需要它被执行/解决。
from fastapi import Depends, FastAPI, Header, HTTPException

app = FastAPI()


async def verify_token(x_token: str = Header(...)):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")


async def verify_key(x_key: str = Header(...)):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")    
    return x_key


@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():
    return [{"item": "Foo"}, {"item": "Bar"}]

这些依赖性将以与普通依赖性相同的方式执行/解决。但是它们的值(如果它们返回任何值)将不会传递给您的path 操作函数

它们可以返回值,也可以不返回值,但这些值不会被使用。

因此,您可以重新使用已经在其他地方使用的普通依赖项(返回一个值) ,即使该值不会被使用,依赖项也将被执行:

依赖与 yield

FastAPI 支持在完成后执行一些额外步骤的依赖项。

例如,您可以使用它来创建一个数据库会话,并在完成后关闭它。

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

如果在有 yield 的依赖项中使用 try 块,则会收到在使用该依赖项时抛出的任何异常。

只有在发送响应之前并包含 yield 语句的代码才会被执行

在响应发送之后,执行 yield 语句后面的代码

这依赖的使用,官网介绍得比较晦涩。同时现在又不准备使用...。官网介绍锚点

中间件(钩子?

“中间件”是一种功能,它可以在通过任何特定路径操作处理每个请求之前处理每个请求。以及返回之前的每个响应

  1. 它接受应用程序中的每个请求

  2. 它可以对该请求执行某些操作或运行任何所需的代码。

  3. 它传递要由应用程序其余部分处理的请求(通过某些路径操作) call_next。
  4. 它将获取应用程序生成的响应(通过某些路径操作)。
  5. 它可以对响应做出响应或运行任何需要的代码。
  6. 然后返回响应

如果您具有依赖项yield,则退出代码将中间件之后运行。

如果有任何后台任务(稍后记录),它们将所有中间件之后运行。

使用

要创建中间件,请@app.middleware("http")在函数顶部使用装饰器。

添加一个自定义标头,X-Process-Time其中包含处理请求和生成响应所花费的时间(以秒为单位):

import time
from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):

    request.state.num = 13

    print(1)
    start_time = time.time()    
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    print(2)
    return response

# 中间件

@app.get('/test/')
async def test(num: int = 0, resquest: Resquest):

    print(resquest.state.num)

    print(3)
    time.sleep(2)
    return num

"""
1
3
2
"""

call_next 负责将此次请求转发给响应的 路由处理,并返回处理后的结果(响应)

Tips:

request.stateRequest对象的一个属性。它可以存储附加到请求本身的任意对象。

Tips:

请记住,可以使用'X-'前缀添加自定义专有标头

但是,如果您希望浏览器中的客户端能够看到自定义标头,则需要使用Starlette 的 CORS 文档记录的参数将其添加到 CORS 配置(CORS (跨源资源共享)expose_headers

更多:高级的中间件使用方法

CORS 跨域设置

  • http://127.0.0.1
  • https://127.0.0.1
  • http://127.0.0.1:800

就算同一个路由,但是不同的协议或端口,因此它们是不同的“来源”。也会被算为跨域请求

为此,后端必须具有“允许的来源”列表。

利用 CORSMiddleware设置

  1. 导入CORSMiddleware
  2. 创建允许的来源列表(作为字符串)。
  3. 将其作为“中间件”添加到FastAPI应用程序。

您还可以指定后端是否允许:

  • 凭证(授权 headers , Cookie 等)。
  • 特定的 HTTP 方法(POSTPUT)或所有带通配符的方法"*"
  • 特定的 HTTP 标头或所有通配符"*"
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def main():
    return {"message": "Hello World"}

CORSMiddleware 官网

The default parameters used by the CORSMiddleware implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context.

The following arguments are supported:

  • allow_origins - A list of origins that should be permitted to make cross-origin requests. E.g. ['https://example.org', 'https://www.example.org']. You can use ['*'] to allow any origin.
  • allow_origin_regex - A regex string to match against origins that should be permitted to make cross-origin requests. eg. 'https://.*\.example\.org'.
  • allow_methods - A list of HTTP methods that should be allowed for cross-origin requests. Defaults to ['GET']. You can use ['*'] to allow all standard methods.
  • allow_headers - A list of HTTP request headers that should be supported for cross-origin requests. Defaults to []. You can use ['*'] to allow all headers. The Accept, Accept-Language, Content-Language and Content-Type headers are always allowed for CORS requests.
  • allow_credentials - Indicate that cookies should be supported for cross-origin requests. Defaults to False.
  • expose_headers - Indicate any response headers that should be made accessible to the browser. Defaults to [].
  • max_age - Sets a maximum time in seconds for browsers to cache CORS responses. Defaults to 600.

The middleware responds to two particular types of HTTP request...

今天是年 30, 新年快乐呀!


相关推荐:

来自系列:fastapi

分类 python下文章:

1.0 爬虫的介绍,和requests模块的简单使用

1.1 数据解析的三种方式。正则表达式, bs4, xpath

2.0 多任务(进程,协程,线程)爬虫:验证码识别,返回头储存,ip代理 介绍。 异步是什么,爬虫异步的方式。线程,进程,介绍

2.0.1 协程的 async/await 实现 爬虫 单线程 + 异步协程的实现

3.0 基于selenium 模块的 爬虫操作。 selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。

更多...

评论([[comments.sum]])

发表

加载更多([[item.son.length-2]])...

发表

2020-11 By chuan.

Python-flask & bootstrap-flask

图片外链来自:fghrsh

互联网ICP备案号:蜀ICP备2020031846号