lagom.integrations.flask   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 87
Duplicated Lines 19.54 %

Test Coverage

Coverage 79.41%

Importance

Changes 0
Metric Value
wmc 6
eloc 43
dl 17
loc 87
ccs 27
cts 34
cp 0.7941
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A FlaskIntegration.__init__() 0 17 2
A FlaskIntegration.magic_route() 17 17 2
A FlaskIntegration.route() 0 18 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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