import datetime, json, logging, os, pytz, random, secrets # , uvicorn from enum import Enum #from datetime import datetime, time, timedelta from fastapi import Body, Cookie, Depends, FastAPI, File, Form, Header, HTTPException, Path, Query, Request, status, UploadFile from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, PlainTextResponse from fastapi.staticfiles import StaticFiles from functools import lru_cache from pydantic import BaseModel, EmailStr, Field from typing import Dict, List, Optional, Set, Union from sqlalchemy import create_engine, text from sqlalchemy.exc import IntegrityError, OperationalError from . import config from app.lib_general import log, logging from app.log import log # Import the routers here first: from app.routers import api_crud, api, account, address, archive, archive_content, contact, event, event_exhibit, event_file, event_person, event_person_detail, event_presentation, event_presenter, event_registration, event_session, flask_cfg, hosted_file, journal, journal_entry, lookup, membership_type, order, order_cart, organization, page, person, post, post_comment, product, site, site_domain, user, user_person, websockets # , items, journals from app.db_sql import db print('### **** *** ** * The Aether FastAPI API app is loading... * ** *** **** ###') #log = logging.getLogger('root') #log.setLevel(logging.ERROR) # DEBUG > INFO > WARNING > ERROR > CRITICAL #logging.basicConfig( #format='[%(asctime)s] %(levelname)s @ %(module)s.%(funcName)s()#%(lineno)d: %(message)s' #) app = FastAPI() @lru_cache() def get_settings(): return config.Settings() app.mount('/static', StaticFiles(directory='static'), name='static') # Set up each route once the router has been imported app.include_router( api_crud.router, prefix='/crud', tags=['CRUD'], #dependencies=[Depends(get_token_header)], #dependencies=[Depends(get_account_header)], #responses={404: {'description': 'Not found'}}, ) app.include_router( api.router, prefix='/api', tags=['API'], ) app.include_router( flask_cfg.router, prefix='/flask_cfg', tags=['Flask CFG'], ) # app.include_router( # flask_cfg.router, # prefix='/redis', # tags=['Redis'], # ) app.include_router( account.router, prefix='/account', tags=['Account'], ) app.include_router( address.router, prefix='/address', tags=['Address'], ) app.include_router( archive.router, prefix='/archive', tags=['Archive'], ) app.include_router( archive_content.router, prefix='/archive/content', tags=['Archive Content'], ) app.include_router( contact.router, prefix='/contact', tags=['Contact'], ) app.include_router( event.router, prefix='/event', tags=['Event'], ) app.include_router( event_exhibit.router, prefix='/event/exhibit', tags=['Event Exhibit'], ) app.include_router( event_file.router, prefix='/event/file', tags=['Event File'], ) app.include_router( event_person.router, prefix='/event/person', tags=['Event Person'], ) app.include_router( event_person.router, prefix='/event/person/detail', tags=['Event Person Detail'], ) app.include_router( event_presentation.router, prefix='/event/presentation', tags=['Event Presenter'], ) app.include_router( event_presenter.router, prefix='/event/presenter', tags=['Event Presenter'], ) app.include_router( event_registration.router, prefix='/event/registration', tags=['Event Registration'], ) app.include_router( event_session.router, prefix='/event/session', tags=['Event Session'], ) app.include_router( hosted_file.router, prefix='/hosted_file', tags=['Hosted File'], ) app.include_router( journal.router, prefix='/journal', tags=['Journal'], ) app.include_router( journal_entry.router, prefix='/journal/entry', tags=['Journal Entry'], ) app.include_router( lookup.router, prefix='/lu', tags=['Lookup'], ) # app.include_router( # membership_group.router, # prefix='/membership/group', # tags=['Membership Group'], # ) # app.include_router( # membership_member.router, # prefix='/membership/member', # tags=['Membership Member'], # ) app.include_router( membership_type.router, prefix='/membership/type', tags=['Membership Type'], ) app.include_router( order.router, prefix='/order', tags=['Order'], ) app.include_router( order_cart.router, prefix='/order/cart', tags=['Order Cart'], ) app.include_router( organization.router, prefix='/organization', tags=['Organization'], ) app.include_router( page.router, prefix='/page', tags=['Page'], ) app.include_router( person.router, prefix='/person', tags=['Person'], ) app.include_router( post.router, prefix='/post', tags=['Post'], ) app.include_router( post_comment.router, prefix='/post/comment', tags=['Post Comment'], ) app.include_router( product.router, prefix='/product', tags=['Product'], ) app.include_router( site.router, prefix='/site', tags=['Site'], ) app.include_router( site_domain.router, prefix='/site/domain', tags=['Site Domain'], ) app.include_router( user.router, prefix='/user', tags=['User'], ) app.include_router( user_person.router, prefix='/user_person', tags=['User Person'], ) app.include_router( websockets.router, #prefix='/websocket', tags=['Websockets'], #dependencies=[Depends(get_token_header)], #dependencies=[Depends(get_account_header)], #responses={404: {'description': 'Not found'}}, ) # BEGIN: CORS origins = [ 'http://fastapi.localhost', 'http://localhost', 'http://192.168.32.20:3000', 'http://192.168.32.20:8080', 'http://localhost:3000', 'http://localhost:5000', 'http://localhost:8080', 'http://fastapi.localhost:5000', 'http://demo.localhost:5000', 'http://localhost:7800', 'https://oneskyit.com', 'http://dev-idaa.localhost:5000', 'http://connect.home:5000', ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_origin_regex='https://.*\.oneskyit\.com', allow_credentials=True, allow_methods=['*'], allow_headers=['*'], #expose_headers=[], #max_age=600, ) # END: CORS @app.on_event('startup') async def startup(): log.setLevel(logging.INFO) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.info('The Aether FastAPI API app is starting up...') #await database.connect() @app.on_event('shutdown') async def shutdown(): log.setLevel(logging.INFO) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.info('The Aether FastAPI API app is shutting down...') #await database.disconnect() #Add the processing time to the response header. @app.middleware('http') async def add_process_time_header(request: Request, call_next): import time start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers['X-Process-Time'] = str(process_time) return response # ### BEGIN ### API Main ### fastapi_root() ### @app.get('/', tags=['Root'], response_class=PlainTextResponse) async def fastapi_root(): log.setLevel(logging.DEBUG) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.info(config.settings.APP_NAME) log.info('***') log.debug('This is debug') # 10 DEBUG log.info('This is info') # 20 INFO log.warning('This is a warning') # 30 WARNING (and WARN) log.error('This is an error') # 40 ERROR log.exception('This is an exception') # 40 ERROR log.critical('This is critical') # 50 CRITICAL log.info('^^^') response_data = {} response_data['message'] = 'This is the Aether API using FastAPI.' current_datetime = datetime.datetime.now() current_datetime_string = current_datetime.isoformat() timezone = pytz.timezone("America/New_York") current_datetime_tz = timezone.localize(current_datetime) current_datetime_tz_string = current_datetime_tz.isoformat() current_datetime_utc = datetime.datetime.utcnow() current_datetime_utc_string = current_datetime_utc.isoformat() current_datetime_utc_localize = pytz.utc.localize(current_datetime_utc) current_datetime_utc_localize_string = current_datetime_utc_localize.isoformat() current_datetime_utc_localize_pst = current_datetime_utc_localize.astimezone(pytz.timezone("America/Los_Angeles")) current_datetime_utc_localize_pst_string = current_datetime_utc_localize_pst.isoformat() response_data['datetime'] = current_datetime_string response_data['datetime_tz'] = current_datetime_tz_string response_data['datetime_utc'] = current_datetime_utc_string response_data['datetime_utc_localize'] = current_datetime_utc_localize_string response_data['datetime_utc_localize_pst'] = current_datetime_utc_localize_pst_string response_data['url_safe_string_4_bytes_1'] = secrets.token_urlsafe(4) response_data['url_safe_string_8_bytes_1'] = secrets.token_urlsafe(8) response_data['url_safe_string_8_bytes_2'] = secrets.token_urlsafe(8) response_data['url_safe_string_8_bytes_3'] = secrets.token_urlsafe(8) response_data['url_safe_string_8_bytes_4'] = secrets.token_urlsafe(8) response_data['url_safe_string_8_bytes_5'] = secrets.token_urlsafe(8) response_data['url_safe_string_16_bytes_1'] = secrets.token_urlsafe(16) response_data['url_safe_string_16_bytes_2'] = secrets.token_urlsafe(16) response_data['url_safe_string_16_bytes_3'] = secrets.token_urlsafe(16) response_data['url_safe_string_16_bytes_4'] = secrets.token_urlsafe(16) response_data['url_safe_string_16_bytes_5'] = secrets.token_urlsafe(16) response_data['hex_string_4_bytes_1'] = secrets.token_hex(4) response_data['hex_string_8_bytes_1'] = secrets.token_hex(8) response_data['hex_string_16_bytes_1'] = secrets.token_hex(16) response_data['hex_string_32_bytes_1'] = secrets.token_hex(32) log.debug(json.dumps(response_data, indent=4)) return json.dumps(response_data, indent=4) # , sort_keys=True # ### END ### API Main ### fastapi_root() ### # ### BEGIN ### API Main ### sql_test() ### # ### TEST TEST TEST ### # @app.get('/sql_test', tags=['Testing'], response_class=PlainTextResponse) async def sql_test(): log.setLevel(logging.DEBUG) # DEBUG, INFO, WARN, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.info('Getting all accounts from DB...') sql = text( """ SELECT id, id_random, name, enable FROM `account` """ ) try: result = db.execute(sql) except Exception as e: log.error('*** An exception happened. ***') log.error(repr(e)) log.error('***') log.error(str(e)) log.error('^^^ exception ^^^') else: if result.rowcount: record_li = [dict(record) for record in result.fetchall()] log.debug(record_li) else: log.error('No records found. Something went wrong.') log.info('Got the account list') response_data = {} response_data['message'] = 'This is the Aether API using FastAPI.' response_data['data'] = record_li return json.dumps(response_data, indent=4) # , sort_keys=True # ### END ### API Main ### sql_test() ###