6. API Documentation

This is the Mamba API documentation.

6.1. Mamba Application

Objects for build Mamba Applications

class mamba.Mamba(options=None)

This object is just a global configuration for mamba applications that act as the central object on them and is able to act as a central registry. It inherits from the :class: ~mamba.utils.borg.Borg so you can just instantiate a new object of this class and it will share all the information between instances.

You create an instance of the Mamba class in your main module or in your Twisted tac file:

from mamba import Mamba
app = Mamba({'name': 'MyApp', 'description': 'My App', ...})
Parameters:options (dict) – options to initialize the application with
class mamba.ApplicationError

ApplicationError raises when an error occurs

6.1.1. AppStyles

class mamba.AppStyles(config_file_name='config/installed_packages.json')

Manager for Application Stylesheets

seealso: Stylesheet

get_styles()

Return the mamba.Stylesheet pool

setup()

Setup the managers

6.1.2. AppScripts

class mamba.application.scripts.AppScripts(config_file_name='config/installed_packages.json')

Manager for Application Scripts

seealso: Script

get_scripts()

Return the mamba.Scripts pool

setup()

Setup the managers

6.1.3. Controllers

class mamba.application.controller.ControllerError

Raised on controller errors

class mamba.Controller(*args, **kwargs)

Mamba Controller Class define a web accesible resource and its actions.

A controller can (and should) be attached to a twisted.web.resource.Resource as a child or to others Controller.

Unlike twisted.web.resource.Resource, Controller don’t use the Twisted URL dispatching mechanism. The Controller uses Router for URL dispatching through the route() decorator:

@route('/hello_world', method='GET')
def helloworld(self, request, **kwargs):
    return 'Hello World'

See also

Router, Route

getChild(name, request)

This method is not supposed to be called because we are overriden the full route dispatching mechanism already built in Twisted.

Class variable level isLeaf is supposed to be always True but any users can override it in their Controller implementation so we make sure that the native twisted behavior is never executed.

If you need Twisted native url dispatching in your site you should use Resource class directly in your code.

Parameters:
  • name (string) – ignored
  • request (Request) – a twisted.web.server.Request specifying meta-information about the request that is being made for this child that is ignored at all.
Return type:

Controller

get_register_path()

Return the controller register path for URL Rewritting

prepare_headers(request, code, headers)

Prepare the back response headers

Parameters:
  • request (Request) – the HTTP request
  • code (int) – the HTTP response code
  • headers (dict) – the HTTP headers
render(request)

Render a given resource. see: twisted.web.resource.IResource‘s render method.

I try to render a router response from the routing mechanism.

Parameters:request (twisted.web.server.Request) – the HTTP request
route_dispatch(request)

Dispatch a route if any through the routing dispatcher.

Parameters:request (Request) – the HTTP request
Returns:twisted.internet.defer.Deferred or mamba.web.response.WebResponse
run(port=8080)

This method is used as a helper for testing purposes while you are developing your controllers.

You should never use this in production.

sendback(result, request)

Send back a result to the browser

Parameters:
  • request (Request) – the HTTP request
  • result (dict) – the result for send back to the browser
class mamba.application.controller.ControllerProvider

Mount point for plugins which refer to Controllers for our applications.

Controllers implementing this reference should implements the IController interface

class mamba.ControllerManager(store=None, package=None)

Uses a ControllerProvider to load, store and reload Mamba Controllers.

_model_store A private attribute that sets the prefix path for the controllers store :param store: if is not None it sets the _module_store attr

build_controller_tree()

Build the controller’s tree

get_controllers()

Return the controllers pool

is_valid_file(file_path)

Check if a file is a Mamba controller file

Parameters:file_path (str) – the file path of the file to check
length()

Returns the controller pool length

load(filename)

Loads a Mamba module

Parameters:filename (str) – the module filname
lookup(module)

Find and return a controller from the pool

Parameters:module (str) – the module to lookup
lookup_path(path)

Lookup for a controller using its path

Parameters:path (str) – the path to lookup for
reload(module)

Reload a controller module

Parameters:module (str) – the module to reload
setup()

Setup the loder and load the Mamba plugins

6.1.4. Models

class mamba.application.model.MambaStorm(name, bases, dict)

Metaclass for solve conflicts when using Storm base classes

If you need to inherit your models from storm.base.Storm class in order to use references before the referenced object had been created in the local scope, you need to set your class __metaclass__ as model.MambaStorm to prevent metaclasses inheritance problems. For example:

class Foo(model.Model, Storm):

    __metaclass__ = model.MambaStorm

warning:

Mamba support for database dump and SQL Schema generation through
Storm classes is possible because a monkeypatching and hack of
regular Storm behaviour, if you are not using Storm base classes
for your Reference's and ReferenceSet's you may experience weird
behaviours like not all the object columns being displayed in your
generated schema.

You should use mamba.application.model.MambaStorm metaclass
and storm.base.Storm classes in order to fix it
class mamba.application.model.ModelError

Base class for Model Exceptions

class mamba.Model

All the models in the application should inherit from this class.

We use the new storm.twisted.transact.Transactor present in the 0.19 version of Storm to run transactions that will block the reactor using a twsited.python.threadpool.ThreadPool to execute them in different threads so our reactor will not be blocked.

You must take care of don’t return any Storm object from the methods that interacts with the storm.Store underlying API because those ones are created in a different thread and cannot be used outside.

If you don’t want any of the methods in your model to run asynchronous inside the transactor you can set the class property __mamba_async__ as False and them will run synchronous in the main thread (blocking the reactor in the process).

We don’t care about the instantiation of the Storm Store because we use zope.transaction through storm.zope.zstorm.ZStorm that will take care of create different instances of Store per thread for us.

classmethod all(klass, order_by=None, desc=False, *args, **kwargs)

Return back all the rows in the database for this model

Parameters:
  • order_by (model property) – order the resultset by the given field/property
  • desc (bool) – if True, order the resultset by descending order

New in version 0.3.6.

copy(orig)

Copy this object properties and return it

create(*args, **kwargs)

Create a new register in the database

create_table(*args, **kwargs)

Create the table for this model in the underlying database system

delete(*args, **kwargs)

Delete a register from the database

dict(traverse=True, json=False, *parent, **kwargs)

Returns the object as a dictionary

Parameters:
  • traverse (bool) – if True traverse over references
  • json (bool) – if True we convert datetime to string and Decimal to float
  • fields – If set we filter only the fields specified,

mutually exclusive with exclude, having precedence if both are set. :type fields: list :param exclude: If set we exclude the fields specified, mutually exclusive with fields, not working if you also set fields. :type exclude: list

