import datetime, redis #from datetime import datetime, time, timedelta from fastapi import APIRouter, Depends, Header, HTTPException, status from pydantic import BaseModel, EmailStr, Field from typing import Dict, List, Optional, Set, Union from .log import * from .db_sql import * async def get_token_header(x_token: str = Header(...)): if x_token != 'fake-super-secret-token': raise HTTPException(status_code=400, detail='X-Token header invalid') async def get_account_header(x_account_id: str = Header(...)): log.setLevel(logging.DEBUG) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) print('get_account_header(): '+x_account_id) if len(x_account_id): log.info('The x-account-id header has a value.') if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id): log.setLevel(logging.DEBUG) log.info('Found the account_id with the account_id_random value: '+x_account_id) account = { 'id': account_id, 'id_random': x_account_id } else: log.setLevel(logging.DEBUG) log.info('The x-account-id was invalid and not empty...') #raise HTTPException(status_code=500) raise HTTPException(status_code=400) # or 404? #return False elif x_account_id == '': log.info('The x-account-id header was empty.') account = { 'id': None, 'id_random': None } return account # Just return the value if it is an integer # Check if the id_random value is a string and the correct length # Attempt to look up id_random key in Redis # If success then return the ID number # If not success and there is a table_name then check the database table passed # If found in database table then store in Redis and return the ID number def redis_lookup_id_random(record_id_random=None, table_name=None): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if record_id_random is None: return False if isinstance(record_id_random, bool): return False if isinstance(record_id_random, int): return record_id_random elif isinstance(record_id_random, str): pass else: log.warning(f'Unexpected data type: {str(type(record_id_random))} Expected type is a string 11 or 22 characters long.') return False if record_id_random and table_name: # WARNING: The record_id_random string length should be checked just in case? if len(record_id_random) < 11: log.warning(f'The length of id_random is too short: {str(record_id_random)} ({len(record_id_random)} chars)') return False elif len(record_id_random) > 22: log.warning(f'The length of id_random is too long {str(record_id_random)} ({len(record_id_random)} chars)') return False else: pass else: log.warning('Missing table_name to select from for id_random') return False r = redis.Redis(host='localhost', port=6379, db=7, password=None, decode_responses=True) key_name = 'record_id:'+record_id_random record_id = r.get(key_name) log.debug(f'Record ID? {str(record_id)}') if record_id: log.info('The record ID was found using the record_id_random value.') log.info(f'TTL for: {key_name} : {str(record_id)} is {str(r.ttl(key_name))} seconds') return int(record_id) elif table_name: data = { 'id_random': record_id_random } sql = f""" SELECT id FROM `{table_name}` AS `table` WHERE `table`.id_random = :id_random; """ if select_results := sql_select(sql=sql, data=data): log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(select_results) log.debug(type(select_results)) if isinstance(select_results, dict): log.info(f"""Record ID random found: {str(select_results['id'])}""") if record_id := select_results.get('id'): r.setex(key_name, datetime.timedelta(minutes=90), value=record_id) return int(record_id) else: log.setLevel(logging.ERROR) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.error('The SQL result was not what was expected.') return False else: log.setLevel(logging.ERROR) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.error('More than one record may have been found. There may be a duplicate id_random.') log.error(select_results) return False else: #log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.info('Record ID random was not found') return None log.setLevel(logging.ERROR) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.error('We should not be here. Something unexpected happened.') return False # Just in case