Working on the basic SQL select API CRUD and lots of models

This commit is contained in:
Scott Idem
2021-03-08 15:53:39 -05:00
parent c7f2b16feb
commit 3d5fafc4bf
36 changed files with 2570 additions and 863 deletions

56
app/routers/address.py Normal file
View File

@@ -0,0 +1,56 @@
import datetime
#from datetime import datetime, time, timedelta
from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, status
from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union
from ..lib_general import *
from ..log import *
from app.config import settings
from app.db_sql import *
from ..models.address_model import *
from ..models.response_model import *
router = APIRouter()
# Working on the address API CRUD - STI 2021-03-08
@router.post('')
async def post_address_obj(
address: Address_Base,
x_account_id: str = Header(...),
return_obj: Optional[bool] = True,
by_alias: Optional[bool] = True,
exclude_unset: Optional[bool] = True,
):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
table_name_insert = 'address'
obj_data_dict = address.dict(by_alias=False, exclude_unset=True)
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(obj_data_dict)
obj_data = lookup_id_random_pop(obj_data_dict)
base_name = Address_Base
if sql_insert_result := sql_insert(table_name=table_name_insert, data=obj_data):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(sql_insert_result)
obj_id = sql_insert_result
else:
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(sql_insert_result)
return mk_resp(data=False, status_code=400)
table_name_select = 'v_address'
sql_select_result = sql_select(table_name=table_name_select, record_id=obj_id)
log.debug(sql_select_result)
resp_data = base_name(**sql_select_result).dict(by_alias=by_alias, exclude_unset=exclude_unset)
return mk_resp(data=resp_data)

View File

@@ -1,119 +0,0 @@
from __future__ import annotations
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 ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
class Address_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
id_random: Optional[str] = Field(
**base_fields['address_id_random'],
alias='address_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='address_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
for_type: Optional[str]
for_id_random: Optional[str]
for_id: Optional[int] #organization: Optional[Organization_Base] = Organization_Base()
name: Optional[str]
attention_to: Optional[str]
organization_name: Optional[str]
line_1: Optional[str]
line_2: Optional[str]
line_3: Optional[str]
city: Optional[str]
country_subdivision_code: Optional[str]
state_province: Optional[str]
postal_code: Optional[str]
country_alpha_2_code: Optional[str]
country: Optional[str]
lu_time_zone_id: Optional[str]
timezone: Optional[str]
latitude: Optional[str]
longitude: Optional[str]
map_url: Optional[str]
congressional_district: Optional[str]
#priority: Optional[int]
#sort: Optional[int]
#group: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
#account: Optional[Account_Base] = Account_Base()
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('address_id_random', always=True)
def address_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 address_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='address')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
#@validator('organization_id', always=True)
#def organization_id_lookup(cls, v, values, **kwargs):
#log.setLevel(logging.WARNING)
#log.debug(locals())
#if values['organization_id']:
#return redis_lookup_id_random(record_id_random=values['organization_id'], table_name='organization')
#return None
@validator('for_id', always=True)
def for_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['for_id_random'] and values['for_type']:
return redis_lookup_id_random(record_id_random=values['for_id_random'], table_name=values['for_type'])
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Address_Base.update_forward_refs()

View File

