flask——接口簡單示例


原文:https://www.cnblogs.com/liuzhen1995/p/8107905.html

 

目錄

前言

1 准備工作

2 具體實現

 

 


前言

最近在搗鼓如何使用阿里雲服務器搭建一個簡單的基於Flask框架的后端接口,剛開始為了圖方便,就直接買了一個Windows Server 2008系統服務器,這也埋下了不小的坑。

 

服務買下來后,會給你一個公網IP和內網IP,由於是第一次學習搭建后端接口,對於如何正確使用阿里雲服務器,來處理好公網IP和內網IP之間的關系埋下了不小的坑,真是對應的一句話:技術的成長往往是一步一個坑。

 

下面簡單說一下搭建Flask服務器端遇到的問題:

首先,Flask自帶了一個服務器,直接使用很方便,不過這個服務器的性能太低,但是對於調試和學習還是綽綽有余。剛開始把代碼放到阿里雲服務器上,並跑通后,測試接口時公網IP無法訪問,那時我以為是Flask自帶服務器的問題,即因為Flask自帶服務器原因導致無法使用公網IP訪問。

 

那么,問題出現了,就要尋找解決辦法吧,網上查找資料給出參照意見:使用nginx +gunicorn來部署Flask相關服務,可以避免公網IP無法訪問問題。然后,我就去找資料,安裝gunicorn,結果運行測試時一直報錯,最后發現gunicorn不支持Windows系統,這也太坑了,早知道我當時買服務器時就不該圖方便,直接買一個基於Linux的系統了。

 

現在,新的問題又來了,既然不能使用nginx +gunicorn來部署Flask相關服務,那就要使用其它方式來解決吧,網上資料參照結果:使用tornado。好,那么我又來查看學習tornado部署應用開發文檔,按照開發文檔部署完畢后,在服務器上跑通后,發現依舊不能使用公網IP進行接口訪問和測試。

 

到了這里,就讓我反思,這個難道真是Flask部署應用服務器問題嗎?后來,就在網上找到了一篇關於阿里雲公網IP無法訪問問題的文章,發現這個需要自己去阿里雲官網上去配置設置。

 

即以上遇到的問題,壓根就不是Flask部署服務器問題,是自己沒有搞清楚阿里雲服務器如何使用的問題......

 

具體配置設置方法見:阿里雲服務器 ECS 訪問不了公網 ip 可能的原因及解決方法

附:

 

 

 


1 准備工作

導入Flask及相關擴展:

pip install flask

pip install flask-pymongo

pip install tornado(此處可選可不選。如果不選擇,直接使用Flask自帶的服務器部署即可;如果選擇,可以使用tornado部署)

 

MongoDB數據庫綁定服務ip地址設置(PS:如果不進行下述設置,默認ip為本機127.0.0.1地址):

打開CMD,進入MongoDB安裝的bin文件夾下,例如我的安裝目錄為:C:\Program Files\MongoDB\Server\3.2\bin

然后在CMD中輸入mongod.exe --bind_ip yourIPadress

其中參數--bind_ip意思:綁定服務IP,若綁定127.0.0.1,則只能本機訪問,不指定默認本地所有IP。(注意:其中yourIPadress填寫自己搭建服務器的內網ip地址)

具體如下圖:

 

 

開啟Flask自帶的服務器,一般使用app.run(),其中一般使用如下三個參數:host(指定ip地址,如果不填寫,默認為127.0.0.1)、port(指定使用的端口,如果不指定,默認為5000端口)、debug(開啟調試模式,默認值為Flase,即不開啟調試模式,如要開啟則可以設置為True)。

 

如果在服務器上搭建Flask接口相關服務,設置其中host=’0.0.0.0’表示在公網ip下的同一個局域網段所有ip都可以訪問這個服務,如果把host指定為其中一個內網ip地址,則這個局域網下所有用戶可以通過訪問這個指定的ip地址訪問Flask服務。

 

后面介紹可以略微看看,也相當於是了解一下nginx +gunicorn以及tornado的基本概念。也可以忽略,直接查看2 具體實現

 

使用nginx +gunicorn來部署Flask相關服務,即不使用Flask自帶的服務器。

 

看到上面的部署方式,作為初學者,不免會有新的疑問,什么是nginx和gunicorn呢?

我自己也是新接觸的,查看了一下網上資料,大概了解了一下。

 

什么是nginx呢?

