JSON file cache. This provides a dict like interface that stores JSON serializable objects. The objects are serialized to JSON and stored in a file. These values can be retrieved at a later time.
| 3931 | |
| 3932 | |
| 3933 | class JSONFileCache: |
| 3934 | """JSON file cache. |
| 3935 | This provides a dict like interface that stores JSON serializable |
| 3936 | objects. |
| 3937 | The objects are serialized to JSON and stored in a file. These |
| 3938 | values can be retrieved at a later time. |
| 3939 | """ |
| 3940 | |
| 3941 | CACHE_DIR = os.path.expanduser(os.path.join('~', '.aws', 'boto', 'cache')) |
| 3942 | |
| 3943 | def __init__(self, working_dir=CACHE_DIR, dumps_func=None): |
| 3944 | self._working_dir = working_dir |
| 3945 | if dumps_func is None: |
| 3946 | dumps_func = self._default_dumps |
| 3947 | self._dumps = dumps_func |
| 3948 | |
| 3949 | def _default_dumps(self, obj): |
| 3950 | return json.dumps(obj, default=self._serialize_if_needed) |
| 3951 | |
| 3952 | def __contains__(self, cache_key): |
| 3953 | actual_key = self._convert_cache_key(cache_key) |
| 3954 | return os.path.isfile(actual_key) |
| 3955 | |
| 3956 | def __getitem__(self, cache_key): |
| 3957 | """Retrieve value from a cache key.""" |
| 3958 | actual_key = self._convert_cache_key(cache_key) |
| 3959 | try: |
| 3960 | with open(actual_key) as f: |
| 3961 | return json.load(f) |
| 3962 | except (OSError, ValueError): |
| 3963 | raise KeyError(cache_key) |
| 3964 | |
| 3965 | def __delitem__(self, cache_key): |
| 3966 | actual_key = self._convert_cache_key(cache_key) |
| 3967 | try: |
| 3968 | key_path = Path(actual_key) |
| 3969 | key_path.unlink() |
| 3970 | except FileNotFoundError: |
| 3971 | raise KeyError(cache_key) |
| 3972 | |
| 3973 | def __setitem__(self, cache_key, value): |
| 3974 | full_key = self._convert_cache_key(cache_key) |
| 3975 | try: |
| 3976 | file_content = self._dumps(value) |
| 3977 | except (TypeError, ValueError): |
| 3978 | raise ValueError( |
| 3979 | f"Value cannot be cached, must be " |
| 3980 | f"JSON serializable: {value}" |
| 3981 | ) |
| 3982 | if not os.path.isdir(self._working_dir): |
| 3983 | os.makedirs(self._working_dir) |
| 3984 | with os.fdopen( |
| 3985 | os.open(full_key, os.O_WRONLY | os.O_CREAT, 0o600), 'w' |
| 3986 | ) as f: |
| 3987 | f.truncate() |
| 3988 | f.write(file_content) |
| 3989 | |
| 3990 | def _convert_cache_key(self, cache_key): |
no outgoing calls