フラスコソースコード解析II:内部ルーティング実装原理

序文

フラスコは、より良い内部統制メカニズムを達成するために、これまで私のお気に入りのPythonのWebフレームワークであり、次のソースフラスコ、ディープで学び、あなたと共有する準備ができて、この2日間、フラスコバージョン1.1.1 。

起動プロセスのフラスコサービスの最後の理解は、私たちが今日達成するために内部ルーティングメカニズムを見てください。

フラスコシリーズ:

  1. 開発フラスコオン
  2. ソースコード解析をフラスコ:サービスが開始

ルーティングについて

いわゆるルーティングは、URL要求の手順と機能の関係に対処することです。

フラスコはまた、URLは、次の2つの方法でルールを作成され、URLに管理ルールを統一されています。

  1. 引数としてURLルールを渡し、URLへの機能を結合し、app.routeデコレータ@使用し、ルーティングの機能として登録プロセスを入れて、この機能は、ビュー機能と呼ばれています。
  2. app.add_url_rule()を使用してください。

あなたがソースコードを読み始める前に、私はこれのいくつかの質問がありますか?

  1. ルーティングを登録するプロセスは何ですか?
  2. フラスコは、URLルールのどの内部管理のですか?
  3. どのように複数の内部URLをバインドする機能を表示するには実装されていますか?
  4. それに合わせて、ビュー機能はどのように動的なURLのですか?
  5. ルーティングは、それが何であるかに一致するプロセスのことですか?

私たちはそれのソースを学ぶためにいくつかの質問でこれを見てみましょう!

テキスト

登録ルート

まず、ルート()デコレータ:

def route(self, rule, **options):       

        def decorator(f):
            endpoint = options.pop("endpoint", None)
            self.add_url_rule(rule, endpoint, f, **options)
            return f

        return decorator

ルートは()ルールは、URLのルールを表し、2つのパラメータがあります。この処理パラメータ関数の後、それが登録されたルートを確認する2種類の方法に相当する方法add_url_role()を呼び出します。私たちは、コードを見て:

def add_url_rule(
        self,
        rule,
        endpoint=None,
        view_func=None,
        provide_automatic_options=None,
        **options
    ):
        
        if endpoint is None:
            endpoint = _endpoint_from_view_func(view_func)
        options["endpoint"] = endpoint
        methods = options.pop("methods", None)

        # if the methods are not given and the view_func object knows its
        # methods we can use that instead.  If neither exists, we go with
        # a tuple of only ``GET`` as default.
        if methods is None:
            methods = getattr(view_func, "methods", None) or ("GET",)
        if isinstance(methods, string_types):
            raise TypeError(
                "Allowed methods have to be iterables of strings, "
                'for example: @app.route(..., methods=["POST"])'
            )
        methods = set(item.upper() for item in methods)

        # Methods that should always be added
        required_methods = set(getattr(view_func, "required_methods", ()))

        # starting with Flask 0.8 the view_func object can disable and
        # force-enable the automatic options handling.
        if provide_automatic_options is None:
            provide_automatic_options = getattr(
                view_func, "provide_automatic_options", None
            )

        if provide_automatic_options is None:
            if "OPTIONS" not in methods:
                provide_automatic_options = True
                required_methods.add("OPTIONS")
            else:
                provide_automatic_options = False

        # Add the required methods now.
        methods |= required_methods

        rule = self.url_rule_class(rule, methods=methods, **options)
        rule.provide_automatic_options = provide_automatic_options

        self.url_map.add(rule)
        if view_func is not None:
            old_func = self.view_functions.get(endpoint)
            if old_func is not None and old_func != view_func:
                raise AssertionError(
                    "View function mapping is overwriting an "
                    "existing endpoint function: %s" % endpoint
                )
            self.view_functions[endpoint] = view_func

パラメータは次のとおりです。

  1. ルール:URLルール
  2. エンドポイント:ルールのエンドポイントを登録するには、デフォルトでは子ビュー関数の名前です
  3. view_func:ビュー機能
  4. provide_automatic_options:フラグOPTIONSメソッドを追加するかどうかを要求する方法
  5. オプション:要求の処理方法などについて

あなたが見る、add_url_rule()最初の処理パラメータであって、

  1. エンドポイントのデフォルトのビュー関数名
  2. デフォルトのメソッドは、要求URLをGETです
  3. リクエストがOPTIONSメソッド提供されていない場合は、メソッドを追加します。

すべての引数が処理された後、URLの書き込みルールは、(ルールオブジェクトが作成され、Mapオブジェクトに追加された)url_map、ビュー機能はview_function辞書を書き込みます。

前記、url_mapはwerkzeug.routing:Map 、ルール、オブジェクトのクラスwerkzeug.routing:Rule 、すなわち、オブジェクトクラスコアフラスコルーティングロジックはWERKZEUGに実装されています

ツール

WERKZEUGはURL解析モジュールが主に使用されているwerkzeug.routing、PythonのWSGIにツールセットを書かれています。

ルール・クラス

ルール・クラスがRuleFactoryクラスから継承、ルールのインスタンスは、URLパターンを表し、WSGIアプリケーションは、多くの異なるURLパターンに対処すると同時に、パラメータマップクラスとして渡されるルールのインスタンスの数を生成します。

Mapクラス

クラスマップストアの例としては、すべての構成規則のURLは、解析し、表示する機能は、要求の一致に対応します。

ルーティング試合

アプリケーションの初期化プロセスでは、すべてのルーティングルールを登録します、あなたはサービスがURLリクエストを受信する(app.url_map)ビューを呼び出すことができ、あなたは、対応するプロセスと原則、対応するビュー機能を見つけるために、一致するようにルーティングするされている必要がありますそれは何ですか?

ユーザーがリクエストフラスコアプリケーションに入ると、この方法は、wsgi_appクラスフラスコを呼び出します。

def wsgi_app(self, environ, start_response):
    
    ctx = self.request_context(environ)
    error = None
    try:
        try:
            ctx.push()
            response = self.full_dispatch_request()
        except Exception as e:
            error = e
            response = self.handle_exception(e)
        except:  # noqa: B001
            error = sys.exc_info()[1]
            raise
        return response(environ, start_response)
    finally:
        if self.should_ignore_error(error):
            error = None
        ctx.auto_pop(error)

処理機能であって、

  1. RequestContextのプロセスオブジェクト初期化app.create_url_adapter()メソッドを呼び出して、オブジェクトを作成し、要求がurl_adapterフィールドに格納されMapAdapterオブジェクトを作成したパラメータ環境マップオブジェクトに渡されます。
  2. RequestContextのオブジェクトがスタック_request_ctx_stackを押します
  3. match_request方法RequestContextのことで、マッチングルールを見つけ、url_ruleの要求とview_argsとフィールドに格納されたパラメータを解析するために、オブジェクトの一致MapAdapterの道を呼び出します
  4. full_dispatch_requestを呼び出します()

次はfull_dispatch_request方法を見て:

def full_dispatch_request(self):
    self.try_trigger_before_first_request_functions()
    try:
        request_started.send(self)
        rv = self.preprocess_request()
        if rv is None:
            rv = self.dispatch_request()
    except Exception as e:
        rv = self.handle_user_exception(e)
    return self.finalize_request(rv)

あなたは、dispatch_requestの実装()の焦点を見ることができます:

def dispatch_request(self):
    req = _request_ctx_stack.top.request
    if req.routing_exception is not None:
        self.raise_routing_exception(req)
    rule = req.url_rule
    # if we provide automatic options for this URL and the
    # request came with the OPTIONS method, reply automatically
    if (
        getattr(rule, "provide_automatic_options", False)
        and req.method == "OPTIONS"
    ):
        return self.make_default_options_response()
    # otherwise dispatch to the handler for that endpoint
    return self.view_functions[rule.endpoint](**req.view_args)

処理プロセスである:、対応するエンドポイントは、今度は、ビューview_functionsから対応する機能を検索し見つけること、要求されたオブジェクトの取得要求を配信要求パラメータ及び内部ロジック機能を表示する配信要求を完了するために処理を戻します。

上記は、内部ルーティングフラスコの原則の実現です。

おすすめ

転載: www.cnblogs.com/ybjourney/p/11789983.html