예제 #1
0
    def cache(self):
        # Remove annoying depcration warning from flask-cache
        from flask.exthook import ExtDeprecationWarning
        warnings.simplefilter('ignore', ExtDeprecationWarning)

        if hasattr(self, '_cache'):
            return self._cache
        if CACHE_BACKEND_URI == 'memory://':
            cache = Cache(app, config={'CACHE_TYPE': 'simple'})
        elif CACHE_BACKEND_URI.startswith('redis://'):
            try:
                from redis import from_url as redis_from_url
                redis_from_url(CACHE_BACKEND_URI)
            except:
                print('BAD REDIS URL PROVIDED BY (CACHE_BACKEND_URI)')
                exit(1)

            cache = Cache(app, config={
                'CACHE_TYPE': 'redis',
                'CACHE_REDIS_URL': CACHE_BACKEND_URI,
                'CACHE_DEFAULT_TIMEOUT': 0  # NEVER EXPIRES
            })

        cache.init_app(self.app)
        self._cache = cache
        return self._cache
예제 #2
0
 def test_21_redis_url_custom_db(self):
     config = {
         'CACHE_TYPE': 'redis',
         'CACHE_REDIS_URL': 'redis://localhost:6379/2',
     }
     cache = Cache()
     cache.init_app(self.app, config=config)
     rconn = self.app.extensions['cache'][cache] \
                 ._client.connection_pool.get_connection('foo')
     assert rconn.db == 2
예제 #3
0
 def test_21_redis_url_custom_db(self):
     config = {
         'CACHE_TYPE': 'redis',
         'CACHE_REDIS_URL': 'redis://localhost:6379/2',
     }
     cache = Cache()
     cache.init_app(self.app, config=config)
     rconn = self.app.extensions['cache'][cache] \
                 ._client.connection_pool.get_connection('foo')
     assert rconn.db == 2
예제 #4
0
 def test_20_redis_url_default_db(self):
     config = {
         'CACHE_TYPE': 'redis',
         'CACHE_REDIS_URL': 'redis://localhost:6379',
     }
     cache = Cache()
     cache.init_app(self.app, config=config)
     from werkzeug.contrib.cache import RedisCache
     assert isinstance(self.app.extensions['cache'][cache], RedisCache)
     rconn = self.app.extensions['cache'][cache] \
                 ._client.connection_pool.get_connection('foo')
     assert rconn.db == 0
예제 #5
0
 def test_20_redis_url_default_db(self):
     config = {
         'CACHE_TYPE': 'redis',
         'CACHE_REDIS_URL': 'redis://localhost:6379',
     }
     cache = Cache()
     cache.init_app(self.app, config=config)
     from werkzeug.contrib.cache import RedisCache
     assert isinstance(self.app.extensions['cache'][cache], RedisCache)
     rconn = self.app.extensions['cache'][cache] \
                 ._client.connection_pool.get_connection('foo')
     assert rconn.db == 0
예제 #6
0
def create_app(object_name):
    """
    An flask application factory, as explained here:
    http://flask.pocoo.org/docs/patterns/appfactories/

    Arguments:
        object_name: the python path of the config object,
                     e.g. app.settings.ProdConfig
    """

    # app = Flask(__name__)
    app = CustomFlask(__name__)

    app.config.from_object(object_name)

    # initialize the cache
    cache = Cache()
    cache.init_app(app)

    # register SQLAlchemy
    db.init_app(app)

    # register Marshmallow
    ma.init_app(app)

    # register flask_restful api
    api.init_app(app)

    # register LoginManager
    login_manager.init_app(app)

    # register our blueprints
    app.register_blueprint(main)

    if not app.debug:
        import logging

        event_handler = logging.FileHandler("logfile.txt")
        event_handler.setFormatter(
            logging.Formatter('%(asctime)s %(levelname)s: %(message)s '
                              '[in %(pathname)s:%(lineno)d]'))

        event_handler.setLevel(logging.WARNING)
        app.logger.addHandler(event_handler)

    return app
예제 #7
0
파일: __init__.py 프로젝트: RuthMunuthi/tms
JINJA_ENVIRONMENT.globals['STATIC_PREFIX'] = '/'

app.route = prefix_route(app.route, '/api/{0}'.format(app.config['VERSION']))

app.config['MEMCACHIER_USERNAME'] = '******'
app.config['MEMCACHIER_PASSWORD'] = '******'
# app.config['MEMCACHIER_SERVERS'] = 'mc3.c1.eu-central-1.ec2.memcachier.com:11211'
app.config['MEMCACHIER_SERVERS'] = None
bcrypt = Bcrypt(app)
db = SQLAlchemy(app)

cache_servers = app.config['MEMCACHIER_SERVERS']
if cache_servers == None:
    # Fall back to simple in memory cache (development)
    cache.init_app(app, config={'CACHE_TYPE': 'simple'})
else:
    cache_user = app.config['MEMCACHIER_USERNAME'] or ''
    cache_pass = app.config['MEMCACHIER_PASSWORD'] or ''
    cache.init_app(app,
                   config={
                       'CACHE_TYPE': 'saslmemcached',
                       'CACHE_MEMCACHED_SERVERS': cache_servers.split(','),
                       'CACHE_MEMCACHED_USERNAME': cache_user,
                       'CACHE_MEMCACHED_PASSWORD': cache_pass
                   })

# cache_servers = app.config['MEMCACHIER_SERVERS']
# if cache_servers == None:
# 	cache.init_app(app, config={'CACHE_TYPE': 'simple'})
# else:
예제 #8
0
def register_cache(app):
    cache = Cache()
    cache.init_app(app)
    return cache
예제 #9
0
    from flask_caching import Cache

# In[] Set up application and server
app = dash.Dash(__name__)

# The stylesheet is based one of the DASH examples
# (oil and gas extraction in New York)
app.css.append_css({'external_url': 'https://rawgit.com/WilliamsTravis/' +
                    'PRF-USDM/master/dash-stylesheet.css'})

# Create server object
server = app.server

# Create and initialize a cache for storing data - data pocket
cache = Cache(config={'CACHE_TYPE': 'simple'})
cache.init_app(server)

