程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

教你一招!用Python和Flask創建REST API!

編輯:Python

REST API 簡介

注意,這裡只是對REST API 的簡單介紹,起到拋磚引玉作用,更加深入內容不在本次學習范圍內,感興趣的小伙伴可以查看相關資料深入學習。此外本號接受該領域的投稿,歡迎聯系雲朵君!

API

API,全名Application Programming Interface (應用程式介面),簡單來說,是品牌開發出的一種接口,讓第三方可以額外開發、應用在自身的產品上的系統溝通介面。

REST API

REST 是一種通過 HTTP 協議設計 API 的架構風格。它的主要優點是其極大的靈活性。只要需要直接從服務器向 Web 應用程序或站點的用戶提供數據,開發人員就會使用 REST API。

REST API 的主要組件:

  • 客戶 — 在用戶端(在他的設備上)啟動的客戶端或程序啟動通信。

  • 服務器 — 使用 API 訪問其功能和數據的服務器。

  • 資源 — 服務器傳輸給客戶端的任何內容(視頻、文本、圖片)。

REST API 通過 HTTP 請求進行通信,完成以下功能——創建、讀取、更新和刪除數據。它們也稱為 CRUD 操作。REST 提供有關請求資源的信息,並使用四種方法來描述如何處理資源:

  • POST — 創建資源;

  • GET — 獲取資源;

  • PUT — 更新資源;

  • DELETE — 刪除資源。

RESTful API

REST,全名Representational State Transfer( 表現層狀態轉移),他是一種設計風格,RESTful 只是轉為形容詞,像是 peace 和平這名詞,轉成形容詞是peaceful,RESTful 則形容以此規范設計的API,稱為RESTful API。

RESTful API 主要由三種元件組成:

  • Nouns 名詞:定義資源位置的URL,每個資源在網路上都會有唯一的位置,就如每戶人家都有唯一的地址一樣。

  • Verbs 動詞:對資源要做的動作。

  • Content Types 資源呈現方式:API 資源可以以多種方式表現,最常用的是JSON,輕量易處理。

所以使用 RESTful 風格設計的API,就有了以下幾種優點及限制:

  1. 有唯一的URL表示資源位置,統一的API 接口。(Uniform Interface)

  2. 無狀態。(Stateless)

Restful API 它允許集成應用程序 app 或與 Restful Web 服務交互。它現在正在成長為連接微服務架構中組件的最常用方法。我們借助 API,能夠獲取或發送數據到網站並執行一些操作,目的是通過 Web 服務完成我們的任務。每個網站都使用不同類型的 API,例如股票市場交易網站,借助 API 獲取當前價格和上下波動。

創建第一個 REST API

同樣,我們創建 Hello world API,它表示如果你對其發出 get 請求,將獲得 JSON 響應,一般情況下, API 給出 JSON 類型的響應。接下來,使用 pip 包管理器安裝 Flask:

pip install flask
pip install flask-restful
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class Helloworld(Resource):
  def __init__(self):
    pass
  def get(self):
    return {
      "Hello": "World"
        }
api.add_resource(Helloworld, '/')
if __name__ == '__main__':
 app.run(debug=True)

ok,到現在已經創建了第一個Rest api,看起來挺簡單的,那麼,什麼是Flask-Restful呢?

Flask restful 定義了資源Resource類,其中包含每個 HTTP 方法的方法。方法名稱應與其對應的 HTTP 方法相同,並以小寫形式書寫,如上代碼中所示。我們發現這些方法沒有路由裝飾器,這是它們是基於資源路由的。無論定義什麼類,我們都可以使用添加資源add_resource方法定義到它的路由以及在對應路由上調用該類。

說明: 在上面的代碼中,我們首先加載需要的父類,然後初始化我們的app和API。之後,我們創建了一個程序,並且我們正在發出一個 GET 請求,說明如果有人點擊了這個程序,那麼他將得到 Hello world 作為 JSON 格式的響應。要打開特定 URL,我們使用 add resource 方法並將其路由到默認斜槓。要運行此文件,可以使用 POSTMAN 工具(一種 API 維護工具)來創建、測試和管理 API。還可以使用requests請求模塊使用以下代碼測試此 API。首先,運行上面的文件,它會給你 localhost URL,然後在另一個命令提示符下,運行下面的代碼文件:

import requests
url = "http://127.0.0.1:5000/"
response = requests.get(url=url)
print(response.text)
{
"Hello": "World"
}

通過 Flask RESTApi 理解 HTTP 請求

通過以上內容的學習,相比大家已經對 REST API 有個初步印象。接下來我們將繼續探索使用 REST API 的不同 HTTP 方法,其中我們定義一個列表,該列表將以字典(JSON 對象)的形式存儲從服務器獲取的所有數據。這是很重要的,因為我們在項目中有不同的api來獲取數據,而不是其他地方的數據。

首先創建一個 API,在其中創建 3 個名為 GET、POST 和 DELETE 的 HTTP 方法,並且在其中創建一個自定義 URL,當請求 POST 方法時,它將以 Name 作為輸入;在請求 GET 方法時,將名稱返回;在DELETE時,如果該名稱存在,我們將刪除該名稱,再次訪問它會給我們 NULL。

