Extension System
Glim provides an extension system where developers can further improve the functionality of glim. The core package is currently providing solutions for the common problems of web development. However, you can easily develop extensions and integrate tightly to glim framework. Ok, ready ? let's get started!
Configuration
In glim, the default configuration comes with a dict namely "extensions". In this key, the enabled app extensions and its configuration should be defined. Consider an example of a redis extension namely "gredis". The extension configuration would be the following;
# app/config/<env>.py
config = {
# ...
'extensions': {
'gredis' : {
'default': {
'host': 'localhost',
'port': '6379',
'db': 0
}
}
},
# ...
}
This configuration simply says to glim that an extension named "gredis" should be enabled with the configuration inside the '"default" key when the web server starts. The default key exists for connection aliasing. It's there for redis extension to handle multiple redis connections.
After this configuration is enabled, glim will look for an extension (a folder) called "gredis" in ext
folder.
Configuration is optional but recommended
In glim, the extensions can also be loaded during runtime with explicitly instantiating the classes of the extension, But the configuration above would be much more easy to boot an extension. You can use manually if an extension doesn't require to be booted up once and used everywhere.
The extension module and start
The following file structure could be used to create extensions;
gredis
āāā __init__.py
āāā gredis.py
āāā requirements
āāā start.py
The gredis.py holds the core classes to use them and a Facade
class that can boot these core objects with configuration and hold the instance of it. The start.py is used bunch of statements when the extension is enabled. "requirements" can be used for 3rd party dependencies of pypi. So, let's have a look at this extension;
# gredis.py
from glim.core import Facade
from glim.component import Extension
from glim.facades import Log
import redis
class GredisExtension(Extension):
def __init__(self, config):
self.config = config
self.active = 'default'
self.connections = {}
for k, config in self.config.items():
self.connections[k] = self.connect(config)
def __getattr__(self, attr):
try:
return getattr(self.connections[self.active], attr)
except redis.RedisError, e:
Log.error(e)
return None
def connection(self, key = None):
if key:
self.active = key
else:
self.active = 'default'
return self
def connect(self, config):
try:
connection = redis.StrictRedis(
host = config['host'],
port = config['port'],
db = config['db'])
connection.ping()
return connection
except redis.RedisError, e:
Log.error(e)
return None
class Redis(Facade):
accessor = GredisExtension
As it can be noticed, this extension has the simplest two class to make redis available for glim. The GredisExtension
includes of the whole implementation of the redis client. The Redis
class is there for to persist the GredisExtension
to the runtime. The Redis
class is only there to keep the GredisExtension instance.
The start.py file would be the following in this case;
from ext.gredis import Redis
def before(config):
Redis.register(config)
The before
function is automatically called by glim after enabling the extension from configuration. The config is also passed by glim's extension loader. Redis.register
statement simply makes the redis instance persist like in a singleton manner but not completely. Glim approach doesn't use any kind of private like constructors or singletons. Instead, it creates Facades to keep the instances in a static manner.
Best practice
Don't use singletons in glim. Use facades to contain object's instance instead. Singletons are bad and they are much more difficult to test.
The installation of an extension
The installation of an extension is to move the extension folder inside ext
folder and install its dependencies. In this case the installation would be the following;
$ . venv/bin/activate
$ cp <gredis-file-path> ext/.
$ pip install requirements
Manual installation.. pff.
Currently, the installation of a glim extension is manual. The further releases of glim will provide great feature to install and enable extensions from command line.
You can check the code of other extensions;
- glim-migrations - RDB Migrations for glim
- glim-jobqueue - A redis job producing / consuming extension
- glim-memcached - The memcached extension for glim.
Updated less than a minute ago