0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Falcon Web Frameworkを使ったPythonでのREST APIの開発とデプロイメント

Posted at

今回の記事では、PyPy上でFalconのウェブフレームワークを使ってPythonでREST APIを開発・デプロイしていきます。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

はじめに:Falconとは何か?

Falconは、スピーディーなWeb APIやアプリのバックエンドを構築するための最小限のWSGIライブラリです。HTTP APIの構築に関しては、他のフレームワークは膨大な量の依存関係や不要な抽象化に悩まされています。Falconは、HTTPとRESTアーキテクチャスタイルを採用したすっきりとしたデザインです。

あなたの頭に浮かぶ最初のことは、おそらく「なぜFalconを使うべきなのか?」ということでしょう。さて、Falconはflask、Django、Bottle、web.pyのような他のpythonのフレームワークと同じくらいパワフルで、高速で、拡張性があり、信頼性が高く、RESTfulなスタイルを奨励しています。ベンチマークによると、FalconはflaskやDjangoよりもpypy上で21倍も高速です。LinkedIn、Leadpages、Wargaming、およびRackspaceのような組織は、すでにアプリケーションにFalconを使用しています。

image.png

Alibaba Cloud ECSへのFalconのインストール

Alibaba Elastic Compute Service (ECS)へのFalconのインストールは、PCへのインストールと同じくらい簡単です。

Alibaba ECS上でUbuntu 16.04をプロビジョニングする

このチュートリアルを参考にして、Alibaba_Cloud上のUbuntu Serverをセットアップしてサーバーをプロビジョニングする手順を参考にしてください。

Ubuntu 16.04にpypy3と依存関係をインストールする

コードを速く動かしたいなら、PyPy を使うべきです。

1、スピード:PythonのプログラムはPyPyの方が高速に動作することが多いです。(JITコンパイラとは何ですか?)
2、メモリ使用量: メモリを大量に消費するPythonプログラム(数百MB以上)はCPythonよりも少ないスペースで動作します。
3、互換性:PyPyは既存のPythonコードと非常に互換性があります。cffiをサポートしており、twistedやDjangoのような一般的なPythonライブラリを動かすことができます。
5、スタックレス: PyPyはデフォルトでスタックレスモードをサポートしています。

$ sudo apt-get install python3-dev
$ wget https://bitbucket.org/pypy/pypy/downloads/pypy3-v6.0.0-linux64.tar.bz2
$ tar -xvf pypy3-v6.0.0-linux64.tar.bz2  -C /opt
$ sudo ln -s /opt/pypy3-v6.0.0-linux64/bin/pypy3 /usr/local/bin/pypy3
$ sudo chown -R <youruser>:<yourgroup> pypy3-v6.0.0-linux64/
$ pypy3
Python 3.5.3 (fdd60ed87e94, Apr 24 2018, 06:10:04)
[PyPy 6.0.0 with GCC 6.2.0 20160901] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>> import this

pypy3をインストールしたら、pypy3のpipと互換性のあるpythonの依存関係をインストールしなければなりません。

$ wget https://bootstrap.pypa.io/get-pip.py
$ pypy3 get-pip.py   # pypy3 -m ensurepip   
$ sudo apt-get install python3-pip
$ pip3 install virtualenvwrapper

virtualenvwrapper をインストールします。

.bashrc または .profile に以下の行を追加します。

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh

pythonの依存関係はvirtualenvでインストールした方が良いです。

$ mkvirtualenv -p /usr/local/bin/pypy3 falconenv
(falconenv):~$ pypy3 -m pip install falcon mongoengine

Ubuntu 16.04にMongodbをインストールする

