Mostly adding event device model, methods, and routes. Also general clean up of code.

This commit is contained in:
Scott Idem
2022-03-09 13:05:19 -05:00
parent 0947032a94
commit f073dd337f
10 changed files with 368 additions and 14 deletions

View File

@@ -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_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, 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
@@ -132,6 +132,11 @@ app.include_router(
# prefix='/event/badge/template',
tags=['Event Badge Template'],
)
app.include_router(
event_device.router,
# prefix='/event/device',
tags=['Event Device'],
)
app.include_router(
event_exhibit.router,
# prefix='/event/exhibit',

View File

@@ -0,0 +1,126 @@
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.event_cfg_models import Event_Cfg_Base
from app.models.event_device_models import Event_Device_Base
from app.models.event_location_models import Event_Location_Base
# ### BEGIN ### API Event Device Methods ### load_event_device_obj() ###
# Updated 2022-03-09
@logger_reset
def load_event_device_obj(
event_device_id: int,
enabled: str = 'enabled', # enabled, disabled, all
limit: int = 100,
offset: int = 0,
by_alias: bool = True,
exclude_unset: bool = True,
model_as_dict: bool = False,
inc_event_cfg: bool = False,
inc_event_location: bool = False,
) -> Event_Device_Base|dict|bool:
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if event_device_rec := sql_select(table_name='v_event_device', record_id=event_device_id): pass
else: return False
log.debug(event_device_rec)
try:
event_device_obj = Event_Device_Base(**event_device_rec)
except ValidationError as e:
log.error(e.json())
return False
log.debug(event_device_obj)
# Updated 2022-03-09
if inc_event_cfg:
log.info('Need to include event configuration...')
event_id = event_device_rec.get('event_id', None)
log.debug(event_id)
if event_cfg_result := load_event_cfg_obj(
event_id = event_id,
):
event_device_obj.event_cfg = event_cfg_result
else: event_device_obj.event_cfg = {} # None
# Updated 2022-03-09
if inc_event_location:
log.info('Need to include event location...')
event_location_id = event_device_rec.get('event_location_id', None)
log.debug(event_location_id)
if event_location_result := load_event_location_obj(
event_location_id = event_location_id,
):
event_device_obj.event_location = event_location_result
else: event_device_obj.event_location = {} # None
if model_as_dict:
return event_device_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) # pylint: disable=no-member
else:
return event_device_obj
# ### END ### API Event Device Methods ### load_event_device_obj() ###
# ### BEGIN ### API Event Device Methods ### get_event_device_rec_list() ###
# Updated 2022-03-09
@logger_reset
def get_event_device_rec_list(
for_type: str, # 'account' is a special case
for_id: str,
enabled: str = 'enabled', # enabled, disabled, all
limit: int = 100,
offset: int = 0,
) -> list|bool:
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if for_id := redis_lookup_id_random(record_id_random=for_id, table_name=for_type): pass
else: return False
if for_type == 'account':
sql_for_type_id = f'`event_device`.account_id = :for_id'
elif for_type == 'event':
sql_for_type_id = f'`event_device`.event_id = :for_id'
elif for_type == 'event_location':
sql_for_type_id = f'`event_device`.event_location_id = :for_id'
else: return False
data = {}
data['for_type'] = for_type
data['for_id'] = for_id
sql_enabled, data['enable'] = sql_enable_part(table_name='event_device', 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 `event_device`.id AS 'event_device_id', `event_device`.id_random AS 'event_device_id_random'
FROM `v_event_device` AS `event_device`
WHERE
{sql_for_type_id}
{sql_enabled}
ORDER BY `event_device`.created_on DESC, `event_device`.updated_on DESC
{sql_limit};
"""
log.debug(sql)
if event_device_rec_li_result := sql_select(data=data, sql=sql, as_list=True):
event_device_rec_li = event_device_rec_li_result
else: # [] or False
event_device_rec_li = event_device_rec_li_result
log.debug(event_device_rec_li_result)
return event_device_rec_li
# ### END ### API Event Device Methods ### get_event_device_rec_list() ###

View File

@@ -5,7 +5,7 @@ from fastapi import File, UploadFile
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from app.db_sql import get_id_random, redis_lookup_id_random, sql_insert, sql_select, sql_update
from app.db_sql import get_id_random, redis_lookup_id_random, sql_enable_part, sql_insert, sql_limit_offset_part, sql_select, sql_update
from app.lib_general import log, logging
from app.methods.hosted_file_methods import load_hosted_file_obj

View File

@@ -4,7 +4,7 @@ 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_insert, sql_select, sql_update
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_methods import load_event_obj

View File

@@ -1,4 +1,3 @@
from __future__ import annotations
import datetime
from typing import Dict, List, Optional, Set, Union
@@ -164,11 +163,9 @@ def load_event_obj(
if inc_event_abstract_list: pass
if inc_event_badge_list: pass
# Updated 2021-06-30
# Updated 2022-03-09
if inc_event_cfg:
log.info('Need to include event configuration...')
# event_id = event_rec.get('event_id', None)
# log.debug(event_id)
if event_cfg_result := load_event_cfg_obj(
event_id = event_id,
inc_event_registration_cfg = inc_event_registration_cfg,
@@ -177,7 +174,7 @@ def load_event_obj(
model_as_dict = model_as_dict,
):
event_obj.event_cfg = event_cfg_result
else: event_obj.event_cfg = None
else: event_obj.event_cfg = {} # None
if inc_event_device_list: pass
if inc_event_exhibit_list: pass

View File

@@ -0,0 +1,124 @@
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
from app.models.event_cfg_models import Event_Cfg_Base
from app.models.event_location_models import Event_Location_Base
# ### BEGIN ### API Event Device Models ### Event_Device_Base() ###
class Event_Device_Base(BaseModel):
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
id_random: Optional[str] = Field(
**base_fields['event_device_id_random'],
alias = 'event_device_id_random',
default_factory = lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
alias = 'event_device_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
event_id_random: Optional[str]
event_id: Optional[int]
event_location_id_random: Optional[str]
event_location_id: Optional[int]
code: Optional[str]
name: Optional[str]
description: Optional[str]
api_secret_key: Optional[str]
host_file_cache_path: Optional[str] # Path for hash file cache only
host_file_temp_path: Optional[str] # Path for copied and renamed temporary files from hash file cache directory
recording_path: Optional[str] # Path to save recordings
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
event_cfg: Optional[Event_Cfg_Base]
event_location: Optional[Event_Location_Base]
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('event_device_id_random', always=True)
def event_device_id_random_copy(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
return values['id_random']
return None
@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')
return None
@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')
return None
@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')
return None
@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')
return None
class Config:
underscore_attrs_are_private = True
allow_population_by_field_name = True
fields = base_fields
# ### END ### API Event Device Models ### Event_Device_Base() ###

View File

@@ -71,7 +71,6 @@ class Event_File_Base(BaseModel):
enable_to: Optional[datetime.datetime] = None
hide: Optional[bool]
priority: Optional[bool]
sort: Optional[int]
group: Optional[str] # Same or similar as file_purpose?

View File

@@ -51,8 +51,8 @@ class Hosted_File_Base(BaseModel):
# metadata: Optional[str]
#hide: Optional[int]
#priority: Optional[int]
# hide: Optional[bool]
# priority: Optional[bool]
# sort: Optional[int]
# group: Optional[str]

101
app/routers/event_device.py Normal file
View File

@@ -0,0 +1,101 @@
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.event_device_methods import get_event_device_rec_list, load_event_device_obj
from app.models.common_field_schema import default_num_bytes
from app.models.event_device_models import Event_Device_Base
from app.models.response_models import Resp_Body_Base, mk_resp
router = APIRouter()
# ### BEGIN ### API Event Device ### get_event_device_obj() ###
# Updated 2022-03-09
@router.get('/event/device/{event_device_id}', response_model=Resp_Body_Base)
async def get_event_device_obj(
event_device_id: str = Query(..., min_length=11, max_length=22),
inc_event_cfg: bool = False,
inc_event_location: bool = False,
commons: Common_Route_Params = Depends(common_route_params),
):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
# ### SECTION ### Secondary data validation
if event_device_id := redis_lookup_id_random(record_id_random=event_device_id, table_name='event_device'): pass
else: return mk_resp(data=None, status_code=404, response=commons.response)
if event_device_rec_result := load_event_device_obj(
event_device_id = event_device_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=event_device_rec_result, response=commons.response)
elif isinstance(event_device_rec_result, list) or event_device_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 Event Device ### get_event_device_obj() ###
# ### BEGIN ### API Event Device ### get_event_obj_device_list() ###
# Updated 2022-03-09
@router.get('/event/{event_id}/device/list', response_model=Resp_Body_Base)
async def get_event_obj_device_list(
event_id: str = Query(..., min_length=11, max_length=22),
inc_event_cfg: bool = False,
inc_event_location: bool = False,
commons: Common_Route_Params = Depends(common_route_params),
):
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): pass
else: return mk_resp(data=None, status_code=404, response=commons.response)
# Updated 2022-03-09
if event_device_rec_list_result := get_event_device_rec_list(
for_type = 'event',
for_id = event_id,
enabled = commons.enabled,
limit = commons.limit,
offset = commons.offset,
):
event_device_result_list = []
for event_device_rec in event_device_rec_list_result:
if load_event_device_result := load_event_device_obj(
event_device_id = event_device_rec.get('event_device_id', None),
enabled = commons.enabled,
inc_event_cfg = inc_event_cfg,
inc_event_location = inc_event_location,
):
event_device_result_list.append(load_event_device_result)
else:
event_device_result_list.append(None)
response_data = event_device_result_list
return mk_resp(data=response_data, response=commons.response)
elif isinstance(event_device_rec_list_result, list) or event_device_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 Event Device ### get_event_obj_device_list() ###

View File

@@ -396,6 +396,7 @@ async def get_person_obj(
@router.get('/account/{account_id}/person/list', response_model=Resp_Body_Base)
async def get_account_obj_person_list(
account_id: str = Query(..., min_length=11, max_length=22),
inc_address: bool = False,
inc_contact: bool = False,
# inc_membership_group_list: bool = False, # The list of all membership groups a person is a part of
@@ -404,6 +405,7 @@ async def get_account_obj_person_list(
# inc_order: bool = False,
# inc_organization: bool = False,
inc_user: bool = False,
commons: Common_Route_Params = Depends(common_route_params),
):
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL