Commit inicial

Habia trabajado un buen poco pero como vi que tenia que separar los
repositorios perdi bastante la historia :c
This commit is contained in:
Daniel Cortes
2020-05-22 00:05:27 -04:00
commit 3568abfbc7
44 changed files with 1841 additions and 0 deletions

71
utils/__init__.py Normal file
View File

@@ -0,0 +1,71 @@
import logging
from collections import Mapping
_log = logging.getLogger('utils')
_log.addHandler(logging.NullHandler())
def pretty_print_json(json_input):
"""Formats and prints json to stdout with colors using pygments"""
import json
from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import TerminalTrueColorFormatter
formatted_json = json.dumps(json_input, indent=2)
print(highlight(formatted_json, JsonLexer(), TerminalTrueColorFormatter()))
def message_response(status, error_message):
"""Sends an error response with the status code of the error and an explanation"""
from django.http import JsonResponse
json_message = {
'status_code': status,
'message': error_message
}
return JsonResponse(json_message, status=status)
# noinspection PyPep8Naming
def require_JSON(function):
"""Decorator to make a view only accept a json body"""
import functools
import json
@functools.wraps(function)
def decorator(*args, **kwargs):
try:
received_json = json.loads(args[0].body)
return function(*args, **kwargs, received_json=received_json)
except json.JSONDecodeError as error:
_log.warning(f'Function {function.__name__} got a non json request body')
return message_response(400, 'Se envío json no valido')
return decorator
def expected_keys(keys, dictionary):
for key in keys:
if key not in dictionary:
return f'No se encuentra {key}'
return None
def replace_key(json, old, new):
json[new] = json[old]
del json[old]
def sanitize_keys(json):
for key in list(json.keys()):
if '-' in key and key in json:
new_key = key.replace('-', '_')
replace_key(json, key, new_key)
return json

54
utils/cache.py Normal file
View File

@@ -0,0 +1,54 @@
import json
import logging
from blake3 import blake3
from redis import Redis
from django.conf import settings
_log = logging.getLogger('cache')
_log.addHandler(logging.NullHandler())
_redis = Redis()
class Cache:
""" Decorator that caches the result of a function
It works by generating a key given the function signature and uses it to store the result
of the function on redis, so if the function is called with the same parameters again it
will be cached and will retrieve the data from redis and will not execute the function.
It is assumed that the function will returns a dictionary that can be formatted to json.
"""
"""If caching is enabled"""
enabled = settings.CUSTOM_CACHE['enabled']
"""Time to expire, by default a week"""
expire = 60 * 60 * 24 * 7
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
if not self.enabled:
_log.info('Cache is disabled, executing function directly')
return self.function(*args, **kwargs)
_log.info(f'Caching function {self.function.__name__} with argument list {args} and dictionary {kwargs}')
key = f'{self.function.__name__}:{self.create_hash_key(args, kwargs)}'
_log.debug(f'Resolved key for function is "{key}"')
if _redis.exists(key):
_log.info(f'Key was in cache')
result = json.loads(_redis.get(key))
return result
else:
_log.info('Key was not in cache')
result = self.function(*args, **kwargs)
_redis.set(key, json.dumps(result), ex=self.expire)
return result
@staticmethod
def create_hash_key(args, kwargs):
return blake3((str(args) + str(kwargs)).encode('utf-8')).hexdigest()