MongoDBはオープンソースのドキュメントデータベースで、高性能、高可用性、自動スケーリングを実現しています。

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
$ echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
$ sudo apt-get update
$ sudo apt-get install -y mongodb-org 
$ sudo systemctl start mongod  
$ sudo systemctl status mongod
# This command will start mongod. Other options are stop | restart | status. 
? mongodb.service - High-performance, schema-free document-oriented database
   Loaded: loaded (/etc/systemd/system/mongodb.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2016-04-25 14:57:20 EDT; 1min 30s ago
 Main PID: 4093 (mongod)
    Tasks: 16 (limit: 512)
   Memory: 47.1M
      CPU: 1.224s
   CGroup: /system.slice/mongodb.service
           ??4093 /usr/bin/mongod --quiet --config /etc/mongod.conf

REST APIの構築

ユーザーがbookを作成したり、bookを更新したり、MongoDBからidでbookを取得したりするbookプロジェクトを作成します。

Falconアプリのディレクトリ構造

image.png

book_project/book/には以下のpythonファイルがあります。

models : modelsではmongoengineのORMを使用しています。mongoengineのDocumentクラスを継承したクラスは、MongoDBデータベースに相当するコレクションを記述しています。ここでは、フィールド名、ISBN、著者名を持つリソースBookを作成しました。リソースのオブジェクトごとにユニークなIDを自動生成してくれます。

from mongoengine import StringField, IntField, Document

class Book(Document):
    name = StringField()
    isbn = IntField()
    author= StringField()

api : bookリソースには、on_get, on_post という enpoint メソッドがあります。各メソッドの使い方は以下のコードコメントに記載されています。

api.pyのソースコードは以下の通りです。

import falcon, json
from .models import Book

class BookResource(object):
    def on_get(self,req,resp,book_id):
        '''
        :param req: A request object
        :param resp: A response object
        :param book_id: book_id received in http path to query book object
        :return:
        '''
        book_obj= Book.objects.get(id=book_id)
        #Query book collection to get a record with id = book_id
        resp.body = json.dumps({'author':book_obj.author,'name':book_obj.name,'isbn':book_obj.isbn})
        #It will set response body as a json object of book fields.
        resp.status = falcon.HTTP_200
        #Finally return 200 response on success

    def on_post(self,req,resp):
        '''
         This method will recevie the book data in request body in order to store it in database
        :param req: It contains json of book's author, name and isbn.
        :param resp:
        :return:
        '''
        book_data = req.media
        #req.media will deserialize json object
        book_obj=Book.objects.create(**book_data)
        #passing book_data to create method. It will create a database document in book collection.
        resp.body = json.dumps({'book_id':str(book_obj.id),'message':'book succesfully created'})
        resp.status=falcon.HTTP_200

指定されたIDの本を取得するためのGETリクエストのエンドポイント:http://<host>:<port>/<book_id>

image.png

データを持つ本を作成するためのPOSTリクエストのエンドポイント:http://<host>:<port>/<book_id>

{"author":<author_name>,"name":<book_name>, "isbn":<isbn>}

image.png

app:これは HTTP リクエストのエントリーポイントで、HTTP パスやその他の設定に基づいたリソースへのルーティングが含まれています。

import falcon
from mongoengine import connect
from .api import BookResource

connect('bookdb', host='127.0.0.1', port=27017)
app = application = falcon.API()
books = BookResource()
app.add_route('/book/{book_id}', books)
app.add_route('/books/', books)

connect(, host=, port=), この行は、与えられた資格情報を使って自動的にmongodbデータベースへの接続を作成します。この接続は、アプリのスコープ全体でグローバルに使用されます。

app = application = falcon.API(), この行は、gunicorn (ウェブアプリケーションサーバ)が自動検索してwsgiアプリとして動作するアプリケーションインスタンスを作成します。

books = BookResource(), この行は、リソースのインスタンスを作成します。

**app.add_route('/book/{book_id}', books)とapp.add_route('/books/', books)**は、httpパスとメソッドをリソースのそれぞれのメソッドにルーティングします。

GunicornとNginxでWebアプリをデプロイする

Gunicorn

Gunicorn 'Green Unicorn'は、Python WSGI HTTP Server for UNIXです。プリフォークワーカーモデルです。Gunicornサーバは様々なWebフレームワークと幅広く互換性があり、シンプルに実装されており、サーバリソースが軽く、かなり高速です。

簡単に言えば、gunicornはHTTPリクエストを理解し、HTTPバイトをPythonオブジェクトに変換することで、Pythonアプリケーションでも理解できるようにします。

以下のコマンドを使ってubuntuマシン上でgunicornを実行してください。

(falconenv):~$ pypy3 -m pip install gunicorn
(falconenv):~/book_project$  gunicorn --reload book.app --bind 127.0.0.1:9000

Nginx

NGINXは、ウェブサーバ、リバースプロキシ、キャッシング、ロードバランシング、メディアストリーミングなどのためのオープンソースソフトウェアです。NGINXは、最大のパフォーマンスと安定性を目指して設計されたWebサーバーとしてスタートしました。HTTPサーバー機能に加えて、NGINXは電子メール(IMAP、POP3、SMTP)のプロキシサーバーとして、またHTTP、TCP、UDPサーバーのリバースプロキシとロードバランサーとしても機能します。

簡単に説明すると、nginxはHTTPリクエストバイトを受信し、HTTPレスポンスバイトをクライアントに送信するソフトウェアです。NginxはHTTPリクエストバイトをpythonアプリケーションサーバ(gunicorn)に転送する役割を担っています。

$ sudo apt-get install nginx

sudo vim falcon_nginx.conf

upstream falcon_gunicorn {
    server 127.0.0.1:9000;
}
 
server {
    listen  80;
    server_name <ALIBABA ECS instance public ip>;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    location / {
            proxy_pass         http://falcon_gunicorn;
            proxy_redirect     off;
            proxy_set_header   Host $host;
    }
}
$ sudo cp falcon_nginx.conf /etc/nginx/sites-enabled/nginx.conf
$ sudo service nginx restart

概要

REST APIを開発して迅速にデプロイするためには、Falconが最良の選択肢の一つであることが証明されています。Alibaba CloudのElastic Compute Service (ECS) Ubuntu Serverにpypy3, falcon, MongoDB, gunicorn, Nginxとその他の依存関係をインストールする必要があります。falconのAPI構文は完全にRESTアーキテクチャに基づいており、適切なルーティング、モデル構造、およびビューを使用して非常に簡単に開発することができます。Falconはスケーラブルなソリューションであり、gunicorn, uwsgi, waitressのようなWSGIサーバ上に簡単にデプロイすることができます。gunicornサーバの上にNginxを追加することで、マイクロサービスのスケーラビリティ、分散性、安全性を向上させることができます。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?