drop_table(*args, **kwargs)

Delete the table for this model in the underlying database system

dump_data(scheme=None)

Dumps the SQL data

dump_indexes()

Dump SQL indexes (used by PostgreSQL and SQLite)

dump_references()

Dump SQL references (used by PostgreSQL)

dump_table()

Dumps the SQL command used for create a table with this model

Parameters:
  • schema (str) – the SQL schema, SQLite by default
  • force_drop (bool) – when True drop the tables always
classmethod find(klass, *args, **kwargs)

Find an object in the underlying database

Some examples:

model.find(Customer.name == u”John”) model.find(name=u”John”) model.find((Customer, City), Customer.city_id == City.id)

New in version 0.3.6.

get_adapter()

Get a valid adapter for this model

get_primary_key()

Return back the model primary key (or keys if it’s compound)

get_uri()

Return an URI instance using the uri config for this model

json

Returns a JSON representation of the object (if possible)

classmethod mamba_database()

Return back the configured underlying mamba database (if any)

on_schema()

Checks if Mamba should take care of this model.

pickle

Returns a Pyhon Pickle representation of the object (if possible)

classmethod read(*args, **kwargs)

Read a register from the database. The give key (usually ID) should be a primary key.

Parameters:id (int) – the ID to get from the database
store(database=None)

Return a valid Storm store for this model

update(*args, **kwargs)

Update a register in the database

uri

Returns the database URI for this model

class mamba.application.model.ModelProvider

Mount point for plugins which refer to Models for our applications

class mamba.ModelManager(store=None, package=None)

Uses a ModelProvider to load, store and reload Mamba Models.

_model_store A private attribute that sets the prefix path for the models store :param store: if is not None it sets the _module_store attr

get_models()

Return the models pool

is_valid_file(file_path)

Check if a file is a Mamba model file

Parameters:file_path (str) – the file path of the file to check
length()

Returns the controller pool length

load(filename)

Loads a Mamba module

Parameters:filename (str) – the module filname
lookup(module)

Find and return a controller from the pool

Parameters:module (str) – the module to lookup
reload(module)

Reload a controller module

Parameters:module (str) – the module to reload
setup()

Setup the loder and load the Mamba plugins

6.2. Mamba Core

Core components of the Mamba framework itself.

6.2.1. Interfaces

Interfaces that are part of the Mamba Core, you are supossed to never use those ones unless you are developing new features for the Mamba framework itself.

class mamba.core.interfaces.INotifier

Every Inotifier class will implement this interface

_notify(ignore, file_path, mask)
Parameters:
  • ignore – ignored parameter
  • file_pathtwisted.python.filepath.Filepath on which the event happened
  • mask (int) – inotify event as hexadecimal mask
notifier

A twisted.internet.inotify.INotify instance where to watch a FilePath

class mamba.core.interfaces.IController

Manba Controllers interface.

Every controller will implement this interface

Parameters:
  • name (str) – Controller’s name
  • desc (str) – Controller’s description
  • loaded (bool) – true if the controller has been loaded, otherwise returns False
class mamba.core.interfaces.IDeployer

Mamba Deployers interface.

Every deployer must implement this interface

class mamba.core.interfaces.IResponse

Mamba Web Response interface.

Every web response must implement this interface.

Parameters:
  • code (int) – the HTTP response code
  • body (string) – the HTTP response body
  • headers (dict) – the HTTP response headers
class mamba.core.interfaces.IMambaSQL

Mamba SQL interface.

I’m usefull to create common SQL queries for create or alter tables for all the SQL backends supported by Mamba.

Parameters:original – the original underlying SQL backend type
class mamba.core.interfaces.ISession

Mamba Session interface. I’m just a Session interface used to store objects in Twisted Sessions

Parameters:session – A mamba session object

6.2.2. Decorators

mamba.core.decorators.cache(size=16)

Cache the results of the function if the same positional arguments are provided.

We only store the size provided (if any) in MB, after that we should perform FIFO queries until the size of the cache is lower than the provided one.

If the size is 0 then an unlimited cache is provided

Notice

The memory size of the int_cache is just an approximation

mamba.core.decorators.unlimited_cache(func)

Just a wrapper over cache decorator to alias @cache(size=0)()

6.2.3. Core Services

Core Services used by mamba applications

class mamba.core.services.threadpool.ThreadPoolService(pool)

Service to being started by twistd

This service handles and serve the ThreadPool that is used by Storm when we use the @transact decorator in out queries to use the Twisted integration

6.2.4. Packages

New in version 0.3.6.

Mamba packages are used by the Mamba reusability system to make posible the reuse of mamba applications and components between mamba applications.

class mamba.core.packages.PackagesManager(config_file='config/installed_packages.json')

The PackagesManager is used to register the shared packages that our mamba applications are going to import and use. The manager is instanced once by the Mamba borg and create and load controllers and models managers for every package that we want to use in our application.

Parameters:config_file (str) – the path to config file that we want to use

New in version 0.3.6.

register_packages()

Register packages found in the config file.

Styles and Scripts are a bit special and we register the main application ones here so we can refer all of them from the Resource subclasses and they will be auto imported in our templates

6.2.5. Resource

Mamba Resource object extends Twisted web Resources mainly to integrate the Jinja2 templating system

class mamba.core.resource.Resource

Mamba resources base class. A web accessible resource that add common properties for scripts in Mamba applications

6.2.6. Session

class mamba.core.session.MambaSession(session)

An authed session store object

class mamba.core.session.Session(site, uid, reactor=None)

Mamba session wrapper

authenticate()

Set authed as True

is_authed()

Return the authed value

set_lifetime(lifetime)

Set the sessionTimeout to lifetime value

Parameters:lifetime (int) – the value to set as session timeout in seconds

6.2.7. Templating

Mamba integrates the Jinja2 templating system as a core component of the framework.

class mamba.core.templating.MambaTemplate(env=None, template=None)

This class loads templates from the Mamba package and is used internally by Mamba. You are not supossed to use this class in your code

Parameters:
  • env (jinja2.Environment) – jinja2 environment
  • template (str) – the template to render
render(**kwargs)

Renders a template

class mamba.core.templating.Template(env=None, controller=None, size=50, template=None)

This class loads and render templates from Mamba Applications view and controller directories.

If controller is not None, then we use the controller directory templates instead of global view ones.

Parameters:
  • env – the Jinja2 environment
  • controller (Controller) – mamba controller that uses the templates
  • cache_size – size of the Jinja2 templating environment
Raises:

TemplateNotFound if no template is found in the filesystem

Raises:

NotConfigured it no parameters are provided

render(template=None, **kwargs)

Renders a template and get the result back

