摄影:产品经理必胜客的披萨比意大利的更符合中国人的口味
在公众号以前的文章里面,我们提到,如果想简单的分享一下文件,我们可以使用一行 Python 命令:
python3 -m http.server
这条命令会开启一个文件分享服务,通过在浏览器访问http://ip:8000
可以看到运行这条命令的文件夹下面的全部文件。点击即可下载。如下图所示:
这种方法,确实简单。但有3个问题:
- 一次只能下载一个文件,如果文件比较大,在下载的过程中其他人无法下载其他文件。
- 当前文件夹下面的所有文件都会出现在网页上,容易导致敏感数据泄露。如果你只想让别人下载其中一个文件,你需要单独给这个文件创建一个文件夹,并在这个文件夹里面执行命令。
- 这个简单的网络服务不稳定。
那有没有更稳定、安全同时也不太难的方案呢?当然是有,那就是使用 fastapi。
fastapi 基于starlette 开发。而 starlette里面有一个返回类型叫做FileResponse
。使用它,可以非常方便地返回文件。我们来看看代码。
首先安装三个库uvicorn/fastapi/aiofiles
:
pip install uvicorn pip install fastapi pip install aiofiles
然后编写代码并保存为FileServer.py
import os from fastapi import FastAPI from starlette.responses import FileResponse @app.get('/record/{filename}') def get_record(filename: str): path = os.path.join('output', filename) ifnot os.path.exists(path): return {'success': False, 'msg': '文件不存在!'} response = FileResponse(path) return response
其中,我把所有文件都存放在当前文件夹下面的output
文件夹中。用户通过访问http://ip:端口/record/文件名
。服务拿到文件名以后,拼出完整的文件路径,传入FileResponse
类并回response
对象。
以上就是全部代码。非常简单直观。
现在我们来运行这个文件服务:
uvicorn FileServer:app --host 0.0.0.0 --port 8888
这样,你想分享具体哪个文件,你就构造一个 URL:http://ip:8888/record/文件名
发给别人。别人直接访问这个 URL 就能来下载对应的文件了。只要对方不知道其他文件的文件名,就无法看到或者下载其他文件。
如果想更安全,你还可以给每个文件做一个单独的文件编号,把编号-地址对应关系存放在数据库中。用户请求的时候,传入的是文件编号,你从数据库查出文件的真实路径再通过FileResponse
返回。