@@ -1,93 +1,194 @@
import datetime
#from datetime import datetime, time, timedelta
from fastapi import APIRouter, Depends, Header, HTTPException, Query, status
from fastapi import APIRouter, Body, Depends, Header, HTTPException, Query, status
from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union
from ..lib_general import *
from ..log import *
from app.config import settings
from app.db import *
#from .journal_models import *
#from .user_models import *
from .user_model import *
from .response_model import *
from app.db_sql import *
from ..models.account_model import *
from ..models.account_cfg_model import *
from ..models.address_model import *
from ..models.contact_model import *
from ..models.order_model import *
from ..models.site_model import *
from ..models.site_domain_model import *
from ..models.user_model import *
from ..models.response_model import *
obj_type_li = {}
obj_type_li['account'] = 'v_account'
obj_type_li['activity_log'] = 'activity_log'
obj_type_li['address'] = 'v_address'
obj_type_li['archive'] = 'v_archive'
obj_type_li['archive_content'] = 'v_archive_content'
obj_type_li['contact'] = 'v_contact'
obj_type_li['event'] = 'v_event'
obj_type_li['event_badge'] = 'v_event_badge'
obj_type_li['event_exhibit'] = 'v_event_exhibit'
obj_type_li['event_location'] = 'v_event_location'
obj_type_li['event_presentation'] = 'v_event_presentation'
obj_type_li['event_presenter'] = 'v_event_presenter'
obj_type_li['event_session'] = 'v_event_session'
obj_type_li['event_track'] = 'v_event_track'
obj_type_li['hosted_file'] = 'v_hosted_file'
obj_type_li['journal'] = 'v_journal'
obj_type_li['log'] = 'log' #'v_log'
obj_type_li['log_client_viewing'] = 'log_client_viewing'
obj_type_li['message'] = 'message' #'v_message'
obj_type_li['order'] = 'v_order'
obj_type_li['order_cart'] = 'v_order_cart'
obj_type_li['order_cart_line'] = 'v_order_cart_line'
obj_type_li['order_line'] = 'v_order_line'
obj_type_li['order_transaction'] = 'order_transaction'
obj_type_li['organization'] = 'v_organization'
obj_type_li['page'] = 'page'
obj_type_li['person'] = 'v_person'
obj_type_li['post'] = 'v_post_detail'
obj_type_li['post_comment'] = 'v_post_comment_detail'
obj_type_li['product'] = 'v_product'
obj_type_li['site'] = 'v_site'
obj_type_li['site_domain'] = 'v_site_domain'
obj_type_li['user'] = 'v_user'
obj_type_li['lu_education_degree'] = 'lu_education_degree'
obj_type_li['lu_education_level'] = 'lu_education_level'
obj_type_li['lu_html_color'] = 'lu_html_color'
obj_type_li['lu_time_zone'] = 'v_lu_time_zone'
obj_type_li['lu_user_status'] = 'lu_user_status'
#obj_type_li['cfg_flask'] = {'table_name': 'cfg_flask', 'base_name': Cfg_Flask_Base}
obj_type_li['stripe_customer'] = 'stripe_customer'
obj_type_li['stripe_log'] = 'stripe_log'
#obj_type_li['api_client_token'] = {'table_name': 'api_client_token', 'base_name': Api_Client_Token_Base}
#obj_type_li['api_key'] = {'table_name': 'api_key', 'base_name': Api_Key_Base}
#obj_type_li['api_token'] = {'table_name': 'api_token', 'base_name': Api_Token_Base}
obj_type_li['account'] = {'table_name': 'account', 'base_name': Account_Base}
obj_type_li['account_cfg'] = {'table_name': 'v_account_cfg_detail', 'base_name': Account_Cfg_Base} # NOTE check view name: *_detail?
#obj_type_li['activity_log'] = {'table_name': 'activity_log', 'base_name': Activity_Log_Base}
obj_type_li['address'] = {'table_name': 'v_address', 'base_name': Address_Base}
obj_type_li['archive'] = {'table_name': 'v_archive', 'base_name': Archive_Base}
obj_type_li['archive_content'] = {'table_name': 'v_archive_content', 'base_name': Archive_Content_Base}
obj_type_li['change_log'] = {'table_name': 'change_log', 'base_name': Change_Log_Base}
obj_type_li['contact'] = {'table_name': 'v_contact', 'base_name': Contact_Base}
obj_type_li['cont_edu_cert'] = {'table_name': 'cont_edu_cert', 'base_name': Cont_Edu_Cert_Base}
obj_type_li['event'] = {'table_name': 'v_event', 'base_name': Event_Base}
obj_type_li['event_badge'] = {'table_name': 'event_badge', 'base_name': Event_Badge_Base}
obj_type_li['event_badge_log'] = {'table_name': 'event_badge_log', 'base_name': Event_Badge_Log_Base}
obj_type_li['event_badge_template'] = {'table_name': 'event_badge_template', 'base_name': Event_Badge_Template_Base}
obj_type_li['event_device'] = {'table_name': 'event_device', 'base_name': Event_Device_Base}
obj_type_li['event_exhibit'] = {'table_name': 'v_event_exhibit', 'base_name': Event_Exhibit_Base} # NOTE check view name: *_detail?
obj_type_li['event_file'] = {'table_name': 'v_event_file', 'base_name': Event_File_Base} # Should this eventually be changed to event_hosted_file
obj_type_li['event_location'] = {'table_name': 'v_event_location', 'base_name': Event_Location_Base}
obj_type_li['event_presentation'] = {'table_name': 'v_event_presentation', 'base_name': Event_Presentation_Base}
obj_type_li['event_presenter'] = {'table_name': 'v_event_presenter', 'base_name': Event_Presenter_Base}
obj_type_li['event_registration'] = {'table_name': 'v_event_registration', 'base_name': Event_Registration_Base}
obj_type_li['event_session'] = {'table_name': 'v_event_session', 'base_name': Event_Session_Base}
obj_type_li['event_track'] = {'table_name': 'v_event_track', 'base_name': Event_Track_Base}
obj_type_li['hosted_file'] = {'table_name': 'hosted_file', 'base_name': Hosted_File_Base}
obj_type_li['hosted_file_link'] = {'table_name': 'hosted_file_link', 'base_name': Hosted_File_Link_Base}
obj_type_li['journal'] = {'table_name': 'v_journal', 'base_name': Journal_Base}
obj_type_li['journal_entry'] = {'table_name': 'v_journal_entry', 'base_name': Journal_Entry_Base}
obj_type_li['log'] = {'table_name': 'log', 'base_name': Log_Base} #'v_log'
obj_type_li['log_client_viewing'] = {'table_name': 'log_client_viewing', 'base_name': Log_Client_Viewing_Base}
obj_type_li['membership'] = {'table_name': 'v_membership', 'base_name': Membership_Base}
obj_type_li['membership_cfg'] = {'table_name': 'v_membership_cfg', 'base_name': Membership_Cfg_Base}
obj_type_li['message'] = {'table_name': 'message', 'base_name': Message_Base} #'v_message'
obj_type_li['order'] = {'table_name': 'v_order', 'base_name': Order_Base}
obj_type_li['order_cart'] = {'table_name': 'v_order_cart', 'base_name': Order_Cart_Base}
obj_type_li['order_cart_line'] = {'table_name': 'v_order_cart_line', 'base_name': Order_Cart_Line_Base}
obj_type_li['order_line'] = {'table_name': 'v_order_line', 'base_name': Order_Line_Base}
obj_type_li['order_transaction'] = {'table_name': 'order_transaction', 'base_name': Order_Transaction_Base}
obj_type_li['organization'] = {'table_name': 'v_organization', 'base_name': Organization_Base}
obj_type_li['page'] = {'table_name': 'page', 'base_name': Page_Base}
obj_type_li['person'] = {'table_name': 'v_person', 'base_name': Person_Base}
obj_type_li['post'] = {'table_name': 'v_post_detail', 'base_name': Post_Base} # NOTE check view name: *_detail?
obj_type_li['post_comment'] = {'table_name': 'v_post_comment_detail', 'base_name': Post_Comment_Base} # NOTE check view name: *_detail?
obj_type_li['product'] = {'table_name': 'v_product', 'base_name': Product_Base}
obj_type_li['site'] = {'table_name': 'site', 'base_name': Site_Base}
obj_type_li['site_domain'] = {'table_name': 'v_site_domain', 'base_name': Site_Domain_Base} # NOTE check view name: *_detail?
obj_type_li['user'] = {'table_name': 'v_user', 'base_name': User_Base}
obj_type_li['user_role'] = {'table_name': 'v_user_role', 'base_name': User_Role_Base} # NOTE check view name: *_detail?
obj_type_li['lu_country'] = {'table_name': 'lu_country', 'base_name': Lu_Country_Base}
obj_type_li['lu_country_subdivision'] = {'table_name': 'lu_country_subdivision', 'base_name': Lu_Country_Subdivision_Base}
obj_type_li['lu_education_degree'] = {'table_name': 'lu_education_degree', 'base_name': Lu_Education_Degree_Base}
obj_type_li['lu_education_level'] = {'table_name': 'lu_education_level', 'base_name': Lu_Education_Level_Base}
obj_type_li['lu_ethnicity'] = {'table_name': 'lu_ethnicity', 'base_name': Lu_Ethnicity_Base}
obj_type_li['lu_file_purpose'] = {'table_name': 'lu_file_purpose', 'base_name': Lu_File_Purpose_Base}
obj_type_li['lu_gender'] = {'table_name': 'lu_gender', 'base_name': Lu_Gender_Base}
obj_type_li['lu_html_color'] = {'table_name': 'lu_html_color', 'base_name': Lu_Html_Color_Base}
obj_type_li['lu_media_type'] = {'table_name': 'lu_media_type', 'base_name': Lu_Media_Type_Base}
obj_type_li['lu_membership_status'] = {'table_name': 'lu_membership_status', 'base_name': Lu_Membership_Status_Base}
obj_type_li['lu_membership_type'] = {'table_name': 'lu_membership_type', 'base_name': Lu_Membership_Type_Base}
obj_type_li['lu_order_status'] = {'table_name': 'lu_order_status', 'base_name': Lu_Order_Status_Base}
obj_type_li['lu_post_topic'] = {'table_name': 'lu_post_topic', 'base_name': Lu_Post_Topic_Base}
obj_type_li['lu_product_type'] = {'table_name': 'lu_product_type', 'base_name': Lu_Product_Type_Base}
obj_type_li['lu_pronoun'] = {'table_name': 'lu_pronoun', 'base_name': Lu_Pronoun_Base}
obj_type_li['lu_race'] = {'table_name': 'lu_race', 'base_name': Lu_Race_Base}
obj_type_li['lu_time_zone'] = {'table_name': 'v_lu_time_zone', 'base_name': Lu_Time_Zone_Base}
obj_type_li['lu_user_role'] = {'table_name': 'lu_user_role', 'base_name': Lu_User_Role_Base}
obj_type_li['lu_user_status'] = {'table_name': 'lu_user_status', 'base_name': Lu_User_Status_Base}
obj_type_li['stripe_customer'] = {'table_name': 'stripe_customer', 'base_name': Stripe_Customer_Base}
obj_type_li['stripe_log'] = {'table_name': 'stripe_log', 'base_name': Stipe_Log_Base}
# obj_type_li['c_idda_membership_profile'] = {'table_name': 'c_idda_membership_profile', 'base_name': C_Idda_Membership_Profile_Base}
# obj_type_li['c_osit_demo_membership_profile'] = {'table_name': 'c_osit_demo_membership_profile', 'base_name': C_Osit_Demo_Membership_Profile_Base}
router = APIRouter()
# Working on the basic API CRUD - STI 2021-03-05
# Working on the basic API CRUD - STI 2021-03-08
#@router.get('/{object_l1}/list')
@router.get('/{object_l1}/{object_id}/list')
@router.get('/{object_l1}/{object_l2}/{object_id}/list')
@router.get('/{object_l1}/{object_l2}/{object_id}/{object_l3}/list')
async def get_obj_li(object_l1: str=None, object_l2: str=None, object_l3: str=None, object_id: str=None, x_account_id: str = Header(...)):
response_data = {}
response_data['object_l1'] = object_l1
response_data['object_l2'] = object_l2
response_data['object_l3'] = object_l3
response_data['object_id'] = object_id
response_data['list'] = 'li'
@router.get('/{obj_type_l1}/list')
@router.get('/{obj_type_l1}/{obj_type_l2}/list')
@router.get('/{obj_type_l1}/{obj_type_l2}/{obj_type_l3}/list')
async def get_obj_li(obj_type_l1: str=None,
obj_type_l2: str=None,
obj_type_l3: str=None,
obj_id: str=None,
for_obj_type: Optional[str] = Query(None, max_length=50),
for_obj_id: Optional[str] = Query(None, max_length=22),
x_account_id: str = Header(...),
by_alias: Optional[bool] = True,
exclude_unset: Optional[bool] = True,
):
log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
sql_result = sql_select(table_name='user', record_id=1)
debug_data = {}
debug_data['obj_type_l1'] = obj_type_l1
debug_data['obj_type_l2'] = obj_type_l2
debug_data['obj_type_l3'] = obj_type_l3
debug_data['obj_id'] = obj_id
debug_data['for_obj_type'] = for_obj_type
debug_data['for_obj_id'] = for_obj_id
response_data['sql_result'] = sql_result
log.debug(debug_data)
return response_data
if obj_type_l1 and obj_type_l2 and obj_type_l3:
obj_name = f'{obj_type_l1}_{obj_type_l2}_{obj_type_l3}'
if obj_name in obj_type_li:
pass
else:
return mk_resp(data=False, status_code=400)
elif obj_type_l1 and obj_type_l2:
obj_name = f'{obj_type_l1}_{obj_type_l2}'
if obj_name in obj_type_li:
pass
else:
return mk_resp(data=False, status_code=400)
elif obj_type_l1:
obj_name = f'{obj_type_l1}'
if obj_name in obj_type_li:
pass
else:
return mk_resp(data=False, status_code=400)
else:
log.warning('We should not be here')
return mk_resp(data=False, status_code=400)
table_name = obj_type_li[obj_name]['table_name']
if for_obj_type and for_obj_id:
for_obj_id = redis_lookup_id_random(record_id_random=for_obj_id, table_name=for_obj_type)
#data = {}
#data[f'{for_obj_type}_id'] = for_obj_id
field_name = f'{for_obj_type}_id'
sql_result = sql_select(table_name=table_name, field_name=f'{for_obj_type}_id', field_value=for_obj_id)
else:
sql_result = sql_select(table_name=table_name)
log.debug(sql_result)
base_name = obj_type_li[obj_name]['base_name']
resp_data_li = []
for record in sql_result:
resp_data = base_name(**record).dict(by_alias=by_alias, exclude_unset=exclude_unset)
resp_data_li.append(resp_data)
return mk_resp(data=resp_data_li)
#@router.get('/{obj_type_l1}/{obj_id_int}')
@router.get('/{obj_type_l1}/{obj_id}')
@router.get('/{obj_type_l1}/{obj_type_l2}/{obj_id}')
@router.get('/{obj_type_l1}/{obj_type_l2}/{obj_type_l3}/{obj_id}')
async def get_obj(obj_type_l1: str=None, obj_type_l2: str=None, obj_type_l3: str=None, obj_id: str=None, x_account_id: str = Header(...),
async def get_obj(obj_type_l1: str=None,
obj_type_l2: str=None,
obj_type_l3: str=None,
obj_id: str=None,
for_obj_type: Optional[str] = Query(None, max_length=50),
for_obj_id: Optional[str] = Query(None, max_length=22),
x_account_id: str = Header(...),
qry_str: Optional[str] = Query(None, max_length=50),
qry_int: Optional[int] = None,
by_alias: Optional[bool] = True,
@@ -101,36 +202,75 @@ async def get_obj(obj_type_l1: str=None, obj_type_l2: str=None, obj_type_l3: str
debug_data['obj_type_l2'] = obj_type_l2
debug_data['obj_type_l3'] = obj_type_l3
debug_data['obj_id'] = obj_id
#debug_data['object_id_int'] = object_id_int
#debug_data['object_id_rand'] = object_id_rand
debug_data['for_obj_type'] = for_obj_type
debug_data['for_obj_id'] = for_obj_id
log.debug(debug_data)
if obj_type_l1 and obj_type_l2 and obj_type_l3:
obj_name = f'{obj_type_l1}_{obj_type_l2}_{obj_type_l3}'
if obj_name in obj_type_li:
table_name = obj_type_li[obj_name]
#table_name = obj_type_li[obj_name]
#table_name = obj_type_li[obj_name]['table_name']
pass
else:
return mk_resp(data=False, status_code=400)
elif obj_type_l1 and obj_type_l2:
obj_name = f'{obj_type_l1}_{obj_type_l2}'
if obj_name in obj_type_li:
table_name = obj_type_li[obj_name]
#table_name = obj_type_li[obj_name]['table_name']
pass
else:
return mk_resp(data=False, status_code=400)
elif obj_type_l1:
obj_name = f'{obj_type_l1}'
if obj_name in obj_type_li:
table_name = obj_type_li[obj_name]
#table_name = obj_type_li[obj_name]['table_name']
pass
else:
return mk_resp(data=False, status_code=400)
else:
log.warning('We should not be here')
return mk_resp(data=False, status_code=400)
table_name = obj_type_li[obj_name]['table_name']
# NOTE: Add a check for the object ID... assuming it is a random ID string for now.
sql_result = sql_select(table_name=table_name, record_id_random=obj_id)
log.debug(sql_result)
resp_data = User_Base(**sql_result).dict(by_alias=by_alias, exclude_unset=exclude_unset)
return mk_resp(data=resp_data)#, details=debug_data)
base_name = obj_type_li[obj_name]['base_name']
resp_data = base_name(**sql_result).dict(by_alias=by_alias, exclude_unset=exclude_unset)
return mk_resp(data=resp_data) #, details=debug_data)
# GET: get object item or list linked to object
@router.get('/{obj_type_l1}/{obj_id}')
@router.get('/{obj_type_l1}/{obj_type_l2}/{obj_id}')
@router.get('/{obj_type_l1}/{obj_type_l2}/{obj_type_l3}/{obj_id}')
def obj_type_li_for_type_for_id(obj_type_l1: str=None,
obj_type_l2: str=None,
obj_type_l3: str=None,
obj_id: str=None,
x_account_id: str = Header(...),
for_obj_type: Optional[str] = Query(None, max_length=50),
for_obj_id: Optional[str] = Query(None, max_length=22),
):
app.logger.setLevel(logging.DEBUG) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
for_obj_id = redis_lookup_id_random(record_id_random=for_obj_id, table_name=for_obj_type)
data = {}
data[f'{for_obj_type}_id'] = for_obj_id
sql = """
SELECT *
FROM `v_address` AS address
WHERE address.account_id = :account_id
"""
response = sql_select_for_rest(data=data, table_name=None, sql=sql, model=None, iso_dates_times=True, resource_ref=True)
return jsonify(response), response['meta']['status_code']

View File

@@ -1,69 +0,0 @@
import copy, datetime, hashlib, logging, os, pytz, redis, secrets
default_num_bytes = 8 # URL safe 8 bytes is 11 characters long and 16 bytes is 22 characters long
xxx_id_random_field_schema: dict = {
'title': 'XXX ID Random',
'description': 'This is an id_random field for this object.',
'min_length': 11,
'max_length': 22,
'example': secrets.token_urlsafe(8) # random each reloading of app with: secrets.token_urlsafe(8)
}
xxx_id_random_field_schema_default: dict = copy.copy(xxx_id_random_field_schema)
xxx_id_random_field_schema_default['default_factory'] = lambda:secrets.token_urlsafe(8)
created_updated_on_field_schema: dict = {
'title': 'Created or Updated On',
'description': 'This is the created or updated on timestamp field for this object. It is filled in by the SQL DB.',
'example': '2021-12-31T21:10:10'
}
base_fields = {}
#base_fields['id_random'] = xxx_id_random_field_schema_default
base_fields['obj_id_random'] = xxx_id_random_field_schema # General or generic object_id_random
base_fields['account_id_random'] = xxx_id_random_field_schema
base_fields['address_id_random'] = xxx_id_random_field_schema
base_fields['archive_id_random'] = xxx_id_random_field_schema
base_fields['contact_id_random'] = xxx_id_random_field_schema
base_fields['event_exhibit_id_random'] = xxx_id_random_field_schema
base_fields['event_file_id_random'] = xxx_id_random_field_schema
base_fields['event_id_random'] = xxx_id_random_field_schema
base_fields['event_presentation_id_random'] = xxx_id_random_field_schema
base_fields['event_registration_id_random'] = xxx_id_random_field_schema
base_fields['fundraising_id_random'] = xxx_id_random_field_schema
base_fields['hosted_file_id_random'] = xxx_id_random_field_schema
base_fields['membership_id_random'] = xxx_id_random_field_schema
base_fields['membership_profile_id_random'] = xxx_id_random_field_schema
base_fields['order_cart_id_random'] = xxx_id_random_field_schema
base_fields['order_cart_line_id_random'] = xxx_id_random_field_schema
base_fields['order_id_random'] = xxx_id_random_field_schema
base_fields['order_line_id_random'] = xxx_id_random_field_schema
base_fields['order_transaction_id_random'] = xxx_id_random_field_schema
base_fields['organization_id_random'] = xxx_id_random_field_schema
base_fields['page_id_random'] = xxx_id_random_field_schema
base_fields['person_id_random'] = xxx_id_random_field_schema
base_fields['post_id_random'] = xxx_id_random_field_schema
base_fields['post_comment_id_random'] = xxx_id_random_field_schema
base_fields['product_id_random'] = xxx_id_random_field_schema
base_fields['site_id_random'] = xxx_id_random_field_schema
base_fields['site_domain_id_random'] = xxx_id_random_field_schema
base_fields['user_id_random'] = xxx_id_random_field_schema
base_fields['created_on'] = created_updated_on_field_schema
base_fields['updated_on'] = created_updated_on_field_schema
base_fields['obj_type'] = {}
base_fields['obj_id_random'] = xxx_id_random_field_schema_default
base_fields['obj_id_rand'] = xxx_id_random_field_schema_default
base_fields['obj_id'] = {}
base_fields['obj_name'] = {}
base_fields['obj_notes'] = {}
base_fields['for_id_random'] = xxx_id_random_field_schema_default
#xxx_id_random_field_schema['alias'] = 'order_id_random'
#base_fields['id_random'] = xxx_id_random_field_schema_default
#xxx_id_random_field_schema['alias'] = 'user_id_random_x'
#c = {'alias': 'user_id_random_x'}
#base_fields['user_id_random'] = combine_dict(xxx_id_random_field_schema, c)

View File

@@ -1,129 +0,0 @@
from __future__ import annotations
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 ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
from .address_model import Address_Base
class Contact_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
#from .address_model import Address_Base
id_random: Optional[str] = Field(
**base_fields['contact_id_random'],
alias='contact_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='contact_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
address_id_random: Optional[str]
address_id: Optional[int]
for_type: Optional[str]
for_id_random: Optional[str]
for_id: Optional[int]
name: Optional[str]
title: Optional[str]
tagline: Optional[str]
description: Optional[str]
lu_time_zone_id: Optional[str]
timezone: Optional[str]
email: Optional[str]
website: Optional[str]
website_name: Optional[str]
phone_mobile: Optional[str]
phone_home: Optional[str]
phone_office: Optional[str]
phone_land: Optional[str]
phone_fax: Optional[str]
facebook: Optional[str]
instagram: Optional[str]
twitter: Optional[str]
linkedin: Optional[str]
other_site_url: Optional[str]
other_site_name: Optional[str]
other_text: Optional[str]
other_json: Optional[Json]
priority: Optional[int]
sort: Optional[int]
group: Optional[str]
#account: Optional[Account_Base] = Account_Base()
address: Optional[Address_Base] = Address_Base()
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('contact_id_random', always=True)
def contact_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 contact_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='contact')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('address_id', always=True)
def address_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values.get('address_id_random', None):
return redis_lookup_id_random(record_id_random=values['address_id_random'], table_name='address')
return None
@validator('for_id', always=True)
def for_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['for_id_random'] and values['for_type']:
return redis_lookup_id_random(record_id_random=values['for_id_random'], table_name=values['for_type'])
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
Contact_Base.update_forward_refs()

View File

@@ -1,55 +0,0 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from .common_field_schema import base_fields
class Core_Object_Base(BaseModel):
app.logger.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
app.logger.debug(locals())
obj_type: str
obj_id_random: str # alias this one based on obj_type?
obj_id_rand: str # alias this one based on obj_type?
obj_id: int # alias this one?
obj_name: Optional[str]
id_random: str # alias this one?
id: int # alias this one?
account_id_random: Optional[str]
account_id: Optional[str]
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
class Example_Object_Base(Core_Object_Base): # Based on Core_Object_Base
title: Optional[str] = None
description: Optional[str] = None
password_set_on: Optional[datetime.datetime] = None
archive_on: Optional[datetime.datetime] = None
logged_in_on: Optional[datetime.datetime] = None
last_activity_on: Optional[datetime.datetime] = None
other_random_fields: dict
list_of_: Optional[dict] = {}
# Create, Read/Get, Update, Delete
# CRUD or CGUD
# def create_object(object_data):
# return False # True, False, or None or object_data
# def get_object(object_id):
# return object_data # False or None
# def update_object(object_id, object_data):
# return False # True, False, or None or object_data
# def delete_object(object_id):
# return False # True, False, or None or object_data

View File

@@ -1,113 +0,0 @@
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 ..lib_general import *
from app.config import settings
from app.db import *
from .user_models import *
#import logging
router = APIRouter()
@router.post(
"/",
response_model=UserOut,
summary='Create a new user account',
status_code=status.HTTP_201_CREATED
)
async def create_user(user: UserIn, x_account_id: str = Header(...)):
"""
Create a new user account
"""
user = {}
user['account_id_random'] = x_account_id
user['username'] = 'Scott.Idem'
user['name'] = 'Scott Idem'
user['email'] = 'Scott.Idem@oneskyit.com'
return user
#@router.patch('/{id_random}', response_model=UserOut, dependencies=[Depends(get_account_header)])
#async def update_user(id_random: str, user: UserIn, x_account_id: str = Header(...)):
#async def update_user(id_random: str, user: UserIn):
@router.patch(
'/{id_random}',
response_model=UserOut,
summary='Update a user account'
)
async def update_user(id_random: str, user: UserIn, x_account_id: str = Depends(get_account_header)):
"""
Update a user account
"""
user = {}
user['id_random'] = id_random
user['account_id_random'] = x_account_id
user['username'] = 'Scott.Idem'
user['name'] = 'Scott Idem'
user['email'] = 'Scott.Idem@oneskyit.com'
user['created_on'] = datetime.now()
user['super'] = True
return user
@router.delete('/{id_random}', response_model=bool)
async def delete_user(id_random: str, x_account_id: str = Depends(get_account_header)):
"""
Delete a user account
"""
return True
return False
@router.get('{object}/', response_model=List[UserOut])
@router.get('{object}/list_all', response_model=List[UserOut])
async def list_users():
"""
Get a list of users
"""
print(settings.APP_NAME)
users = [{'username': 'test.user.1'}, {'username': 'test.user.2'}, {'username': 'Scott.Idem'}]
print('Getting all users...')
sql = """
SELECT *
FROM `user`
WHERE id=1
"""
records = sql_select(sql=sql, as_list=True)
#records = sql_select(table_name='user')
if records:
print('Got the user list')
return records
else:
print('No user records found')
raise HTTPException(status_code=404)
@router.get('/{username}')
async def get_user_username(username: str, x_account_id: str = Header(...)):
return {'username': username}
#@router.get('/me')
#async def get_user_current():
#user_out: UserOut
#return {'username': 'test.user'}

View File

@@ -1,49 +0,0 @@
from datetime import datetime, time, timedelta
from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union
from ..lib_general import *
from ..log import *
from app.config import settings
from app.db import *
router = APIRouter()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: Optional[str] = Field(None, example='A very nice Item')
price: float
tax: Optional[float] = None
is_offer: Optional[bool] = None
#tags: List[str] = [] # not unique tags
tags: Set[str] = set() # unique tags
image: Optional[Image] = None # one image
images: Optional[List[Image]] = None # or as a list of images
@router.get('/')
async def read_items():
return [{'name': 'Item Foo'}, {'name': 'item Bar'}]
@router.get('/{item_id}')
async def read_item(item_id: str):
return {'name': 'Fake Specific Item', 'item_id': item_id}
@router.put(
'/{item_id}',
tags=['Extra Tag'],
responses={403: {'description': 'Operation forbidden'}},
)
async def update_item(item_id: str):
if item_id != 'foo':
raise HTTPException(status_code=403, detail='You can only update the item: foo')
return {'item_id': item_id, 'name': 'The Fighters'}

View File

@@ -1,40 +0,0 @@
from datetime import datetime, time, timedelta
from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union
class JournalBase(BaseModel):
#id_random: str = None # This should not be None. It is required.
#id_random: str = Field(None, example='iyOrkTnHEuyYUNeePbEdIg', min_length=11, max_length=22)
account_id_random: str = None # This should not be None. It is required.
user_id_random: str = Field(None, example='iyOrkTnHEuyYUNeePbEdIg', min_length=11, max_length=22)
default_private: Optional[bool] = None
default_public: Optional[bool] = None
default_personal: Optional[bool] = None
default_professional: Optional[bool] = None
private_passcode: str = Field(None, example='my passcode', min_length=3, max_length=20)
title: str = Field(None, example='The Journal Title', min_length=3, max_length=200)
summary: Optional[str] = None
hide: Optional[bool] = None
status: Optional[int] = None
archive_on: Optional[datetime] = None
archive: Optional[bool] = None
priority: Optional[bool] = None
sort: Optional[int] = None
group: Optional[str] = None
notes: Optional[str] = None
class JournalIn(JournalBase):
id_random: str = Field(None, example='iyOrkTnHEuyYUNeePbEdIg', min_length=11, max_length=22)
class JournalOut(JournalBase):
id_random: str = Field(None, example='iyOrkTnHEuyYUNeePbEdIg', min_length=11, max_length=22)
created_on: datetime
update_on: Optional[datetime] = None

View File

@@ -1,159 +0,0 @@
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 ..lib_general import *
from ..log import *
from app.config import settings
from app.db import *
from .journal_models import *
router = APIRouter()
@router.post(
"/",
response_model=JournalOut,
response_model_exclude_unset=True,
summary='Create a new journal account',
status_code=status.HTTP_201_CREATED
)
async def create_journal(journal: JournalIn, x_account_id: str = Header(...)):
"""
Create a new journal account
"""
journal = dict(journal)
table_name = 'journal'
# Look up the journal['account_id_random'] and match to a record ID from Redis
if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id):
journal['account_id'] = account_id
journal.pop('account_id_random')
else:
print('Something went wrong with the id_random lookup.')
raise HTTPException(status_code=500)
if result := sql_insert(table_name=table_name, record=journal, id_random_length=16):
print(type(result))
if type(result) == int: # isinstance(result, int):
# Select the new record to return as a response.
if new_journal := dict(sql_select(table_name=table_name, record_id=result)):
return new_journal
else:
print('New journal record was not found.')
raise HTTPException(status_code=400)
else:
print('There is likely a duplicate record. A new record was not created.')
raise HTTPException(status_code=400)
else:
print('No journal record was not created')
raise HTTPException(status_code=400)
#@router.patch('/{id_random}', response_model=JournalOut, dependencies=[Depends(get_account_header)])
#async def update_journal(id_random: str, journal: JournalIn, x_account_id: str = Header(...)):
#async def update_journal(id_random: str, journal: JournalIn):
@router.patch(
'/{id_random}',
response_model=JournalOut,
summary='Update a journal account'
)
async def update_journal(id_random: str, journal: JournalIn, x_account_id: str = Depends(get_account_header)):
"""
Update a journal account
"""
journal = {}
journal['id_random'] = id_random
journal['account_id_random'] = x_account_id
journal['title'] = 'tit'
journal['summary'] = 'sum'
#journal['created_on'] = datetime.now()
journal['default_private'] = True
journal['default_public'] = False
journal['default_personal'] = False
journal['default_professional'] = False
return journal
@router.delete('/{id_random}', response_model=bool)
async def delete_journal(id_random: str, x_account_id: str = Depends(get_account_header)):
"""
Delete a journal account
"""
return True
return False
@router.get('/', response_model=List[JournalOut])
@router.get('/list_all', response_model=List[JournalOut])
async def list_journals():
"""
Get a list of journals
"""
log.setLevel(logging.DEBUG)
log.debug(str(locals().keys())+' | '+str(locals().values()))
log.debug(locals())
journals = [{'journalname': 'test.journal.1'}, {'journalname': 'test.journal.2'}, {'journalname': 'Scott.Idem'}]
log.info('Getting all journals...')
sql = """
SELECT *
FROM `journal`
/*WHERE id=1*/
"""
#records = sql_select(sql=sql, as_list=True)
records = sql_select(table_name='v_journal', as_list=True)
if records:
log.info('Got the journal list')
return records
else:
log.info('No journal records found')
raise HTTPException(status_code=404)
@router.get(
'/{journal_id_random}',
response_model=JournalOut,
summary='Get a journal with an id (id_random)'
)
async def get_journal_id(journal_id_random: str, x_account_id: str = Header(...)):
"""
Get a journal with an id (id_random)
"""
log.setLevel(logging.WARN) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id):
#journal['account_id'] = account_id
#journal.pop('account_id_random')
pass
else:
log.warning('Something went wrong with the id_random lookup.')
raise HTTPException(status_code=500)
if journal_id := redis_lookup_id_random(table_name='journal', record_id_random=journal_id_random):
#journal['journal_id'] = journal_id
#journal.pop('account_id_random')
pass
else:
log.warning('Something went wrong with the id_random lookup.')
raise HTTPException(status_code=500)
record = sql_select(table_name='v_journal', record_id=journal_id)
if record:
log.info('Got the journal')
return record
else:
log.info('No journal record found')
raise HTTPException(status_code=404)

View File

@@ -1,62 +0,0 @@
from __future__ import annotations
import datetime, hashlib, logging, os, pytz, redis, secrets
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator
from ..lib_general import *
from ..log import *
from .common_field_schema import base_fields
from app.config import settings
# The pydantic BaseModel to help make consistent REST responses - STI 2021-03-05
class Resp_Body_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
data: Union[dict, list]
meta: Optional[dict]
# The make response function for REST - STI 2021-03-05
def mk_resp(data={}, dict_to_json=None, status_code=200, status_message=None, status_name=None, success=True, details=None, by_alias=True, exclude_unset=True):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
if data is None: data = { 'result': None }
elif data == False: data = { 'result': False }
elif data == True: data = { 'result': True }
resp_body = {}
resp_body['data'] = data
resp_body['meta'] = {}
resp_body['meta']['details'] = details
resp_body['meta']['status_code'] = status_code
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
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)
log.debug(type(resp_body['data']))
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

