Skip to content

Commit 8cb8c19

Browse files
thegreatyamorijcalarcon98
authored andcommitted
feat: TT-43 create decorators to add new custom attributes to response
1 parent 844b24c commit 8cb8c19

File tree

4 files changed

+108
-9
lines changed

4 files changed

+108
-9
lines changed

.gitignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,4 @@ migration_status.csv
3838
.DS_Store
3939

4040
# windows env variables
41-
.env.bat
42-
# mac / linux env variables
43-
.env
44-
#PowerShell env variables
45-
.env.ps1
41+
env.*

time_tracker_api/projects/projects_model.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,16 @@
1111
from time_tracker_api.customers.customers_model import (
1212
create_dao as customers_create_dao,
1313
)
14+
from time_tracker_api.project_types.project_types_model import (
15+
create_dao as project_types_create_dao,
16+
)
1417
from time_tracker_api.customers.customers_model import CustomerCosmosDBModel
1518
from utils.query_builder import CosmosDBQueryBuilder
16-
from utils.extend_model import add_customer_name_to_projects
19+
from utils.extend_model import (
20+
add_customer_name_to_projects,
21+
add_custom_attribute_in_list,
22+
add_custom_attribute
23+
)
1724

1825

1926
class ProjectDao(CRUDDao):
@@ -101,9 +108,18 @@ class ProjectCosmosDBDao(APICosmosDBDao, ProjectDao):
101108
def __init__(self, repository):
102109
CosmosDBDao.__init__(self, repository)
103110

104-
def get_all(
105-
self, conditions: dict = None, project_ids: List = None, **kwargs
106-
) -> list:
111+
@add_custom_attribute('customer', customers_create_dao())
112+
@add_custom_attribute('project_type', project_types_create_dao())
113+
def get(self, id) -> ProjectCosmosDBModel:
114+
"""
115+
Get one project an active client
116+
:param (str) id: project's id
117+
"""
118+
return super().get(id)
119+
120+
@add_custom_attribute_in_list('customer', customers_create_dao())
121+
@add_custom_attribute_in_list('project_type', project_types_create_dao())
122+
def get_all(self, conditions: dict = None, project_ids: List = None, **kwargs) -> list:
107123
"""
108124
Get all the projects an active client has
109125
:param (dict) conditions: Conditions for querying the database

time_tracker_api/projects/projects_namespace.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,51 @@
7070
},
7171
)
7272

73+
project_type_nested_field = ns.model('ProjectType', {
74+
'name': fields.String(
75+
title='Name',
76+
required=True,
77+
max_length=50,
78+
description='Name of the project type',
79+
example=faker.random_element(["Customer", "Training", "Internal"]),
80+
),
81+
'description': NullableString(
82+
title='Description',
83+
required=False,
84+
max_length=250,
85+
description='Comments about the project type',
86+
example=faker.paragraph(),
87+
)
88+
})
89+
90+
customer_nested_field = ns.model('Customer', {
91+
'name': fields.String(
92+
title='Name',
93+
required=True,
94+
max_length=50,
95+
description='Name of the customer',
96+
example=faker.company(),
97+
),
98+
'description': NullableString(
99+
title='Description',
100+
required=False,
101+
max_length=250,
102+
description='Description about the customer',
103+
example=faker.paragraph(),
104+
)
105+
})
106+
73107
project_response_fields = {
108+
# TODO: Remove this DEAD CODE
74109
'customer_name': fields.String(
75110
required=True,
76111
title='Customer Name',
77112
max_length=50,
78113
description='Name of the customer of the project',
79114
example=faker.company(),
80115
),
116+
'customer': fields.Nested(customer_nested_field),
117+
'project_type': fields.Nested(project_type_nested_field),
81118
}
82119
project_response_fields.update(common_fields)
83120

utils/extend_model.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,56 @@
1+
from functools import wraps
12
import re
23

34

5+
def add_custom_attribute(attr, dao):
6+
"""
7+
Decorator to add an custom attribute in model, based on entity's id
8+
:param (attr) attribute: name of the new attribute
9+
:param (dao) dao: related entity to the model
10+
"""
11+
def decorator_for_single_item(func):
12+
@wraps(func)
13+
def wrapper(*args, **kwargs):
14+
entity_model = func(*args, **kwargs)
15+
attribute_id = f"{attr}_id"
16+
value_id = entity_model.__dict__[attribute_id]
17+
18+
try:
19+
related_entity = dao.get(value_id)
20+
setattr(entity_model, attr, related_entity)
21+
except:
22+
print(f"This item isn't related a {attribute_id}")
23+
24+
return entity_model
25+
return wrapper
26+
return decorator_for_single_item
27+
28+
29+
def add_custom_attribute_in_list(attr, dao):
30+
"""
31+
Decorator to add an custom attribute in model_list, based on entity's id
32+
:param (attr) attribute: name of the new attribute
33+
:param (dao) dao: related entity to the model
34+
"""
35+
def decorator_for_list_item(func):
36+
@wraps(func)
37+
def wrapper(*args, **kwargs):
38+
entity_model_list = func(*args, **kwargs)
39+
attribute_id = f"{attr}_id"
40+
41+
related_entity_list = dao.get_all()
42+
related_entities_ids_dict = {x.id: x for x in related_entity_list}
43+
44+
for entity_model in entity_model_list:
45+
value_id = entity_model.__dict__[attribute_id]
46+
setattr(entity_model, attr,
47+
related_entities_ids_dict.get(value_id))
48+
49+
return entity_model_list
50+
return wrapper
51+
return decorator_for_list_item
52+
53+
454
def add_customer_name_to_projects(projects, customers):
555
"""
656
Add attribute customer_name in project model, based on customer_id of the

0 commit comments

Comments
 (0)