Parameters:template (string) – the template to render
class mamba.core.templating.TemplateError

Base class for Mamba Template related exceptions

class mamba.core.templating.NotConfigured

Raised when we are missing configuration

6.3. Deployment

Mamba integrates the Fabric deployment library and it’s used by Mamba itself to release new versions and deploy the framework to the live mamba web site. To see an example of usage you can check the mamba devel package on GitHub.

class mamba.deployment.deployer.DeployerImporter(filename)

Imports DeployerConfig files in a very similar way as __import__ does

mamba.deployment.deployer.deployer_import(name, path)

Import a deployer configuration file as Python code and initializes it

class mamba.deployment.fabric_deployer.FabricDeployer

Fabric Deployment System compatible with Mamba Plugabble Interface

deploy(config_file=None)

Deploys the system following the configuration in the config file

identify()

Returns the deployer identity

load(config_file)

Load the workflow rules from a Mamba .dc Python file

Parameters:config_file (str) – The file where to load the configuration from
operation_mode()

Return the operation mode for this deployer

class mamba.deployment.fabric_deployer.FabricMissingConfigFile

Fired when missing config file is detected

class mamba.deployment.fabric_deployer.FabricConfigFileDontExists

Fired when the config file does not exists

class mamba.deployment.fabric_deployer.FabricNotValidConfigFile

Fired when the config file is not valid

6.4. Http

Mamba Http Headers

class mamba.http.headers.Headers

An object that build the Application page header and returns it as a well formated XHTML/HTML string.

get_description_content()

Returns the Headers description

get_doctype()

Get the configured or default mamba doctype (html by default)

get_favicon_content(media='/media')

Returns the favicon

Parameters:media (str) – a media directory to add, defaults to /media
get_generator_content()

Returns the meta generator content

get_language_content()

Returns the Headers language

get_mamba_content()

Returns mamba specific meta content

6.5. Utils

Subpackage containing the modules that implement common utilities

6.5.1. Borg

class mamba.utils.borg.Borg

The Mamba Borg Class.

Every object created using the Borg pattern will share their information, as long as they refer to the same state information. This is a more elegant type of singleton, but, in other hand, Borg objects doesn’t have the same ID, every object have his own ID

Borg objects doesn’t share data between inherited classes. If a class A inherits from Borg and a class B inherits from A then A and B doesn’t share the same namespace

Example:

class LockerManager(borg.Borg):

    def __init__(self):
        super(LockerManager, self).__init__()

Used as:

>>> from managers import LockerManager
>>> manager1 = LockerManager()
>>> manager1.name = 'Locker One'
>>> manager2 = LockerManager()
>>> print(manager2.name)
Locker One
>>>

6.5.2. CamelCase

class mamba.utils.camelcase.CamelCase(camelize)

Stupid class that just offers stupid CamelCase funcionallity

Parameters:camelize (str) – the string to camelize
camelize(union=False)

Camelize and return camelized string

Parameters:union (bool) – if true is will use a space between words

6.5.3. Converter

class mamba.utils.converter.Converter

Object Converter class

static fix_common(value)

Fix commons uncommons

static serialize(obj)

Serialize an object and returns it back

6.5.4. config.Database

This class is used to load configuration files in JSON format from the file system. If no config is provided a basic configuration based on SQLite is automatically created for us.

class mamba.utils.config.Database(config_file='config/database.json')

Database configuration object

This object load and parses the configuration details for the database access using a JSON configuration file with this format:

{
    'uri': 'sqlite:',
    'min_threads': 5,
    'max_threads': 20,
    'auto_adjust_pool_size': false,
    'create_table_behaviours': {
        'create_table_if_not_exists': true,
        'drop_table': false
    },
    'drop_table_behaviours': {
        'drop_if_exists': true,
        'restrict': true,
        'cascade': false
    }
}

Where uri is the Storm URI format for create ZStores and min, max threads are the minimum and maximum threads in the thread pool for operate with the database. If auto_adjust_pool_size is True, the size of the thread pool should be adjust dynamically.

For create_table_bevaviour possible values are:

create_if_not_exists
this is the default behaviour and it should add ‘IF DONT EXISTS’ to the table creation scripts
drop_table
this behaviour will always drop a table before try to create it. Be carefull with this behaviour because you can lose all your data if you dont take care of it

If no config_file or invalid config_file is given at first load attempt, then a fallback default settings with a SQLite in memory table are returned back.

If you loaded a valid config file and you instance the database config again with an invalid JSON format file, then a fallback default settings with SQLite in memory URI is returned back in order to preserve your data (if we don’t fallback to a default configuration you can overwrite important data in your previous well configured environment).

If you loaded a valid config file and pass a non existent or a void file in the constructor you get back your previous config so you can use it like a singleton instance:

config.Database('path/to/my_valid/config.json')
...
cfg = config.Database()

If you want to clear your config and return it back to a default state you should pass ‘clean’ or ‘default’ as parameter:

config.Database('default')

If the URI property is a dictionary, mamba will then create configuration and conections for each element in the dictionary using the key as ZStorm name and the value as the URI. Then you can get speific stores for specific URI’s using the store method in the database object.

Parameters:config_file (str) – the file to load the configuration from, it can (and should) be empty to get back the previous configured data
static write(options)

Write options to the configuration file

Parameters:options (dict) – the options from the mamba-admin commands tool

6.5.5. config.Application

As with the previous one, this class is used to load configuration related with the application from files in JSON format in the file system. If no configuration file is provided, a basic configuration is automatically created for us.

class mamba.utils.config.Application(config_file='')

Application configuration object

This object loads and parses the Mamba application configuration options using a JSON file with the following format:

{
    "name": "Mamba Application",
    "description": "Mamba application description",
    "version": 1.0
    "port": 8080,
    "doctype": "html",
    "content_type": "text/html",
    "description": "My cool application",
    "language": "en",
    "description": "This is my cool application",
    "favicon": "favicon.ico",
    "platform_debug": false,
    "development": true,
    "debug": false
}

If we want to force the mamba application to run under some specific twisted reactor, we can add the “reactor” option to the configuration file to enforce mamba to use the configured reactor.

Parameters:config_file (str) – the JSON file to load

6.5.6. config.InstalledPackages

New in version 0.3.6.

This is used to load configuration realated to the Mamba reusability system. If no configuration file is provided (or it doesn’t exists), a basic configuration is automatically created for us.

class mamba.utils.config.InstalledPackages(config_file='')

Instaleld Packages configuration object

This object loads and parses configuration that indicates to the Mamba framework that this application have to import and register the indicated shared packages.

The JSON file must follow this format:

