create account

[Python Tips] Caching data with CacheTools by themarkymark

View this thread on: hive.blogpeakd.comecency.com
· @themarkymark ·
[Python Tips] Caching data with CacheTools
![](https://steemitimages.com/DQmSsFP8BDE1DkXNN9hh1729MRexyqupLEKfWJTsRskjt33/image.png) 

# My Python Tips Series

* [f-strings in Python 3.6](https://steemit.com/programming/@themarkymark/python-tips-f-strings-in-python-3-6-and-why-you-should-be-using-them)
* [Underscores in numeric literals](https://steemit.com/programming/@themarkymark/python-tips-underscores-in-numeric-literals)
* [A better interactive shell](https://steemit.com/programming/@themarkymark/python-tips-a-better-interactive-shell)
* [Secrets Module - New in 3.6](https://steemit.com/programming/@themarkymark/python-tips-secrets-module-new-in-3-6)
* [PEP 8](https://steemit.com/programming/@themarkymark/python-tips-pep-8)
* [Slices](https://steemit.com/programming/@themarkymark/python-tips-slices)
* [Named Tuples](https://steemit.com/programming/@themarkymark/python-tips-named-tuples)
* [Destructuring](https://steemit.com/programming/@themarkymark/python-tips-destructuring)
* [Counter](https://steemit.com/programming/@themarkymark/python-tips-counter)
* [Type Annotation](https://steemit.com/programming/@themarkymark/python-tips-type-annotation)
* [Jupyter Notebooks](https://steemit.com/programming/@themarkymark/python-tips-jupyter-notebooks)
* [Getting Help](https://busy.org/@themarkymark/python-tips-getting-help)
* [Virtual Environments](https://steemit.com/programming/@themarkymark/python-tips-virtual-environments)
* [Expiring Dict](https://steemit.com/programming/@themarkymark/python-tips-expiring-dict)
* [DRY Programming](https://steemit.com/programming/@themarkymark/python-tips-dry-programming)
* [Knowing what exists](https://steemit.com/programming/@themarkymark/python-tips-knowing-what-exists)
* [Apscheduler](https://steemit.com/utopian-io/@themarkymark/python-tips-apscheduler)

# What is cachetools?

"This module provides various memoizing collections and decorators, including variants of the Python 3 Standard Library @lru_cache function decorator."
<sub>- Cachetools docs</sub>

Cachetools is a great tool when you need to cache frequently used data that has a high creation cost.  A good example is in my Global Blacklist API where I fetch tribe data.  I don't want to keep hitting the Scotbot API to get the data as it is more resource-intensive than just looking in ram and doesn't change often.  By using cachetools I am able to cache the data for an hour and only refresh the data when it isn't in cache anymore or has never been accessed previously.

Cachetools is built on top of the [expiring dictionary](https://steemit.com/programming/@themarkymark/python-tips-expiring-dict) module.

# How to use cachetools

I will walk you through the basic use of the module to get you started, if you have further questions or want to do something more advanced, I recommend checking out the  [docs](https://cachetools.readthedocs.io/en/stable/).

#### Install cachetools

You will need to make sure you have the cache tools package before using it.

`pip install -U cachetools`

This will install cachetools and update it if you already have it installed.  I recommend using a [Python environment](https://steemit.com/programming/@themarkymark/python-tips-virtual-environments) but you can also install it globally.

#### Import cachetools

Now that you have cachetools installed, you can import it into your code.  For most applications, you will need **cached** and **TTLCache**.

`from cachetools import cached, TTLCache`

#### Configure your cache

You can have multiple caches, but you need at least one to take advantage of cachetools.  The settings for your cache depend on your application and caching needs.  If the data doesn't change often, you can typically get away with a longer time to live (TTL) unless it is critical to have up to date data.  How much you benefit from caching will depend on how frequently you access the data, how expensive it is to get the data, and how often the data is cached when you require it.  

`cache = TTLCache(maxsize=100, ttl=3600)`

This creates a new cache with a max size of 100 elements and a time to live of 3600 seconds (1 hour).  If you use more than 100 elements, the older elements will be removed from the cache.  Don't use my suggested settings here, decide based on your application needs.

The two things to consider is how many data elements will you typically need to cache and how expensive is it to get that data.

#### Decorate your functions

If you don't understand [decorators](https://realpython.com/primer-on-python-decorators/), I recommend reading up on them to become familiar.  In short, a decorate is syntactic sugar to wrap another function with a helper function.

Any function that returns a result you want cached, you can decorate with your cache.

`@cached(cache)`

It is really that simple.  Let me give you an example.

```
@cached(cache)
def load_data():
   # run slow data to get all user data
   user_data = db.fetch_user_data()
   
  return user_data
```

If you have not run the function before for that particular user or the data is older than 1 hour, it will run the slow database query to fetch the data and return it.  If the data is already cached and is not older than 1 hour, you will receive the data from the cache instead.

For the global blacklist, the data I gather takes 1-10 seconds in some cases and is only done once per hour thanks to caching.  I use two forms of caching in the Global Blacklist API and cachetools is only used for collecting Tribes data, I use simple memory caching of variables for most of the data.

# Putting it all together

```
from cachetools import cached, TTLCache

cache = TTLCache(maxsize=100, ttl=3600)

@cached(cache)
def load_data():
   # run slow data to get all user data
   user_data = db.fetch_user_data()
   
  return user_data
```




👍  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 382 others
👎  , , , , , ,
properties (23)
authorthemarkymark
permlinkpython-tips-caching-data-with-cachetools
categorydevelopment
json_metadata{"community":"busy","app":"busy/2.5.6","format":"markdown","tags":["development","dev","python","python-tips","busy","palnet","technology","neoxian"],"users":["themarkymark","lru","cached"],"links":["https://steemit.com/programming/@themarkymark/python-tips-f-strings-in-python-3-6-and-why-you-should-be-using-them","https://steemit.com/programming/@themarkymark/python-tips-underscores-in-numeric-literals","https://steemit.com/programming/@themarkymark/python-tips-a-better-interactive-shell","https://steemit.com/programming/@themarkymark/python-tips-secrets-module-new-in-3-6","https://steemit.com/programming/@themarkymark/python-tips-pep-8","https://steemit.com/programming/@themarkymark/python-tips-slices","https://steemit.com/programming/@themarkymark/python-tips-named-tuples","https://steemit.com/programming/@themarkymark/python-tips-destructuring","https://steemit.com/programming/@themarkymark/python-tips-counter","https://steemit.com/programming/@themarkymark/python-tips-type-annotation"],"image":["https://steemitimages.com/DQmSsFP8BDE1DkXNN9hh1729MRexyqupLEKfWJTsRskjt33/image.png"]}
created2019-09-22 17:27:54
last_update2019-09-22 17:27:54
depth0
children5
last_payout2019-09-29 17:27:54
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length5,785
author_reputation1,774,011,078,363,575
root_title"[Python Tips] Caching data with CacheTools"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id90,826,908
net_rshares-1,172,864,919,807
author_curate_reward""
vote details (453)
@coininstant ·
it says python 3.6 so I would go 
pip3 install -U cachetools 
On a mac python comes with 2.7 for pip so this kind of little thing would always throw me off! lol thanks!!
👍  , ,
👎  
properties (23)
authorcoininstant
permlinkpy8vc0
categorydevelopment
json_metadata{"tags":["development"],"app":"steemit/0.1"}
created2019-09-22 18:00:00
last_update2019-09-22 18:00:00
depth1
children1
last_payout2019-09-29 18:00:00
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length169
author_reputation87,713,432,894,136
root_title"[Python Tips] Caching data with CacheTools"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id90,827,762
net_rshares70,994,551,847
author_curate_reward""
vote details (4)
@themarkymark · (edited)
$0.13
You should be using 3.7.4 for security reasons and some features only work in 3.7.x, and most installations use 2.7 still unless you specifically upgrade it.
👍  ,
👎  ,
properties (23)
authorthemarkymark
permlinkpy8vdd
categorydevelopment
json_metadata{"tags":["development"],"app":"steemit/0.1"}
created2019-09-22 18:00:51
last_update2019-09-22 18:01:12
depth2
children0
last_payout2019-09-29 18:00:51
cashout_time1969-12-31 23:59:59
total_payout_value0.067 HBD
curator_payout_value0.067 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length157
author_reputation1,774,011,078,363,575
root_title"[Python Tips] Caching data with CacheTools"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id90,827,793
net_rshares611,154,314,944
author_curate_reward""
vote details (4)
@cryptorg ·
Another great python tutorial that bring values to those needing it. Let's put this code to some use and see how it behaves.
👍  ,
properties (23)
authorcryptorg
permlinkre-themarkymark-2019922t22530831z
categorydevelopment
json_metadata{"tags":["development","dev","python","python-tips","busy","palnet","technology","neoxian"],"app":"esteem/2.2.0-surfer","format":"markdown+html","community":"esteem.app"}
created2019-09-22 19:53:03
last_update2019-09-22 19:53:03
depth1
children0
last_payout2019-09-29 19:53:03
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length124
author_reputation8,806,415,131,458
root_title"[Python Tips] Caching data with CacheTools"
beneficiaries
0.
accountesteemapp
weight1,000
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id90,830,572
net_rshares12,906,415,777
author_curate_reward""
vote details (2)
@imwatsi ·
Hey, great Python series. Nice to meet a fellow Python coder here :)
👍  ,
properties (23)
authorimwatsi
permlinkpy8zlp
categorydevelopment
json_metadata{"tags":["development"],"app":"steemit/0.1"}
created2019-09-22 19:32:18
last_update2019-09-22 19:32:18
depth1
children0
last_payout2019-09-29 19:32:18
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length68
author_reputation131,386,362,730,495
root_title"[Python Tips] Caching data with CacheTools"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id90,830,159
net_rshares12,894,740,545
author_curate_reward""
vote details (2)
@mattsanthonyit ·
I will definitely keep an eye on this and use it. Thanks for sharing this with us.

Posted using [Partiko Android](https://partiko.app/referral/mattsanthonyit)
👍  
properties (23)
authormattsanthonyit
permlinkmattsanthonyit-re-themarkymark-python-tips-caching-data-with-cachetools-20190922t173145780z
categorydevelopment
json_metadata{"app":"partiko","client":"android"}
created2019-09-22 17:31:45
last_update2019-09-22 17:31:45
depth1
children0
last_payout2019-09-29 17:31:45
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length159
author_reputation1,608,954,545,783,204
root_title"[Python Tips] Caching data with CacheTools"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id90,827,023
net_rshares145,153,880
author_curate_reward""
vote details (1)