API¶
This is the Mamba API documentation.
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', ...})
Mamba only works in the GNU/Linux operating system (for now).
Parameters: options (dict) – options to initialize the application with
-
class
mamba.
ApplicationError
¶ ApplicationError raises when an error occurs
AppStyles¶
-
class
mamba.
AppStyles
¶ Manager for Application Stylesheets
seealso:
Stylesheet
-
get_styles
()¶ Return the
mamba.Stylesheet
pool
-
load
(filename)¶ Load a new stylesheet file
-
lookup
(key)¶ Find and return a stylesheet from the pool
-
reload
(style)¶ Send a COMET / WebSocket petition to reload a specific CSS file.
Parameters: style ( AppStyle
) – the CSS file to reloadJavaScript to use:
var queryString = '?reload=' + new Date().getTime(); // ExtJS - Sencha var el = Ext.get(styleName); // jQuery var el = $(styleName); // LungoJS var el = $$(styleName); el.dom.href = el.dom.href.replace(/\?.*|$/, queryString);
-
setup
()¶ Setup the loader and load the stylesheets
-
Controllers¶
-
class
mamba.
Controller
¶ 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 othersController
.Unlike
twisted.web.resource.Resource
,Controller
don’t use the Twisted URL dispatching mechanism. TheController
usesRouter
for URL dispatching through theroute()
decorator:@route('/hello_world', method='GET') def helloworld(self, request, **kwargs): return 'Hello World'
-
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 alwaysTrue
but any users can override it in theirController
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
) – atwisted.web.server.Request
specifying meta-information about the request that is being made for this child that is ignored at all.
Return type:
-
get_register_path
()¶ Return the controller register path for URL Rewritting
-
prepare_headers
(request, code, headers)¶ Prepare the back response headers
Parameters:
-
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 requestReturns: twisted.internet.defer.Deferred
ormamba.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.
-
-
class
mamba.
ControllerManager
¶ Uses a ControllerProvider to load, store and reload Mamba Controllers.
_model_store
A private attribute that sets the prefix path for the controllers store-
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
-
lookup
(module)¶ Find and return a controller from the pool
Parameters: module (str) – the module to lookup
-
setup
()¶ Setup the loader and load the Mamba plugins
-
Models¶
-
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 atwsited.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.We don’t care about the instantiation of the Storm
Store
because we usezope.transaction
throughstorm.zope.zstorm.ZStorm
that will take care of create different instances ofStore
per thread for us.-
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
-
drop_table
(*args, **kwargs)¶ Delete the table for this model in the underlying database system
-
dump_data
()¶ Dumps the SQL data
-
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
-
get_adapter
()¶ Get a valid adapter for this model
-
get_uri
()¶ Return an URI instance using the uri config for this model
-
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
-
update
(*args, **kwargs)¶ Update a register in the database
-
uri
¶ Returns the database URI for this model
-
Mamba Core¶
Core components of the Mamba framework itself.
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_path –
twisted.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:
-
class
mamba.core.interfaces.
IDeployer
¶ Mamba Deployers interface.
Every deployer must implement this interface
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)()
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
-
Utils¶
Subpackage containing the modules that implement common utilities
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 >>>
CamelCase¶
Converter¶
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_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')
Parameters: config_file (str) – the file to load the configuration from, it can (and should) be empty to get back the previous configured data
Web¶
Subpackage containing the modules that implement web stuff for projects
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
Page¶
-
class
mamba.web.
Page
(app)¶ This represents a full web page in mamba applications. It’s usually the root page of your web site/application.
Parameters: app ( Application
) – The Mamba Application that implements this page-
add_script
(script)¶ Adds a script to the page
-
entityType
= <InterfaceClass twisted.web.resource.IResource>¶
-
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 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}
-
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
-
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
-
Response¶
-
class
mamba.web.
Response
(code, subject, headers)¶ Mamba web request response base dummy object
Parameters:
-
class
mamba.web.
Ok
(subject='', headers={})¶ Ok 200 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
- subject (
-
class
mamba.web.
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
- subject (
-
class
mamba.web.
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
- subject (
-
class
mamba.web.
Conflict
(subject, value, message='')¶ Error 409 Conflict found
Parameters:
-
class
mamba.web.
AlreadyExists
(subject, value, message='')¶ Error 409 Conflict found in POST
Parameters:
-
class
mamba.web.
NotImplemented
(url, message='')¶ Error 501 Not Implemented
Parameters:
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
(*args, **kwargs)¶ Dispatch a route and return back the appropiate response.
Parameters: - controller (
Controller
) – the mamba controller - request (
twisted.web.server.Request
) – the HTTP request
- controller (
-
install_routes
(controller)¶ Install all the routes in a controller.
Parameters: controller ( Controller
) – the controller where to fid routes
-
register_route
(controller, route)¶ Decorator that register a route for the given controller
Parameters: - controller (
Controller
) – the controller where to register the route - route (
Route
) – theRoute
to register
- controller (
-
route
(url, method='GET')¶ Register routes for controllers or full REST resources.
-
class
mamba.web.
RouteDispatcher
(router, controller, request)¶ 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
-
Stylesheets¶
-
class
mamba.web.
Stylesheet
(path='', prefix='styles')¶ Object that represents an stylesheet or a less script
Parameters:
-
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
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 Pthon 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.
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:
-
backend
¶ Return the type of backend this databse is using
-
database
¶ Return the database name we are using
-
dump
(model_manager, full=False)¶ Dumps the full database
Parameters: - model_manager (
ModelManager
) – the model manager from mamba application - full (bool) – should be dumped full?
- model_manager (
-
host
¶ Return the hostname this database is using
-
reset
(model_manager)¶ Delete all the data in the database and return it to primitive state
Parameters: model_manager ( ModelManager
) – the model manager from mamba application
-
start
()¶ Starts the Database (and the threadpool)
-
stop
()¶ Stops the Database (and the threadpool)
-
store
()¶ 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 atwsited.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.We don’t care about the instantiation of the Storm
Store
because we usezope.transaction
throughstorm.zope.zstorm.ZStorm
that will take care of create different instances ofStore
per thread for us.-
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
-
drop_table
(*args, **kwargs) Delete the table for this model in the underlying database system
-
dump_data
() Dumps the SQL data
-
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
-
get_adapter
() Get a valid adapter for this model
-
get_uri
() Return an URI instance using the uri config for this model
-
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
-
update
(*args, **kwargs) Update a register in the database
-
uri
Returns the database URI for this model
-
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
-
drop_table
()¶ Return SQLite syntax for drop this model table
-
insert_data
()¶ Return the SQL syntax needed to insert the data already present in the table.
-
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 INTEGERParameters: column ( storm.properties
) – the Storm properties column to parse
-
parse_references
()¶ Just skips because SQLite doen’t know anything about foreign keys
-
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_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
-
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
-
insert_data
()¶ Return the SQL syntax needed to insert the data already present in the table.
-
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 smallintParameters: column ( storm.properties
) – the Storm properties column to parse
-
parse_enum
(column)¶
-
parse_references
()¶ Get all the
storm.references.Reference
and create foreign keys for the SQL creation scriptIf 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
-
drop_table
()¶ Return PostgreSQL syntax for drop this model table
-
insert_data
()¶ Return the SQL syntax needed to insert the data already present in the table.
-
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’ integerParameters: 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.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 scriptIf 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
-
Monkey Patches¶
-
class
mamba.enterprise.database.
PropertyColumnMambaPatch
(prop, cls, attr, name, primary, variable_class, variable_kwargs)¶ We need to monkey patch part of Storm to can use size, unsigned and auto_increment named values in Properties.
I’am supossed to work well with Storm since rev 223 (v0.12)
Extension Point¶
-
class
mamba.
ExtensionPoint
(mcs, name, bases, attrs)¶ Extensions mount point
This class serves 3 purposes:
- A way to declare a mount point for plugins or extensions point.
- A way to register a plugin in a particular mount point.
- 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)