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, Response, status from app.config import settings from app.models.common_field_schema import base_fields, default_num_bytes # ### BEGIN ### API Response Model ### Resp_Body_Base() ### # The pydantic BaseModel to help make consistent REST responses. # Updated 2021-03-05 class Resp_Body_Base(BaseModel): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) # test_prop: Optional[str] = Field( # alias = 'test_prop_alias' # ) data: Union[list, dict] meta: Optional[dict] # ### END ### API Response Model ### Resp_Body_Base() ### # ### BEGIN ### API Response Model ### mk_resp() ### # The method for making responses for REST. Returns a dict, but currently uses Resp_Body_Base inside the function. # Update 2021-08-23 def mk_resp( data: None|bool|dict|list, tmp_file_path: None|str = None, dict_to_json: bool = False, status_code: int = 200, status_message: str = '', status_name: str = '', success: bool = True, details: str = '', by_alias: bool = True, exclude_unset: bool = True, response: Response = None ) -> dict: log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if data is None: data_out = { 'result': data } elif data == False: data_out = { 'result': data } elif data == True: data_out = { 'result': data } elif isinstance(data, dict): log.info('Data type is a dict') data_out = data elif isinstance(data, list): log.info('Data type is a list') data_out = data elif isinstance(data, int): log.info('Data type is an int') data_out = { 'result': data } elif isinstance(data, str): log.info('Data type is a str') data_out = { 'result': data } else: # Assuming it is still and object. This should be improved. Example model type: "" log.info('Data type is other') data_out = data.dict(by_alias=by_alias, exclude_unset=exclude_unset) # log.debug(data_out) resp_body = {} resp_body['data'] = data_out resp_body['meta'] = {} resp_body['meta']['details'] = details resp_body['meta']['status_code'] = status_code if status_message: resp_body['meta']['status_message'] = status_message else: resp_body['meta']['status_message'] = settings.HTTP_STATUS_LI[status_code]['message'] resp_body['meta']['status_name'] = settings.HTTP_STATUS_LI[status_code]['name'] resp_body['meta']['success'] = success resp_body['meta']['tmp_file_path'] = tmp_file_path if isinstance(data, bool): resp_body['meta']['data_type'] = 'bool' elif isinstance(data, int): resp_body['meta']['data_type'] = 'int' elif isinstance(data, str): resp_body['meta']['data_type'] = 'str' elif isinstance(data, dict): resp_body['meta']['data_type'] = 'dict' elif isinstance(data, list): resp_body['meta']['data_type'] = 'list' resp_body['meta']['data_list_count'] = len(data) if response: log.debug(response) if status_code == 400: log.warning('Likely bad request') response.status_code = status.HTTP_400_BAD_REQUEST elif status_code == 401: response.status_code = status.HTTP_401_UNAUTHORIZED # elif status_code == 402: response.status_code = status.HTTP_402_X elif status_code == 403: response.status_code = status.HTTP_403_FORBIDDEN elif status_code == 404: log.info('No results') response.status_code = status.HTTP_404_NOT_FOUND elif status_code == 408: response.status_code = status.HTTP_408_REQUEST_TIMEOUT elif status_code == 429: response.status_code = status.HTTP_429_TOO_MANY_REQUESTS elif status_code == 500: response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR elif status_code == 501: response.status_code = status.HTTP_501_NOT_IMPLEMENTED elif status_code == 502: response.status_code = status.HTTP_502_BAD_GATEWAY elif status_code == 503: response.status_code = status.HTTP_503_SERVICE_UNAVAILABLE elif status_code == 504: response.status_code = status.HTTP_504_GATEWAY_TIMEOUT # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL # log.debug(resp_body) # log.debug(type(resp_body['data'])) # import json # with open('data.txt', 'w') as outfile: # json.dump(resp_body['data'], outfile) resp_body_obj = Resp_Body_Base(**resp_body) log.debug(resp_body_obj) resp_body_dict = resp_body_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) log.debug(resp_body_dict) return resp_body_dict # ### END ### API Response Model ### mk_resp() ###