Work membership and general clean up

This commit is contained in:
Scott Idem
2021-03-17 19:30:13 +00:00
parent 4785781cac
commit b57e51e8e7
8 changed files with 118 additions and 45 deletions

View File

@@ -10,17 +10,18 @@ from .log import *
from .db_sql import sql_select from .db_sql import sql_select
async def get_token_header(x_token: str = Header(...)): # ### BEGIN ### API Lib General ### async get_token_header() ###
async def get_token_header(x_token:str = Header(...)):
if x_token != 'fake-super-secret-token': if x_token != 'fake-super-secret-token':
raise HTTPException(status_code=400, detail='X-Token header invalid') raise HTTPException(status_code=400, detail='X-Token header invalid')
# ### END ### API Lib General ### async get_token_header() ###
async def get_account_header(x_account_id: str = Header(...)): # ### BEGIN ### API Lib General ### async get_account_header() ###
async def get_account_header(x_account_id:str = Header(...)):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())
print('get_account_header(): '+x_account_id)
if len(x_account_id): if len(x_account_id):
log.info('The x-account-id header has a value.') 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): if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id):
@@ -38,24 +39,22 @@ async def get_account_header(x_account_id: str = Header(...)):
account = { 'id': None, 'id_random': None } account = { 'id': None, 'id_random': None }
return account return account
# ### END ### API Lib General ### async get_account_header() ###
# ### BEGIN ### API Lib General ### redis_lookup_id_random() ###
# Just return the value if it is an integer # Just return the value if it is an integer
# Check if the id_random value is a string and the correct length # Check if the id_random value is a string and the correct length
# Attempt to look up id_random key in Redis # Attempt to look up id_random key in Redis
# If success then return the ID number # If success then return the ID number
# If not success and there is a table_name then check the database table passed # 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 # 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): def redis_lookup_id_random(record_id_random:int|str, table_name:str):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())
if record_id_random is None: return False if isinstance(record_id_random, str): pass
if isinstance(record_id_random, bool): return False elif isinstance(record_id_random, int): return record_id_random
if isinstance(record_id_random, int):
return record_id_random
elif isinstance(record_id_random, str):
pass
else: else:
log.warning(f'Unexpected data type: {str(type(record_id_random))} Expected type is a string 11 or 22 characters long.') log.warning(f'Unexpected data type: {str(type(record_id_random))} Expected type is a string 11 or 22 characters long.')
return False return False
@@ -119,11 +118,13 @@ def redis_lookup_id_random(record_id_random=None, table_name=None):
log.setLevel(logging.ERROR) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.ERROR) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.error('We should not be here. Something unexpected happened.') log.error('We should not be here. Something unexpected happened.')
return False # Just in case return False # Just in case
# ### BEGIN ### API Lib General ### redis_lookup_id_random() ###
# ### BEGIN ### API Lib General ### lookup_id_random_pop() ###
# Look up and resolve id_random values to their id # Look up and resolve id_random values to their id
# Remove the unneeded *_id_random key from the dict # Remove the unneeded *_id_random key from the dict
def lookup_id_random_pop(obj_data=None): def lookup_id_random_pop(obj_data:dict):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())
@@ -236,3 +237,4 @@ def lookup_id_random_pop(obj_data=None):
obj_data.pop('from_object_id_random') obj_data.pop('from_object_id_random')
return obj_data return obj_data
# ### END ### API Lib General ### lookup_id_random_pop() ###

0
app/models/__init__.py Normal file
View File

View File

@@ -5,8 +5,7 @@ from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from ..lib_general import * from ..lib_general import *
from ..log import * from ..db_sql import sql_select
from .db_sql import sql_select
#from .address_model import Address_Base #from .address_model import Address_Base
#from .contact_model import Contact_Base #from .contact_model import Contact_Base
@@ -160,17 +159,16 @@ def save_membership_obj(order_obj_new:Membership_Base=None):
else: return False else: return False
log.debug(order_line_obj_resp) log.debug(order_line_obj_resp)
return order_id return order_id
# ### END ### API Membership Model ### save_membership_obj() ### # ### END ### API Membership Model ### save_membership_obj() ###
# ### BEGIN ### API Membership Model ### get_membership_obj() ### # ### BEGIN ### API Membership Model ### load_membership_obj() ###
def get_membership_obj(membership_id=None, inc_membership_profile=None, inc_membership_cfg=None, inc_cust_profile=None): def load_membership_obj(membership_id:int|str, inc_membership_profile:bool=False, inc_membership_cfg:bool=False, inc_extended_profile:bool=False) -> Membership_Base:
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())
if membership_id := redis_lookup_id_random(record_id_random=membership_id, table_name='membership'): pass if membership_id := redis_lookup_id_random(record_id_random=membership_id, table_name='membership'): pass
else: else: return False
return False
if membership_rec := sql_select(table_name='v_membership', record_id=membership_id): if membership_rec := sql_select(table_name='v_membership', record_id=membership_id):
#log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL #log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
@@ -190,14 +188,14 @@ def get_membership_obj(membership_id=None, inc_membership_profile=None, inc_memb
membership_rec['cfg'] = membership_cfg_rec membership_rec['cfg'] = membership_cfg_rec
if inc_cust_profile: if inc_extended_profile:
account_code = membership_rec.get('account_code', None) account_code = membership_rec.get('account_code', None)
table_name = f'c_{account_code}_membership_profile' table_name = f'c_{account_code}_membership_profile'
if cust_profile_rec := sql_select(table_name=table_name, field_name='membership_id', field_value=membership_id): if extended_profile_rec := sql_select(table_name=table_name, field_name='membership_id', field_value=membership_id):
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL #log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(cust_profile_rec) log.debug(extended_profile_rec)
membership_rec['cust_profile'] = cust_profile_rec membership_rec['extended_profile'] = extended_profile_rec
#log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL #log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(membership_rec) log.debug(membership_rec)
@@ -211,4 +209,4 @@ def get_membership_obj(membership_id=None, inc_membership_profile=None, inc_memb
log.error(e.json()) log.error(e.json())
return membership_obj return membership_obj
# ### END ### API Membership Model ### get_membership_obj() ### # ### END ### API Membership Model ### load_membership_obj() ###

View File

@@ -36,8 +36,8 @@ class Membership_Cfg_Base(BaseModel):
reject_message: Optional[str] reject_message: Optional[str]
renew_message: Optional[str] renew_message: Optional[str]
#cust_membership_profile: Optional[str] # list of dicts outlining custom membership profile fields for client #extended_membership_profile: Optional[str] # list of dicts outlining extended (custom) membership profile fields for client
cust_membership_profile: Optional[Json] = '[]' # list of dicts outlining custom membership profile fields for client extended_membership_profile: Optional[Json] = '[]' # list of dicts outlining extended (custom) membership profile fields for client
default_no_reply_email: Optional[str] default_no_reply_email: Optional[str]
default_no_reply_name: Optional[str] default_no_reply_name: Optional[str]
@@ -216,7 +216,7 @@ class Membership_Base(BaseModel):
user: 'Optional[User_Base]' = User_Base() user: 'Optional[User_Base]' = User_Base()
cfg: 'Optional[Membership_Cfg_Base]' = Membership_Cfg_Base() cfg: 'Optional[Membership_Cfg_Base]' = Membership_Cfg_Base()
cust_profile: Optional[dict] = {} extended_profile: Optional[dict] = {}
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now) _processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)

View File

@@ -11,7 +11,7 @@ from .order_cart_model import Order_Cart_Base
# ### BEGIN ### API Order Cart Methods ### load_order_cart_obj() ### # ### BEGIN ### API Order Cart Methods ### load_order_cart_obj() ###
def load_order_cart_obj(order_cart_id:int|str=None, inc_order_cart_line_li=None, inc_order_cart_cfg=None): def load_order_cart_obj(order_cart_id:int|str, inc_order_cart_line_li:bool=False, inc_order_cart_cfg:bool=False):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())

View File

@@ -13,13 +13,10 @@ from .order_model import Order_Base
# ### BEGIN ### API Order Model ### save_order_obj() ### # ### BEGIN ### API Order Model ### save_order_obj() ###
def save_order_obj(order_obj_new:Order_Base=None, repl_order_line_list:bool=False): def save_order_obj(order_obj_new:Order_Base, repl_order_line_list:bool=False):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())
if not order_obj_new:
return False
log.debug(order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True)) log.debug(order_obj_new.dict(by_alias=False, exclude_defaults=False, exclude_unset=True))
order_line_obj_li_curr = [] # Initialize to store order_line list order_line_obj_li_curr = [] # Initialize to store order_line list
@@ -160,7 +157,7 @@ def save_order_obj(order_obj_new:Order_Base=None, repl_order_line_list:bool=Fals
# ### BEGIN ### API Order Model ### load_order_obj() ### # ### BEGIN ### API Order Model ### load_order_obj() ###
def load_order_obj(order_id=None, inc_order_line_li=None, inc_order_cfg=None, inc_person_obj=None, inc_user_obj=None): def load_order_obj(order_id:int|str, inc_order_line_li:bool=False, inc_order_cfg:bool=False, inc_person_obj:bool=False, inc_user_obj:bool=False):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())

View File

@@ -5,13 +5,13 @@ from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator
from ..lib_general import * from ..lib_general import *
from ..log import *
from app.config import settings from app.config import settings
from .common_field_schema import base_fields, default_num_bytes from .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 - STI 2021-03-05 # The pydantic BaseModel to help make consistent REST responses - STI 2021-03-05
class Resp_Body_Base(BaseModel): class Resp_Body_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
@@ -19,16 +19,18 @@ class Resp_Body_Base(BaseModel):
data: Union[dict, list] data: Union[dict, list]
meta: Optional[dict] meta: Optional[dict]
# ### END ### API Response Model ### Resp_Body_Base() ###
# The make response function for REST - STI 2021-03-05 # ### BEGIN ### API Response Model ### mk_resp() ###
def mk_resp(data:dict={}, dict_to_json:bool=None, status_code:int=200, status_message:str=None, status_name:str=None, success:bool=True, details:bool=None, by_alias:bool=True, exclude_unset:bool=True): # The make response function for REST - STI 2021-03-17
def mk_resp(data:None|bool|dict|list, 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):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals()) log.debug(locals())
if data is None: data = { 'result': None } if data is None: data = { 'result': data }
elif data == False: data = { 'result': False } elif data == False: data = { 'result': data }
elif data == True: data = { 'result': True } elif data == True: data = { 'result': data }
resp_body = {} resp_body = {}
resp_body['data'] = data resp_body['data'] = data
@@ -54,11 +56,6 @@ def mk_resp(data:dict={}, dict_to_json:bool=None, status_code:int=200, status_me
log.debug(type(resp_body['data'])) log.debug(type(resp_body['data']))
resp_body = Resp_Body_Base(**resp_body).dict(by_alias=by_alias, exclude_unset=exclude_unset) resp_body = Resp_Body_Base(**resp_body).dict(by_alias=by_alias, exclude_unset=exclude_unset)
#resp_body_json = resp_body.json(by_alias=True, exclude_unset=False)
#response = app.response_class(
#response=resp_body_json,
#status=status_code,
#mimetype='application/json'
#)
return resp_body return resp_body
# ### END ### API Response Model ### mk_resp() ###

View File

@@ -12,6 +12,7 @@ from app.db_sql import *
from .api_crud import delete_obj_template, get_obj_template, get_obj_li_template, patch_obj_template, post_obj_template from .api_crud import delete_obj_template, get_obj_template, get_obj_li_template, patch_obj_template, post_obj_template
from ..models.membership_model import Membership_Base from ..models.membership_model import Membership_Base
from ..models.membership_methods import load_membership_obj
from ..models.response_model import * from ..models.response_model import *
@@ -90,6 +91,84 @@ async def get_membership_obj_li(
return result return result
# Look up is only for account, person, or user records
@router.get('/lookup', response_model=Resp_Body_Base)
async def lookup_membership_obj(
for_obj_id: Union[int,str],
for_obj_type: str = Query(..., min_length=2, max_length=50),
x_account_id: str = Header(...),
inc_membership_profile: bool = True,
inc_membership_cfg: bool = True,
inc_extended_profile: bool = True,
by_alias: bool = True,
exclude_unset: bool = True,
):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
obj_type = 'membership'
base_name = Membership_Base
if for_obj_id := redis_lookup_id_random(record_id_random=for_obj_id, table_name=for_obj_type): pass
else: return mk_resp(data=False, status_code=404) # Not Found
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
data = {}
as_list = False
if for_obj_type == 'account' and for_obj_id:
data['account_id'] = for_obj_id
sql_where_for_obj_type = """`membership`.account_id = :account_id"""
sql_limit = ''
as_list = True
elif for_obj_type == 'person' and for_obj_id:
data['person_id'] = for_obj_id
sql_where_for_obj_type = """`membership`.person_id = :person_id"""
sql_limit = 'LIMIT 1'
elif for_obj_type == 'user' and for_obj_id:
data['user_id'] = for_obj_id
sql_where_for_obj_type = """`membership`.user_id = :user_id"""
sql_limit = 'LIMIT 1'
else:
log.debug(f'Object type={for_obj_type}; Object ID={for_obj_id}')
return mk_resp(data=False, status_code=400) # Bad Request
sql = f"""
SELECT id AS 'membership_id', id_random AS 'membership_id_random'
FROM `membership` AS `membership`
WHERE {sql_where_for_obj_type}
{sql_limit}
"""
# This will return a list if selecting by account ID
membership_obj_result = sql_select(data=data, sql=sql, as_list=as_list)
if isinstance(membership_obj_result, dict):
membership_id = membership_obj_result.get('membership_id', None)
membership_obj = load_membership_obj(
membership_id=membership_id,
inc_membership_profile=inc_membership_profile,
inc_membership_cfg=inc_membership_cfg,
inc_extended_profile=inc_extended_profile
).dict(by_alias=by_alias, exclude_unset=exclude_unset)
data = membership_obj
elif isinstance(membership_obj_result, list):
membership_obj_li = []
for membership_obj in membership_obj_result:
membership_id = membership_obj.get('membership_id', None)
membership_obj_li.append(
load_membership_obj(
membership_id=membership_id,
inc_membership_profile=inc_membership_profile,
inc_membership_cfg=inc_membership_cfg,
inc_extended_profile=inc_extended_profile
).dict(by_alias=by_alias, exclude_unset=exclude_unset)
)
data = membership_obj_li
else:
log.debug(membership_obj_result)
return mk_resp(data=None, status_code=404) # Not Found
return mk_resp(data=data)
@router.get('/{obj_id}', response_model=Resp_Body_Base) @router.get('/{obj_id}', response_model=Resp_Body_Base)
async def get_membership_obj( async def get_membership_obj(
obj_id: str = Query(..., min_length=1, max_length=22), obj_id: str = Query(..., min_length=1, max_length=22),