{
    "packages": {
        "package_one": {"autoimport": true, "use_scripts": true},
        "package_two": {"autoimport": true, "use_scripts": false},
        "package_three": {"autoimport": false, "use_scripts": true}
    }
}

The packages must be installed already in the system

Parameters:config_file (str) – the JSON file to load

6.5.7. Less

class mamba.utils.less.LessCompiler(style, exe='lessc', path=None)

Compile LESS scripts if LESS NodeJS compiler is present. Otherwise adds the less.js JavaScript compiler to the page.

compile()

Compile a LESS script

class mamba.utils.less.LessResource(path=None)

Mamba LessResource class define a web accesible LESS script

entityType = <InterfaceClass twisted.web.resource.IResource>
getChild(path, request)

Retrieve a ‘child’ resource from me.

Implement this to create dynamic resource generation – resources which are always available may be registered with self.putChild().

This will not be called if the class-level variable ‘isLeaf’ is set in your subclass; instead, the ‘postpath’ attribute of the request will be left as a list of the remaining path elements.

For example, the URL /foo/bar/baz will normally be:

| site.resource.getChild('foo').getChild('bar').getChild('baz').

However, if the resource returned by ‘bar’ has isLeaf set to true, then the getChild call will never be made on it.

Parameters and return value have the same meaning and requirements as those defined by L{IResource.getChildWithDefault}.

getChildWithDefault(path, request)

Retrieve a static or dynamically generated child resource from me.

First checks if a resource was added manually by putChild, and then call getChild to check for dynamic resources. Only override if you want to affect behaviour of all child lookups, rather than just dynamic ones.

This will check to see if I have a pre-registered child resource of the given name, and call getChild if I do not.

@see: L{IResource.getChildWithDefault}

putChild(path, child)

Register a static child.

You almost certainly don’t want ‘/’ in your path. If you intended to have the root of a folder, e.g. /foo/, you want path to be ‘’.

@see: L{IResource.putChild}

render(request)

Render a given resource. See L{IResource}’s render method.

I delegate to methods of self with the form ‘render_METHOD’ where METHOD is the HTTP that was used to make the request. Examples: render_GET, render_HEAD, render_POST, and so on. Generally you should implement those methods instead of overriding this one.

render_METHOD methods are expected to return a byte string which will be the rendered page, unless the return value is C{server.NOT_DONE_YET}, in which case it is this class’s responsibility to write the results using C{request.write(data)} and then call C{request.finish()}.

Old code that overrides render() directly is likewise expected to return a byte string or NOT_DONE_YET.

@see: L{IResource.render}

render_GET(request)

Try to compile a LESS file and then serve it as CSS

render_HEAD(request)

Default handling of HEAD method.

I just return self.render_GET(request). When method is HEAD, the framework will handle this correctly.

6.5.8. Output

Output printing functionallity based and partially taken from Gentoo portage system

6.6. Web

Subpackage containing the modules that implement web stuff for projects

6.6.1. AsyncJSON

class mamba.web.asyncjson.AsyncJSON(value)

Asynchronous JSON response.

I use a cooperate Twisted task in order to create a producer that send huge amounts of JSON data in an asynchronous way.

If the data being serialized into JSON is huge, the serialization process can take longest than the browser waiting response and can block itself the web server, preventing other requests from being serviced. This class prevents that type of inconveniences.

This class is based on Jean Paul Calderone post at:
http://jcalderone.livejournal.com/55680.html

6.6.2. Page

class mamba.web.Page(app, template_paths=None, cache_size=50, loader=None)

This represents a full web page in mamba applications. It’s usually the root page of your web site/application.

The controllers for the routing system are eregistered here. We first register any package shared controller because we want to overwrite them if our application defines the same routes.

Parameters:
  • app (Application) – The Mamba Application that implements this page
  • template_paths – additional template paths for resources
  • cache_size – the cache size for Jinja2 Templating system
  • loader – Jinja2 custom templating loader
add_script(script)

Adds a script to the page

add_template_paths(paths)

Add template paths to the underlying Jinja2 templating system

entityType = <InterfaceClass twisted.web.resource.IResource>
generate_dispatches()

Generate singledispatches

getChild(path, request)

If path is an empty string or index, render_GET should be called, if not, we just look at the templates loaded from the view templates directory. If we find a template with the same name than the path then we render that template.

Caution

If there is a controller with the same path than the path parameter then it will be hidden and the template in templates path should be rendered instead

Parameters:
  • path (str) – the path
  • request – the Twisted request object
getChildWithDefault(path, request)

Retrieve a static or dynamically generated child resource from me.

First checks if a resource was added manually by putChild, and then call getChild to check for dynamic resources. Only override if you want to affect behaviour of all child lookups, rather than just dynamic ones.

This will check to see if I have a pre-registered child resource of the given name, and call getChild if I do not.

@see: L{IResource.getChildWithDefault}

initialize_templating_system(template_paths, cache_size, loader)

Initialize the Jinja2 templating system for static HTML resources

insert_scripts()

Insert scripts to the HTML

insert_stylesheets()

Insert stylesheets into the HTML

putChild(path, child)

Register a static child.

You almost certainly don’t want ‘/’ in your path. If you intended to have the root of a folder, e.g. /foo/, you want path to be ‘’.

@see: L{IResource.putChild}

register_controllers()

Add a child for each controller in the ControllerManager

register_shared_controllers()

Add a child for each shared package controller. If the package includes a static files directory we add an asset for it

New in version 0.3.6.

render(request)

Render a given resource. See L{IResource}’s render method.

I delegate to methods of self with the form ‘render_METHOD’ where METHOD is the HTTP that was used to make the request. Examples: render_GET, render_HEAD, render_POST, and so on. Generally you should implement those methods instead of overriding this one.

render_METHOD methods are expected to return a byte string which will be the rendered page, unless the return value is C{server.NOT_DONE_YET}, in which case it is this class’s responsibility to write the results using C{request.write(data)} and then call C{request.finish()}.

Old code that overrides render() directly is likewise expected to return a byte string or NOT_DONE_YET.

@see: L{IResource.render}

render_GET(request)

Renders the index page or other templates of templates directory

render_HEAD(request)

Default handling of HEAD method.

I just return self.render_GET(request). When method is HEAD, the framework will handle this correctly.

run(port=8080)

Method to run the application within Twisted reactor

This method exists for testing purposes only and fast controller test-development-test workflow. In production you should use twistd

Parameters:port (number) – the port to listen

6.6.3. Response

class mamba.web.response.Response(code, subject, headers)

Mamba web request response base dummy object

