GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

falconry

falcon – Falconは、高性能なマイクロサービス、アプリケーションバックエンド、およびより高いレベルのフレームワークを構築するための、ベアメタルのPy..

投稿日:

Falconは、高性能なマイクロサービス、アプリケーションバックエンド、およびより高いレベルのフレームワークを構築するための、ベアメタルのPython Web APIフレームワークです。 https://falcon.readthedocs.io/en/stable/

ファルコンWebフレームワーク

Falconは、大規模なアプリケーションバックエンドとマイクロサービスを構築するための、信頼性の高い、高性能のPython Webフレームワークです。 RESTアーキテクチャスタイルを奨励し、非常に効果的なままで、できるだけ少なくしようとします。

FalconアプリケーションはWSGIサーバーと連携し、CPython 2.7、CPython 3.4+、PyPy2.7、PyPy3.5の下でチャンピオンのように動作します。

サポートファルコン開発

ファルコンはあなたが素晴らしいアプリを作るのを助けましたか? 1回限りの寄付で、または企業スポンサーになることで、今すぐあなたの支持を示してください。 後者はクールな機会を得て、ブランドをPython開発者に宣伝し、サポートを優先させます。

ファルコン開発をサポートする方法を学ぶ

クイックリンク

ファルコンはどう違うのですか?

完全性は最終的に追加するものがなくなったときではなく、もはや持ち去るものがなくなったときに達成されます。

– アントワン・ドゥ・サン・テグジュペリ

私たちは大規模なマイクロサービスと応答性の高いアプリケーションバックエンドの要求をサポートするようにFalconを設計しました。 Falconは、必要に応じてベアメタルのパフォーマンス、信頼性、柔軟性を提供することにより、より一般的なPython Webフレームワークを補完します。

高速。 同じハードウェア、より多くの要求。 Falconは他のほとんどのPythonフレームワークよりも数倍高速にリクエストを処理します。 追加のスピードブーストのために、Falconは利用可能なときにCythonでコンパイルし、 PyPyでもうまく動作します。 別のプログラミング言語への移行を考えていますか? ファルコン+ PyPyでベンチマーク

信頼性のある。 私たちは大きな変更を加えるのを避けるために徹底的に取り組んでいます。私たちは完全に文書化されており、( SemVerの精神のなかで )主なバージョンの増加だけで導入されています。 コードは多数の入力で厳密にテストされており、常に100%のカバレッジが必要です。 Sixとmimeparseはサードパーティの唯一の依存関係です。

フレキシブル。 Falconは、API開発者の多くの決定と実装の詳細を残しています。 これにより、実装をカスタマイズして調整するための自由度が広がります。 Falconのミニマリストデザインにより、PythonコミュニティのメンバーはFalconのアドオンと補完的なパッケージを独立して開発することができます

デバッグ可能。 ファルコンは魔法を避ける。 どちらの入力がどの出力につながるかは簡単に分かります。 未処理の例外はカプセル化もマスクもされません。 自動リクエスト本文の解析などの潜在的に驚くべき動作は、デフォルトで十分に文書化され、無効になっています。 最後に、フレームワーク自体については、論理パスを簡単かつ理解しやすいように注意します。 このため、大規模な展開では、コードを推論してエッジケースをデバッグするのが簡単になります。

特徴

  • 高度に最適化された拡張可能なコードベース
  • URIテンプレートとRESTに基づくリソースクラスによる直感的なルーティング
  • 要求クラスと応答クラスを使用したヘッダーとボディへの簡単なアクセス
  • ミドルウェアコンポーネントとフックによるDRY要求処理
  • 慣習的なHTTPエラー応答
  • 簡単な例外処理
  • WSGIヘルパーとモックを使ったユニットテスト
  • CPython 2.7、CPython 3.4+、PyPy2.7、PyPy3.5サポート
  • Cythonが利用可能な場合、CPythonで約20%の速度向上

ファルコンを使っているのは誰ですか?

