Cicada000‘s Xlog

Cicada000‘s Xlog

twitter
telegram
bilibili
github

用Python寫一個部署在Vercel上的API

cover

首先,歡迎訪問 這裡 來看看我搞了啥,訪問 這裡 來查看 JSON 數據,訪問 這裡 來查看項目源碼。

起因#

  看到 lz233 的 一言 之後非常心水,想自己搞一個,另外想添加一點新的功能(例如使用 GET 參數來獲取指定類型的句子等),但是我又想滿足這兩個條件:一、不要部署在伺服器上。二、要自己能添加和刪除句子和功能。但是議案搜尋下來沒有找到我想要的答案,於是便開始琢磨這自己整一個了。

  在開始整一個之前,我就知道了 Vercel 有提供 Serverless Functions 這個功能,但以為只有 Go 語言的項目才能使用,又萌生了臨時學一把 Go 語言的想法。但是在我閱讀 文檔 之後,發現 Python 也在支持的列表之中,這真是太巧了,於是,開整!

support-python

过程#

  其實基礎的教程網絡上和官方的文檔都給的比較明白了,你可以在倉庫中的 /api 目錄下新建一個 index.py  文件,裡面寫上這些:

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 需要引入的模塊和指定的版本(版本也可以不寫):

cowpy==1.0.3

  然後直接部署,就可以看到官方的實例已經成功的展示出來了:

 _______________________________________________ 
< Hello from Python from a Serverless Function! >
 -----------------------------------------------
     \   ^__^
      \  (oo)\_______
         (__)\       )\/\
           ||----w |
           ||     ||

  這便是我第一次接觸 Vercel 的 Serverless Functions。隨著深入的了解,我更加驚奇的發現,它竟然可以使用 Flask 框架來搭建!知道了這點,我更加開心了,畢竟「使用 Flask 框架搭建信息系統」可是信息技術課必修內容之一,雖然上課摸魚摸得多但終究還是會一點的,下面便是一個來自 Johnson の備忘錄 的示例:

index.py:

from flask import Flask, request
import requests
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'Hello from Flask Github!'

requirements.txt:

Flask==1.1.2
Werkzeug==1.0.0
uvicorn
requests
pydantic

  之後便可以看到返回的數據:

Hello from Flask Github!

  有了這兩個示例,我便大概弄懂了具體的細節,就將屬於我的 一言 API 給寫好了,具體的使用方法可以看 Github 項目中的 README。

插曲#

  在寫程序的時候遠不是上面一句話一筆帶過那麼簡單,在這之間我其實踩了許許多多的坑,這麼一個小小的項目零零散散耗費了我兩天的時間才做好WSFW,下面我就挑幾點令我印象比較深的來講。

一、模塊的引入#

  因為要獲取隨機 JSON 數據和處理 JSON 數據,我便在 index.py 裡寫了:

import requests , json , random

  乍看之下好像沒什麼問題,是的,它的確沒問題🤣,但是在 requirements.txt 中的時候就得這麼寫:

requests
pyjson
pyrandom

  是的,有的模塊名稱與它的文件名稱不同,在引入的時候必須區分仔細。

二、文本的編碼#

  變量類型的統一這種低級問題我相信就不必強調了雖然我在這裡翻了很多車,我想要強調的一點就是文本的編碼問題。變量中的字符在經過各個函數的蹂躏和摧殘之後可能會由於編碼問題而產生錯誤(中文這點就是難搞)。以我的項目為例,我想輸出的效果是這樣:

{
    "text": "逸一時,誤一世,逸久逸久罷矣齡。",
    "by": "田所浩二",
    "from": "《真夏の夜の淫夢》",
    "time": "1919.8.10"
}

  但是在前面的時候輸出的結果卻是這樣:

{
    "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#

  在這次經歷中,還給我留下深刻印象的點就是要多看輸出的日誌,這在排查和解決錯誤的時候極為有用(也怪我經驗不足,第一次搞這玩意)。

log

結語#

  這是我第一次用 Python 搞一個不算太正經的項目,從中也或許到了許多經驗,學到了許多課本上不會教的知識,這也是我急著把這篇文章趕出來的原因。也希望我能保持這種鑽研的精神,迎難而上。

最後的最後,我絕對不會說一開始我其實沒用 Flask 框架,後來因為不知道怎麼處理 GET 請求才用了 Flask,我也不會說 Safari 瀏覽器訪問好像還是有亂碼的問題存在......

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。