Parameters:
  • code (int) – the HTML code for the response
  • subject (Response or dict or str) – the subject body of he response
  • headers (dict or a list of dicts) – the HTTP headers to return back in the response to the browser
class mamba.web.response.Ok(subject='', headers={})

Ok 200 HTTP Response

Parameters:
  • subject (Response or dict or str) – the subject body of the response
  • headers (dict or a list of dicts) – the HTTP headers to return back in the response to the browser
class mamba.web.response.Created(subject='', headers={})

Ok Created 201 HTTP Response

Parameters:
  • subject (Response or dict or str) – the subject body of the response
  • headers (dict or a list of dicts) – the HTTP headers to return back in the response to the browser
class mamba.web.response.MovedPermanently(url)

Ok 301 Moved Permanently HTTP Response

Parameters:url (str) – the url where the resource has been moved
class mamba.web.response.Found(url)

Ok 302 Found HTTP Response

Parameters:url (str) – the url where we want to redirect the browser
class mamba.web.response.SeeOther(url)

Ok 303 See Other HTTP Response

Parameters:url (str) – the url where to find the information via GET
class mamba.web.response.NotFound(subject, headers={})

Error 404 Not Found HTTP Response

Parameters:
  • subject (Response or dict or str) – the subject body of he response
  • headers (dict or a list of dicts) – the HTTP headers to return back in the response to the browser
class mamba.web.response.BadRequest(subject='', headers={})

BadRequest 400 HTTP Response

Parameters:
  • subject (Response or dict or str) – the subject body of he response
  • headers (dict or a list of dicts) – the HTTP headers to return back in the response to the browser
class mamba.web.response.Unauthorized(subject='Unauthorized', headers={})

Unauthorized 401 HTTP Response

class mamba.web.response.Conflict(subject, value, message='')

Error 409 Conflict found

Parameters:
  • subject (Response or dict or str) – the subject body of he response
  • value – the value of the conflicted operatio
  • message (str) – a customer user messahe for the response
class mamba.web.response.AlreadyExists(subject, value, message='')

Error 409 Conflict found in POST

Parameters:
  • subject (Response or dict or str) – the subject body of he response
  • value – the value of the conflicted operatio
  • message (str) – a customer user messahe for the response
class mamba.web.response.NotImplemented(url, message='')

Error 501 Not Implemented

Parameters:
  • url (str) – the URL that is not implemented
  • message (str) – a user custom message describing the problem
class mamba.web.response.InternalServerError(message)

Error 500 Internal Server Error

Parameters:message (str) – a user custom message with a description of the nature of the error

6.6.4. Routing

class mamba.web.Route(method, url, callback)

I am a Route in the Mamba routing system.

compile()

Compiles the regex matches using the complete URL

validate(dispatcher)

Validate a given path against stored URLs. Returns None if nothing matched itself otherwise

Parameters:dispatcher (RouteDispatcher) – the dispatcher object that containing the information to validate
class mamba.web.Router

I store, lookup, cache and dispatch routes for Mamba

A route is stores as:
[methods][route][Controller.__class__.__name__]
dispatch(controller, request)

Dispatch a route and return back the appropiate response.

Parameters:
  • controller (Controller) – the mamba controller
  • request (twisted.web.server.Request) – the HTTP request
install_routes(controller)

Install all the routes in a controller.

Parameters:controller (Controller) – the controller where to fid routes
register_route(controller, route, func_name)

Method that register a route for the given controller

Parameters:
  • controller (Controller) – the controller where to register the route
  • route (Route) – the Route to register
  • func_name (str) – the callable object name
route(url, method='GET')

Register routes for controllers or full REST resources.

class mamba.web.RouteDispatcher(router, controller, request, url=True)

Look for a route, compile/process if neccesary and return it

lookup()

I traverse the URLs at router picking up the ones that match the controller name and then process it to validate which ones match by path/arguments to a particular Route

If nothing match just returns None

6.6.5. Scripts

class mamba.web.Script(path='', prefix='scripts')

Object that represents an script

Parameters:
  • path (str) – the path of the script
  • prefix (str) – the prefix where the script reside
class mamba.web.ScriptManager(scripts_store=None)

Manager for Scripts

load(filename)

Load a new script file

lookup(key)

Find and return a script from the pool

setup()

Setup the loader and load the scripts

class mamba.web.ScriptError

Generic class for Script exceptions

class mamba.web.script.InvalidFile

Fired if a file is lacking the mamba css or less headers

class mamba.web.script.InvalidFileExtension

Fired if the file has not a valid extension (.css or .less)

class mamba.web.script.FileDontExists

Raises if the file does not exists

6.6.6. Stylesheets

class mamba.web.Stylesheet(path='', prefix='styles')

Object that represents an stylesheet or a less script

Parameters:
  • path (str) – the path of the stylesheet
  • prefix (str) – the prefix where the stylesheets reside
class mamba.web.StylesheetError

Generic class for Stylesheet exceptions

class mamba.web.InvalidFile

Fired if a file is lacking the mamba css or less headers

class mamba.web.InvalidFileExtension

Fired if the file has not a valid extension (.css or .less)

class mamba.web.FileDontExists

Raises if the file does not exists

6.6.7. Url Sanitizer

class mamba.web.url_sanitizer.UrlSanitizer

Sanitize URLs for a correct use

6.6.8. WebSockets

class mamba.web.websocket.WebSocketProtocol(*args, **kwargs)

Wrapped protocol to handle Websockaet transport layer. Thw websocket protocol just wrap another protocol to provide a WebSocket transport.

warning::
This protocol is not HTTP

How to use it?:

from twisted.internet import protocol

from mamba.web import websocket

class EchoFactory(protocol.Protocol):

    def dataReceived(self, data):
        # this is the websocket data frame
        self.transport.write(data)

class EchoFactory(protocol.Factory):
    protocol = EchoProtocol


reactor.listenTCP(6543, websocket.WebSocketFactory(EchoFactory()))

New in version 0.3.6.

close(reason='')

Close the connection.

This includes telling the other side we are closing the connection.

If the other ending didn’t signal that the connection is beign closed, then we might not see their last message, but since their last message should, according to the specification, be a simpel acknowledgement, it shouldn’t be a problem.

Refer to [RFC6455][Page 35][Page 41] for more details

codecs

Return the list of available codecs (WS protocols)

complete_hybi00(challenge)

Generate the response for a HyBi-00 challenge.

dataReceived(data)

Protocol dataReceived

If our state is HANDSHAKE then we capture the request path fo echo it back to those browsers that require it (Chrome mainly) and set our state to NEGOTIATION

If our state is NEGOTIATION we look at the headers to check if we have one complete set. If we can’t validate headers we just lose connection