摘抄自百度百科(https://baike.baidu.com/item/nginx/3817705?fr=aladdin)的一段解釋:Nginx是一款輕量級Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。其特點是占有內存少,並發能力強,事實上nginx的並發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。

 

什么是gunicorn呢?

摘抄自網上一遍文章(http://www.pythontip.com/blog/post/5155/)一段解釋:Gunicorn“綠色獨角獸”是一個被廣泛使用的高性能的Python WSGI UNIX HTTP服務器,移植自Ruby的獨角獸(Unicorn )項目,使用pre-fork worker模式,具有使用非常簡單,輕量級的資源消耗,以及高性能等特點。

Gunicorn 服務器作為wsgi app的容器,能夠與各種Web框架兼容(flask,django等),得益於gevent等技術,使用Gunicorn能夠在基本不改變wsgi app代碼的前提下,大幅度提高wsgi app的性能。

 

看到上面的解決辦法,試着搭建安裝,發現gunicorn不支持Windows系統,坑啊,早知道這樣就買一個Linux服務器。

使用gunicorn報錯信息:

復制代碼
Traceback (most recent call last):

  File "d:\program files (x86)\python27\Lib\runpy.py", line 174, in _run_module_as_main

    "__main__", fname, loader, pkg_name)

  File "d:\program files (x86)\python27\Lib\runpy.py", line 72, in _run_code

    exec code in run_globals

  File "E:\WorkPlace\Git_python\liu_demo\venv\Scripts\gunicorn.exe\__main__.py", line 5, in <module>

  File "e:\workplace\git_python\liu_demo\venv\lib\site-packages\gunicorn\app\wsgiapp.py", line 10, in <module>

    from gunicorn.app.base import Application

  File "e:\workplace\git_python\liu_demo\venv\lib\site-packages\gunicorn\app\base.py", line 12, in <module>

    from gunicorn import util

  File "e:\workplace\git_python\liu_demo\venv\lib\site-packages\gunicorn\util.py", line 9, in <module>

    import fcntl

ImportError: No module named fcntl
復制代碼

 

 

 

然而我的服務器依舊是Windows版本,Flask服務器環境還是要搭建,那么得采用什么方案呢?

此處推薦采用tornado。

那么什么是tornado呢?

摘抄至網上一篇文章http://www.tornadoweb.cn/)介紹:Tornado 是 FriendFeed 使用的可擴展的非阻塞式 web 服務器及其相關工具的開源版本。這個 Web 框架看起來有些像 web.py 或者 Google 的 webapp,不過為了能有效利用非阻塞式服務器環境,這個 Web 框架還包含了一些相關的有用工具 和優化。

Tornado 和現在的主流 Web 服務器框架(包括大多數 Python 的框架)有着明顯的區別:它是非阻塞式服務器,而且速度相當快。得利於其 非阻塞的方式和對 epoll 的運用,Tornado 每秒可以處理數以千計的連接,這意味着對於實時 Web 服務來說,Tornado 是一個理想的 Web 框架。我們開發這個 Web 服務器的主要目的就是為了處理 FriendFeed 的實時功能 ——在 FriendFeed 的應用里每一個活動用戶都會保持着一個服務器連接。(關於如何擴容 服務器,以處理數以千計的客戶端的連接的問題,請參閱 C10K problem。)

 

至於具體怎么運用,可以查看上面文章介紹,也可以參見下文的具體使用代碼。

 

 


2 具體實現

看到下面具體實現代碼,會讓大家感嘆,Python的確是一個優美的語言,Flask框架也的確是對應小而又輕量級的框架美稱呀。使用MongoDB數據庫,操作數據庫也變得極為簡單。

 

在看下面代碼之前,需要簡單說一下REST的基本思想原理,也相當於是我自己進一步加深印象吧。下面解釋應用自阮一峰博客的一個評論,我感覺這樣描述的很在理。

 

REST四個基本原則:
1.使用HTTP動詞:GET POST PUT DELETE;
2.無狀態連接,服務器端不應保存過多上下文狀態,即每個請求都是獨立的;
3.為每個資源設置URI;
4.通過XML JSON進行數據傳遞;
實現上述原則的架構即可稱為RESTFul架構。
1.互聯網環境下,任何應用的架構和API可以被快速理解;
2.分布式環境下,任何請求都可以被發送到任意服務器;
3.異構環境下,任何資源的訪問和使用方式都統一;

 

看到上面介紹,既然說了REST方式使用HTTP動詞GET POST PUT DELETE來實現相關操作。

那么下面代碼就簡單實現一下這四個動詞的具體操作功能。

GET:實現從服務器后台獲取數據功能,例如登陸接口功能實現;

POST:實現向服務器后台提交數據功能,例如注冊接口功能實現;

PUT:實現修改服務器后台已有數據功能;

DELETE:實現刪除服務器后台已有數據功能。

 

看完上面介紹,下面就請看代碼:

如果不使用tornado,直接使用下面一個mongo.py文件中代碼即可實現本文標題所述功能:

復制代碼
#coding=utf-8
#mongo.py
from flask import Flask,abort
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo


app = Flask(__name__)

app.config['MONGO_DBNAME'] = 'rest'
app.config['MONGO_URI'] = 'mongodb://172.18.252.20:27017/rest'  #如果部署在本上,其中ip地址可填127.0.0.1

mongo = PyMongo(app)

@app.route('/login', methods=['GET'])
def get_all_users():
  star = mongo.db.userInfo.find()
  output = []
  for s in star:
    output.append({'name' : s['name'], 'pwd' : s['pwd']})
  return jsonify({'result' : output})


@app.route('/register', methods=['POST'])
def add_user():
  star = mongo.db.userInfo
  name = request.json['name']
  pwd = request.json['pwd']
  star_id = star.insert({'name': name, 'pwd': pwd})
  new_star = star.find_one({'_id': star_id })
  output = {'name' : new_star['name'], 'pwd' : new_star['pwd']}
  return jsonify({'result' : output})

@app.route('/modify/<string:name>', methods=['PUT'])
def update_user(name):
    user = mongo.db.userInfo.find({"name":name})
    output = []
    for s in user:
      output.append({'name': s['name'], 'pwd': s['pwd']})
    if len(output) == 0:
      abort(404)
    mongo.db.userInfo.update({"name":name},{'$set':{"name":"LZ111"}})
    return jsonify({'result': output})

@app.route('/delete/<string:name>', methods=['DELETE'])
def delete_user(name):
    user = mongo.db.userInfo.find({"name": name})
    output = []
    for s in user:
      output.append({'name': s['name'], 'pwd': s['pwd']})
    if len(output) == 0:
      abort(404)
    mongo.db.userInfo.remove({'name': name})
    return jsonify({'result': True})

# 接
口收到多個參數
@app.route('/users/<page>/<count>', methods=['GET'])
def get_user_list(page, count):
return jsonify({'page': page, 'count': count})

if __name__ == '__main__': # app.run(host = '0.0.0.0', port = 80, debug = True) app.run()
復制代碼

 

如果使用tornado,新建一個tornado_server.py文件,添加以下代碼,作為Flask服務啟動部署,也可以實現相關功能:

復制代碼
#coding=utf-8
#tornado_server.py
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop

from mongo import app


http_server = HTTPServer(WSGIContainer(app))
# http_server.listen(9000)  #此時,開啟端口9000,默認本機127.0.0.1的IP地址
http_server.bind(80, "172.18.252.20")# 開啟端口為9000,172.18.252.20為內網ip地址,也可以設置為0.0.0.0,
http_server.start(1)
IOLoop.instance().start()
復制代碼

 

看完上面代碼,點擊運行,即可實現相關接口功能了。既然是接口,GET方式還好說,如果是POST方式,使用瀏覽器就不那么好操作了,此時我們需要使用一款接口測試軟件,在這里我推薦使用Postman(PS:Postman百度經驗介紹Postman官網下載鏈接  , 附加百度雲盤WIN64位下載鏈接:https://pan.baidu.com/s/12t09OMcrezgNY3_JfYFx8g 密碼:z1vk),如果有同學使用基於Linux相關系統,推薦使用CURL來實現。

 

下面就正式開始使用Postman測試Get、Post、Put和Delete方式接口:

Get方式,選中下圖中下拉框GET方式,直接輸入URL,然后點擊Send藍色按鈕即可得到請求數據。

 

 

Post方式,選中下拉框中Post方式,這里由於要發送數據,需要稍微設置一下。

首先,在下圖中Headers中要選擇Content-Type的數據方式,這里我選擇的是json格式:

 

然后,點開下圖中Body,選擇raw,添加要存入的json格式數據,如下:

 

最后,點擊Send按鈕,在最下面出現相關提示信息后,即可查看Post請求結果。

 

Put方式操作和Get方式雷同,不同的是需要選中操作方式為Put,具體如下圖:

 

 

Delete方式和Put請求幾乎一樣,不同的是一個執行修改操作,一個執行刪除操作而已,具體如下圖:

 

 

基本操作就這樣,看完上面代碼,發現使用FLask+MongoDB寫后端接口是不是特別簡單?

 

 

參考資料:
1.Designing a RESTful API with Python and Flask(PS:附加一個中文版,不過里面代碼有bug)

2.理解RESTful架構

3.MONGODB RESTFUL API WITH FLASK

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM