FastAPI搭建Web服务器

发布时间 2023-11-06 23:55:33作者: 七落安歌

FastAPI搭建Web服务器

1、基于FastAPI之web站点开发

# 第一步:导入模块
from fastapi import FastAPI
# 导入响应报文Response模块
from fastapi import Response
# 导入服务器uvicorn模块
import uvicorn

# 第二步:创建FastAPI对象
app = FastAPI()

# 第三步:通过@app路由装饰器收发数据
# @app.get(参数) : 按照GET方式接受请求数据
# 请求资源的 url路径
@app.get("/index.html")
def main():
    with open('source/html/index.html','rb') as f:
        data = f.read()
    # return 返回响应数据
    # Response(content = data, media_type = 'text/html')
    # 参数1:响应数据
    # 参数2:数据格式
    return Response(content = data, media_type = 'text/html')

# 第四步:运行服务器
# 参数1:框架对象
# 参数2:ip地址
# 参数3:端口号
uvicorn.run(app,host = '127.0.0.1', port = 8000)

运行结果:

image-20231023173420260

2、Web服务器和浏览器的通讯流程

实际上Web服务器和浏览器的通讯流程并不是一次性完成的,这里html代码中也会有访问服务器的代码,比如请求图片资源。

image-20231023173950023

  • 浏览器在访问index.html后,浏览器多次请求了0.jpg、1.jpg等资源

这些jpg的访问都是来自index.html

image-20231023175435275

3、浏览器访问Web服务器的通讯流程

image-20231023175521968

浏览器访问Web服务器的通讯流程

  1. 浏览器 (127.0.0.1/index.html) ==> 向Web服务器请求index.html
  2. Web服务器 (返回index.html) ==> 浏览器
  3. 浏览器解析index.html发现需要0.jpg ==>发送请求给 Web服务器请求0.jpg
  4. Web服务器 收到请求返回0.jpg ==> 浏览器 接受0.jpg

通讯过程能够成功的前提

浏览器发送的0.jpg请求, Web服务器可以做出响应, 也就是代码如下

# 当浏览器发出对图片 0.jpg请求的时候,函数返回相应资源
@app.get('/images/0.jpg')
def get_image():
    with open('source/images/0.jpg', 'rb') as f:
        data = f.read()
    return Response(content=data, media_type='jpg')

4、加载图片资源

那么当html文件中存在多个需要的加载的图片,那么代码要向如下所写的吗?

# 导入FastAPI模块
from fastapi import FastAPI
# 导入响应报文Response模块
from fastapi import Response
# 导入服务器uvicorn模块
import uvicorn

# 创建FastAPI框架对象
app = FastAPI()


@app.get("/images/0.jpg")
def func_01():
    with open("source/images/0.jpg", "rb") as f:
        data = f.read()
        print(data)
    return Response(content=data, media_type="jpg")


@app.get("/images/1.jpg")
def func_02():
    with open("source/images/1.jpg", "rb") as f:
        data = f.read()
    return Response(content=data, media_type="jpg")


@app.get("/images/2.jpg")
def func_03():
    with open("source/images/2.jpg", "rb") as f:
        data = f.read()
    return Response(content=data, media_type="jpg")


@app.get("/images/3.jpg")
def func_04():
    with open("source/images/3.jpg", "rb") as f:
        data = f.read()
    return Response(content=data, media_type="jpg")


@app.get("/images/4.jpg")
def func_05():
    with open("source/images/4.jpg", "rb") as f:
        data = f.read()
    return Response(content=data, media_type="jpg")


@app.get("/images/5.jpg")
def func_06():
    with open("source/images/5.jpg", "rb") as f:
        data = f.read()
    return Response(content=data, media_type="jpg")


@app.get("/images/6.jpg")
def func_07():
    with open("source/images/6.jpg", "rb") as f:
        data = f.read()
    return Response(content=data, media_type="jpg")


@app.get("/gdp.html")
def func_08():
    with open("source/html/gdp.html") as f:
        data = f.read()
    return Response(content=data, media_type="text/source")


@app.get("/index.html")
def main():
    with open("source/html/index.html") as f:
        data = f.read()
    # return 返回响应数据
    # Response(content=data, media_type="text/source"
    # 参数1: 响应数据
    # 参数2: 数据格式
    return Response(content=data, media_type="text/html")


# 运行服务器
# 参数1: 框架对象
# 参数2: IP地址
# 参数3: 端口号
uvicorn.run(app, host="127.0.0.1", port=8000)

对以上代码观察,会发现每一张图片0.jpg、1.jpg、2.jpg就需要一个函数对应, 如果我们需要1000张图片那就需要1000个函数对应, 显然这样做代码的重复太多了。

5、基于Web请求的FastAPI通用装置

# 当请求为 /images/0.jpg时,path ==> 0.jpg
@app.get('/images/{path}')
# 注意这里的参数要设置为{path}
# path:str 指定path为字符串类型的数据
def get_pic(path:str):
    # 这里open()的路径就是 ==> f'source/images/0.jpg'
    with open('source/images/{path}', 'rb') as f:
        data = f.read()
	return Response(content = data, media_type = 'jpg')

  • 同理,申请不同的页面的请求资源时,也可以使用path作为参数传入,而实现代码的复用。

完整代码:

# 导入FastAPI模块
from fastapi import FastAPI
# 导入响应报文Response模块
from fastapi import Response
# 导入服务器uvicorn模块
import uvicorn

# 创建FastAPI框架对象
app = FastAPI()


# 当请求为 /images/0.jpg 时, path ==> 0.jpg
@app.get("/images/{path}")
# 注意这里的参数需要设置为 path
# path : str ==> 指定path为字符串类型的数据
def get_pic(path: str):
    # 这里open()的路径就是 ==> f"source/images/0.jpg"
    with open(f"source/images/{path}", "rb") as f:
        data = f.read()
    # return 返回响应数据
    # Response(content=data, media_type="jpg")
    # 参数1: 响应数据
    # 参数2: 数据格式
    return Response(content=data, media_type="jpg")


@app.get("/{path}")
def get_html(path: str):
    with open(f"source/html/{path}", 'rb') as f:
        data = f.read()
    # return 返回响应数据
    # Response(content=data, media_type="text/source"
    # 参数1: 响应数据
    # 参数2: 数据格式
    return Response(content=data, media_type="text/html")


# 运行服务器
# 参数1: 框架对象
# 参数2: IP地址
# 参数3: 端口号
uvicorn.run(app, host="127.0.0.1", port=8000)