View File

@@ -1,140 +0,0 @@
from __future__ import annotations
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 ..lib_general import *
from ..log import *
from .common_field_schema import base_fields, default_num_bytes
#from .account_model import Account_Base
from .contact_model import Contact_Base
#from .organization_model import Organization_Base
#from .person_model import Person_Base
class User_Base(BaseModel):
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
log.debug(locals())
#from .account_model import Account_Base
#from .contact_model import Contact_Base
#from .organization_model import Organization_Base
#from .person_model import Person_Base
#if TYPE_CHECKING:
#from .person_model import Person_Base
id_random: Optional[str] = Field(
**base_fields['user_id_random'],
alias='user_id_random',
default_factory=lambda:secrets.token_urlsafe(default_num_bytes),
)
id: Optional[int] = Field(
#alias='user_id'
)
account_id_random: Optional[str]
account_id: Optional[int]
contact_id_random: Optional[str]
contact_id: Optional[int]
organization_id_random: Optional[str]
organization_id: Optional[int]
person_id_random: Optional[str]
person_id: Optional[int]
username: Optional[str]
name: Optional[str]
email: Optional[str]
email_verified: Optional[bool]
password: Optional[str]
auth_key: Optional[str]
enable: Optional[bool]
enable_from: Optional[datetime.datetime] = None
enable_to: Optional[datetime.datetime] = None
super: Optional[bool]
manager: Optional[bool]
administrator: Optional[bool]
public: Optional[bool]
verified: Optional[bool]
status_id: Optional[int]
status_name: Optional[str]
password_set_on: Optional[datetime.datetime] = None
password_reset_token: Optional[str] = None
password_reset_expire_on: Optional[datetime.datetime] = None
logged_in_on: Optional[datetime.datetime] = None
last_activity_on: Optional[datetime.datetime] = None
#account: Optional[Account_Base]# = Account_Base()
contact: Optional[Contact_Base]# = Contact_Base()
#organization: Optional[Organization_Base]# = Organization_Base()
#person: Optional[Person_Base]# = Person_Base()
notes: Optional[str]
created_on: Optional[datetime.datetime] = None
updated_on: Optional[datetime.datetime] = None
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
#@validator('user_id_random', always=True)
def user_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 user_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['id_random']:
log.debug(values['id_random'])
return redis_lookup_id_random(record_id_random=values['id_random'], table_name='user')
return None
@validator('account_id', always=True)
def account_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['account_id_random']:
return redis_lookup_id_random(record_id_random=values['account_id_random'], table_name='account')
return None
@validator('contact_id', always=True)
def contact_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['contact_id_random']:
return redis_lookup_id_random(record_id_random=values['contact_id_random'], table_name='contact')
return None
@validator('organization_id', always=True)
def organization_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['organization_id_random']:
return redis_lookup_id_random(record_id_random=values['organization_id_random'], table_name='organization')
return None
@validator('person_id', always=True)
def person_id_lookup(cls, v, values, **kwargs):
log.setLevel(logging.WARNING)
log.debug(locals())
if values['person_id_random']:
return redis_lookup_id_random(record_id_random=values['person_id_random'], table_name='person')
return None
class Config:
underscore_attrs_are_private = True
fields = base_fields
User_Base.update_forward_refs()

