Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: TT-43 create decorators to add new custom attributes to response
  • Loading branch information
thegreatyamori authored and jcalarcon98 committed May 28, 2021
commit 8cb8c194f2760c079eda34e37efb459a84f52187
6 changes: 1 addition & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,4 @@ migration_status.csv
.DS_Store

# windows env variables
.env.bat
# mac / linux env variables
.env
#PowerShell env variables
.env.ps1
env.*
24 changes: 20 additions & 4 deletions time_tracker_api/projects/projects_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@
from time_tracker_api.customers.customers_model import (
create_dao as customers_create_dao,
)
from time_tracker_api.project_types.project_types_model import (
create_dao as project_types_create_dao,
)
from time_tracker_api.customers.customers_model import CustomerCosmosDBModel
from utils.query_builder import CosmosDBQueryBuilder
from utils.extend_model import add_customer_name_to_projects
from utils.extend_model import (
add_customer_name_to_projects,
add_custom_attribute_in_list,
add_custom_attribute
)


class ProjectDao(CRUDDao):
Expand Down Expand Up @@ -101,9 +108,18 @@ class ProjectCosmosDBDao(APICosmosDBDao, ProjectDao):
def __init__(self, repository):
CosmosDBDao.__init__(self, repository)

def get_all(
self, conditions: dict = None, project_ids: List = None, **kwargs
) -> list:
@add_custom_attribute('customer', customers_create_dao())
@add_custom_attribute('project_type', project_types_create_dao())
def get(self, id) -> ProjectCosmosDBModel:
"""
Get one project an active client
:param (str) id: project's id
"""
return super().get(id)

@add_custom_attribute_in_list('customer', customers_create_dao())
@add_custom_attribute_in_list('project_type', project_types_create_dao())
def get_all(self, conditions: dict = None, project_ids: List = None, **kwargs) -> list:
"""
Get all the projects an active client has
:param (dict) conditions: Conditions for querying the database
Expand Down
37 changes: 37 additions & 0 deletions time_tracker_api/projects/projects_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,51 @@
},
)

project_type_nested_field = ns.model('ProjectType', {
'name': fields.String(
title='Name',
required=True,
max_length=50,
description='Name of the project type',
example=faker.random_element(["Customer", "Training", "Internal"]),
),
'description': NullableString(
title='Description',
required=False,
max_length=250,
description='Comments about the project type',
example=faker.paragraph(),
)
})

customer_nested_field = ns.model('Customer', {
'name': fields.String(
title='Name',
required=True,
max_length=50,
description='Name of the customer',
example=faker.company(),
),
'description': NullableString(
title='Description',
required=False,
max_length=250,
description='Description about the customer',
example=faker.paragraph(),
)
})

project_response_fields = {
# TODO: Remove this DEAD CODE
'customer_name': fields.String(
required=True,
title='Customer Name',
max_length=50,
description='Name of the customer of the project',
example=faker.company(),
),
'customer': fields.Nested(customer_nested_field),
'project_type': fields.Nested(project_type_nested_field),
}
project_response_fields.update(common_fields)

Expand Down
50 changes: 50 additions & 0 deletions utils/extend_model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
from functools import wraps
import re


def add_custom_attribute(attr, dao):
"""
Decorator to add an custom attribute in model, based on entity's id
:param (attr) attribute: name of the new attribute
:param (dao) dao: related entity to the model
"""
def decorator_for_single_item(func):
@wraps(func)
def wrapper(*args, **kwargs):
entity_model = func(*args, **kwargs)
attribute_id = f"{attr}_id"
value_id = entity_model.__dict__[attribute_id]

try:
related_entity = dao.get(value_id)
setattr(entity_model, attr, related_entity)
except:
print(f"This item isn't related a {attribute_id}")

return entity_model
return wrapper
return decorator_for_single_item


def add_custom_attribute_in_list(attr, dao):
"""
Decorator to add an custom attribute in model_list, based on entity's id
:param (attr) attribute: name of the new attribute
:param (dao) dao: related entity to the model
"""
def decorator_for_list_item(func):
@wraps(func)
def wrapper(*args, **kwargs):
entity_model_list = func(*args, **kwargs)
attribute_id = f"{attr}_id"

related_entity_list = dao.get_all()
related_entities_ids_dict = {x.id: x for x in related_entity_list}

for entity_model in entity_model_list:
value_id = entity_model.__dict__[attribute_id]
setattr(entity_model, attr,
related_entities_ids_dict.get(value_id))

return entity_model_list
return wrapper
return decorator_for_list_item


def add_customer_name_to_projects(projects, customers):
"""
Add attribute customer_name in project model, based on customer_id of the
Expand Down