If out state is CHALLENGE we have to call authentication related code for protocol versions HyBi-00/Hixie-76. For more information refer to http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#page-5

If our state is FRAMES then we parse it.

We always kick any pending frames after each call to dataReceived. This is neccesary because frames might have started being sended early we can get write()s from our protocol above when they makeConnection() inmediately before the browser actually send any data. In those cases, we need to manually kick pending frames.

handle_challenge()

Handle challenge. This is exclusive to HyBi-00/Hixie-76

handle_frames()

Use the correct frame parser and send parsed data to the underlying protocol

handle_handshake()

Handle initial request. These look very much like HTTP requests but aren’t. We have to capture the request path to echo it back to the browsers that care about.

These lines looks like:

GET /some/path/to/a/websocket/resource HTTP/1.1
handle_negotiation()

Handle negotiations here. We perform some basic checks here, for example we check if the protocol being used is WebSocket and if we support the version used by the browser.

In the case that we don’t support the broser version wew send back an HTTP/1.1 404 Bad Request message with a list of our supported protocol versions as is defined in the [RFC6455][Section 4.4]

is_hybi00

Determine whether a given set of headers are HyBi-00 compilant

parse_headers(headers)

Parse raw HTTP headers.

Parameters:headers (str) – the headers to parse
secure

Borrowed technique for determining whether this connection is over SSL/TLS

write(data)

Write to the transport.

Parameters:data – the buffer data to write
writeSequence(data)

Write a sequence of data to the transport

Parameters:data – the sequence to be written
class mamba.web.websocket.WebSocketFactory(wrappedFactory)

Factory that wraps another factory to provide WebSockets transports for all of its protocols

protocol

alias of WebSocketProtocol

class mamba.web.websocket.HyBi07Frame(buf)

A WebSocket HiBi-07+ frame object representation

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

For more information about WebSocket framing read [RFC6455][Section 5.2]

Parameters:buf – the buffer data
generate(opcode=1)

Generate a HyBi-07+ frame.

This function always creates unmasked frames, and attemps to use the smallest possible lengths.

Parameters:opcode (int) – the opcode to use: 0x1 -> Text 0x2 -> Binary
mask(buf, key)

Mask or unmask a buffer of bytes with a masking key

The masking key is a 32-bit value chosen by the browser client. The key shouldn’t affect the length of the Payload data. The used algorithm is the following. Octet i of the transformed data is the XOR of octet i of the original data with octet at index i modulo 4 of the masking key:

j = i % 4
octet[i] = octet[i] ^ key[j]

This means that if a third party have access to the key used by our connection we are exposed. For more information about this please, refer to [RFC6455][Page31]

Parameters:
  • buf – the buffer to mask or unmask
  • key – the masking key, it shoudl be exactly four bytes long
parse()

Parse HyBi-07+ frame.

class mamba.web.websocket.HyBi00Frame(buf)

A WebSocket HyBi-00 frame object representation

Frame type byte <--------------------------------------.
    |      |                                            |
    |      `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+
    |                                                   |
    `--> (0x80 to 0xFE) --> Length --> Data... ------->-'

The implementation of this protocol is really simple, in HyBi-00/Hixie-76 only 0x00-0xFF is valid so we use 0x00 always as opcode and then put the buffer between the opcode and the last 0xFF.

Only 0x00 to 0xFE values are allowed in the buffer (because the 0xFF is used mark for the end of the buffer).

For more information about this read [HyBi-00/Hixie-76][Page 6]

Parameters:buf – the buffer data
generate(opcode=0)

Generate a HyBi-00/Hixie-76 frame.

is_valid

Check if the buffer is valid (no xff characters on it)

parse()

Parse a HyBi-00/Hixie-76 frame.

class mamba.web.websocket.InvalidProtocolVersionPreamble

Send invalid protocol version response

class mamba.web.websocket.HandshakePreamble

Common HandShake preamble class for all protocols

write_to_transport(transport)

Write data to the wrapped transport

Parameters:transport – the underlying transport
class mamba.web.websocket.HyBi07HandshakePreamble(protocol)

HyBi-07 preamble

generate_accept_opening(protocol)

Generates the accept response for a given key.

Concatenates the Sec-WebSocket-Key given by the client with the string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 to form a response that proves the handshake was received by the server by taking the SHA-1 hash of this encoding it to base64 and echoing back to the client.

Refer to [RFC6455][Page 7] for more details.

class mamba.web.websocket.HyBi00HandshakePreamble(protocol)

HyBi-00 preamble

write_to_transport(transport, response)

Write data to the wrapped transport and add a hibi00 auth response

Parameters:
  • transport – the underlying transport
  • response – the generated HyBi-00/Hixie-76 response
class mamba.web.websocket.WebSocketError

Fired when something went wrong

class mamba.web.websocket.NoWebSocketCodec

Fired when we can’t handle the codec (WS protocol)

class mamba.web.websocket.InvalidProtocolVersion

Fired when the protocol version is not supported

class mamba.web.websocket.InvalidCharacterInHyBi00Frame

Fired when a xff charecter is found in HyBi-00/Hixie-76 frame buffer

class mamba.web.websocket.ReservedFlagsInFrame

Fired when any of the three reserved bits of HyBi-07 are set on

class mamba.web.websocket.UnknownFrameOpcode

Fired when we get an unused RFC6455 frame opcode

6.7. Enterprise

This is the package that give you access to Database layers. You can use traditional Open Source SQL solutions as PostgreSQL PostgreSQL, MySQL or SQLite as well as No-SQL Open Source solutions as MongoDB (work in progress).

The SQL database access is performed through Storm with some monkey patching to make possible database creation from the Python defined model.

Mamba is supossed to work fine with Storm since revision 223 of the bazaar repository in Storm-0.12 but we only tested it with version 0.19.

6.7.1. SQL through Storm

class mamba.Database(pool=None, testing=False)

Storm ORM database provider for Mamba.

Parameters:pool (twisted.python.threadpool.ThreadPool) – the thrad pool for this database
adjust_poolsize(min_threads=None, max_threads=None)

Adjusts the underlying threadpool size

Parameters:
  • min (int) – minimum number of threads
  • max (int) – maximum number of threads
backend

Return the type or types of backends this databse is using

database

Return the database name or names we are using

dump(model_manager, scheme=None, full=False)

Dumps the full database

Parameters:
  • model_manager (ModelManager) – the model manager from mamba application
  • scheme (str) – dump which scheme? if None just everything
  • full (bool) – should be dumped full?
host

Return the hostname or hostnames this database is using

reset(model_manager, scheme=None)

Delete all the data in the database and return it to primitive state

