Passed
Push — master ( 38bed0...e25529 )
by torrua
01:14
created

app.api.views   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 92
dl 0
loc 139
rs 10
c 0
b 0
f 0

4 Functions

Rating   Name   Duplication   Size   Complexity  
A create_blueprint_data() 0 12 2
A separate_arguments() 0 9 3
C universal_get() 0 63 10
A get_api_properties() 0 7 1
1
import os
2
from distutils.util import strtobool
3
4
from flask import request, Blueprint, Response, json
5
6
from app.engine import Session
7
from app.api.schemas.author import blue_print_export as bp_author
8
from app.api.schemas.definition import blue_print_export as bp_definition
9
from app.api.schemas.event import blue_print_export as bp_event
10
from app.api.schemas.key import blue_print_export as bp_key
11
from app.api.schemas.setting import blue_print_export as bp_setting
12
from app.api.schemas.syllable import blue_print_export as bp_syllable
13
from app.api.schemas.type import blue_print_export as bp_type
14
from app.api.schemas.word import blue_print_export as bp_word
15
16
API_PATH = os.getenv("API_PATH", "/api")
17
API_VERSION = os.getenv("API_VERSION", "/v1")
18
19
20
def universal_get(session, schema_full, schema_nested, model, many: bool = True):
21
    """
22
    Return entity from DB through GET request
23
    :param session:
24
    :param schema_full:
25
    :param schema_nested:
26
    :param model:
27
    :param many:
28
    :return:
29
    """
30
    args = {**request.args}
31
32
    detailed = bool(strtobool(args.pop("detailed", "False")))
33
    event_id = args.pop("event_id", None)
34
    case_sensitive = bool(strtobool(args.pop("case_sensitive", "False")))
35
    model_args, skipped_args = separate_arguments(model, args)
36
    model_query = session.query(model)
37
38
    # TODO REFACTORING
39
    api_section = request.path.strip("/").split("/")[-1]
40
    if event_id and (api_section in ["words", "keys"]):
41
        model_query = model.by_event(event_id=int(event_id))
42
43
    if model_args:
44
        for attr, value in model_args.items():
45
            if str(value).isdigit():
46
                value = int(value)
47
                model_query = model_query.filter(getattr(model, attr) == value)
48
                continue
49
50
            value = value.replace("*", "%")
51
            name_attr = getattr(model, attr)
52
            name_filter = (
53
                name_attr.like(value) if case_sensitive else name_attr.ilike(value)
54
            )
55
56
            model_query = model_query.filter(name_filter)
57
58
    model_entities = model_query.all() if many else model_query.first()
59
    count = (
60
        len(model_entities)
61
        if many
62
        else len(
63
            [
64
                model_entities,
65
            ]
66
        )
67
    )
68
69
    schema = schema_full if detailed else schema_nested
70
    data = schema.dump(model_entities, many=many)
71
72
    return Response(
73
        mimetype="application/json",
74
        response=json.dumps(
75
            {
76
                "result": True,
77
                "data": data,
78
                "count": count,
79
                "skipped_arguments": skipped_args,
80
            }
81
        ),
82
        status=200,
83
    )
84
85
86
def separate_arguments(model, args):
87
    skipped_args = {}
88
    model_args = {}
89
    for parameter, value in args.items():
90
        if parameter in model.attributes_all():
91
            model_args[parameter] = value
92
        else:
93
            skipped_args[parameter] = value
94
    return model_args, skipped_args
95
96
97
def get_api_properties(entity):
98
    entity_name = entity.__tablename__.lower().removesuffix("s")
99
    section_name = f"/{entity_name}s"
100
    api_name = f"{entity_name}_api"
101
    blueprint = Blueprint(api_name, __name__)
102
    data = (blueprint, section_name)
103
    return blueprint, data
104
105
106
def create_blueprint_data(session, entity, schema_nested, schema_full):
107
    api_blueprint, api_data = get_api_properties(entity)
108
109
    @api_blueprint.route("/", methods=["GET"])
110
    def entity_get():
111
        """
112
        Get Entity by Entity's parameters Function
113
        """
114
        with session:
115
            return universal_get(session, schema_full, schema_nested, entity)
116
117
    return api_data
118
119
120
dictionary_bp_data = [
121
    bp_author,
122
    bp_definition,
123
    bp_event,
124
    bp_key,
125
    bp_setting,
126
    bp_syllable,
127
    bp_type,
128
    bp_word,
129
]
130
131
with Session() as app_session:
132
    dictionary_api_data = [
133
        create_blueprint_data(app_session, *data) for data in dictionary_bp_data
134
    ]
135
136
blueprints = [
137
    {"blueprint": api[0], "url_prefix": f"{API_PATH}{API_VERSION}{api[1]}"}
138
    for api in dictionary_api_data
139
]
140