如何正确地将依赖项注入Flask中?

时间:2018-12-04 21:31:04

标签: python-3.x flask dependency-injection

我正在编写我的第一个Flask应用程序。到目前为止,我已经通过执行此操作使一切正常工作(请注意,此代码将分散在多个文件中):

   scanf(" %hu",&arr[i].salary);
   scanf(" %hu",&arr[i].bonus);
   scanf(" %hu",&arr[i].deduction);

但是,我对这段代码并不特别满意。控制器方法尚未封装到适当的类中,依赖项未正确注入,并且似乎没有办法封装控制器方法。所有这些问题似乎都以依赖注入为核心,所以恕我直言,这可能是真正的问题。鉴于此,在这种情况下我将如何进行依赖注入?

1 个答案:

答案 0 :(得分:1)

使用Dependency Injector。这是您的应用程序的外观。

列出application.py

import json

from dependency_injector import containers, providers
from dependency_injector.ext import flask
from flask import Flask


# Services

class Response:

    def __init__(self, data):
        self.data = data

    def json(self):
        return self.data


class GooglePlacesSearchProvider:

    def __init__(self, url, api_key):
        ...

    def get_by_phone_number(self, phone, language):
        return Response({'result': 'phone-number-lookup-result'})

    def get_by_address(self, phone, language):
        return Response({'result': 'address-lookup-result'})


# Views

def search_with_phone_number(phone: str, language: str, places_provider: GooglePlacesSearchProvider):
    resp = places_provider.get_by_phone_number(phone, language)
    return from_response(resp)


def search_with_address(address: str, language: str, places_provider: GooglePlacesSearchProvider):
    resp = places_provider.get_by_address(address, language)
    return from_response(resp)


def from_response(resp: Response):
    return json.dumps(resp.json(), ensure_ascii=False)


# Container

class ApplicationContainer(containers.DeclarativeContainer):
    """Application container."""

    app = flask.Application(Flask, __name__, instance_relative_config=True)

    config = providers.Configuration()

    places_provider = providers.Factory(
        GooglePlacesSearchProvider,
        config.services.places.url,
        config.services.places.api_key,
    )

    search_with_phone_number_view = flask.View(
        search_with_phone_number,
        places_provider=places_provider,
    )

    search_with_address_view = flask.View(
        search_with_address,
        places_provider=places_provider,
    )


# Application factory

def create_app():
    container = ApplicationContainer()
    container.config.from_yaml('config.yml')
    container.config.services.places.api_key.from_env('PLACES_API_KEY')

    app = container.app()
    app.container = container

    app.add_url_rule(
        '/search/phone/<phone>/<language>',
        view_func=container.search_with_phone_number_view.as_view(),
    )
    app.add_url_rule(
        '/search/address/<address>/<language>',
        view_func=container.search_with_address_view.as_view(),
    )

    return app


if __name__ == '__main__':
    HOST = 'localhost'
    PORT = 5000
    app = create_app()
    app.run(HOST, PORT)

列出config.yml

services:
  places:
    url: "https://maps.googleapis.com/maps/api/place/findplacefromtext/json"

并且在运行应用程序时,您需要提供API密钥作为环境变量:

PLACES_API_KEY=key python -m application

我建议将其拆分为多个文件。看看依赖注入器Flask tutorial