FlaskIntegration.magic_route()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 17
Ratio 100 %

Code Coverage

Tests 1
CRAP Score 4.6796

Importance

Changes 0
Metric Value
cc 2
eloc 10
nop 3
dl 17
loc 17
ccs 1
cts 8
cp 0.125
crap 4.6796
rs 9.9
c 0
b 0
f 0
1
"""
2
Flask API (https://www.flaskapi.org/)
3
"""
4
5 1
from typing import Type, List, Optional, Any, Dict, Callable
6
7 1
from flask import Flask, request
8
9 1
from ..definitions import ConstructionWithoutContainer
10 1
from ..interfaces import ExtendableContainer, WriteableContainer
11
12
13 1
class _Request:
14 1
    pass
15
16
17
# Exposing a type to be flask's request
18
# for now it's an any type but later this could be better.
19 1
Request: Any = _Request
20
21
22 1
class FlaskIntegration:
23
    """
24
    Wraps a flask app and a container so that dependencies are provided to
25
    flask routes
26
    """
27
28 1
    flask_app: Flask
29 1
    _container: WriteableContainer
30 1
    _request_singletons: List[Type]
31 1
    _injection_map: Dict[Callable, Callable]
32
33 1
    def __init__(
34
        self,
35
        app: Flask,
36
        container: ExtendableContainer,
37
        request_singletons: Optional[List[Type]] = None,
38
    ):
39
        """
40
41
        :param app: The flask app to provide dependency injection for
42
        :param request_singletons: A list of types that should be singletons for a request
43
        :param container: an existing container to provide dependencies
44
        """
45 1
        self.flask_app = app
46 1
        self._container = container.clone()
47 1
        self._container[Request] = ConstructionWithoutContainer(lambda: request)
48 1
        self._request_singletons = request_singletons or []
49 1
        self._injection_map = {}
50
51 1
    def route(self, rule, **options):
52
        """Equivalent to the flask @route decorator
53
        Injectable arguments should be set by making the default value
54
        lagom.injectable
55
        """
56
57 1
        def _decorator(f):
58 1
            endpoint = options.pop("endpoint", None)
59 1
            if f not in self._injection_map:
60 1
                self._injection_map[f] = self._container.partial(
61
                    f, shared=self._request_singletons
62
                )
63 1
            self.flask_app.add_url_rule(
64
                rule, endpoint, self._injection_map[f], **options
65
            )
66 1
            return f
67
68 1
        return _decorator
69
70 1 View Code Duplication
    def magic_route(self, rule, **options):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
71
        """Equivalent to the flask @route decorator
72
        The injection container will try and bind all arguments
73
        """
74
75
        def _decorator(f):
76
            endpoint = options.pop("endpoint", None)
77
            if f not in self._injection_map:
78
                self._injection_map[f] = self._container.magic_partial(
79
                    f, shared=self._request_singletons
80
                )
81
            self.flask_app.add_url_rule(
82
                rule, endpoint, self._injection_map[f], **options
83
            )
84
            return f
85
86
        return _decorator
87