View File

@@ -1,45 +0,0 @@
from datetime import datetime, time, timedelta
from pydantic import BaseModel, EmailStr, Field
from typing import Dict, List, Optional, Set, Union
class UserBase(BaseModel):
#id_random: str = None # This should not be None. It is required.
account_id_random: str = None # This should not be None. It is required.
username: str = Field(None, example='New.User', min_length=3, max_length=100)
name: Optional[str] = None
email: EmailStr
email_verified: Optional[bool] = None
enable: Optional[bool] = None
enable_from: Optional[datetime] = None
enable_to: Optional[datetime] = None
super: Optional[bool] = None
manager: Optional[bool] = None
administrator: Optional[bool] = None
verified: Optional[bool] = None
notes: Optional[str] = None
class UserIn(UserBase):
#id_random: str = None
password: str = Field(None, example='My Difficult Password!', min_length=10)
class UserOut(UserBase):
id_random: str = None
password_set_on: Optional[datetime] = None
password_reset_token: Optional[str] = None
password_reset_expire_on: Optional[datetime] = None
logged_in_on: Optional[datetime] = None
last_activity_on: Optional[datetime] = None
created_on: datetime
update_on: Optional[datetime] = None
class UserInDB(UserBase):
hashed_password: str
password_set_on: Optional[datetime] = None
password_reset_token: Optional[str] = None
password_reset_expire_on: Optional[datetime] = None
logged_in_on: Optional[datetime] = None
last_activity_on: Optional[datetime] = None