創建一個文件並編寫以下代碼:

from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
data = []
class People(Resource):
  def get(self):
  for x in data:
    if x['Data'] == name:
     return x
  return {'Data': None}
 def post(self, name):
   temp = {'Data': name}
   data.append(temp)
   return temp
 def delete(self):
   for ind, x in enumerate(data):
    if x['Data'] == name:
     temp = data.pop(ind)
     return {'Note': 'Deleted'}
api.add_resource(People, '/Name/')
if __name__ == '__main__':
 app.run(debug=True)

打開 POSTMAN API 工具並點擊每個 HTTP 方法請求。首先,當我們使用 post 請求Name時,它給了我們一個name。在獲取請求時,我們將返回name。它在刪除時被刪除,當再次將其取回時,它會給你返回 NULL。

結果如下

如何在 Flask REST API 中使用裝飾器

我們使用帶有 API 的裝飾器來監控 IP 地址、cookie 等。我們將繼續學習如何使用帶有裝飾器的Flask API。裝飾器是一個將另一個函數作為參數並返回另一個函數的函數。也可以將其理解為在不改變或修改當前功能的情況下,為現有功能提供一些附加功能的功能。

這裡我們創建一個新文件,我將通過創建兩個裝飾器來展示。在第一個文件中,編寫返回代碼執行時間的外部時間函數。我們從 functools 模塊(用於高階 python 函數的標准模塊)導入應用於 wrapper 函數的 wrap 裝飾器 。它通過復制所有參數來更新包裝函數。

from flask import Flask
from flask_restful import Resource, Api
import datetime
from flask import request
from functools import wraps
app = Flask(__name__)
api = Api(app)
def time(function=None):
  @wraps(function)
   def wrapper(*args, **kwargs):
     s = datetime.datetime.now()
     _ = function(*args, **kwargs)
     e = datetime.datetime.now()
     print("Execution Time : {} ".format(e-s))
     return _
   return wrapper
class HelloWorld(Resource):
  @monitor
   def get(self):
     return {"hello": "world"}
api.add_resource(HelloWorld, "/")
if __name__ == "__main__":
  app.run(debug=True)

我們創建第二個裝飾器來監視cookie和IP地址,因此創建下面的函數。不是向hello world函數添加時間裝飾器,而是添加監視器裝飾器並運行代碼。

def monitor(function=None):
    @wraps(function)
    def wrapper(*args, **kwargs):
        _ = function(*args, **kwargs)
        print("Ip Address  : {} ".format(request.remote_user))
        print("Cookies : {} ".format(request.cookies))
        print(request.user_agent)
        return _
    return wrapper

如何使 Flask API 更安全

當我們設計API時,我們也應該注意安全性,因為很多人會訪問它。因為API可能包含一些雙方之間的機密數據,因此我們可以指定只有授權的人可以訪問API,那該怎麼辦?此時可以使用Flask基本身份驗證。當然,此時需要使用pip命令安裝這個flask模塊。

pip install flask-httpauth

我們正在構建一個API並定義User數據字典,其中包含用戶名和密碼。當在實時用例中工作時,可以通過配置文件或從數據庫中接受用戶名和密碼。首先,我們創建一個主要函數來匹配用戶名和密碼,並創建一個GET方法,該方法表示任何點擊此API的人,如果沒有登錄,我們就無法訪問數據。

from flask import Flask
from flask_restful import Resource, Api
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__)
api = Api(app, prefix="/api/v1")
auth = HTTPBasicAuth()
USER_DATA = {
 "admin": "SuperSecretPwd"
}
#route to verify the password
@auth.verify_password
def verify(username, password):
 if not(username and password):
   return False
  return USER_DATA.get(username) == password
class PrivateResource(Resource):
 @auth.login_required
 def get(self):
    return {"How's the Josh": "High"}
api.add_resource(PrivateResource, '/private')
if __name__ == '__main__':
  app.run(debug=True)

當我們使用POSTMAN運行上述文件時,我們會嘗試在沒有登錄的情況下獲取數據,以便給你演示未經授權的訪問權限。

現在轉到授權,並單擊Basic authorization。輸入用戶名和密碼,然後點擊GET請求以獲得所需的結果。

這是保護 Flask API 的方法,也是最基本的方法,當然還有更多更高級的方法,這裡不做過多的介紹。

如何在 Flask API 上啟用跟蹤

至此我們已經了解了如何保護我們的 API,在未經授權的登錄禁止訪問,但是如果我們還想知道訪問者的位置(緯度和經度點)、IP 地址、服務器名稱(例如訪問API 的人的詳細信息),我們還可以繼續配置,使用 REST API 的基本flask跟蹤應用程序。首先,使用 PIP 命令安裝flask跟蹤包。

pip install flask-track-usage

接下來看下該程序:

from flask import Flask, g
app = Flask(__name__)
app.config['TRACK_USAGE_USE_FREEGEOIP'] = False
app.config['TRACK_USAGE_INCLUDE_OR_EXCLUDE_VIEWS'] = 'include'
from flask_track_usage import TrackUsage
from flask_track_usage.storage.printer import PrintWriter
from flask_track_usage.storage.output import OutputWriter
t = TrackUsage(app, [
  PrintWriter(),
  OutputWriter(transform=lambda s: "OUTPUT: " + str(s))
 ])
@t.include
@app.route('/')
def index():
   g.track_var["optional"] = "Write_Something"
   return "Hello"
#Run the application
if __name__ == "__main__":
  app.run(debug=True)

該程序通過導入 Track Usage、Input writer 和 output writer 來創建一個跟蹤應用程序。將flask app傳遞給 Track 包並使用輸出編寫器,並使用 lambda 函數以字符串格式寫入輸出。之後在 slash 上創建一個基本路由,並將跟蹤應用程序作為裝飾器包含在內。g 代表全局,表示數據在上下文中是全局的。因此,創建一個基本 API,它在浏覽器返回"Hello",同時在後端獲得所有人員的信息。

如何為REST API編寫單元測試代碼

現在已經為案例創建了一個不錯的REST API。盡管如此,我們還需要為REST API編寫單元測試代碼,因為從API中識別常見錯誤,並確保生產安全是至關重要的。

如下是創建一個名為run的新文件並開發以下簡單API。

from flask import Flask
from flask_restful import Resource, Api
import json
app = Flask(__name__)
api = Api(app)
class Helloworld(Resource):
 def __init__(self):
   pass
 def get(self):
   return json.dumps({"Message": "Fine"})
api.add_resource(Helloworld, '/')
if __name__ == '__main__':
  app.run(debug=True)

現在創建另一個名為test的文件,在其中編寫用於對API進行單元測試的代碼。最常見的情況是執行以下三個基本單元測試。

  • 檢查響應碼是否為200

  • 檢查從API編寫的內容是否為應用程序JSON格式

  • 檢查我們正在訪問的所有鍵是否都存在於API數據處理中

from run import app
import unittest
class FlaskTest(unittest.TestCase):
 #Check for response 200
 def test_inde(self):
  tester = app.test_client(self) #tester object
  response = tester.get("/")
   statuscode = response.status_code
   self.assertEqual(statuscode, 200)
 #check if the content return is application JSON
 def test_index_content(self):
  tester = app.test_client(self)
   response = tester.get("/")
   self.assertEqual(response.content_type, "application/json")
 #check the Data returned
 def test_index_data(self):
   tester = app.test_client(self)
  response = tester.get("/")
   self.assertTrue(b'Message' in response.data)
if __name__ == '__main__':
 unittest.main()

如果你已經學習過網絡爬蟲,你應該知道 200 響應意味著對特定 URL 的請求已成功發出,並返回響應。

好了,這就是本文的全部內容。到這裡我們已經學會了從頭開始創建 Flask REST API ,並輕松安全地對其進行維護。

Flask 作為 Python Web 領域最為著名的輕量級 Web 開發框架,對於致力於 Web 開發的同學來說,掌握基本的 Flask 技能還是非常有必要的,你學會了嗎?

推薦閱讀:
入門: 最全的零基礎學Python的問題  | 零基礎學了8個月的Python  | 實戰項目 |學Python就是這條捷徑
干貨:爬取豆瓣短評,電影《後來的我們》 | 38年NBA最佳球員分析 |   從萬眾期待到口碑撲街!唐探3令人失望  | 笑看新倚天屠龍記 | 燈謎答題王 |用Python做個海量小姐姐素描圖 |碟中諜這麼火,我用機器學習做個迷你推薦系統電影
趣味:彈球游戲  | 九宮格  | 漂亮的花 | 兩百行Python《天天酷跑》游戲!
AI: 會做詩的機器人 | 給圖片上色 | 預測收入 | 碟中諜這麼火,我用機器學習做個迷你推薦系統電影
小工具: Pdf轉Word,輕松搞定表格和水印! | 一鍵把html網頁保存為pdf!|  再見PDF提取收費! | 用90行代碼打造最強PDF轉換器,word、PPT、excel、markdown、html一鍵轉換 | 制作一款釘釘低價機票提示器! |60行代碼做了一個語音壁紙切換器天天看小姐姐!|

年度爆款文案

  • 1).臥槽!Pdf轉Word用Python輕松搞定!

  • 2).學Python真香!我用100行代碼做了個網站,幫人PS旅行圖片,賺個雞腿吃

  • 3).首播過億,火爆全網,我分析了《乘風破浪的姐姐》,發現了這些秘密 

  • 4).80行代碼!用Python做一個哆來A夢分身 

  • 5).你必須掌握的20個python代碼,短小精悍,用處無窮 

  • 6).30個Python奇淫技巧集 

  • 7).我總結的80頁《菜鳥學Python精選干貨.pdf》,都是干貨 

  • 8).再見Python!我要學Go了!2500字深度分析!

  • 9).發現一個舔狗福利!這個Python爬蟲神器太爽了,自動下載妹子圖片

點閱讀原文,看B站我的20個視頻!


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved