From 90d761996624ece0645113a4d369a4673a646f84 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Fri, 11 Mar 2022 17:12:55 -0500 Subject: [PATCH] Added new route, methods, and models for data_store. Also minor code clean up and less debug. --- app/main.py | 7 +- app/methods/data_store_methods.py | 262 ++++++++++++++++++++++++++++++ app/models/common_field_schema.py | 1 + app/models/data_store_models.py | 121 ++++++++++++++ app/models/event_device_models.py | 13 +- app/routers/data_store.py | 212 ++++++++++++++++++++++++ app/routers/event_file.py | 4 +- app/routers/hosted_file.py | 6 +- 8 files changed, 608 insertions(+), 18 deletions(-) create mode 100644 app/methods/data_store_methods.py create mode 100644 app/models/data_store_models.py create mode 100644 app/routers/data_store.py diff --git a/app/main.py b/app/main.py index ce16c09..87aa3c1 100644 --- a/app/main.py +++ b/app/main.py @@ -18,7 +18,7 @@ from . import config from app.log import log, logging # Import the routers here first: -from app.routers import api_crud, api, importing, account, activity_log, address, archive, archive_content, contact, cont_edu_cert, cont_edu_cert_person, event, event_badge, event_badge_template, event_device, event_exhibit, event_exhibit_tracking, event_file, event_importing, event_location, event_person, event_person_detail, event_person_tracking, event_presentation, event_presenter, event_registration, event_session, flask_cfg, hosted_file, journal, journal_entry, log_client_viewing, lookup, membership_cfg, membership_group, membership_person_group, membership_person, membership_person_profile, membership_type, membership_person_type, order, order_v3, order_line, order_cart, organization, page, person, person_user, post, post_comment, product, site, site_domain, user, websockets, e_cvent, c_idaa, e_impexium +from app.routers import api_crud, api, importing, account, activity_log, address, archive, archive_content, contact, cont_edu_cert, cont_edu_cert_person, data_store, event, event_badge, event_badge_template, event_device, event_exhibit, event_exhibit_tracking, event_file, event_importing, event_location, event_person, event_person_detail, event_person_tracking, event_presentation, event_presenter, event_registration, event_session, flask_cfg, hosted_file, journal, journal_entry, log_client_viewing, lookup, membership_cfg, membership_group, membership_person_group, membership_person, membership_person_profile, membership_type, membership_person_type, order, order_v3, order_line, order_cart, organization, page, person, person_user, post, post_comment, product, site, site_domain, user, websockets, e_cvent, c_idaa, e_impexium from app.db_sql import db @@ -117,6 +117,11 @@ app.include_router( cont_edu_cert_person.router, tags=['Cont Edu Cert Person'], ) +app.include_router( + data_store.router, + prefix='/data_store', + tags=['Data Store'], +) app.include_router( event.router, # prefix='/event', diff --git a/app/methods/data_store_methods.py b/app/methods/data_store_methods.py new file mode 100644 index 0000000..e857694 --- /dev/null +++ b/app/methods/data_store_methods.py @@ -0,0 +1,262 @@ +import datetime + +from typing import Dict, List, Optional, Set, Union +from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator + +from app.db_sql import redis_lookup_id_random, sql_enable_part, sql_insert, sql_limit_offset_part, sql_select, sql_update +from app.lib_general import log, logging, logger_reset + +from app.methods.event_cfg_methods import load_event_cfg_obj +from app.methods.event_location_methods import load_event_location_obj + +from app.models.common_field_schema import default_num_bytes +from app.models.data_store_models import Data_Store_Base + + +# ### BEGIN ### API Data Store Methods ### load_data_store_obj() ### +# Updated 2022-03-11 +@logger_reset +def load_data_store_obj( + data_store_id: int, + enabled: str = 'enabled', # enabled, disabled, all + limit: int = 10, + offset: int = 0, + by_alias: bool = True, + exclude_unset: bool = True, + model_as_dict: bool = False, + ) -> Data_Store_Base|dict|bool: + log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + if data_store_rec := sql_select(table_name='v_data_store', record_id=data_store_id): pass + else: return False + + log.debug(data_store_rec) + + try: + data_store_obj = Data_Store_Base(**data_store_rec) + except ValidationError as e: + log.error(e.json()) + return False + log.debug(data_store_obj) + + if model_as_dict: + return data_store_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) # pylint: disable=no-member + else: + return data_store_obj +# ### END ### API Data Store Methods ### load_data_store_obj() ### + + +# ### BEGIN ### API Data Store Methods ### load_data_store_obj_w_code() ### +# NOTE: This is customized to look for records with or without an account_id and some code. By default only the first sorted result will be returned. +# NOTE: By default the first sorted result should be the one for a specific account with some code. If a result with a null account_id and some code is found it will be returned if no account_id specific results are found. +# Updated 2022-03-11 +@logger_reset +def load_data_store_obj_w_code( + account_id: int, + code: str, + enabled: str = 'enabled', # enabled, disabled, all + limit: int = 1, + offset: int = 0, + by_alias: bool = True, # NOTE: For now this is ignored + exclude_unset: bool = True, # NOTE: For now this is ignored + model_as_dict: bool = False, # NOTE: For now this is ignored + ) -> Data_Store_Base|dict|bool: + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + data = {} + data['account_id'] = account_id + data['code'] = code + + sql_enabled, data['enable'] = sql_enable_part(table_name='data_store', enabled=enabled) # Reasonably safe return str and bool + sql_limit = sql_limit_offset_part(limit=limit, offset=offset) # Reasonably safe return str + + log.debug(data) + + sql = f""" + SELECT * + FROM `v_data_store` AS `data_store` + WHERE + ( + `data_store`.account_id = :account_id + OR `data_store`.account_id IS NULL + ) + AND `data_store`.code = :code + {sql_enabled} + ORDER BY `data_store`.account_id DESC, `data_store`.created_on DESC, `data_store`.updated_on DESC + {sql_limit}; + """ + log.debug(sql) + + if data_store_rec_li_result := sql_select(data=data, sql=sql, as_list=True): + data_store_rec_li = data_store_rec_li_result + else: # [] or False + data_store_rec_li = data_store_rec_li_result + + log.debug(data_store_rec_li_result) + + data_store_obj_li = [] + if data_store_rec_li: + for data_store_rec in data_store_rec_li: + try: + data_store_obj = Data_Store_Base(**data_store_rec) + data_store_obj_li.append(data_store_obj) + except ValidationError as e: + log.error(e.json()) + data_store_obj_li.append(None) + # return False + log.debug(data_store_obj) + else: pass + + log.debug(data_store_obj_li) + return data_store_obj_li + + # if model_as_dict: + # return data_store_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) # pylint: disable=no-member + # else: + # return data_store_obj +# ### END ### API Data Store Methods ### load_data_store_obj_w_code() ### + + +# ### BEGIN ### API Data Store Methods ### get_data_store_rec_list() ### +# Updated 2022-03-11 +@logger_reset +def get_data_store_rec_list( + account_id: int, + for_type: str, # 'account' is a special case + for_id: int, + person_id: int = None, + user_id: int = None, + code: str = None, + enabled: str = 'enabled', # enabled, disabled, all + limit: int = 100, + offset: int = 0, + ) -> list|bool: + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + # if for_type and for_id: + # if for_id := redis_lookup_id_random(record_id_random=for_id, table_name=for_type): pass + # else: return False + + if account_id: + sql_account_id = f'`data_store`.account_id = :account_id' + # if code: + # sql_code = f'`data_store`.code = :code' + + data = {} + data['account_id'] = account_id + data['code'] = code + # data['for_type'] = for_type + # data['for_id'] = for_id + + sql_enabled, data['enable'] = sql_enable_part(table_name='data_store', enabled=enabled) # Reasonably safe return str and bool + sql_limit = sql_limit_offset_part(limit=limit, offset=offset) # Reasonably safe return str + + sql = f""" + SELECT `data_store`.id AS 'data_store_id', `data_store`.id_random AS 'data_store_id_random' + FROM `v_data_store` AS `data_store` + WHERE + {sql_account_id} + + {sql_enabled} + ORDER BY `data_store`.created_on DESC, `data_store`.updated_on DESC + {sql_limit}; + """ + log.debug(sql) + + if data_store_rec_li_result := sql_select(data=data, sql=sql, as_list=True): + data_store_rec_li = data_store_rec_li_result + else: # [] or False + data_store_rec_li = data_store_rec_li_result + + log.debug(data_store_rec_li_result) + + return data_store_rec_li +# ### END ### API Data Store Methods ### get_data_store_rec_list() ### + + +# ### BEGIN ### API Data Store Methods ### create_update_data_store_obj() ### +# Updated 2022-03-11 +def create_update_data_store_obj( + data_store_dict_obj: Data_Store_Base|dict, + data_store_id: int|str = None, + create_sub_obj: bool = False, + fail_any: bool = False, # Fail if any thing goes wrong for sub objects + return_outline: bool = False, + ) -> int|bool: + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + # ### SECTION ### Secondary data validation + log.info('Checking requirements...') + if data_store_id: + log.info(f'Data Store ID passed. Update existing Data Store. Data Store ID: {data_store_id}') + + if data_store_id := redis_lookup_id_random(record_id_random=data_store_id, table_name='data_store'): pass + else: + log.error('Data Store ID passed but is invalid. Failed requirement.') + return False + else: + log.info('No Data Store ID passed. Create new Data Store. Required: None; Optional: Account ID, For Type, For ID, Person ID, User ID') + + if account_id := redis_lookup_id_random(record_id_random=account_id, table_name='account'): pass + elif account_id is None: pass + else: + log.warning('Missing or invalid Account ID passed. Failed requirement.') + log.info(f'Account ID: {account_id}') + return False + + log.info('Create dictionary or Pydantic object') + log.debug(type(data_store_dict_obj)) + if isinstance(data_store_dict_obj, dict): + data_store_dict = data_store_dict_obj + if data_store_id: + data_store_dict['data_store_id'] = data_store_id + if account_id: + account_dict['account_id'] = account_id + try: + data_store_obj = Data_Store_Base(**data_store_dict) + except ValidationError as e: + log.error(e.json()) + return False + else: + data_store_obj = data_store_dict_obj + if data_store_id: + # NOTE: Can't update the ID alias if it was never set. + data_store_obj.id = data_store_id + if account_id: + data_store_obj.account_id = account_id + log.debug(data_store_obj) + + data_store_dict = data_store_obj.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'account', 'created_on', 'updated_on'}) + + # ### SECTION ### Process data + if data_store_id: + if data_store_dict_up_result := sql_update(data=data_store_dict, table_name='data_store', rm_id_random=True): pass + else: + log.warning(f'Data Store not updated. Data Store ID: {data_store_id}') + log.debug(data_store_dict_up_result) + return False + log.debug(data_store_dict_up_result) + else: + if data_store_dict_in_result := sql_insert(data=data_store_dict, table_name='data_store', rm_id_random=True, id_random_length=8): pass + else: + log.warning(f'Data Store not created.') + log.debug(data_store_dict_in_result) + return False + log.debug(data_store_dict_in_result) + + data_store_id = data_store_dict_in_result + + data_store_outline = {} + data_store_outline['data_store_id'] = data_store_id + + if return_outline: + log.debug(f'Returning the Data Store Outline: {data_store_outline}') + return data_store_outline + else: + log.debug(f'Returning the Data Store ID: {data_store_id}') + return data_store_id +# ### END ### API Data Store Methods ### create_update_data_store_obj() ### diff --git a/app/models/common_field_schema.py b/app/models/common_field_schema.py index 81ea072..7fd6790 100644 --- a/app/models/common_field_schema.py +++ b/app/models/common_field_schema.py @@ -31,6 +31,7 @@ base_fields['archive_content_id_random'] = xxx_id_random_field_schema base_fields['contact_id_random'] = xxx_id_random_field_schema base_fields['cont_edu_cert_id_random'] = xxx_id_random_field_schema base_fields['cont_edu_cert_person_id_random'] = xxx_id_random_field_schema +base_fields['data_store_id_random'] = xxx_id_random_field_schema base_fields['event_exhibit_id_random'] = xxx_id_random_field_schema base_fields['event_exhibit_tracking_id_random'] = xxx_id_random_field_schema base_fields['event_file_id_random'] = xxx_id_random_field_schema diff --git a/app/models/data_store_models.py b/app/models/data_store_models.py new file mode 100644 index 0000000..4d9d7fe --- /dev/null +++ b/app/models/data_store_models.py @@ -0,0 +1,121 @@ +import datetime, hashlib, logging, os, pytz, redis, secrets + +from typing import Dict, List, Optional, Set, Union +from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator + +from app.db_sql import redis_lookup_id_random +from app.lib_general import log, logging + +from app.models.common_field_schema import base_fields, default_num_bytes + + +# ### BEGIN ### API Data Store Models ### Data_Store_Base() ### +class Data_Store_Base(BaseModel): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + id_random: Optional[str] = Field( + **base_fields['data_store_id_random'], + alias = 'data_store_id_random', + default_factory = lambda:secrets.token_urlsafe(default_num_bytes), + ) + id: Optional[int] = Field( + alias = 'data_store_id' + ) + + account_id_random: Optional[str] + account_id: Optional[int] + + for_type: Optional[str] + for_id_random: Optional[str] + for_id: Optional[int] + + person_id_random: Optional[str] + person_id: Optional[int] + + user_id_random: Optional[str] + user_id: Optional[int] + + code: Optional[str] + + name: Optional[str] + description: Optional[str] + + # json: Optional[str] # "json" is reserved; need to change field name? json_str? + text: Optional[str] + meta_json: Optional[str] + meta_text: Optional[str] + + enable: Optional[bool] + + hide: Optional[bool] + priority: Optional[bool] + sort: Optional[int] + group: Optional[str] + + notes: Optional[str] + + created_on: Optional[datetime.datetime] = None + updated_on: Optional[datetime.datetime] = None + + # Including convenience data + # This is only for convenience. Probably going to keep unless it causes a problem. + + # Including JSON data + # other_json: Optional[Json] + # meta_json: Optional[Json] + + # Including other related objects + + _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) + + #@validator('data_store_id_random', always=True) + def data_store_id_random_copy(cls, v, values, **kwargs): + if values['id_random']: + return values['id_random'] + return None + + @validator('id', always=True) + def data_store_id_lookup(cls, v, values, **kwargs): + if isinstance(v, int) and v > 0: return v + elif id_random := values.get('id_random'): + return redis_lookup_id_random(record_id_random=id_random, table_name='data_store') + return None + + @validator('account_id', always=True) + def account_id_lookup(cls, v, values, **kwargs): + if isinstance(v, int) and v > 0: return v + elif id_random := values.get('account_id_random'): + return redis_lookup_id_random(record_id_random=id_random, table_name='account') + return None + + @validator('for_id', always=True) + def for_id_lookup(cls, v, values, **kwargs): + log.setLevel(logging.WARNING) + log.debug(locals()) + if isinstance(v, int) and v > 0: return v + elif values.get('for_id_random') and values.get('for_type'): + for_id_random = values.get('for_id_random') + for_type = values.get('for_type') + return redis_lookup_id_random(record_id_random=for_id_random, table_name=for_type) + return None + + @validator('person_id', always=True) + def person_id_lookup(cls, v, values, **kwargs): + if isinstance(v, int) and v > 0: return v + elif id_random := values.get('person_id_random'): + return redis_lookup_id_random(record_id_random=id_random, table_name='person') + return None + + @validator('user_id', always=True) + def user_id_lookup(cls, v, values, **kwargs): + if isinstance(v, int) and v > 0: return v + elif id_random := values.get('user_id_random'): + return redis_lookup_id_random(record_id_random=id_random, table_name='user') + return None + + class Config: + underscore_attrs_are_private = True + allow_population_by_field_name = True + fields = base_fields +# ### END ### API Data Store Models ### Data_Store_Base() ### diff --git a/app/models/event_device_models.py b/app/models/event_device_models.py index c4331c9..9160de6 100644 --- a/app/models/event_device_models.py +++ b/app/models/event_device_models.py @@ -23,6 +23,7 @@ class Event_Device_Base(BaseModel): id: Optional[int] = Field( alias = 'event_device_id' ) + account_id_random: Optional[str] account_id: Optional[int] @@ -79,9 +80,6 @@ class Event_Device_Base(BaseModel): @validator('id', always=True) def event_device_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - if isinstance(v, int) and v > 0: return v elif id_random := values.get('id_random'): return redis_lookup_id_random(record_id_random=id_random, table_name='event_device') @@ -89,9 +87,6 @@ class Event_Device_Base(BaseModel): @validator('account_id', always=True) def account_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - if isinstance(v, int) and v > 0: return v elif id_random := values.get('account_id_random'): return redis_lookup_id_random(record_id_random=id_random, table_name='account') @@ -99,9 +94,6 @@ class Event_Device_Base(BaseModel): @validator('event_id', always=True) def event_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - if isinstance(v, int) and v > 0: return v elif id_random := values.get('event_id_random'): return redis_lookup_id_random(record_id_random=id_random, table_name='event') @@ -109,9 +101,6 @@ class Event_Device_Base(BaseModel): @validator('event_location_id', always=True) def event_location_id_lookup(cls, v, values, **kwargs): - log.setLevel(logging.WARNING) - log.debug(locals()) - if isinstance(v, int) and v > 0: return v elif id_random := values.get('event_location_id_random'): return redis_lookup_id_random(record_id_random=id_random, table_name='event_location') diff --git a/app/routers/data_store.py b/app/routers/data_store.py new file mode 100644 index 0000000..e0245f0 --- /dev/null +++ b/app/routers/data_store.py @@ -0,0 +1,212 @@ +import datetime, pytz, time +from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, Response, status +from pydantic import BaseModel, EmailStr, Field +from typing import Dict, List, Optional, Set, Union + +from app.lib_general import log, logging, common_route_params, Common_Route_Params +from app.config import settings +from app.db_sql import sql_insert, sql_update, sql_insert_or_update, sql_select, sql_delete, get_id_random, redis_lookup_id_random + +from app.routers.api_crud import delete_obj_template, get_obj_template, get_obj_li_template, patch_obj_template, post_obj_template + +from app.methods.data_store_methods import create_update_data_store_obj, get_data_store_rec_list, load_data_store_obj, load_data_store_obj_w_code + +from app.models.common_field_schema import default_num_bytes +from app.models.data_store_models import Data_Store_Base +from app.models.response_models import Resp_Body_Base, mk_resp + + +router = APIRouter() + + +# ### BEGIN ### API Data Store Routers ### post_data_store_obj() ### +# Updated 2022-03-11 +@router.post('/data_store', response_model=Resp_Body_Base) +async def post_data_store_obj( + data_store_obj: Data_Store_Base, + + return_obj: bool = True, + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + # ### SECTION ### Secondary data validation + # None + + # ### SECTION ### Process data + if data_store_id := create_update_data_store_obj( + data_store_dict_obj = data_store_obj, + ): pass + else: + log.warning('Likely bad request') + return mk_resp(data=False, status_code=400, response=commons.response, status_message='Not created. Something failed while processing the data. Check the field names and data types.') # Bad Request + + # ### SECTION ### Return successful results + if return_obj: + data_store_obj = load_data_store_obj( + data_store_id = data_store_id, + inc_event_cfg = inc_event_cfg, + inc_event_location = inc_event_location, + ) + data = data_store_obj + else: + data_store_id_random = get_id_random(record_id=data_store_id, table_name='data_store') + data = {} + data['data_store_id'] = data_store_id + data['data_store_id_random'] = data_store_id_random + return mk_resp(data=data, response=commons.response) +# ### END ### API Data Store Routers ### post_data_store_obj() ### + + +# ### BEGIN ### API Data Store Routers ### patch_data_store_obj() ### +# Updated 2022-03-11 +@router.patch('/data_store/{data_store_id}', response_model=Resp_Body_Base) +async def patch_data_store_obj( + data_store_obj: Data_Store_Base, + data_store_id: str = Query(..., min_length=11, max_length=22), + + return_obj: Optional[bool] = True, + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + # ### SECTION ### Secondary data validation + data_store_id_random = data_store_id # This is used later for the response data + if data_store_id := redis_lookup_id_random(record_id_random=data_store_id, table_name='data_store'): pass + else: return mk_resp(data=None, status_code=404, response=commons.response, status_message='The Data Store ID was invalid or not found.') + + # ### SECTION ### Process data + if data_store_up_result := create_update_data_store_obj( + data_store_dict_obj = data_store_obj, + data_store_id = data_store_id, + ): pass + else: + log.warning('Likely bad request') + return mk_resp(data=False, status_code=400, response=commons.response, status_message='Not updated. Something failed while processing the data. Check the field names and data types.') # Bad Request + + # ### SECTION ### Return successful results + if return_obj: + data_store_obj = load_data_store_obj( + data_store_id = data_store_id, + ) + data = data_store_obj + else: + data = {} + data['data_store_id'] = data_store_id + data['data_store_id_random'] = data_store_id_random + return mk_resp(data=data, response=commons.response) +# ### END ### API Data Store Routers ### patch_data_store_obj() ### + + +# ### BEGIN ### API Data Store ### get_data_store_obj() ### +# Updated 2022-03-11 +@router.get('/data_store/{data_store_id}', response_model=Resp_Body_Base) +async def get_data_store_obj( + data_store_id: str = Query(..., min_length=11, max_length=22), + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + # ### SECTION ### Secondary data validation + if data_store_id := redis_lookup_id_random(record_id_random=data_store_id, table_name='data_store'): pass + else: return mk_resp(data=None, status_code=404, response=commons.response) + + if data_store_rec_result := load_data_store_obj( + data_store_id = data_store_id, + limit = commons.limit, + enabled = commons.enabled, + inc_event_cfg = inc_event_cfg, + inc_event_location = inc_event_location, + ): + log.info('Loading successful. Returning result') + return mk_resp(data=data_store_rec_result, response=commons.response) + elif isinstance(data_store_rec_result, list) or data_store_rec_result is None: # Empty list or None + log.info('No results') + return mk_resp(data=None, status_code=404, response=commons.response) # Not Found + else: + log.warning('Likely bad request') + return mk_resp(data=False, status_code=400, response=commons.response) # Bad Request +# ### END ### API Data Store ### get_data_store_obj() ### + + +# ### BEGIN ### API Data Store ### get_data_store_obj_w_code() ### +# Updated 2022-03-11 +@router.get('/data_store/code/{data_store_code}', response_model=Resp_Body_Base) +async def get_data_store_obj_w_code( + data_store_code: str = Query(..., min_length=3, max_length=50), + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + # ### SECTION ### Secondary data validation + # None + + # NOTE: Currently this returns a list: load_data_store_obj_w_code() + # NOTE: Only the first sorted record is needed + if data_store_obj_result := load_data_store_obj_w_code( + account_id = commons.x_account_id, + code = data_store_code, + limit = 1, # commons.limit, + enabled = commons.enabled, + ): + log.info('Loading successful. Returning result') + data_store_obj = data_store_obj_result[0] # Get first record only + return mk_resp(data=data_store_obj, response=commons.response) + elif isinstance(data_store_obj_result, list) or data_store_obj_result is None: # Empty list or None + log.info('No results') + return mk_resp(data=None, status_code=404, response=commons.response) # Not Found + else: + log.warning('Likely bad request') + return mk_resp(data=False, status_code=400, response=commons.response) # Bad Request +# ### END ### API Data Store ### get_data_store_obj_w_code() ### + + +# ### BEGIN ### API Data Store ### get_account_obj_data_store_list() ### +# Updated 2022-03-11 +@router.get('/account/{account_id}/data_store/list', response_model=Resp_Body_Base) +async def get_account_obj_data_store_list( + account_id: str = Query(..., min_length=11, max_length=22), + + commons: Common_Route_Params = Depends(common_route_params), + ): + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.debug(locals()) + + if account_id := redis_lookup_id_random(record_id_random=account_id, table_name='account'): pass + else: return mk_resp(data=None, status_code=404, response=commons.response) + + # Updated 2022-03-11 + if data_store_rec_list_result := get_data_store_rec_list( + account_id = account_id, + for_type = 'account', + for_id = account_id, + enabled = commons.enabled, + limit = commons.limit, + offset = commons.offset, + ): + data_store_result_list = [] + for data_store_rec in data_store_rec_list_result: + if load_data_store_result := load_data_store_obj( + data_store_id = data_store_rec.get('data_store_id', None), + enabled = commons.enabled, + ): + data_store_result_list.append(load_data_store_result) + else: + data_store_result_list.append(None) + response_data = data_store_result_list + return mk_resp(data=response_data, response=commons.response) + elif isinstance(data_store_rec_list_result, list) or data_store_rec_list_result is None: # Empty list or None + log.info('No results') + return mk_resp(data=None, status_code=404, response=commons.response) # Not Found + else: + log.warning('Likely bad request') + return mk_resp(data=False, status_code=400, response=commons.response) # Bad Request +# ### END ### API Data Store ### get_account_obj_data_store_list() ### diff --git a/app/routers/event_file.py b/app/routers/event_file.py index bff6485..c06be82 100644 --- a/app/routers/event_file.py +++ b/app/routers/event_file.py @@ -136,7 +136,7 @@ async def download_event_file( commons: Common_Route_Params = Depends(common_route_params), ): - log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) # ### SECTION ### Secondary data validation @@ -192,7 +192,7 @@ async def get_event_file_obj( exclude_unset: bool = True, response: Response = Response, ): - log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if event_file_id := redis_lookup_id_random(record_id_random=event_file_id, table_name='event_file'): pass diff --git a/app/routers/hosted_file.py b/app/routers/hosted_file.py index 72b2068..913fbf5 100644 --- a/app/routers/hosted_file.py +++ b/app/routers/hosted_file.py @@ -168,7 +168,7 @@ async def upload_files_fake( exclude_unset: bool = True, response: Response = Response, ): - log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.debug(file_info_li) @@ -409,7 +409,7 @@ async def get_hosted_file_obj( exclude_unset: Optional[bool] = True, response: Response = Response, ): - log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if hosted_file_id := redis_lookup_id_random(record_id_random=hosted_file_id, table_name='hosted_file'): pass @@ -440,7 +440,7 @@ async def download_tmp( exclude_unset: Optional[bool] = True, response: Response = Response, ): - log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL + log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) full_dest_path = 'admin/temp/order_line/order_line_list_2021-11-23_1310.xlsx'