# Create a container for the graphs
layout = dict(
    autosize=True,
    height=500,
    font=dict(color='black'),
    titlefont=dict(color='black',
                   size='20',
                   weight='bold'),
    margin=dict(
        l=55,
        r=35,
        b=65,
        t=55,
        pad=4
예제 #10
0
def register_cache(app):
    cache = Cache()
    cache.init_app(app)
    return cache
예제 #11
0
"""
  Created by kebo on 2018/7/28
"""

from flask import Flask, jsonify, Response
from app.utils.res import Res
from app.utils.cache import cached, delete_like
import os

from flask_cache import Cache
app = Flask(__name__)
cache = Cache(config={'CACHE_TYPE': 'simple'})
cache.init_app(app)  # 注册缓存
# 重写缓存key_prefix机制
cache.cached = cached
cache.delete_like = delete_like

app.config.from_object('app.settings')

# 注册蓝图
from app.api.v1 import api_v1 as api_v1_blueprint
app.register_blueprint(api_v1_blueprint, url_prefix='/service/api/v1')

from app.admin import admin as admin_blueprint
app.register_blueprint(admin_blueprint, url_prefix='/service/admin')


@app.route('/service/static/uploads/<path>/<uri>')
def get_image(path, uri):
    sep = os.path.sep
    uri = path + sep + uri
예제 #12
0
    - Supported communication to human by sound
    - Record and process sound of human
    - Organize code to class method
"""

__author__ = "Chau.Tran"
__version__ = "1.4"

# TO DO LISTS
# 1. Add web interface
# 2. Add to process and support sound from human

flask_chatbot = Flask(__name__)

cache = Cache(flask_chatbot, config={'CACHE_TYPE': 'simple'})
cache.init_app(flask_chatbot)


def make_cached_key():
    get_args = request.args
    post_args = request.form

    if post_args:
        return flask.request.path + '?' + urllib.urlencode(
            [(k, v) for k in sorted(post_args)
             for v in sorted(post_args.getlist(k))])

    if get_args:
        return flask.request.path + '?' + urllib.urlencode(
            [(k, v) for k in sorted(get_args)
             for v in sorted(get_args.getlist(k))])
예제 #13
0
class FlaskJanitoo(object):

    def __init__(self, app=None, options=None, db=None):
        self._app = app
        self._db = db
        self.options = options
        if self.options is not None and 'conf_file' in self.options and self.options['conf_file'] is not None:
            logging_fileConfig(self.options['conf_file'])
        self._listener = None
        self._listener_lock = None
        self._sleep = 0.25
        self.menu_left = []
        # Bower
        self.bower = Bower()
        # Caching
        self.cache = Cache()

    def __del__(self):
        """
        """
        try:
            self.stop_listener()
        except Exception:
            pass

    def init_app(self, app, options, db=None):
        """
        """
        if app is not None:
            self._app = app
        if options is not None:
            self.options = options
        if db is not None:
            self._db = db
        if self.options is not None and 'conf_file' in self.options and self.options['conf_file'] is not None:
            logging_fileConfig(self.options['conf_file'])

        # Flask-Cache
        self.cache.init_app(self._app)
        # Flask-Bower
        self.bower.init_app(self._app)

        self._event_manager = EventManager(self._app)
        self._app.jinja_env.globals["emit_event"] = self._event_manager.template_emit
        if not hasattr(self._app, 'extensions'):
            self._app.extensions = {}
        self._app.extensions['options'] = self.options
        self._app.extensions['bower'] = self.bower
        self._app.extensions['cache'] = self.cache
        self._app.extensions['janitoo'] = self
        try:
            self._sleep = int(self._app.config['FLASKJANITOO_SLEEP'])
            if self._sleep <= 0 :
                self._sleep = 0.25
        except KeyError:
            self._sleep = 0.25
        except ValueError:
            self._sleep = 0.25
        # Use the newstyle teardown_appcontext if it's available,
        # otherwise fall back to the request context
        if hasattr(self._app, 'teardown_appcontext'):
            self._app.teardown_appcontext(self.teardown)
        else:
            self._app.teardown_request(self.teardown)
        signal.signal(signal.SIGTERM, self.signal_term_handler)
        signal.signal(signal.SIGINT, self.signal_term_handler)
        self._listener_lock = threading.Lock()

        self.create_listener()

    def create_listener(self):
        """Create the listener on first call
        """
        self._listener = ListenerThread(self._app, self.options)

    @property
    def listener(self):
        """Start the listener on first call
        """
        self.start_listener()
        return self._listener

    def start_listener(self):
        """Start the listener on first call
        """
        try:
            self._listener_lock.acquire()
            if not self._listener.is_alive():
                self._listener.start()
        finally:
            self._listener_lock.release()

    def stop_listener(self):
        """Stop the listener
        """
        try:
            self._listener_lock.acquire()
            self._listener.stop()
            try:
                self._listener.join()
            except RuntimeError:
                pass
            self._listener = None
        finally:
            self._listener_lock.release()

    def extend_blueprints(self, group):
        """
        """
        for entrypoint in iter_entry_points(group = '%s.blueprint'%'janitoo_manager'):
            logger.info('Add blueprint from %s', entrypoint.module_name )
            bprint, url = entrypoint.load()()
            self._app.register_blueprint(bprint, url_prefix=url)
        for entrypoint in iter_entry_points(group = '%s.menu_left'%group):
            logger.info('Extend menu_left with %s', entrypoint.module_name )
            self.menu_left.append(entrypoint.load()())
        self._app.template_context_processors[None].append(lambda : dict(jnt_menu_left=self.menu_left))

    def extend_network(self, group):
        """"Extend the network with methods found in entrypoints
        """
        if self._listener and self._listener.network:
            self._listener.network.extend_from_entry_points(group)
        else:
            raise RuntimeError("Can't extend an uninitialized network")

    def extend_listener(self, group):
        """"Extend the network with methods found in entrypoints
        """
        if self._listener:
            self._listener.extend_from_entry_points(group)
        else:
            raise RuntimeError("Can't extend an uninitialized listener")

    def signal_term_handler(self, signal, frame):
        """
        """
        logger.info("[ %s ] - Received signal %s", self.__class__.__name__, signal)
        if self._listener and self._listener.is_alive():
            self._listener.stop()
            try:
                self._listener.join()
            except AssertionError:
                logger.exception("Catched exception in signal_term_handler: ")
            except RuntimeError:
                logger.exception("Catched exception in signal_term_handler: ")
        sys.exit(0)

    #~ def connect(self):
        #~ return sqlite3.connect(current_app.config['SQLITE3_DATABASE'])

    #~ @property
    #~ def backend(self):
        #~ ctx = stack.top
        #~ if ctx is not None:
            #~ if not hasattr(ctx, 'tinyflow_backend'):
                #~ ctx.tinyflow_backend = self._backend
            #~ return ctx.tinyflow_backend
#~
    #~ @property
    #~ def thread(self):
        #~ ctx = stack.top
        #~ if ctx is not None:
            #~ if not hasattr(ctx, 'tinyflow_server'):
                #~ ctx.tinyflow_server = self._server
            #~ return ctx.tinyflow_server
#~
    def teardown(self, exception):
        pass
예제 #14
0
from flask_cache import Cache
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from markdown.extensions.wikilinks import WikiLinkExtension

DocTrainApp = Flask(__name__)
DocTrainApp.config.from_pyfile("conf.py", False)

DocTrainDB = SQLAlchemy()
DocTrainDB.init_app(DocTrainApp)

from models import init_db
from models.user_models import User

DocTrainCache = Cache()
DocTrainCache.init_app(DocTrainApp)

login_manager = LoginManager()


@login_manager.user_loader
def load_user(userid):
    return User.query.filter_by(id=userid).first()


login_manager.login_view = "/login"
login_manager.init_app(DocTrainApp)

from views.index import blueprint as index_blueprint
from views.project import blueprint as project_blueprint
예제 #15
0
def register_cache(app):
    cache = Cache(config={'CACHE_TYPE': 'redis'})
    cache.init_app(app)
    return cache
예제 #16
0
파일: rfsvc.py 프로젝트: pranab/avenir
# permissions and limitations under the License.

import os
import sys
from flask import Flask, jsonify, request
from flask import current_app
#from flask.ext.cache import Cache
from flask_cache import Cache
sys.path.append(os.path.abspath("../supv"))
from rf import *

#REST service random forest prediction
app = Flask(__name__)
cache = Cache()
app.config['CACHE_TYPE'] = 'simple'
cache.init_app(app)

configPath = sys.argv[1]
portNum = int(sys.argv[2])

@app.route('/rf/predict/<string:recs>', methods=['GET'])
def predict(recs):
	print recs
	nrecs = recs.replace(",,", "\n")
	print nrecs
 	resp = getResponse(nrecs)
	return resp


@app.route('/rf/predict/batch', methods=['GET', 'POST'])
def batchPredict():
예제 #17
0
def register_cache(app):
    cache = Cache(config={'CACHE_TYPE': 'redis'})
    cache.init_app(app)
    return cache
예제 #18
0
def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)

    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'eyesight.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    CORS(app, support_credentials=True)

    # 使用Flask-Cache
    # http://www.pythondoc.com/flask-cache/index.html

    # Check Configuring Flask-Cache section for more details
    cache = Cache(app, config={'CACHE_TYPE': 'simple'})
    cache.init_app(app)

    cachePortrait = Cache(app, config={'CACHE_TYPE': 'simple'})
    cachePortrait.init_app(app)

    @cache.cached(timeout=5, key_prefix='classIdCnt')
    def cache_classIdCnt(method, data):
        if (method == "save"):
            saved_id = json.dumps(data)
            cache.set('classidcnt', saved_id, timeout=5)

            print("classid缓存成功")
        elif (method == "load"):
            return cache.get('classidcnt')

    @cachePortrait.cached(timeout=5, key_prefix='portrait')
    def cache_portrait(method, data):
        if (method == "save"):

            saved_portrait = json.dumps(data)
            #print(saved_portrait)
            cache.set('portrait', saved_portrait, timeout=5)

            print("portrait缓存成功")
        elif (method == "load"):
            print(cache.get('portrait'))
            return cache.get('portrait')

    #Video streaming generator function
    def gen(type):
        while True:
            if type == 'POST':
                fopen = [open('loaded.jpg', 'rb').read()]
                frame = fopen[0]
                time.sleep(0.1)
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

            elif type == 'UDP':
                sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

                host = ''
                port = 1082
                server_address = (host, port)

                #允许复用地址
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                sock.bind(server_address)
                print("UDP LINK BIND COMPLETE")
                data, server = sock.recvfrom(65507)
                print("Fragment size : {}".format(len(data)))
                if len(data) == 4:
                    # This is a message error sent back by the server
                    if (data == "FAIL"):
                        continue
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + data + b'\r\n')

    # a simple page that says hello
    @app.route('/hello', methods=['GET', 'POST'])
    def hello():
        if (request.method == 'POST'):
            post_json = request.get_json()
            return jsonify({'you sent': post_json}), 201
        else:
            return jsonify({'about': "Hello World"})

    # route带参数
    #  http://127.0.0.1:5000/multi/100
    @app.route('/multi/<int:num>', methods=['GET'])
    def get_multuply(num):
        return jsonify({'result': num * 10})

    # API Objectdatas resource

    @app.route('/api/objectdatas', methods=['GET', 'POST'])
    def api_objects():
        if (request.method == 'POST'):
            objects_json = request.get_json()
            obj_ndarray = np.array(objects_json['data'][1])
            obj_name = objects_json['data'][0]
            print(obj_ndarray)
            cv2.imwrite('eyesight/objectdatas/%s.jpg' % obj_name, obj_ndarray)
            print("目标剪切图片保存完成")
            return 201

        else:
            print("GET")

    # API livestream
    @app.route('/api/livestream/udp', methods=['GET'])
    def api_livestream():
        # Create a UDP socket

        return Response(gen('UDP'),
                        mimetype='multipart/x-mixed-replace; boundary=frame')

    # API classid
    # 每一帧目标捕获数统计
    @app.route('/api/classid', methods=['GET', 'POST'])
    def api_classid():
        if (request.method == 'POST'):
            classid_json = request.get_json()

            classid_data = classid_json['data']
            print(classid_data)
            cache_classIdCnt("save", classid_data)

            return jsonify({'clasdid_data': classid_data}), 201

        elif (request.method == 'GET'):

            print("GET CLASS ID---")
            print(cache_classIdCnt("load", None))
            return cache_classIdCnt("load", None)

    #API portrait
    @app.route('/api/portrait', methods=['GET', 'POST'])
    def api_portrait():
        if (request.method == 'POST'):
            portrait_json = request.get_json()

            portrait_data = portrait_json['data']
            print('[POST Portrait Data]')

            cache_portrait("save", portrait_data)
            return jsonify({'portrait_data': portrait_data}), 201

        elif (request.method == 'GET'):
            print("[GET Portrait Data]")

            print(cache_portrait("load", None))
            return cache_portrait("load", None)

    # sample
    #serach query
    @app.route('/search', methods=['GET', 'POST'])
    @cross_origin(supports_credentials=True)
    def search():
        params = {'query': request.args.get('query')}
        if params['query'] == 'test':
            persons = [{
                'name': 'david',
                'age': 10
            }, {
                'name': 'black',
                'age': 19
            }]
            print("test")
            return json.dumps(persons)

        if params['query'] == 'object':
            path = 'eyesight/objectdatas'
            datas = []
            for file in os.listdir(path):
                name = file.split(':', 1)[0]
                value = file.split(':', 1)[1][:-3]
                #img = cv2.imread(path + '/'+file).tolist()
                with open(path + '/' + file, 'rb') as f:
                    img = base64.b64encode(f.read())
                img = img.decode('utf-8')  #将image2str转为str
                #imgstr = bytes.decode(img)
                #img = Response(img, mimetype="image/jpeg")
                #print(name+value)
                datas.append({'img': img, 'name': name, 'value': value})
            #print(datas)
            return json.dumps(datas)

        return "OK"

    from . import db
    db.init_app(app)

    from . import auth
    app.register_blueprint(auth.bp)
    return app
예제 #19
0
파일: v2ex.py 프로젝트: imlyj/slack_bot
def test(data):
    return data['message'].startswith('v2ex')


def handle(data, cache=None, **kwargs):
    message = data['message']
    ids = fetch(cache=cache, force=(True if u'刷新' in message else False))
    contents = []
    for id in ids:
        topic = cache.get(TOPIC_KEY.format(id))
        if not topic:
            continue
        node = topic['node']
        msg = u'<{0}|{1} [{2}]>   <{3}|{4}>'.format(TOPIC_URL.format(id),
                                                    cgi.escape(topic['title']),
                                                    topic['published'],
                                                    NODE_URL.format(node),
                                                    node)
        contents.append(msg)
    return '\n'.join(contents)


if __name__ == '__main__':
    from flask import Flask
    from flask_cache import Cache
    app = Flask(__name__)
    cache = Cache()
    cache.init_app(app, config={'CACHE_TYPE': 'simple'})
    with app.app_context():
        print handle({'message': 'v2ex'}, cache, app)
예제 #20
0
    def test_17_dict_config(self):
        cache = Cache(config={'CACHE_TYPE': 'simple'})
        cache.init_app(self.app)

        assert cache.config['CACHE_TYPE'] == 'simple'
예제 #21
0
# coding:utf-8
from flask import Flask  # 默认
from flask_cache import Cache  # 缓存

# from pymysqlpool import ConnectionPool
# app入口定义
app = Flask(__name__)

cache = Cache()
config = {
    'CACHE_TYPE': 'redis',
    'CACHE_REDIS_HOST': '127.0.0.1',
    'CACHE_REDIS_PORT': 6379,
    'CACHE_REDIS_DB': '1',
    # 'CACHE_REDIS_PASSWORD': '******'
}
app.config.from_object(config)
cache.init_app(app, config)
app.config.update(SECRET_KEY='tanxiangyu')
예제 #22
0
 def test_19_dict_config_both(self):
     cache = Cache(config={'CACHE_TYPE': 'null'})
     cache.init_app(self.app, config={'CACHE_TYPE': 'simple'})
     from werkzeug.contrib.cache import SimpleCache
     assert isinstance(self.app.extensions['cache'][cache], SimpleCache)
예제 #23
0
 def test_18_dict_config_initapp(self):
     cache = Cache()
     cache.init_app(self.app, config={'CACHE_TYPE': 'simple'})
     from cachelib import SimpleCache
     assert isinstance(self.app.extensions['cache'][cache], SimpleCache)
예제 #24
0
    def test_17_dict_config(self):
        cache = Cache(config={'CACHE_TYPE': 'simple'})
        cache.init_app(self.app)

        assert cache.config['CACHE_TYPE'] == 'simple'
예제 #25
0
 def test_21_init_app_sets_app_attribute(self):
     cache = Cache()
     cache.init_app(self.app)
     assert cache.app == self.app
예제 #26
0
파일: gbtsvc.py 프로젝트: yeedas/avenir
# permissions and limitations under the License.

import os
import sys
from flask import Flask, jsonify, request
from flask import current_app
#from flask.ext.cache import Cache
from flask_cache import Cache
sys.path.append(os.path.abspath("../supv"))
from gbt import *

#REST service gradient boosted tree prediction
app = Flask(__name__)
cache = Cache()
app.config['CACHE_TYPE'] = 'simple'
cache.init_app(app)

configPath = sys.argv[1]
portNum = int(sys.argv[2])


@app.route('/gbt/predict/<string:recs>', methods=['GET'])
def predict(recs):
    print recs
    nrecs = recs.replace(",,", "\n")
    print nrecs
    resp = getResponse(nrecs)
    return resp


@app.route('/gbt/predict/batch', methods=['GET', 'POST'])
예제 #27
0
 def test_19_dict_config_both(self):
     cache = Cache(config={'CACHE_TYPE': 'null'})
     cache.init_app(self.app, config={'CACHE_TYPE': 'simple'})
     from werkzeug.contrib.cache import SimpleCache
     assert isinstance(self.app.extensions['cache'][cache], SimpleCache)