Package: fastapi-cachette
FastAPI CachetteFeaturesOpinionated Cache Extension for FastAPI Asynchronous Web Framework;
This is an extension aiming at making cache access on the server
By configuration at startup of the FastAPI App instance, you can set the backend and other
configuration options and have it remain a class constant when using FastAPI's
intuitiveDependency Injectionsystem.The design has built-in limitations like fixed codec and backend once the app has been launched and
encourage developers to design their applications with this in mind.Most of the Backend implementation is directly lifted fromfastapi-cacheby@long2iceexcluding the MongoDB backend option.Configuration OptionsThe following are the current available configuration keys that can be set on this FastAPI extension
on startup either by using a method which returns a list of tuples or a Pydantic BaseSettings object
(See examples below or inexamples/folder)backend -- optional; must be one of ["dynamodb", "inmemory", "memcached", "mongodb", "redis"];
  defaults to using inmemory option which required no extra package dependencies. To use other
  listed options;
codec -- optional; serialization and de-serialization format to have cache values stored in
  the cache backend of choice as a string of selected encoding. once fetched, will have their
  decoded values returned of the same format. must be one of ["feather", "msgpack", "parquet",
  "pickle"]; if none is defined, will vanilla codec of basic string conversion will be used.
ttl -- optional; the time-to-live or amount before this cache item expires within the cache;
  defaults to 60 (seconds) and must be between 1 second to 1 hour (3600 seconds).
redis_url -- required when backend set to "redis"; the url set to redis-server instance with
  or without provided authentication in such formats "redis://user:password@host:port" and
  "redis://host:port" respectively.
memcached_host -- required when backend set to "memcached"; the host endpoint to the memcached
  distributed memory caching system.
table_name -- required when backend set to "dynamodb" or "mongodb"; name of the cache table or
  collection in case of "mongodb" backend to have key-value pairs stored; defaults to
  "fastapi-cachette".
region -- required when backend set to "dynamodb" and "dynamodb_url" not set; one of Amazon
  Web Services listed Regions which can be found on this Documentation
  [Page](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones)
dynamodb_url -- required when backend set to "dynamodb" and "region" not set; this option is
  used when setting up your own DynamoDB Local instance according to this
  [Guide](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal)
database_name -- required when backend set to "mongodb"; the database name to be automatically
  created if not exists on the MongoDB instance and store the cache table; defaults to
  "fastapi-cachette-database"
mongodb_url -- required when backend set to "mongodb"; the url set to MongoDB database
  instance with or without provided authentication in such formats
  "mongodb://user:password@host:port" and "mongodb://host:port" respectively.ExamplesThe following shows and example of setting up FastAPI Cachette in its default configuration, which
is an In-Memory cache implementation.fromfastapiimportFastAPI,Dependsfromfastapi.responsesimportPlainTextResponsefromfastapi_cachetteimportCachettefrompydanticimportBaseModelapp=FastAPI()### Routing ###classPayload(BaseModel):key:strvalue:str@app.post('/',response_class=PlainTextResponse)asyncdefsetter(payload:Payload,cachette:Cachette=Depends()):awaitcachette.put(payload.key,payload.value)return'OK'@app.get('/{key}',response_class=PlainTextResponse,status_code=200)asyncdefgetter(key:str,cachette:Cachette=Depends()):value:str=awaitcachette.fetch(key)returnvalueAnd then this is how you set up a FastAPI Cachette with Redis support enabled.fromfastapiimportFastAPI,Dependsfromfastapi.responsesimportPlainTextResponsefromfastapi_cachetteimportCachettefrompydanticimportBaseModelapp=FastAPI()@Cachette.load_configdefget_cachette_config():return[('backend','redis'),('redis_url','redis://localhost:6379')]classPayload(BaseModel):key:strvalue:str@app.post('/',response_class=PlainTextResponse)asyncdefsetter(payload:Payload,cachette:Cachette=Depends()):awaitcachette.put(payload.key,payload.value)return'OK'@app.get('/{key}',response_class=PlainTextResponse,status_code=200)asyncdefgetter(key:str,cachette:Cachette=Depends()):value:str=awaitcachette.fetch(key)returnvalueUpcoming Features (To-Do List)Implementflushandflush_expiredmethods on individual backends
(Not needed for Redis & Memcached backends)Memcached Authentication (No SASL Support)
Change library?DynamoDB Authentication (Add AWS Access Key ID and AWS Access Secret Key to configuration).Boto3 Version Fix; Current version restrictions vulnerable toaiohttpbug.Add behaviors responding to "Cache-Control" request headerMore character validations for URLs and Database/Table/Collection names in configuration optionsInstallationThe easiest way to start working with this extension with pippipinstallfastapi-cachette# orpoetryaddfastapi-cachetteWhen you familiarize with the basic structure of how to Dependency Inject Cachette within your
endpoints, please experiment more of using external backends withextrasinstallations like# Install FastAPI Cachette's extra requirements to Redis supportpipinstallfastapi-cachette--install-option"--extras-require=redis"# or Install FastAPI Cachette's support to Memcachedpoetryaddfastapi-cachette[memcached]# or Special JSON Codec written on Rust at lightning speedpoetryaddfastapi-cachette[orjson]# or Include PyArrow package making DataFrame serialization much easierpipinstallfastapi-cachette--install-option"--extras-require=dataframe"# or MongoDB and DynamoDB supportspoetryaddfastapi-cachette[mongodb]pipinstallfastapi-cachette--install-option"--extras-require=dynamodb"Getting StartedThis FastAPI extension utilizes "Dependency Injection" (To be continued)Configuration of this FastAPI extension must be done at startup using "@Cachette.load_config"
decorator (To be continued)These are all available options with explanations and validation requirements (To be continued)ExamplesThe following examples show you how to integrate this extension to a FastAPI App (To be continued)See "examples/" foldersTo run examples, first you must install extra dependenciesDo all in one go with this command...pipinstallaiobotocoreaiomcachemotoruvicornredis# orpoetryinstall--extrasexamplesDo individual example with this command...pipinstallredis# orpoetryinstall--extrasredisContributionsSee features and write tests I guess.Test Environment SetupThis project utilizes multiple external backend services namely AWS DynamoDB, Memcached, MongoDB and
Redis as backend service options as well as a possible internal option called InMemoryBackend. In
order to test viability, we must have specific instances of these set up in the background of our
testing environmentWith Docker-ComposeUtilize orchestration file attached to reposity anddocker-composecommand to set up testing
instances of backend services using the following command...docker-composeup-dWhen you are finished, you can stop and remove background running backend instances with the
following command...docker-composedownWithout Docker-ComposeIf you are usingarm64architecture on your local machine like I am with my fancy MacBook Pro,
there is a chance that yourdocker-compose(V1) is not properly configured and have caused you
many headaches. The following commands will allow you to replicate docker-compose orchestration
command given above.AWS DynamoDB Localdockerrun--detach--rm-ti-p8000:8000--namecachette-dynamodbamazon/dynamodb-local:latestMemcacheddockerrun--detach--rm-ti-p11211:11211--namecachette-memcachedmemcached:bullseyeMongoDBdockerrun--detach--rm-ti-p27017:27017--namecachette-mongodbmongo:latestRedisdockerrun--detach--rm-ti-p6379:6379--namecachette-redisredis:bullseyeAnd finally, to stop and remove running instances, run the following command[!-z$(dockerps-fname="cachette-*"-q|tr-d'\n')]\&&dockerkill$(dockerps-fname="cachette-*"-q)TestsNow that you have background running backend instances, you can proceed with the tests by usingpytestcommand as such...pytestOr you can configure the command to run specific tests as such...pytest-ktest_load_invalid_configs# orpytest-ktest_set_then_clearAll test suites must be placed undertests/folder or its subfolders.LicenseThis project is licensed under the terms of the MIT license.