Package: fastapi-plugins
Plugins for FastAPI framework, high performance, easy to learn, fast to code, ready for productionfastapi-pluginsFastAPI framework plugins - simple way to sharefastapicode and utilities across applications.The concept isplugin- plug a functional utility into your application without or with minimal effort.CacheMemcachedRedisSchedulerControlVersionEnvironmentHealthHeartbeatApplication settings/configurationLoggingCeleryMQand much more is already in progress...ChangesSeerelease notesInstallationby default containsRedisSchedulerControlLoggingmemcachedaddsMemcachedalladd everything abovepipinstallfastapi-plugins
pipinstallfastapi-plugins[memcached]pipinstallfastapi-plugins[all]Quick startPluginAdd information about plugin system.Application settingsAdd information about settings.Application configurationAdd information about configuration of an applicationComplete exampleimportfastapiimportfastapi_pluginsfromfastapi_plugins.memcachedimportMemcachedSettingsfromfastapi_plugins.memcachedimportmemcached_plugin,TMemcachedPluginimportasyncioimportaiojobsimportaioredisimportcontextlibimportlogging@fastapi_plugins.registered_configurationclassAppSettings(fastapi_plugins.ControlSettings,fastapi_plugins.RedisSettings,fastapi_plugins.SchedulerSettings,fastapi_plugins.LoggingSettings,MemcachedSettings,):api_name:str=str(__name__)logging_level:int=logging.DEBUGlogging_style:fastapi_plugins.LoggingStyle=fastapi_plugins.LoggingStyle.logjson@fastapi_plugins.registered_configuration(name='sentinel')classAppSettingsSentinel(AppSettings):redis_type=fastapi_plugins.RedisType.sentinelredis_sentinels='localhost:26379'@contextlib.asynccontextmanagerasyncdeflifespan(app:fastapi.FastAPI):config=fastapi_plugins.get_config()awaitfastapi_plugins.config_plugin.init_app(app,config)awaitfastapi_plugins.config_plugin.init()awaitfastapi_plugins.log_plugin.init_app(app,config,name=__name__)awaitfastapi_plugins.log_plugin.init()awaitmemcached_plugin.init_app(app,config)awaitmemcached_plugin.init()awaitfastapi_plugins.redis_plugin.init_app(app,config=config)awaitfastapi_plugins.redis_plugin.init()awaitfastapi_plugins.scheduler_plugin.init_app(app=app,config=config)awaitfastapi_plugins.scheduler_plugin.init()awaitfastapi_plugins.control_plugin.init_app(app,config=config,version=__version__,environ=config.model_dump())awaitfastapi_plugins.control_plugin.init()yieldawaitfastapi_plugins.control_plugin.terminate()awaitfastapi_plugins.scheduler_plugin.terminate()awaitfastapi_plugins.redis_plugin.terminate()awaitmemcached_plugin.terminate()awaitfastapi_plugins.log_plugin.terminate()awaitfastapi_plugins.config_plugin.terminate()app=fastapi_plugins.register_middleware(fastapi.FastAPI(lifespan=lifespan))@app.get("/")asyncdefroot_get(cache:fastapi_plugins.TRedisPlugin,conf:fastapi_plugins.TConfigPlugin,logger:fastapi_plugins.TLoggerPlugin)->typing.Dict:ping=awaitcache.ping()logger.debug('root_get',extra=dict(ping=ping,api_name=conf.api_name))returndict(ping=ping,api_name=conf.api_name)@app.post("/jobs/schedule/<timeout>")asyncdefjob_post(timeout:int=fastapi.Query(...,title='the job sleep time'),cache:fastapi_plugins.TRedisPlugin,scheduler:fastapi_plugins.TSchedulerPlugin,logger:fastapi_plugins.TLoggerPlugin)->str:asyncdefcoro(job_id,timeout,cache):awaitcache.set(job_id,'processing')try:awaitasyncio.sleep(timeout)iftimeout==8:logger.critical('Ugly erred job%s'%job_id)raiseException('ugly error')exceptasyncio.CancelledError:awaitcache.set(job_id,'canceled')logger.warning('Cancel job%s'%job_id)exceptException:awaitcache.set(job_id,'erred')logger.error('Erred job%s'%job_id)else:awaitcache.set(job_id,'success')logger.info('Done job%s'%job_id)job_id=str(uuid.uuid4()).replace('-','')logger=awaitfastapi_plugins.log_adapter(logger,extra=dict(job_id=job_id,timeout=timeout))# noqa E501logger.info('New job%s'%job_id)awaitcache.set(job_id,'pending')logger.debug('Pending job%s'%job_id)awaitscheduler.spawn(coro(job_id,timeout,cache))returnjob_id@app.get("/jobs/status/<job_id>")asyncdefjob_get(job_id:str=fastapi.Query(...,title='the job id'),cache:fastapi_plugins.TRedisPlugin,)->typing.Dict:status=awaitcache.get(job_id)ifstatusisNone:raisefastapi.HTTPException(status_code=starlette.status.HTTP_404_NOT_FOUND,detail='Job%snot found'%job_id)returndict(job_id=job_id,status=status)@app.post("/memcached/demo/<key>")asyncdefmemcached_demo_post(key:str=fastapi.Query(...,title='the job id'),cache:fastapi_plugins.TMemcachedPlugin,)->typing.Dict:awaitcache.set(key.encode(),str(key+'_value').encode())value=awaitcache.get(key.encode())returndict(ping=(awaitcache.ping()).decode(),key=key,value=value)DevelopmentIssues and suggestions are welcome throughissuesLicenseThis project is licensed under the terms of the MIT license.Changes0.12.0 (2023-03-24)[feature]Annotatedsupport0.11.0 (2022-09-19)[feature]redis-pyreplacesaioredis0.10.0 (2022-07-07)[feature]Updateaioredisto2.x.x[feature]Addfakeredisoptionally for development purpose0.9.1 (2022-06-16)[fix]Fix empty router prefix for control plugin0.9.0 (2021-09-27)[feature]Logging plugin[feature]Middleware interface - register middleware at application0.8.2 (2021-09-23)[fix]Fix dependency for aioredis0.8.1 (2021-03-31)[fix]Fix settings for Python 3.70.8.0 (2021-03-31)[feature]Settings plugin0.7.0 (2021-03-29)[feature]Control plugin with Health, Heartbeat, Environment and Version0.6.1 (2021-03-24)[fix]Bumpaiojobsto get rid of not required dependencies0.6.0 (2020-11-26)[feature]Memcached0.5.0 (2020-11-25)[bug] remove__all__since no API as such (#6).[typo] Fix typos in README (#7).[feature] Add Redis TTL (#8).0.4.2 (2020-11-24)[bug] Fix Redis URL (#4).0.4.1 (2020-06-16)Refactor requirements0.4.0 (2020-04-09)structure and split dependencies toextra0.3.0 (2020-04-07)Scheduler: tasks scheduler based onaiojobs0.2.1 (2020-04-06)Redis: pre-start0.2.0 (2019-12-11)Redis: sentinels0.1.0 (2019-11-20)Initial release: simple redis pool client