ファルコンは、次のような組織の数が増えて世界中で使用されています。

  • 7才
  • クロニター
  • EMC
  • ハリケーン電気
  • リードページ
  • OpenStack
  • ラックスペース
  • Shiftgig
  • tempfil.es
  • Operaソフトウェア

コミュニティや商業プロジェクトにFalconフレームワークを使用している場合は、 Who’s Using Falconのウィキに情報を追加することを検討してください

コミュニティ

プロジェクトでは、いくつかのFalconアドオン、テンプレート、補完パッケージを利用できます。 Falcon wikiのいくつかを出発点として挙げましたが、追加のリソースをPyPIで検索することもできます。

GitterのFalconryコミュニティは、質問をしてあなたのアイデアを共有するのに最適な場所です。 あなたは鷹匠/ユーザで私たちを見つけることができます。 また、フレームワーク自体の設計と開発を議論するためのfalconry / devの部屋もあります。

私たちの行動規範に従って 、コミュニティの議論に参加しているすべての人が専門的に行動し、建設的な議論を促すための例を挙げることを期待しています。 コミュニティの各個人は、積極的で建設的で生産的な文化を創造する責任があります。

インストール

PyPy

PyPyはFalconアプリを実行する最速の方法です。 PyPy2.7とPyPy3.5はどちらもPyPy v5.10以降でサポートされています。

$ pip install falcon

または、最新のベータ版またはリリース候補がインストールされている場合は、それをインストールします。

$ pip install --pre falcon

CPython

Falconは、 CPython 2.7および3.4​​+も完全にサポートしています。

Falconフレームワークのために、PyPI上で普遍的なホイールが利用可能です。 インストールは次のように簡単です:

$ pip install falcon

ujsonが利用可能であれば、Falconはそれを使用してメディア(de)のシリアライゼーション、エラーのシリアライゼーション、およびクエリ文字列の解析を高速化します。 ujsonはctypesのオーバーヘッドのために標準のjsonモジュールよりも実際にPyPyの方が遅くなる可能性があるので、CPythonのデプロイメントではujsonを使用することをお勧めしujson

$ pip install ujson

Falconホイールをインストールすると、開発環境ですぐに起動して実行することができますが、アプリケーションを本番環境に配備する際のスピードをさらに高めるために、FalconはCythonでコンパイルできます。

次のコマンドは、pipにCythonをインストールするよう指示し、Falconのsetup.pyを呼び出すと、Cycloneの存在を検出し、FalconフレームワークをシステムのデフォルトのCコンパイラでコンパイル(AKA cythonize)します。

$ pip install cython
$ pip install --no-binary :all: falcon

Cythonが呼び出されていることを確認するには、-vをpipに渡してコンパイルコマンドをエコーし​​ます。

$ pip install -v --no-binary :all: falcon

OS Xへのインストール

Cythonをコンパイルするには、Xcodeコマンドラインツールが必要です。 次のコマンドでインストールします。

$ xcode-select --install

Clangコンパイラは、認識できないコマンドラインオプションをエラーとして処理します。たとえば、次のようになります。

clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future]

未使用機能に関する警告が表示されることもあります。 これらの問題を回避するには、次のように追加のClang Cコンパイラフラグを設定します。

$ export CFLAGS="-Qunused-arguments -Wno-unused-function"

依存関係

ファルコンは6とpython-mimeparseに依存します。 python-mimeparseは、同様にmimeparseという名前のプロジェクトをよりよく管理したフォークです。 通常、正しいパッケージはFalconのsetup.pyによって選択されます。 ただし、代替戦略を使用して依存関係を管理する場合は、エラーを回避するために正しいパッケージをインストールするように注意してください。

WSGIサーバー

FalconはWSGIを話すので、Falconアプリケーションを提供するにはWSGIサーバーが必要です。 GunicornとuWSGIはそこではより一般的なものですが、WSGIアプリケーションをロードできるものは何でもできます。

$ pip install [gunicorn|uwsgi]

ソースコード

Falcon はGitHub住んでいるので、コードの参照、ダウンロード、フォークなどを簡単に行えます。引っ張り要求はいつでも歓迎です! また、あなたが幸せになれば、プロジェクトにスターを付けることを覚えておいてください。 🙂

レポをクローンしたり、GitHubからtarballをダウンロードしたら、Falconを次のようにインストールすることができます:

$ cd falcon
$ pip install .

コードを編集する場合は、最初にメインリポジトリをフォークし、デスクトップにフォークをクローンし、シンボリックリンクを使用してフォークをインストールしてください。コードを変更すると、自動的に変更が自動的に利用できるようになります。あなたのアプリを再インストールする必要はありません:

$ cd falcon
$ pip install -e .

クローン作成されたリポジトリのディレクトリに切り替えて、pytestを実行することで、Falconフレームワークの変更を手動でテストできます。

$ cd falcon
$ pip install -r requirements/tests
$ pytest tests

あるいは、デフォルトのテストセットを実行するには:

$ pip install tox && tox

使用可能な環境の完全なリストについては、 tox.iniファイルを参照してください。

ドキュメントを読む

ファルコンコードベースのドキュメントストリングは非常に広範で、REPLを実行したままでフレームワークを学ぶことで、さまざまなモジュールやクラスを質問できるようにすることをお勧めします。

オンラインドキュメントはhttps://falcon.readthedocs.ioから入手できます

次のように、同じドキュメントをローカルにビルドすることができます:

$ pip install tox && tox -e docs

ドキュメントが作成されたら、ブラウザで次のインデックスページを開いてドキュメントを表示できます。 OS Xでは、次のように簡単です:

$ open docs/_build/html/index.html

Linuxの場合:

$ xdg-open docs / _build / html / index.html

入門

ここでは、FalconベースのAPIを作成する方法を示す単純でわかりやすい例を示します。

# things.py

# Let's get this party started!
import falcon


# Falcon follows the REST architectural style, meaning (among
# other things) that you think in terms of resources and state
# transitions, which map to HTTP verbs.
class ThingsResource(object):
    def on_get(self, req, resp):
        """Handles GET requests"""
        resp.status = falcon.HTTP_200  # This is the default status
        resp.body = ('\nTwo things awe me most, the starry sky '
                     'above me and the moral law within me.\n'
                     '\n'
                     '    ~ Immanuel Kant\n\n')

# falcon.API instances are callable WSGI apps
app = falcon.API()

# Resources are represented by long-lived class instances
things = ThingsResource()

# things will handle all requests to the '/things' URL path
app.add_route('/things', things)

上の例は、uWSGIやGunicornなどのWSGIサーバーを使用して実行できます。 例えば:

$ pip install gunicorn
$ gunicorn things:app

次に、別の端末で:

$ curl localhost:8000/things

より複雑な例

ここでは、ヘッダーとクエリパラメータの読み取り、エラーの処理、および要求と応答の本体の操作を示す、より複雑な例を示します。

import json
import logging
import uuid
from wsgiref import simple_server

import falcon
import requests


class StorageEngine(object):

    def get_things(self, marker, limit):
        return [{'id': str(uuid.uuid4()), 'color': 'green'}]

    def add_thing(self, thing):
        thing['id'] = str(uuid.uuid4())
        return thing


class StorageError(Exception):

    @staticmethod
    def handle(ex, req, resp, params):
        description = ('Sorry, couldn\'t write your thing to the '
                       'database. It worked on my box.')

        raise falcon.HTTPError(falcon.HTTP_725,
                               'Database Error',
                               description)


class SinkAdapter(object):

    engines = {
        'ddg': 'https://duckduckgo.com',
        'y': 'https://search.yahoo.com/search',
    }

    def __call__(self, req, resp, engine):
        url = self.engines[engine]
        params = {'q': req.get_param('q', True)}
        result = requests.get(url, params=params)

        resp.status = str(result.status_code) + ' ' + result.reason
        resp.content_type = result.headers['content-type']
        resp.body = result.text