Parameters:
  • model_manager (ModelManager) – the model manager from mamba application
  • scheme (str) – the specific scheme to reset (if any)
start()

Starts the Database (and the threadpool)

stop()

Stops the Database (and the threadpool)

store(database='mamba', ensure_connect=False)

Returns a Store per-thread through storm.zope.zstorm.ZStorm

class mamba.Model

All the models in the application should inherit from this class.

We use the new storm.twisted.transact.Transactor present in the 0.19 version of Storm to run transactions that will block the reactor using a twsited.python.threadpool.ThreadPool to execute them in different threads so our reactor will not be blocked.

You must take care of don’t return any Storm object from the methods that interacts with the storm.Store underlying API because those ones are created in a different thread and cannot be used outside.

If you don’t want any of the methods in your model to run asynchronous inside the transactor you can set the class property __mamba_async__ as False and them will run synchronous in the main thread (blocking the reactor in the process).

We don’t care about the instantiation of the Storm Store because we use zope.transaction through storm.zope.zstorm.ZStorm that will take care of create different instances of Store per thread for us.

classmethod all(klass, order_by=None, desc=False, *args, **kwargs)

Return back all the rows in the database for this model

Parameters:
  • order_by (model property) – order the resultset by the given field/property
  • desc (bool) – if True, order the resultset by descending order

New in version 0.3.6.

copy(orig)

Copy this object properties and return it

create(*args, **kwargs)

Create a new register in the database

create_table(*args, **kwargs)

Create the table for this model in the underlying database system

delete(*args, **kwargs)

Delete a register from the database

dict(traverse=True, json=False, *parent, **kwargs)

Returns the object as a dictionary

Parameters:
  • traverse (bool) – if True traverse over references
  • json (bool) – if True we convert datetime to string and Decimal to float
  • fields – If set we filter only the fields specified,

mutually exclusive with exclude, having precedence if both are set. :type fields: list :param exclude: If set we exclude the fields specified, mutually exclusive with fields, not working if you also set fields. :type exclude: list

drop_table(*args, **kwargs)

Delete the table for this model in the underlying database system

dump_data(scheme=None)

Dumps the SQL data

dump_indexes()

Dump SQL indexes (used by PostgreSQL and SQLite)

dump_references()

Dump SQL references (used by PostgreSQL)

dump_table()

Dumps the SQL command used for create a table with this model

Parameters:
  • schema (str) – the SQL schema, SQLite by default
  • force_drop (bool) – when True drop the tables always
classmethod find(klass, *args, **kwargs)

Find an object in the underlying database

Some examples:

model.find(Customer.name == u”John”) model.find(name=u”John”) model.find((Customer, City), Customer.city_id == City.id)

New in version 0.3.6.

get_adapter()

Get a valid adapter for this model

get_primary_key()

Return back the model primary key (or keys if it’s compound)

get_uri()

Return an URI instance using the uri config for this model

json

Returns a JSON representation of the object (if possible)

classmethod mamba_database()

Return back the configured underlying mamba database (if any)

on_schema()

Checks if Mamba should take care of this model.

pickle

Returns a Pyhon Pickle representation of the object (if possible)

classmethod read(*args, **kwargs)

Read a register from the database. The give key (usually ID) should be a primary key.

Parameters:id (int) – the ID to get from the database
store(database=None)

Return a valid Storm store for this model

update(*args, **kwargs)

Update a register in the database

uri

Returns the database URI for this model

6.7.2. Specific SQL Backends and Adaptors (used internally by Mamba)

It’s probable that you never use those ones by yourself

class mamba.enterprise.sqlite.SQLite(model)

This class implements the SQLite syntax layer for mamba

Parameters:module (Model) – the module to generate SQLite syntax for
create_table()

Return the SQLite syntax for create a table with this model

detect_primary_key()

Detect the primary key for the model and return it back with the correct SQLite syntax

Returns:a string with the correct SQLite syntax
Return type:str
Raises:SQLiteMissingPrimaryKey on missing primary key
detect_uniques()

Checks if the model has an __mamba_unique__ property. If so, we create a compound unique with the fields specified inside __mamba_unique__. This variable must be a tuple of tuples.

Example: (
(‘field1’, ‘field2’), (‘field3’, ‘field4’, ‘field5’)

)

drop_table()

Return SQLite syntax for drop this model table

get_compound_indexes()

Checks if the model has an __mamba_index__ property. If so, we create a compound index with the fields specified inside __mamba_index__. This variable must be a tuple of tuples.

Example: (
(‘field1’, ‘field2’), (‘field3’, ‘field4’, ‘field5’)

)

get_primary_key_columns()

Return one or more primary key column(s)

get_primary_key_names()

Return one or more primary key name(s)

insert_data(scheme)

Return the SQL syntax needed to insert the data already present in the table.

is_compound_key(name)

Detects if given name is part of a compound primary key

Returns:bool
parse(column)

This funciton is just a fallback to text (tears are comming)

parse_column(column)

Parse a Storm column to the correct SQLite value type. For example, if we pass a column of type storm.variable.IntVariable with name amount we get back:

amount integer
Parameters:column (storm.properties) – the Storm properties column to parse
parse_references()

Get all the storm.references.Reference and create foreign keys for the SQL creation script if the SQLite version is equal or better than 3.6.19

If we are using references we should define our classes in a correct way. If we have a model that have a relation of many to one, we should define a many-to-one Storm relationship in that object but we must create a one-to-many relation in the related model. That means if for example we have a Customer model and an Adress model and we need to relate them as one Customer may have several addresses (in a real application address may have a relation many-to-many with customer) we should define a relation with Reference from Address to Customer using a property like Address.customer_id and a ReferenceSet from Customer to Address like:

Customer.addresses = ReferenceSet(Customer.id, Address.id)

In the case of many-to-many relationships, mamba create the relation tables by itself so you dont need to take care of yourself.

static register()

Register this component

class mamba.enterprise.mysql.MySQL(model)

This class implements the MySQL syntax layer for mamba

Parameters:module (Model) – the module to generate MySQL syntax for
create_table()

Return the MySQL syntax for create a table with this model

detect_indexes()

Go through all the fields defined in the model and create a index constraint if the index property is set on the field.

detect_primary_key()

Detect the primary key for the model and return it back with the correct MySQL syntax, Example:

PRIMARY KEY(id)
Returns:a string with the correct MySQL syntax
Return type:str
Raises:MySQLMissingPrimaryKey on missing primary key
detect_uniques()

Go through all the fields defined in the model and create a unique key if the unique property is set on the field.

drop_table()

Return MySQL syntax for drop this model table

engine

Return back the type of engine defined for this MySQL table, if no engnine has been configured use InnoDB as default

get_compound_indexes()

Checks if the model has an __mamba_index__ property. If so, we create a compound index with the fields specified inside __mamba_index__. This variable must be a tuple of tuples.

Example: (
(‘field1’, ‘field2’), (‘field3’, ‘field4’, ‘field5’)

)

get_compound_uniques()

Checks if the model has an __mamba_unique__ property. If so, we create a compound unique with the fields specified inside __mamba_unique__. This variable must be a tuple of tuples.

Example: (
(‘field1’, ‘field2’), (‘field3’, ‘field4’, ‘field5’)

)

get_primary_key_columns()

Return one or more primary key column(s)

get_primary_key_names()

Return one or more primary key name(s)

get_single_indexes()

Goes through every field looking for an index parameter.

get_single_uniques()

Goes through every field looking for an unique parameter.

insert_data(scheme)

Return the SQL syntax needed to insert the data already present in the table.

is_compound_key(name)

Detects if given name is part of a compound primary key

Returns:bool
parse(column)

This function is just a fallback to text (tears are comming)

parse_column(column)

Parse a Storm column to the correct MySQL value type. For example, if we pass a column of type SmallIntVariable with name amount we get back:

amount smallint
Parameters:column (storm.properties) – the Storm properties column to parse
parse_decimal(column)

Parse decimal sizes for MySQL, for example:

decimal(10,2)
Parameters:column (storm.properties.Decimal) – the Storm properties column to parse
parse_enum(column)

Parse an enum column

Parameters:column (storm.properties) – the Storm properties column to parse
parse_int(column)

Parse an specific integer type for MySQL, for example:

smallint UNSIGNED
Parameters:column (storm.properties.Int) – the Storm properties column to parse
parse_references()

Get all the storm.references.Reference and create foreign keys for the SQL creation script

If we are using references we should define our classes in a correct way. If we have a model that have a relation of many to one, we should define a many-to-one Storm relationship in that object but we must create a one-to-many relation in the related model. That means if for example we have a Customer model and an Adress model and we need to relate them as one Customer may have several addresses (in a real application address may have a relation many-to-many with customer) we should define a relation with Reference from Address to Customer using a property like Address.customer_id and a ReferenceSet from Customer to Address like:

Customer.addresses = ReferenceSet(Customer.id, Address.id)

In the case of many-to-many relationships, mamba create the relation tables by itself so you dont need to take care of yourself.

static register()

Register this component

class mamba.enterprise.postgres.PostgreSQL(model)

This class implements the PostgreSQL syntax layer for mamba

Parameters:module (Model) – the module to generate PostgreSQL syntax for
create_table()

Return the PostgreSQL syntax for create a table with this model

detect_primary_key()

Detect the primary key for the model and return it back with the correct PostgreSQL syntax, Example:

PRIMARY KEY(‘id’)
Returns:a string with the correct PostgreSQL syntax
Return type:str
Raises:PostgreSQLMissingPrimaryKey on missing primary key
detect_uniques()

Checks if the model has an __mamba_unique__ property. If so, we create a compound unique with the fields specified inside __mamba_unique__. This variable must be a tuple of tuples.

Example: (
(‘field1’, ‘field2’), (‘field3’, ‘field4’, ‘field5’)

)

drop_table()

Return PostgreSQL syntax for drop this model table

get_compound_indexes()

Checks if the model has an __mamba_index__ property. If so, we create a compound index with the fields specified inside __mamba_index__. This variable must be a tuple of tuples.

Example: (
(‘field1’, ‘field2’), (‘field3’, ‘field4’, ‘field5’)

)

get_primary_key_columns()

Return one or more primary key column(s)

get_primary_key_names()

Return one or more primary key name(s)

insert_data(scheme)

Return the SQL syntax needed to insert the data already present in the table.

is_compound_key(name)

Detects if given name is part of a compound primary key

Returns:bool
parse(column)

This function is just a fallback to text (tears are comming)

parse_column(column)

Parse a Storm column to the correct PostgreSQL value type. For example, if we pass a column of type storm.variable.IntVariable with name amount we get back:

‘amount’ integer
Parameters:column (storm.properties) – the Storm properties column to parse
parse_enum(column)

Parses an enumeration column type. In PostgreSQL enumerations are created using CREATE TYPE <name> AS ENUM (<values>); format so we need to parse it separeted from regular column parsing.

We have to add the table name to the enum name as we can’t define more than one enum with the same name.

Parameters:column (storm.properties) – the Storm properties column to parse
parse_references()

Get all the storm.references.Reference and create foreign keys for the SQL creation script

If we are using references we should define our classes in a correct way. If we have a model that have a relation of many to one, we should define a many-to-one Storm relationship in that object but we must create a one-to-many relation in the related model. That means if for example we have a Customer model and an Adress model and we need to relate them as one Customer may have several addresses (in a real application address may have a relation many-to-many with customer) we should define a relation with Reference from Address to Customer using a property like Address.customer_id and a ReferenceSet from Customer to Address like:

Customer.addresses = ReferenceSet(Customer.id, Address.id)

In the case of many-to-many relationships, mamba create the relation tables by itself so you dont need to take care of yourself.

static register()

Register this component

class mamba.enterprise.database.AdapterFactory(scheme, model)

This is a factory which produces SQL Adapters.

Parameters:
  • scheme (str) – the database scheme (one of PostgreSQL, MySQL, SQLite)
  • model (Model) – the model to use with this adapter

6.8. Extension Point

class mamba.ExtensionPoint(mcs, name, bases, attrs)

Extensions mount point

This class serves 3 purposes:

  1. A way to declare a mount point for plugins or extensions point.
  2. A way to register a plugin in a particular mount point.
  3. A way to retrieve the plugins that have been registered.

The system works by declaring classes that serves as mount points. Since I subclass type I can be used as a metaclass, for example:

class ShareProvider:
    '''
    Mount point for plugins which refer to share services that can
    be used.

    Plugins implementing this reference should provide the
    following attributes:

    =========== ===================================================
    name        Share service name
    url         The URL to connect with the service
    username    The username which connect to the service
    password    The user password
    API_key     The API Key to use with the service
    =========== ===================================================

    '''
    __metaclass__ = ExtensionPoint

Then we can subclass those mount points in order to define plugins. As the plugin will also inherits from the metaclass, they will be auto registered just for subclassing the provider:

class Twitter(ShareProvider):
    name = 'Twitter'
    url = 'http://api.twitter.com/'
    ...

We can register any Share provider plugin just subclassing from the ShareProvider class and then use it to share our contents:

for share_service in ShareProvider.plugins:
    share_service().share(SharedObject)