View File

@@ -1,149 +0,0 @@
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 ..lib_general import *
from ..log import *
from app.config import settings
from app.db import *
from .user_models import *
router = APIRouter()
@router.post(
"/",
response_model=UserOut,
response_model_exclude_unset=True,
summary='Create a new user account',
status_code=status.HTTP_201_CREATED
)
async def create_user(user: UserIn, x_account_id: str = Header(...)):
"""
Create a new user account
"""
user = dict(user)
table_name = 'user'
# Look up the user['account_id_random'] and match to a record ID from Redis
if account_id := redis_lookup_id_random(table_name='account', record_id_random=x_account_id):
user['account_id'] = account_id
user.pop('account_id_random')
else:
print('Something went wrong with the id_random lookup.')
raise HTTPException(status_code=500)
if result := sql_insert(table_name=table_name, record=user, id_random_length=16):
print(type(result))
if type(result) == int: # isinstance(result, int):
# Select the new record to return as a response.
if new_user := dict(sql_select(table_name=table_name, record_id=result)):
return new_user
else:
print('New user record was not found.')
raise HTTPException(status_code=400)
else:
print('There is likely a duplicate record. A new record was not created.')
raise HTTPException(status_code=400)
else:
print('No user record was not created')
raise HTTPException(status_code=400)
#@router.patch('/{id_random}', response_model=UserOut, dependencies=[Depends(get_account_header)])
#async def update_user(id_random: str, user: UserIn, x_account_id: str = Header(...)):
#async def update_user(id_random: str, user: UserIn):
@router.patch(
'/{id_random}',
response_model=UserOut,
summary='Update a user account'
)
async def update_user(id_random: str, user: UserIn, x_account_id: str = Depends(get_account_header)):
"""
Update a user account
"""
log.setLevel(logging.DEBUG)
log.debug(locals())
user = {}
user['id_random'] = id_random
user['account_id_random'] = x_account_id
user['username'] = 'Scott.Idem'
user['name'] = 'Scott Idem'
user['email'] = 'Scott.Idem@oneskyit.com'
user['created_on'] = datetime.now()
user['super'] = True
return user
@router.delete('/{id_random}', response_model=bool)
async def delete_user(id_random: str, x_account_id: str = Depends(get_account_header)):
"""
Delete a user account
"""
log.setLevel(logging.DEBUG)
log.debug(locals())
return True
return False
@router.get('/', response_model=List[UserOut])
@router.get('/list_all', response_model=List[UserOut])
async def list_users(x_account: str = Depends(get_account_header)):
"""
Get a list of users
"""
log.setLevel(logging.DEBUG)
log.debug(locals())
if x_account['id']:
log.info('The x-account-id was given and is not empty...')
sql = """
SELECT *
FROM `user`
WHERE account_id = :account_id
"""
records = sql_select(table_name='user', field_name='account_id', field_value=x_account['id'], as_list=True)
elif x_account['id'] is None:
log.info('The x-account-id was given, but is empty...')
sql = """
SELECT *
FROM `user`
"""
records = sql_select(table_name='user', as_list=True)
if records:
log.info('Returning a user list...')
return records
else:
log.info('No user records found...')
raise HTTPException(status_code=404)
@router.get('/{username}')
async def get_user_username(username: str, x_account: str = Depends(get_account_header)):
log.setLevel(logging.DEBUG)
log.debug(locals())
data = {}
data['username'] = username
if x_account['id']:
sql = """
SELECT *
FROM `user`
WHERE account_id = :account_id AND username=:username
"""
data['account_id'] = x_account['id']
elif x_account['id'] is None:
sql = """
SELECT *
FROM `user`
WHERE (account_id IS NULL OR account_id = "") AND username=:username
"""
record = sql_select(sql=sql, data=data)
return record

View File

@@ -6,7 +6,7 @@ import aioredis, asyncio, json
from ..lib_general import *
from ..log import *
from app.config import settings
from app.db import *
from app.db_sql import *
router = APIRouter()