class AuthMiddleware(object):

    def process_request(self, req, resp):
        token = req.get_header('Authorization')
        account_id = req.get_header('Account-ID')

        challenges = ['Token type="Fernet"']

        if token is None:
            description = ('Please provide an auth token '
                           'as part of the request.')

            raise falcon.HTTPUnauthorized('Auth token required',
                                          description,
                                          challenges,
                                          href='http://docs.example.com/auth')

        if not self._token_is_valid(token, account_id):
            description = ('The provided auth token is not valid. '
                           'Please request a new token and try again.')

            raise falcon.HTTPUnauthorized('Authentication required',
                                          description,
                                          challenges,
                                          href='http://docs.example.com/auth')

    def _token_is_valid(self, token, account_id):
        return True  # Suuuuuure it's valid...


class RequireJSON(object):

    def process_request(self, req, resp):
        if not req.client_accepts_json:
            raise falcon.HTTPNotAcceptable(
                'This API only supports responses encoded as JSON.',
                href='http://docs.examples.com/api/json')

        if req.method in ('POST', 'PUT'):
            if 'application/json' not in req.content_type:
                raise falcon.HTTPUnsupportedMediaType(
                    'This API only supports requests encoded as JSON.',
                    href='http://docs.examples.com/api/json')


class JSONTranslator(object):
    # NOTE: Starting with Falcon 1.3, you can simply
    # use req.media and resp.media for this instead.

    def process_request(self, req, resp):
        # req.stream corresponds to the WSGI wsgi.input environ variable,
        # and allows you to read bytes from the request body.
        #
        # See also: PEP 3333
        if req.content_length in (None, 0):
            # Nothing to do
            return

        body = req.stream.read()
        if not body:
            raise falcon.HTTPBadRequest('Empty request body',
                                        'A valid JSON document is required.')

        try:
            req.context['doc'] = json.loads(body.decode('utf-8'))

        except (ValueError, UnicodeDecodeError):
            raise falcon.HTTPError(falcon.HTTP_753,
                                   'Malformed JSON',
                                   'Could not decode the request body. The '
                                   'JSON was incorrect or not encoded as '
                                   'UTF-8.')

    def process_response(self, req, resp, resource):
        if 'result' not in resp.context:
            return

        resp.body = json.dumps(resp.context['result'])


def max_body(limit):

    def hook(req, resp, resource, params):
        length = req.content_length
        if length is not None and length > limit:
            msg = ('The size of the request is too large. The body must not '
                   'exceed ' + str(limit) + ' bytes in length.')

            raise falcon.HTTPRequestEntityTooLarge(
                'Request body is too large', msg)

    return hook


class ThingsResource(object):

    def __init__(self, db):
        self.db = db
        self.logger = logging.getLogger('thingsapp.' + __name__)

    def on_get(self, req, resp, user_id):
        marker = req.get_param('marker') or ''
        limit = req.get_param_as_int('limit') or 50

        try:
            result = self.db.get_things(marker, limit)
        except Exception as ex:
            self.logger.error(ex)

            description = ('Aliens have attacked our base! We will '
                           'be back as soon as we fight them off. '
                           'We appreciate your patience.')

            raise falcon.HTTPServiceUnavailable(
                'Service Outage',
                description,
                30)

        # An alternative way of doing DRY serialization would be to
        # create a custom class that inherits from falcon.Request. This
        # class could, for example, have an additional 'doc' property
        # that would serialize to JSON under the covers.
        #
        # NOTE: Starting with Falcon 1.3, you can simply
        # use resp.media for this instead.
        resp.context['result'] = result

        resp.set_header('Powered-By', 'Falcon')
        resp.status = falcon.HTTP_200

    @falcon.before(max_body(64 * 1024))
    def on_post(self, req, resp, user_id):
        try:
            # NOTE: Starting with Falcon 1.3, you can simply
            # use req.media for this instead.
            doc = req.context['doc']
        except KeyError:
            raise falcon.HTTPBadRequest(
                'Missing thing',
                'A thing must be submitted in the request body.')

        proper_thing = self.db.add_thing(doc)

        resp.status = falcon.HTTP_201
        resp.location = '/%s/things/%s' % (user_id, proper_thing['id'])


# Configure your WSGI server to load "things.app" (app is a WSGI callable)
app = falcon.API(middleware=[
    AuthMiddleware(),
    RequireJSON(),
    JSONTranslator(),
])

db = StorageEngine()
things = ThingsResource(db)
app.add_route('/{user_id}/things', things)

# If a responder ever raised an instance of StorageError, pass control to
# the given handler.
app.add_error_handler(StorageError, StorageError.handle)

# Proxy some things to another service; this example shows how you might
# send parts of an API off to a legacy system that hasn't been upgraded
# yet, or perhaps is a single cluster that all data centers have to share.
sink = SinkAdapter()
app.add_sink(sink, r'/search/(?P<engine>ddg|y)\Z')

# Useful for debugging problems in your API; works with pdb.set_trace(). You
# can also use Gunicorn to host your app. Gunicorn can be configured to
# auto-restart workers when it detects a code change, and it also works
# with pdb.
if __name__ == '__main__':
    httpd = simple_server.make_server('127.0.0.1', 8000, app)
    httpd.serve_forever()

貢献する

プロジェクトに興味をお持ちいただきありがとうございます! 私たちは、すべてのスキルレベルの開発者からの引き取り要求を歓迎します。 まず、GitHubのマスターブランチを個人アカウントにフォークし、フォークを開発環境にクローンします。

貢献したいと思っていますが、まだ何かを念頭に置いていない場合は、 次のマイルストーンに記載されている問題をご覧ください 作業したいものがある場合は、すぐにコメントを残して、重複しないようにしてください。 前もって感謝します!

このプロジェクトのすべての貢献者および保守者は、行動規範の対象であることに注意してください。

プルリクエストを提出する前に、適切なテストが追加/更新されていること(そして、既存のテストには変更が残っていることを確認してください)、コーディングスタイルはPEP 8に従います。

コミットメッセージは、 AngularJS規約を使用してフォーマットする必要があります。

コメントは、GitHubニックネームと適切なプレフィックスを使用してインラインコメントのプレフィックスを付加するという追加の要件とともに、 Googleのスタイルガイドに従います

  • TODO(リッカー):ダメージ報告!
  • 注意(リッカー):まあ、それは確かに知って良いです。
  • PERF(リカー):最寄のスターベースまでの移動時間?
  • APPSEC(リッカー):すべての信頼には、裏切りの可能性があります。

Kurt Griffiths(GH、Gitter、Twitterのkgriffs )は、Falconフレームワークの元々の作成者であり、現在John Vrbanac(GHとGitterのjmvrbanac 、Twitterのjvrbanac )とともにプロジェクトを共同管理しています。 ファルコンはあなたと同じようにスタイリッシュなユーザーと貢献者のコミュニティが成長していくことで開発されています。

ご不明な点がございましたら、お気軽にお気軽にご連絡ください。 Gitterのfalconry / devで私たちを見つけることができます。

関連項目: CONTRIBUTING.md

法的

個々のソースファイルに記載されている個人および企業寄稿者による著作権2013-2018

ファルコンイメージジョンオニールの礼儀。

Apache License、Version 2.0(以下「ライセンス」)の下でライセンスされています。 ライセンスの遵守を除いて、Falconフレームワークの一部を使用することはできません。 貢献者は、同じライセンスの下で自分の仕事をライセンスすることに同意します。 お客様は、 http://www.apache.org/licenses/LICENSE-2.0でライセンスのコピーを入手することができます

適用法または書面による合意が必要な場合を除き、本ライセンスに基づいて配布されるソフトウェアは、明示的または黙示的にいかなる種類の保証または条件もなく「現状有姿」で配布されます。 ライセンスに基づいて許可および制限を規定する特定の言語については、ライセンスを参照してください。







-falconry
-, , , , , ,

執筆者: