Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Imagination DocumentationRelease 1.5
Juti Noppornpitak
July 01, 2013
CONTENTS
i
ii
Imagination Documentation, Release 1.5
Copyright Juti Noppornpitak <[email protected]>
Author Juti Noppornpitak <[email protected]>
License MIT
Imagination is a reusable component framework whose objectives are:
• encapsulates an object into a single object with the lazy loader, inspired by many frameworks (e.g., SymfonyFramework in PHP and Spring Framework in Java),
• improves code maintainability by encapsulating reusable components (or dependencies) in a global memory,inspired by JavaBeans,
• introduce the concept of the aspect-oriented programming (AOP), inspired by AspectJ.
Want to get started? Please read Getting Started.
Note: Imagination plays the big role in Tori Web Framework (http://shiroyuki.com/work/project-tori) dealing withclean routing and globally referencing to any defined reusable components.
CONTENTS 1
Imagination Documentation, Release 1.5
2 CONTENTS
CHAPTER
ONE
HOW TO INSTALL
Python 3.3
3
Imagination Documentation, Release 1.5
4 Chapter 1. How to Install
CHAPTER
TWO
RELEASES
Development Version
• Support Python 3.3
• Add a point cut
Version 1.5
• Added support for aspect-oriented programming and introduced some backward incompatibility.
Version 1.0
• Simple object collection repository
5
Imagination Documentation, Release 1.5
6 Chapter 2. Releases
CHAPTER
THREE
REFERENCE
3.1 Getting Started
Author Juti Noppornpitak
As I am a lazy lad, I will guide you, the reader, through the framework with this example.
Note: This example is based on the actual test.
3.1.1 Simple Setup
Then, we also have the code base as followed:
stage-app/main.py <-- this is the main script to bootstrap and run this app.imagination.xmlrestaurant.py
where main.py has the following content while using Imagination 1.5 or higher:
# Imagination 1.5+from imagination.helper.assembler import Assemblerfrom imagination.helper.data import Transformerfrom imagination.locator import Locator
locator = Locator() # pretty much like entity managertransformer = Transformer(locator) # data transformer as a mandatory extension for Assemblerassembler = Assembler(transformer)
assembler.load(’imagination.xml’)
or the following one with Imagination 1.0:
# Imagination 1.0from imagination.locator import Locator
locator = Locator()locator.load_xml(’imagination.xml’)
# Imagination
7
Imagination Documentation, Release 1.5
3.1.2 Advanced Setup with Aspect-oriented Programming
Warning: This section is applicable with Imagination 1.5 or higher.
First of all, let’s define two actors (entity) in this story: alpha as a customer and charlie as a chef/server.
<?xml version="1.0" encoding="utf-8"?><imagination>
<entity id="alpha" class="restaurant.Alpha"><param type="entity" name="accompany">beta</param>
</entity><entity id="charlie" class="restaurant.Charlie"/>
</imagination>
With this, in the code, we can get any of the actors by:
alpha = locator.get(’alpha’) # to get "alpha".
Then, suppose that before charlie cooks, he needs to listen when customers want to eat. In the old fashion way, wemight have done.:
# restaurant.pyclass Charlie(object): # entity "charlie"
# anything before ...
def cook(self):order = []
order.append(alpha.order()) # "egg and becon"
# do cooking...
# anthing after ...
# main.pylocator.get(’charlie’).take_care(locator.get(’alpha’))locator.get(’charlie’).cook()
or:
# main.pylocator.get(’charlie’).take_order(locator.get(’alpha’).order())locator.get(’charlie’).cook()
Note: Assume that charlie has methods take_care or take_order and alpha has a method order.
Well, it works but Charlie needs to know alpha. What if there are more people added into the story. Then, the codewill become unnecessarily messy. Let’s apply AOP then.
By doing that, first, Charlie is slightly modified.
class Charlie(object): # entity "charlie"# anything before ...
def cook(self):# do cooking...
8 Chapter 3. Reference
Imagination Documentation, Release 1.5
# anthing after ...
Then, in imagination.xml, we now add interceptions.
<?xml version="1.0" encoding="utf-8"?><imagination>
<entity id="alpha" class="restaurant.Alpha"><param type="entity" name="accompany">beta</param><interception before="charlie" do="cook" with="order">
<param type="unicode" name="item">egg and becon</param></interception>
</entity><entity id="charlie" class="restaurant.Charlie"/>
</imagination>
Finally, in main.py, we can just write:
locator.get(’charlie’).cook()
On execution, assuming that alpha sends the order to the central queue, alpha will intercept before charlie cook byordering “egg and becon”. Then, charlie will take the order from the central queue.
Note: Read Assembler for the configuration specification.
Now, eventually, we have the cleaner code that do exactly what we want in the more maintainable way.
3.2 imagination.action
Author Juti Noppornpitak
Version 1.5
Usage Internal
The module contains the classes used for interceptable actions/methods of any instance ofimagination.entity.Entity.
Note: Copyright (c) 2012 Juti Noppornpitak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen-tation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use,copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of theSoftware.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PAR-TICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT-WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3.2. imagination.action 9
Imagination Documentation, Release 1.5
class imagination.action.Action(*args, **kwargs)Method wrapper for intercepting actions
nameName of the action
referenceReference of the action
class imagination.action.EventTypeType of intercepting events
post_action = ‘after’Event after the execution that doesn’t care about the returned value from the action.
post_condition = ‘post’Event after the execution that only concerns about the returned value from the action.
pre_action = ‘before’Event before the execution that doesn’t care about the input given to the action.
pre_condition = ‘pre’Event before the execution that only concerns about the input given to the action.
3.2.1 Supplementary documentation
Because Sphinx doesn’t know how to interpret the doc block of any methods withimagination.decorator.validator.restrict_type(), this section serves as a missing docu-mentation.
imagination.action.Action.register(interception)Register the interception for this action.
Parameters interception (imagination.meta.interception.Interception) – the metadata for the inter-ception
3.3 imagination.decorator.validator
Author Juti Noppornpitak
Availability 1.5
The module contains reusable input validators.
Note: Copyright (c) 2012 Juti Noppornpitak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen-tation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use,copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of theSoftware.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PAR-TICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
10 Chapter 3. Reference
Imagination Documentation, Release 1.5
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT-WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
imagination.decorator.validator.restrict_type(*restricted_list, **restricted_map)The method decorator to validate the type of inputs given to the method.
Parameters
• restricted_list – the list of types to restrict the type of each parameter in the same order asthe parameter given to the method.
• restricted_map – the map of types to restrict the type of each parameter by name.
When the input fails the validation, an exception of type TypeError is throw.
There are a few exceptions:
• If the given type is None, there will be no restriction.
• If the given type is long, the value of int and float are also valid.
• If the given type is unicode, the valud of str is also valid.
Warning: In Imagination 1.6, types unicode and long are no longer have fallback check in order tosupport Python 3.3.
from imagination.decorator.validator import restrict_type
# Example on a function@restrict_type(unicode)def say(context):
print context
class Person(object):# Example on a constructor@restrict_type(unicode, int)def __init__(self, name, age):
self.name = nameself.age = age
self.__friends = []
# Example on an instance method@restrict_type(Person)def add_friend(self, person):
self.__friends.append(person)
3.4 imagination.entity
Author Juti Noppornpitak
The module contains the package entity used to be an intermediate between imagination.locator.Locatorand imagination.loader.Loader and simulate the singleton class on the package in the Loader.
Note: Copyright (c) 2012 Juti Noppornpitak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen-tation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use,
3.4. imagination.entity 11
Imagination Documentation, Release 1.5
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of theSoftware.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PAR-TICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT-WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class imagination.entity.Entity(*args, **kwargs)Entity represents the package, reference and instance of the reference.
Parameters
• id – the service identifier (string).
• loader – a service loader which is an instance of imagination.loader.Loader.
• args (dict) – constructor’s parameters
• kwargs – constructor’s parameters
If the loader is not an instance of imagination.loader.Loaderor any classes based on imagination.loader.Loader, the exceptionimagination.exception.UnknownLoaderError will be thrown.
Note: This class is to similar to the decorator tori.decorator.common.singleton andtori.decorator.common.singleton_with from Tori Framework, except that it is not a singleton class and soany arbitrary class referenced by the loader only lasts as long as the entity lives.
Note: In version 1.5, the entity has the ability to fork an non-supervised instance of the reference.
activatedCheck if the entity is already activated.
This will also inspects if the entity already loads a singleton instance into the memory.
argument_dictionaryGet the argument dictionary.
argument_listGet the argument list.
fork()
Version 1.5
Fork an instance of the class defined for the loader.
idEntity ID
Return type strint or unicode or integer
instanceGet the singleton instance of the class defined for the loader.
12 Chapter 3. Reference
Imagination Documentation, Release 1.5
interceptableFlag if this entity is interceptable
Return type boolean
interceptionsRetrieve the list of interceptions.
loaderPackage loader
Return type imagination.loader.Loader
tagsRetrieve the entity tags.
Return type list
3.5 imagination.exception
exception imagination.exception.DeprecatedAPIException thrown when a deprecated API is used.
exception imagination.exception.DuplicateKeyWarningWarning thrown when an internal dictionary detects an attempt of re-assignment to the direction by the existedkey.
exception imagination.exception.ForbiddenForkErrorException thrown only when a locator try to fork a proxy.
exception imagination.exception.IncompatibleBlockErrorException thrown when imagination.locator.Locator.load_xml() cannot process the entityblock.
exception imagination.exception.LockedEntityExceptionException thrown when a caller attempts to update any of alterable properties of an instance ofimagination.entity.Entity when it is in the locked state.
exception imagination.exception.MisplacedValidatorErrorException thrown when a validator is used with type (e.g., class, perimitive types etc.)
exception imagination.exception.MultipleInterceptingEventsWarningWarning thrown when more than one intercepting event is detected.
exception imagination.exception.NonCallableErrorException thrown when imagination.action.Action tries to execute a non-callable reference.
exception imagination.exception.UnknownEntityErrorException thrown when imagination.locator.Locator constructor receives an unusable entity.
exception imagination.exception.UnknownFileErrorException thrown when imagination.locator.Locator.load_xml() cannot locate the file on thegiven path.
exception imagination.exception.UnknownProxyErrorException thrown when imagination.helper.assembler.Assembler could not find the proxy.
3.5. imagination.exception 13
Imagination Documentation, Release 1.5
3.6 Assembler
Module imagination.helper.assembler
Author Juti Noppornpitak
Dependency kotoba 3.0
Availability 1.5
The module contains the assembler to constuct loaders and entites based on the configuration and register to a particularlocator.
3.6.1 XML Schema
Note: This is the master specification document for the configuration.
The schema is defined as followed:
# Base
<imagination>(ENTITY)*
</imagination>
# Entity
ENTITY = <entity id="ENTITY_ID"class="ENTITY_CLASS"(interceptable="(true|false)")?(option=ENTITY_OPTIONS)?
>(CONSTRUCTOR_PARAMETER)*(INTERCEPTION)*
</entity>
ENTITY_OPTIONS=(factory-mode)
# Constructor’s parameter and initial parameter
CONSTRUCTOR_PARAMETER = INITIAL_PARAMETER= <parameter type="PARAMETER_TYPE" name="PARAMETER_NAME">
(PARAMETER_VALUE|ENTITY_ID|CLASS_IDENTIFIER)</parameter>
# See the section "Parameter Types" for PARAMETER_TYPE.
# Event
EVENT=(before|pre|post|after)
INTERCEPTION = <interception EVENT="REFERENCE_ENTITY_IDENTIFIER"do="REFERENCE_ENTITY_METHOD"with="THIS_ENTITY_METHOD"
>(INITIAL_PARAMETER)*
</interception>
14 Chapter 3. Reference
Imagination Documentation, Release 1.5
where:
• ENTITY_ID is the identifier of the entity.
• ENTITY_CLASS is the fully-qualified class name of the entity. (e.g.tori.service.rdb.EntityService)
• option is the option of the entity where ENTITY_OPTIONS can have one or more of:
– factory-mode: always fork the instance of the given class.
– no-interuption: any methods of the entity cannot be interrupted.
• REFERENCE_ENTITY_IDENTIFIER is the reference’s entity identifier
• REFERENCE_ENTITY_METHOD is the reference’s method name
• THIS_ENTITY_METHOD is this entity’s method name
• EVENT is where the REFERENCE_ENTITY_METHOD is intercepted.
– before is an event before the execution of the method of the reference (reference method) regardless tothe given arguments to the reference method.
– pre is an event on pre-contact of the reference method and concerning about the arguments given to thereference method. The method of the entity (the intercepting method) takes the same paramenter as thereference method.
– post is an event on post-contact of the reference method and concerning about the result returned by thereference method. The intercepting method for this event takes only one parameter which is the resultfrom the reference method or any previous post-contact interceptors.
– after is an event after the execution of the reference method regardless to the result reterned by thereference method.
3.6.2 Parameter Types
TypeName
Data Type
unicode Unicode (default)bool Boolean 1
float Floatint Integerclass Class reference 2
entity imagination.entity.Entity 3
3.6.3 Example
<?xml version="1.0" encoding="utf-8"?><imagination>
<entity id="alpha" class="dummy.lazy_action.Alpha"><param type="entity" name="accompany">beta</param><interception before="charlie" do="cook" with="order">
<param type="unicode" name="item">egg and becon</param>
1Only any variations (letter case) of the word ‘true’ or ‘false’ are considered as a valid boolean value.2The module and package specified as the value of <param> is loaded when Assembler.load() is executed.3The encapsulated instance of the entity specified as the value of <param> is instantiated when Assembler.load() is executed or when
the instance is given with a proxy (imagination.proxy.Proxy).
3.6. Assembler 15
Imagination Documentation, Release 1.5
</interception><interception pre="charlie" do="repeat" with="confirm"/><interception before="charlie" do="serve" with="speak_to_accompany">
<param type="str" name="context">watch your hand</param></interception><interception before="charlie" do="serve" with="wash_hands"/><interception after="me" do="eat" with="speak">
<param type="str" name="context">merci</param></interception>
</entity><entity id="beta" class="dummy.lazy_action.Beta"/><entity id="charlie" class="dummy.lazy_action.Charlie"/>
</imagination>
Note: Copyright (c) 2012 Juti Noppornpitak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen-tation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use,copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of theSoftware.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PAR-TICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT-WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3.6.4 API
class imagination.helper.assembler.Assembler(*args, **kwargs)The entity assembler via configuration files.
Parameters transformer – an instance of imagination.helper.data.Transformer
load(filepath)Load the configuration.
Parameters filepath (string or unicode) – the file path to the configuration.
locatorThe injected locator via the data transformer.
Return type imagination.locator.Locator
3.6.5 Supplementary documentation
Because Sphinx doesn’t know how to interpret the doc block of any methods withimagination.decorator.validator.restrict_type(), this section serves as a missing docu-mentation.
Assembler.load(filepath)Load the configuration.
16 Chapter 3. Reference
Imagination Documentation, Release 1.5
Parameters filepath (string or unicode) – the file path to the configuration.
3.7 imagination.loader
Author Juti Noppornpitak
The module contains the package loader used to improve code maintainability.
Note: Copyright (c) 2012 Juti Noppornpitak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen-tation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use,copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of theSoftware.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PAR-TICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT-WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class imagination.loader.Loader(path_to_package)Package loader with lazy loading
path_to_package is a string representing the package path.
For example:
# In this case, we load the default renderer of Tori framework.loader = Loader(’tori.renderer.DefaultRenderer’)# Then, instantiate the default renderer.renderer = loader.package(’app.views’)
filenameGet the path to the package.
moduleGet a reference to the module.
nameGet the name of the package.
packageGet a reference to the package.
3.8 imagination.locator
Author Juti Noppornpitak
The module contains the entity locator used to promote reusability of components.
3.7. imagination.loader 17
Imagination Documentation, Release 1.5
Note: Copyright (c) 2012 Juti Noppornpitak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documen-tation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use,copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of theSoftware.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PAR-TICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT-WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class imagination.locator.LocatorEntity locator
find_by_tag(tag_label)Retrieve entities by tag_label.
Parameters tag_label – tag label
fork(id)Fork the entity identified by id.
Parameters id – entity identifier
get(id)Retrieve the entity identified by id.
Parameters id – entity identifier
Returns the requested entity
get_wrapper(id)Retrieve the entity wrapper identified by id.
Parameters id – entity identifier
Returns the requested entity wrapper
has(id)Check if the entity with id is already registered.
load_xml(file_path)Load the entities from a XML configuration file at file_path.
Status Deprecated in 1.5
set(id, entity)Set the given entity by id.
18 Chapter 3. Reference
PYTHON MODULE INDEX
iimagination.action, ??imagination.decorator.validator, ??imagination.entity, ??imagination.exception, ??imagination.helper.assembler, ??imagination.loader, ??imagination.locator, ??
19