Back
Featured image of post 用Python写一个部署在Vercel上的API

用Python写一个部署在Vercel上的API

Vercel真好用

首先,欢迎访问 这里 来看看我搞了啥,访问 这里 来查看JSON数据,访问 这里 来查看项目源码。

起因

  看到 lz233 的 一言 之后非常心水,想自己搞一个,另外想添加一点新的功能(例如使用GET参数来获取指定类型的句子等),但是我又想满足这两个条件:一、不要部署在服务器上。二、要自己能添加和删除句子和功能。但是议案搜寻下来没有找到我想要的答案,于是便开始琢磨这自己整一个了。

  在开始整一个之前,我就知道了Vercel有提供 Serverless Functions 这个功能,但以为只有Go语言的项目才能使用,又萌生了临时学一把Go语言的想法。但是在我阅读 文档 之后,发现Python也在支持的列表之中,这真是太巧了,于是,开整!

过程

  其实基础的教程网络上和官方的文档都给的比较明白了,你可以在仓库中的 /api 目录下新建一个 index.py  文件,里面写上这些:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from http.server import BaseHTTPRequestHandler
from cowpy import cow

class handler(BaseHTTPRequestHandler):

    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        message = cow.Cowacter().milk('Hello from Python from a Serverless Function!')
        self.wfile.write(message.encode())
        return

  并且在同一个目录下新建一个 requirements.txt  文件,用于告诉Vercel需要引入的模块和指定的版本(版本也可以不写):

1
cowpy==1.0.3

  然后直接部署,就可以看到官方的实例已经成功的展示出来了:

1
2
3
4
5
6
7
8
 _______________________________________________ 
< Hello from Python from a Serverless Function! >
 -----------------------------------------------
     \   ^__^
      \  (oo)\_______
         (__)\       )\/\
           ||----w |
           ||     ||

  这便是我第一次接触Vercel的Serverless Functions。随着深入的了解,我更加惊奇的发现,它竟然可以使用Flask框架来搭建!知道了这点,我更加开心了,毕竟「使用Flask框架搭建信息系统」可是信息技术课必修内容之一,虽然上课摸鱼摸得多但终究还是会一点的,下面便是一个来自 Johnsonの备忘录 的示例:

index.py:

1
2
3
4
5
6
7
8
from flask import Flask, request
import requests

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello from Flask Github!'

requirements.txt:

1
2
3
4
5
Flask==1.1.2
Werkzeug==1.0.0
uvicorn
requests
pydantic

  之后便可以看到返回的数据:

1
Hello from Flask Github!

  有了这两个示例,我便大概弄懂了具体的细节,就将属于我的 一言API 给写好了,具体的使用方法可以看Github项目中的README。

插曲

  在写程序的时候远不是上面一句话一笔带过那么简单,在这之间我其实踩了许许多多的坑,这么一个小小的项目零零散散耗费了我两天的时间才做好WSFW,下面我就挑几点令我印象比较深的来讲。

一、模块的引入

  因为要获取随机JSON数据和处理JSON数据,我便在index.py里写了:

1
import requests , json , random

  乍看之下好像没什么问题,是的,它的确没问题🤣,但是在requirements.txt中的时候就得这么写:

1
2
3
requests
pyjson
pyrandom

  是的,有的模块名称与它的文件名称不同,在引入的时候必须区分仔细。

二、文本的编码

  变量类型的统一这种低级问题我相信就不必强调了虽然我在这里翻了很多车,我想要强调的一点就是文本的编码问题。变量中的字符在经过各个函数的蹂躏和摧残之后可能会由于编码问题而产生错误(中文这点就是难搞)。以我的项目为例,我想输出的效果是这样:

1
2
3
4
5
6
{
    "text": "逸一时,误一世,逸久逸久罢矣龄。",
    "by": "田所浩二",
    "from": "《真夏の夜の淫梦》",
    "time": "1919.8.10"
}

  但是在前面的时候输出的结果却是这样:

1
2
3
4
5
6
{
    "text": "\u9038\u4e00\u65f6\uff0c\u8bef\u4e00\u4e16\uff0c\u9038\u4e45\u9038\u4e45\u7f62\u77e3\u9f84\u3002",
    "by": "\u7530\u6240\u6d69\u4e8c",
    "from": "\u300a\u771f\u590f\u306e\u591c\u306e\u6deb\u68a6\u300b",
    "time": "1919.8.10"
}

  经过一番摸索和排查之后,原来是在使用json.dumps函数的时候输出中文的默认编码是Unicode,而我想要的是以UTF-8编码输出,于是加上了ensure_ascii=False,完成。

三、记得看log

  在这次经历中,还给我留下深刻印象的点就是要多看输出的日志,这在排查和解决错误的时候极为有用(也怪我经验不足,第一次搞这玩意)。

结语

  这是我第一次用Python搞一个不算太正经的项目,从中也或许到了许多经验,学到了许多课本上不会教的知识,这也是我急着把这篇文章赶出来的原因。也希望我能保持这这种钻研的精神,迎难而上。

最后的最后,我绝对不会说一开始我其实没用Flask框架,后来因为不知道怎么处理GET请求才用了Flask,我也不会说Safari浏览器访问好像还是有乱码的问题存在……

Wait a Second...
萌ICP备20223301号
本页面共被访问
© Licensed Under CC BY-NC-SA 4.0