import datetime, json, time, urllib from fastapi import APIRouter, Body, Depends, Header, HTTPException, Path, Query, Response, status from fastapi.responses import FileResponse 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, common_route_params_min, Common_Route_Params_Min from app.db_sql import sql_insert, sql_update, sql_insert_or_update, sql_select, sql_delete, redis_lookup_id_random, lookup_id_random_pop from app.models.response_models import * from app.models.api_crud_models import * # Modularized Imports from app.object_definitions.legacy_v1 import obj_type_li from app.methods.api_crud_methods import ( post_obj_template, patch_obj_template, get_obj_li_template, get_obj_template, delete_obj_template ) router = APIRouter() # ### BEGIN ### API CRUD ### get_obj_li_lx() ### @router.get('/{obj_type_l1}/list') async def get_obj_li_l1( obj_type_l1: str = Path(min_length=2, max_length=50), for_obj_type: Optional[str] = Query(None, max_length=50), for_obj_id: Optional[str] = Query(None, max_length=22), use_alt_table: bool = False, use_alt_base: bool = False, hidden: str = 'not_hidden', order_by_li: str = Header(None), jp: Optional[Union[str, None]] = None, file_type: str = 'CSV', return_file: Optional[bool] = False, commons: Common_Route_Params = Depends(common_route_params), ): return handle_get_obj_li(obj_type_l1=obj_type_l1, for_obj_type=for_obj_type, for_obj_id=for_obj_id, use_alt_table=use_alt_table, use_alt_base=use_alt_base, hidden=hidden, order_by_li=order_by_li, jp=jp, file_type=file_type, return_file=return_file, commons=commons) @router.get('/{obj_type_l1}/{obj_type_l2}/list') async def get_obj_li_l2( obj_type_l1: str = Path(min_length=2, max_length=50), obj_type_l2: str = Path(min_length=2, max_length=50), for_obj_type: Optional[str] = Query(None, max_length=50), for_obj_id: Optional[str] = Query(None, max_length=22), use_alt_table: bool = False, use_alt_base: bool = False, hidden: str = 'not_hidden', order_by_li: str = Header(None), jp: Optional[Union[str, None]] = None, file_type: str = 'CSV', return_file: Optional[bool] = False, commons: Common_Route_Params = Depends(common_route_params), ): return handle_get_obj_li(obj_type_l1=obj_type_l1, obj_type_l2=obj_type_l2, for_obj_type=for_obj_type, for_obj_id=for_obj_id, use_alt_table=use_alt_table, use_alt_base=use_alt_base, hidden=hidden, order_by_li=order_by_li, jp=jp, file_type=file_type, return_file=return_file, commons=commons) @router.get('/{obj_type_l1}/{obj_type_l2}/{obj_type_l3}/list') async def get_obj_li_l3( obj_type_l1: str = Path(min_length=2, max_length=50), obj_type_l2: str = Path(min_length=2, max_length=50), obj_type_l3: str = Path(min_length=2, max_length=50), for_obj_type: Optional[str] = Query(None, max_length=50), for_obj_id: Optional[str] = Query(None, max_length=22), use_alt_table: bool = False, use_alt_base: bool = False, hidden: str = 'not_hidden', order_by_li: str = Header(None), jp: Optional[Union[str, None]] = None, file_type: str = 'CSV', return_file: Optional[bool] = False, commons: Common_Route_Params = Depends(common_route_params), ): return handle_get_obj_li(obj_type_l1=obj_type_l1, obj_type_l2=obj_type_l2, obj_type_l3=obj_type_l3, for_obj_type=for_obj_type, for_obj_id=for_obj_id, use_alt_table=use_alt_table, use_alt_base=use_alt_base, hidden=hidden, order_by_li=order_by_li, jp=jp, file_type=file_type, return_file=return_file, commons=commons) def handle_get_obj_li( obj_type_l1: str, obj_type_l2: Optional[str] = None, obj_type_l3: Optional[str] = None, for_obj_type: Optional[str] = None, for_obj_id: Optional[str] = None, use_alt_table: bool = False, use_alt_base: bool = False, hidden: str = 'not_hidden', order_by_li: Optional[Union[str, None]] = None, jp: Optional[Union[str, None]] = None, file_type: str = 'CSV', return_file: Optional[bool] = False, commons: Common_Route_Params = None, ): log.setLevel(logging.INFO) # 1. Resolve Object Name if obj_type_l1 and obj_type_l2 and obj_type_l3: obj_name = f'{obj_type_l1}_{obj_type_l2}_{obj_type_l3}' elif obj_type_l1 and obj_type_l2: obj_name = f'{obj_type_l1}_{obj_type_l2}' else: obj_name = obj_type_l1 if obj_name not in obj_type_li: return mk_resp(data=False, status_code=400, response=commons.response) # 2. Resolve Tables/Models table_name = obj_type_li[obj_name].get('table_name_alt') if use_alt_table else obj_type_li[obj_name]['table_name'] base_name = obj_type_li[obj_name].get('base_name_alt') if use_alt_base else obj_type_li[obj_name]['base_name'] # 3. Handle Filters (jp / legacy and_qry) and_qry = {} if jp: try: jp_obj = json.loads(urllib.parse.unquote(jp)) if jp_obj.get('and_qry'): and_qry = jp_obj['and_qry'] except: pass # 4. Handle Parent Context if for_obj_type and for_obj_id: fid = redis_lookup_id_random(record_id_random=for_obj_id, table_name=for_obj_type) and_qry[f'{for_obj_type}_id'] = fid # 5. DB Query sql_result = sql_select( table_name = table_name, and_qry = and_qry, limit = commons.limit, offset = commons.offset, as_list = True ) if sql_result is False: return mk_resp(data=False, status_code=500, response=commons.response) resp_data = [base_name(**rec).dict(by_alias=True) for rec in sql_result] if base_name else sql_result return mk_resp(data=resp_data, response=commons.response) # Remaining Route Templates (Minimal stubs that call Methods) @router.get('/{obj_type_l1}/{obj_id}') async def get_obj_l1(obj_type_l1: str, obj_id: str, commons: Common_Route_Params = Depends(common_route_params)): return get_obj_template(obj_id=obj_id, obj_type=obj_type_l1, response=commons.response) @router.patch('/{obj_type_l1}/{obj_id}') async def patch_obj_l1(obj_type_l1: str, obj_id: str, data: dict, commons: Common_Route_Params = Depends(common_route_params)): return patch_obj_template(obj_type=obj_type_l1, data=data, obj_id=obj_id, response=commons.response) @router.delete('/{obj_type_l1}/{obj_id}') async def delete_obj_l1(obj_type_l1: str, obj_id: str, commons: Common_Route_Params = Depends(common_route_params)): return delete_obj_template(obj_type=obj_type_l1, obj_id=obj_id, response=commons.response)