Commits

Lynn Rees committed 350dd1d

- add serializers

Comments (0)

Files changed (57)

callchain/active_auto/chain.py

 
 from callchain.chain import RootMixin
 from callchain.config import Defaults
-from callchain.keys import KRoot, KCall, KChain
 from callchain.patterns import Pathways, Nameways
-from callchain.services.queue import KThings, KResult
+from callchain.keys.core import KThings, KResult
+from callchain.keys.base import KRoot, KCall, KChain
 from callchain.call import ChainMixin, PriorityMixin, inside
 
 ###############################################################################
 
 
 class thingchain(Pathways):
+    
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
 
 @appifies(KThings, KRoot, KChain, KCall)
 
 
 class chain(Pathways):
+
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
     class filter(Nameways):
-        key = 'callchain.services.filter.KFilter'
+        key = 'callchain.key.filter.KFilter'
         filter = 'callchain.active_auto.chainlet.filterchain'
 
     class collect(Nameways):
-        key = 'callchain.services.filter.KCollect'
+        key = 'callchain.key.filter.KCollect'
         collect = 'callchain.active_auto.chainlet.collectchain'
 
     class set(Nameways):
-        key = 'callchain.services.filter.KSet'
+        key = 'callchain.key.filter.KSet'
         set = 'callchain.active_auto.chainlet.setchain'
 
     class slice(Nameways):
-        key = 'callchain.services.filter.KSlice'
+        key = 'callchain.key.filter.KSlice'
         slice = 'callchain.active_auto.chainlet.slicechain'
 
     class combine(Nameways):
-        key = 'callchain.services.order.KCombine'
+        key = 'callchain.key.order.KCombine'
         combine = 'callchain.active_auto.chainlet.combinechain'
 
     class map(Nameways):
-        key = 'callchain.services.map.KMap'
+        key = 'callchain.key.map.KMap'
         map = 'callchain.active_auto.chainlet.mapchain'
 
     class delay(Nameways):
-        key = 'callchain.services.map.KDelay'
+        key = 'callchain.key.map.KDelay'
         delay = 'callchain.active_auto.chainlet.delaychain'
 
     class repeat(Nameways):
-        key = 'callchain.services.map.KRepeat'
+        key = 'callchain.key.map.KRepeat'
         repeat = 'callchain.active_auto.chainlet.repeatchain'
 
     class order(Nameways):
-        key = 'callchain.services.order.KOrder'
+        key = 'callchain.key.order.KOrder'
         order = 'callchain.active_auto.chainlet.orderchain'
 
     class random(Nameways):
-        key = 'callchain.services.order.KRandom'
+        key = 'callchain.key.order.KRandom'
         random = 'callchain.active_auto.chainlet.randomchain'
 
     class reduce(Nameways):
-        key = 'callchain.services.reduce.KReduce'
+        key = 'callchain.key.reduce.KReduce'
         reduce = 'callchain.active_auto.chainlet.reducechain'
 
     class math(Nameways):
-        key = 'callchain.services.reduce.KMath'
+        key = 'callchain.key.reduce.KMath'
         math = 'callchain.active_auto.chainlet.mathchain'
 
     class truth(Nameways):
-        key = 'callchain.services.reduce.KTruth'
+        key = 'callchain.key.reduce.KTruth'
         truth = 'callchain.active_auto.chainlet.truthchain'
 
 

callchain/active_auto/chainlet.py

 from twoq.ordering import RandomMixin, OrderMixin, CombineMixin
 from twoq.filtering import FilterMixin, CollectMixin, SetMixin, SliceMixin
 
-from callchain.services import KResult
+from callchain.keys.core import KResult
 from callchain.call import ChainMixin, PriorityMixin
-from callchain.services.map import KDelay, KRepeat, KMap
-from callchain.keys import KCall, KChain, KConfig, KLinked
-from callchain.services.reduce import KMath, KReduce, KTruth
+from callchain.keys.map import KDelay, KRepeat, KMap
+from callchain.keys.reduce import KMath, KReduce, KTruth
 from callchain.chain import (
     BranchMixin, BranchletMixin, ChainletMixin, LinkedMixin)
-from callchain.services.order import KRandom, KOrder, KCombine
-from callchain.services.filter import KCollect, KSet, KSlice, KFilter
+from callchain.keys.order import KRandom, KOrder, KCombine
+from callchain.keys.base import KCall, KChain, KConfig, KLinked
+from callchain.keys.filter import KCollect, KSet, KSlice, KFilter
 
 __all__ = (
     'mathchain', 'truthchain', 'reducechain', 'collectchain', 'setchain',

callchain/active_auto/event.py

 from twoq.active import AutoResultMixin
 
 from callchain.config import Defaults
+from callchain.keys.apps import events
 from callchain.chain import EventRootMixin
-from callchain.services.apps import events
 from callchain.call import EventMixin, einside
-from callchain.services import KThings, KResult
+from callchain.keys.core import KThings, KResult
 from callchain.patterns import Pathways, Nameways
-from callchain.keys import KEvent, KEventRoot, KEventCall
+from callchain.keys.base import KEvent, KEventRoot, KEventCall
 
 ###############################################################################
 ## thing event chain ##########################################################
 class thingevent(Pathways):
     chain = 'callchain.active_auto.chainlet.chainlink'
 
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
 
 @appifies(KThings, KEventRoot, KEvent, KEventCall)
 class event(Pathways):
     chain = 'callchain.active_auto.chainlet.chainlink'
 
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
     class filter(Nameways):
-        key = 'callchain.services.filter.KFilter'
+        key = 'callchain.key.filter.KFilter'
         filter = 'callchain.active_auto.eventlet.filterevent'
 
     class collect(Nameways):
-        key = 'callchain.services.filter.KCollect'
+        key = 'callchain.key.filter.KCollect'
         collect = 'callchain.active_auto.eventlet.collectevent'
 
     class combine(Nameways):
-        key = 'callchain.services.order.KCombine'
+        key = 'callchain.key.order.KCombine'
         combine = 'callchain.active_auto.eventlet.combineevent'
 
     class set(Nameways):
-        key = 'callchain.services.filter.KSet'
+        key = 'callchain.key.filter.KSet'
         set = 'callchain.active_auto.eventlet.setevent'
 
     class slice(Nameways):
-        key = 'callchain.services.filter.KSlice'
+        key = 'callchain.key.filter.KSlice'
         slice = 'callchain.active_auto.eventlet.sliceevent'
 
     class map(Nameways):
-        key = 'callchain.services.map.KMap'
+        key = 'callchain.key.map.KMap'
         map = 'callchain.active_auto.eventlet.mapevent'
 
     class delay(Nameways):
-        key = 'callchain.services.map.KDelay'
+        key = 'callchain.key.map.KDelay'
         delay = 'callchain.active_auto.eventlet.delayevent'
 
     class repeat(Nameways):
-        key = 'callchain.services.map.KRepeat'
+        key = 'callchain.key.map.KRepeat'
         repeat = 'callchain.active_auto.eventlet.repeatevent'
 
     class order(Nameways):
-        key = 'callchain.services.order.KOrder'
+        key = 'callchain.key.order.KOrder'
         order = 'callchain.active_auto.eventlet.orderevent'
 
     class random(Nameways):
-        key = 'callchain.services.order.KRandom'
+        key = 'callchain.key.order.KRandom'
         random = 'callchain.active_auto.eventlet.randomevent'
 
     class reduce(Nameways):
-        key = 'callchain.services.reduce.KReduce'
+        key = 'callchain.key.reduce.KReduce'
         reduce = 'callchain.active_auto.eventlet.reduceevent'
 
     class math(Nameways):
-        key = 'callchain.services.reduce.KMath'
+        key = 'callchain.key.reduce.KMath'
         math = 'callchain.active_auto.eventlet.mathevent'
 
     class truth(Nameways):
-        key = 'callchain.services.reduce.KTruth'
+        key = 'callchain.key.reduce.KTruth'
         truth = 'callchain.active_auto.eventlet.truthevent'
 
 

callchain/active_auto/eventlet.py

 from twoq.filtering import FilterMixin, CollectMixin, SetMixin, SliceMixin
 
 from callchain.call import EventMixin
-from callchain.services.queue import KResult
-from callchain.services.map import KDelay, KRepeat, KMap
-from callchain.services.reduce import KMath, KReduce, KTruth
-from callchain.keys import KEventCall, KEvent, KLinked, KConfig
-from callchain.services.order import KRandom, KOrder, KCombine
+from callchain.keys.core import KResult
+from callchain.keys.map import KDelay, KRepeat, KMap
+from callchain.keys.reduce import KMath, KReduce, KTruth
+from callchain.keys.order import KRandom, KOrder, KCombine
 from callchain.chain import (
     ChainletMixin, EventBranchMixin, BranchletMixin, LinkedMixin)
-from callchain.services.filter import KCollect, KSet, KSlice, KFilter
+from callchain.keys.filter import KCollect, KSet, KSlice, KFilter
+from callchain.keys.base import KEventCall, KEvent, KLinked, KConfig
 
 __all__ = (
     'mathevent', 'truthevent', 'reduceevent', 'collectevent', 'setevent',

callchain/active_man/chain.py

 
 from callchain.chain import RootMixin
 from callchain.config import Defaults
-from callchain.services import KThings, KResult
-from callchain.keys import KRoot, KCall, KChain
 from callchain.patterns import Pathways, Nameways
+from callchain.keys.core import KThings, KResult
+from callchain.keys.base import KRoot, KCall, KChain
 from callchain.call import ChainMixin, PriorityMixin, inside
 
 ###############################################################################
 
 
 class thingchain(Pathways):
+    
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
 
 @appifies(KThings, KRoot, KChain, KCall)
 
 
 class chain(Pathways):
+
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
     class filter(Nameways):
-        key = 'callchain.services.filter.KFilter'
+        key = 'callchain.key.filter.KFilter'
         filter = 'callchain.active_man.chainlet.filterchain'
 
     class collect(Nameways):
-        key = 'callchain.services.filter.KCollect'
+        key = 'callchain.key.filter.KCollect'
         collect = 'callchain.active_man.chainlet.collectchain'
 
     class set(Nameways):
-        key = 'callchain.services.filter.KSet'
+        key = 'callchain.key.filter.KSet'
         set = 'callchain.active_man.chainlet.setchain'
 
     class slice(Nameways):
-        key = 'callchain.services.filter.KSlice'
+        key = 'callchain.key.filter.KSlice'
         slice = 'callchain.active_man.chainlet.slicechain'
 
     class combine(Nameways):
-        key = 'callchain.services.order.KCombine'
+        key = 'callchain.key.order.KCombine'
         combine = 'callchain.active_man.chainlet.combinechain'
 
     class map(Nameways):
-        key = 'callchain.services.map.KMap'
+        key = 'callchain.key.map.KMap'
         map = 'callchain.active_man.chainlet.mapchain'
 
     class delay(Nameways):
-        key = 'callchain.services.map.KDelay'
+        key = 'callchain.key.map.KDelay'
         delay = 'callchain.active_man.chainlet.delaychain'
 
     class repeat(Nameways):
-        key = 'callchain.services.map.KRepeat'
+        key = 'callchain.key.map.KRepeat'
         repeat = 'callchain.active_man.chainlet.repeatchain'
 
     class order(Nameways):
-        key = 'callchain.services.order.KOrder'
+        key = 'callchain.key.order.KOrder'
         order = 'callchain.active_man.chainlet.orderchain'
 
     class random(Nameways):
-        key = 'callchain.services.order.KRandom'
+        key = 'callchain.key.order.KRandom'
         random = 'callchain.active_man.chainlet.randomchain'
 
     class reduce(Nameways):
-        key = 'callchain.services.reduce.KReduce'
+        key = 'callchain.key.reduce.KReduce'
         reduce = 'callchain.active_man.chainlet.reducechain'
 
     class math(Nameways):
-        key = 'callchain.services.reduce.KMath'
+        key = 'callchain.key.reduce.KMath'
         math = 'callchain.active_man.chainlet.mathchain'
 
     class truth(Nameways):
-        key = 'callchain.services.reduce.KTruth'
+        key = 'callchain.key.reduce.KTruth'
         truth = 'callchain.active_man.chainlet.truthchain'
 
 

callchain/active_man/chainlet.py

 from twoq.ordering import RandomMixin, OrderMixin, CombineMixin
 from twoq.filtering import FilterMixin, CollectMixin, SetMixin, SliceMixin
 
-from callchain.services import KResult
+from callchain.keys.core import KResult
 from callchain.call import ChainMixin, PriorityMixin
-from callchain.services.map import KDelay, KRepeat, KMap
-from callchain.keys import KCall, KChain, KConfig, KLinked
-from callchain.services.reduce import KMath, KReduce, KTruth
+from callchain.keys.map import KDelay, KRepeat, KMap
+from callchain.keys.reduce import KMath, KReduce, KTruth
 from callchain.chain import (
     BranchMixin, BranchletMixin, ChainletMixin, LinkedMixin)
-from callchain.services.order import KRandom, KOrder, KCombine
-from callchain.services.filter import KCollect, KSet, KSlice, KFilter
+from callchain.keys.order import KRandom, KOrder, KCombine
+from callchain.keys.base import KCall, KChain, KConfig, KLinked
+from callchain.keys.filter import KCollect, KSet, KSlice, KFilter
 
 __all__ = (
     'mathchain', 'truthchain', 'reducechain', 'collectchain', 'setchain',
     'slicechain', 'filterchain', 'delaychain', 'repeatchain', 'mapchain',
-    'randomchain', 'orderchain',
+    'randomchain', 'orderchain', 'chainlet', 'combinechain',
 )
 
 

callchain/active_man/event.py

 from twoq.active import ManResultMixin
 
 from callchain.config import Defaults
+from callchain.keys.apps import events
 from callchain.chain import EventRootMixin
-from callchain.services.apps import events
 from callchain.call import EventMixin, einside
-from callchain.services import KThings, KResult
+from callchain.keys.core import KThings, KResult
 from callchain.patterns import Pathways, Nameways
-from callchain.keys import KEvent, KEventRoot, KEventCall
+from callchain.keys.base import KEvent, KEventRoot, KEventCall
 
 ###############################################################################
 ## thing event chain ##########################################################
 class thingevent(Pathways):
     chain = 'callchain.active_man.chainlet.chainlink'
 
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
 
 @appifies(KThings, KEventRoot, KEvent, KEventCall)
 class event(Pathways):
     chain = 'callchain.active_man.chainlet.chainlink'
 
+    class loads(Nameways):
+        key = 'callchain.keys.loads.KLoads'
+        loads = 'callchain.services.loads.Loads'
+
+    class dumps(Nameways):
+        key = 'callchain.keys.dumps.KDumps'
+        loads = 'callchain.services.dumps.Dumps'
+
     class logger(Nameways):
-        key = 'callchain.contrib.keys.KLogger'
-        logger = 'callchain.contrib.logger.loglet'
+        key = 'callchain.keys.core.KLogger'
+        logger = 'callchain.services.core.loglet'
 
     class filter(Nameways):
-        key = 'callchain.services.filter.KFilter'
+        key = 'callchain.key.filter.KFilter'
         filter = 'callchain.active_man.eventlet.filterevent'
 
     class collect(Nameways):
-        key = 'callchain.services.filter.KCollect'
+        key = 'callchain.key.filter.KCollect'
         collect = 'callchain.active_man.eventlet.collectevent'
 
     class combine(Nameways):
-        key = 'callchain.services.order.KCombine'
+        key = 'callchain.key.order.KCombine'
         combine = 'callchain.active_man.eventlet.combineevent'
 
     class set(Nameways):
-        key = 'callchain.services.filter.KSet'
+        key = 'callchain.key.filter.KSet'
         set = 'callchain.active_man.eventlet.setevent'
 
     class slice(Nameways):
-        key = 'callchain.services.filter.KSlice'
+        key = 'callchain.key.filter.KSlice'
         slice = 'callchain.active_man.eventlet.sliceevent'
 
     class map(Nameways):
-        key = 'callchain.services.map.KMap'
+        key = 'callchain.key.map.KMap'
         map = 'callchain.active_man.eventlet.mapevent'
 
     class delay(Nameways):
-        key = 'callchain.services.map.KDelay'
+        key = 'callchain.key.map.KDelay'
         delay = 'callchain.active_man.eventlet.delayevent'
 
     class repeat(Nameways):
-        key = 'callchain.services.map.KRepeat'
+        key = 'callchain.key.map.KRepeat'
         repeat = 'callchain.active_man.eventlet.repeatevent'
 
     class order(Nameways):
-        key = 'callchain.services.order.KOrder'
+        key = 'callchain.key.order.KOrder'
         order = 'callchain.active_man.eventlet.orderevent'
 
     class random(Nameways):
-        key = 'callchain.services.order.KRandom'
+        key = 'callchain.key.order.KRandom'
         random = 'callchain.active_man.eventlet.randomevent'
 
     class reduce(Nameways):
-        key = 'callchain.services.reduce.KReduce'
+        key = 'callchain.key.reduce.KReduce'
         reduce = 'callchain.active_man.eventlet.reduceevent'
 
     class math(Nameways):
-        key = 'callchain.services.reduce.KMath'
+        key = 'callchain.key.reduce.KMath'
         math = 'callchain.active_man.eventlet.mathevent'
 
     class truth(Nameways):
-        key = 'callchain.services.reduce.KTruth'
+        key = 'callchain.key.reduce.KTruth'
         truth = 'callchain.active_man.eventlet.truthevent'
 
 

callchain/active_man/eventlet.py

 from twoq.filtering import FilterMixin, CollectMixin, SetMixin, SliceMixin
 
 from callchain.call import EventMixin
-from callchain.services.queue import KResult
-from callchain.services.map import KDelay, KRepeat, KMap
-from callchain.services.reduce import KMath, KReduce, KTruth
-from callchain.keys import KEventCall, KEvent, KLinked, KConfig
-from callchain.services.order import KRandom, KOrder, KCombine
+from callchain.keys.core import KResult
+from callchain.keys.map import KDelay, KRepeat, KMap
+from callchain.keys.reduce import KMath, KReduce, KTruth
+from callchain.keys.order import KRandom, KOrder, KCombine
 from callchain.chain import (
     ChainletMixin, EventBranchMixin, BranchletMixin, LinkedMixin)
-from callchain.services.filter import KCollect, KSet, KSlice, KFilter
+from callchain.keys.filter import KCollect, KSet, KSlice, KFilter
+from callchain.keys.base import KEventCall, KEvent, KLinked, KConfig
 
 __all__ = (
     'mathevent', 'truthevent', 'reduceevent', 'collectevent', 'setevent',
     'sliceevent', 'filterevent', 'delayevent', 'repeatevent', 'mapevent',
-    'randomevent', 'orderevent', 'eventlet'
+    'randomevent', 'orderevent', 'eventlet', 'combineevent'
 )
 
 

callchain/call.py

 from callchain.managers import Events
 from callchain.core import ConfigMixin
 from callchain.patterns import Pathways
-from callchain.keys import NoServiceError
+from callchain.keys.base import NoServiceError
 from callchain.support import Empty, Queue, PriorityQueue, total_ordering
 
 

callchain/contrib/__init__.py

-# -*- coding: utf-8 -*-
-'''callchain extensions'''

callchain/contrib/keys.py

-# -*- coding: utf-8 -*-
-'''callchain contrib keys'''
-
-#from appspace.keys import Attribute
-
-from callchain.services.queue import KService
-
-
-class KLogger(KService):
-
-    '''logging key'''
-
-#    logger = Attribute('the logger')
-
-    def debug(msg):  # @NoSelf
-        '''log debug message'''
-
-    def warning(msg):  # @NoSelf
-        '''log warning message'''
-
-    def info(msg):  # @NoSelf
-        '''log info message'''
-
-    def error(msg):  # @NoSelf
-        '''log error message'''
-
-    def critical(msg):  # @NoSelf
-        '''log critical message'''
-
-    def exception(msg):  # @NoSelf
-        '''log exception message'''

callchain/contrib/logger.py

-# -*- coding: utf-8 -*-
-'''callchain logging'''
-
-import sys
-import logging
-from logging.handlers import HTTPHandler, SysLogHandler
-from logging.handlers import TimedRotatingFileHandler, SMTPHandler
-
-from appspace import appifies
-from stuf.utils import clsname
-
-from callchain.core import CoreMixin
-from callchain.chain import BranchMixin, ChainletMixin
-
-from callchain.contrib.keys import KLogger
-
-
-class _LogStdout(object):
-
-    '''file-like object for sending stdout output to a logger.'''
-
-    def __init__(self, logger, level=logging.DEBUG):
-        '''
-        build stdout logger
-
-        @param logger: logger
-        @param level: logging level (default: `logging.DEBUG`
-        '''
-        # Set logger level
-        if level == logging.DEBUG:
-            self.logger = logger.debug
-        elif level == logging.CRITICAL:
-            self.logger = logger.critical
-        elif level == logging.ERROR:
-            self.logger = logger.error
-        elif level == logging.WARNING:
-            self.logger = logger.warning
-        elif level == logging.INFO:
-            self.logger = logger.info
-
-    def write(self, msg):
-        '''Writes non-empty strings to logger.'''
-        if msg.lstrip().rstrip() != '':
-            self.logger(msg)
-
-
-@appifies(KLogger)
-class loglet(ChainletMixin, BranchMixin, CoreMixin):
-
-    '''logging chainlet'''
-
-    def _setup(self, root):
-        '''
-        build logger
-
-        @param root: root chain
-        '''
-        super(loglet, self)._setup(root)
-        settings = self._G.log
-        self.logger = logging.getLogger(settings.get('NAME', clsname(root)))
-        # set logging level
-        self.logger.setLevel(settings.LEVEL)
-        # log formatter
-        format = logging.Formatter(
-            # log entry format
-            settings.ENTRY,
-            # date format
-            settings.DATE,
-        )
-        # coroutine to setup log handlers
-        def setlog(thislog): #@IgnorePep8
-            thislog.setFormatter(format)
-            self.logger.addHandler(thislog)
-        # log to STDOUT
-        if settings.stream:
-            setlog(logging.StreamHandler())
-            # redirect STDOUT to the logger
-            if settings.stream.STDOUT:
-                # sets log level STDOUT is displayed under
-                sys.stdout = _LogStdout(self.logger, settings.stream.LEVEL)
-        # log to a rotating file that with periodic backup deletions
-        if settings.rotating.ENABLED:
-            setlog(TimedRotatingFileHandler(
-                # log file path
-                settings.rotating.PATH,
-                # interval to backup log file
-                settings.rotating.INTERVAL,
-                # number of backups to keep
-                settings.rotating.BACKUPS,
-            ))
-        # email log entries to an email address
-        if settings.email.ENABLED:
-            setlog(SMTPHandler(
-                # mail server
-                settings.email.HOST,
-                # from email address
-                settings.email.FROM,
-                # to email address
-                settings.email.TO,
-                # email subject
-                settings.email.SUBJECT,
-            ))
-        # send log entries to a web server
-        if settings.http.ENABLED:
-            setlog(HTTPHandler(
-                # web server host
-                settings.http.HOST,
-                # web url
-                settings.http.URL,
-                # http method
-                settings.http.METHOD,
-            ))
-        # send log entries to syslog
-        if settings.syslog.ENABLED:
-            setlog(SysLogHandler(
-                # syslog host
-                (settings.syslog.HOST, settings.syslog.PORT),
-                # syslog user
-                settings.syslog.FACILITY,
-            ))
-        assert self.logger.handlers, 'configure at least one logging handler'
-
-    def debug(self, msg):
-        '''log debug message'''
-        self.logger.debug(msg)
-        return self
-
-    def warning(self, msg):
-        '''log warning message'''
-        self.logger.warning(msg)
-        return self
-
-    def info(self, msg):
-        '''log info message'''
-        self.logger.info(msg)
-        return self
-
-    def error(self, msg):
-        '''log error message'''
-        self.logger.error(msg)
-        return self
-
-    def critical(self, msg):
-        '''log critical message'''
-        self.logger.critical(msg)
-        return self
-
-    def exception(self, msg):
-        '''log exception message'''
-        self.logger.exception(msg)
-        return self

callchain/keys.py

-# -*- coding: utf-8 -*-
-'''callchain reset keys'''
-
-from appspace.keys import AppspaceKey, Attribute
-
-
-class KDefaults(AppspaceKey):
-
-    '''default settings key'''
-
-
-class KRequired(AppspaceKey):
-
-    '''required settings key'''
-
-
-class NoServiceError(Exception):
-
-    '''no service error'''
-
-
-class KResetType(AppspaceKey):
-
-    '''reset type key'''
-
-    def reset():  # @NoSelf
-        '''reset previously accessed `lazybase` attributes'''
-
-
-class KResetLocal(KResetType):
-
-    '''reset thread local key'''
-
-
-class KSettings(KResetLocal):
-
-    '''settings key'''
-
-
-class KCore(KResetLocal):
-
-    '''core key'''
-
-    G = Attribute('external application global settings')
-
-    def __init__(root):  # @NoSelf
-        '''
-        init
-
-        @param root: root chain
-        '''
-
-
-class KConfig(KCore):
-
-    '''configuration access key'''
-
-    defaults = Attribute('default settings by their lonesome')
-    required = Attribute('required settings by their lonesome')
-
-
-class KRoot(KConfig):
-
-    '''root chain key'''
-
-    def __init__(pattern=None, required=None, defaults=None, **kw):  # @NoSelf
-        '''
-        init
-
-        @param pattern: pattern configuration or appspace label (default: None)
-        @param required: required settings (default: None)
-        @param defaults: default settings (default: None)
-        '''
-
-    def __call__(*args):  # @NoSelf
-        '''new chain session'''
-
-    def back(branch):  # @NoSelf
-        '''
-        handle return from branch chain
-
-        @param branch: branch chain
-        '''
-
-
-class KEventRoot(KRoot):
-
-    '''root event key'''
-
-    def __init__(  # @NoSelf
-        patterns=None,
-        events=None,
-        required=None,
-        defaults=None,
-        *args,
-        **kw
-    ):
-        '''
-        init
-
-        @param patterns: pattern config or eventspace label (default: None)
-        @param events: events configuration (default: None)
-        @param required: required settings (default: None)
-        @param defaults: default settings (default: None)
-        '''
-
-    def event(event):  # @NoSelf
-        '''
-        create or fetch `event`
-
-        @param event: event label
-        '''
-
-    def unevent(event):  # @NoSelf
-        '''
-        drop `event`
-
-        @param event: event label
-        '''
-
-
-class KChain(KResetLocal):
-
-    '''chain key'''
-
-    def chain(call, key=False, *args, **kw):  # @NoSelf
-        '''
-        add `call` or appspaced `call` to call chain, partializing it with any
-        passed arguments
-
-        @param call: call or appspaced call label
-        @param key: appspace key (default: False)
-        '''
-
-    def clear():  # @NoSelf
-        '''clear things'''
-
-    def tap(call, key=False):  # @NoSelf
-        '''
-        add call
-
-        @param call: callable or appspace label
-        @param key: link call chain key (default: False)
-        '''
-
-    def wrap(call, key=False):  # @NoSelf
-        '''build current callable from factory'''
-
-
-class KEvent(KChain):
-
-    '''event chain key'''
-
-    def on(event, call, key=False, *args, **kw):  # @NoSelf
-        '''
-        bind call to `event`
-
-        @param event: event label
-        @param call: label for call or eventspaced thing
-        @param key: key label (default: False)
-        '''
-
-    def off(event):  # @NoSelf
-        '''
-        clear calls bound to `event`
-
-        @param event: event label
-        '''
-
-    def trigger(*events):  # @NoSelf
-        '''
-        extend primary call chain with partials bound to `events`
-
-        @param *events: event labels
-        '''
-
-
-class KCall(KResetLocal):
-
-    '''call key'''
-
-    L = Attribute('local settings extracted')
-    Meta = Attribute('local settings')
-    port = Attribute('python 2.x <-> python 3.x porting helper')
-    space = Attribute('external appspace interface')
-
-    def __enter__():  # @NoSelf
-        '''enter execution context'''
-
-    def __exit__(e, t, b):  # @NoSelf
-        '''exit execution context'''
-
-    def switch(label, key=False):  # @NoSelf
-        '''
-        overt switch to linked chain configured in external appspace
-
-        @param label: linked chain label
-        @param key: linked chain chain key (default: False)
-        '''
-
-    def commit():  # @NoSelf
-        '''consume call chain'''
-
-
-class KEventCall(KCall):
-
-    '''event call key'''
-
-    def fire(*events):  # @NoSelf
-        '''
-        run calls bound to `events` **NOW**
-
-        @param *events: event labels
-        '''
-
-    def queues(*events):  # @NoSelf
-        '''
-        ordered mapping of processing queues for `events`
-
-        @param *events: event labels
-        '''
-
-
-class KBranch(KCore):
-
-    ''''branch key'''
-
-    G = Attribute('root external global settings')
-    M = Attribute('root external appspace manager')
-    _G = Attribute('root internal global settings')
-    _M = Attribute('root internal appspace manager')
-    root = Attribute('root object')
-
-
-class KEventBranch(KBranch):
-
-    '''event branch key'''
-
-    E = Attribute('local event registry')
-
-
-class KLinked(KBranch):
-
-    '''linked chain mixin'''
-
-    def close():  # @NoSelf
-        '''close out linked chain and switch to root chain'''
-
-
-class KChainletKey(KBranch):
-
-    def back():  # @NoSelf
-        '''switch back to root chain'''

callchain/keys/__init__.py

+# -*- coding: utf-8 -*-
+'''callchain service keys'''

callchain/keys/apps.py

+# -*- coding: utf-8 -*-
+'''events appconf'''
+
+from callchain.patterns import Pathways
+
+
+class events(Pathways):
+    key = 'callchain.key.event.EEvent'
+    # 1. before event
+    before = 'callchain.key.event.EBefore'
+    # 2. work event
+    work = 'callchain.key.event.EWork'
+    # 3. change event
+    change = 'callchain.key.event.EChange'
+    # 4. any event
+    any = 'callchain.key.event.EAny'
+    # 5. after event
+    after = 'callchain.key.event.EAfter'
+    # 6. problem event
+    problem = 'callchain.key.event.EProblem'
+    # 7. event that runs irrespective
+    anyway = 'callchain.key.event.EAnyway'

callchain/keys/base.py

+# -*- coding: utf-8 -*-
+'''callchain reset keys'''
+
+from appspace.keys import AppspaceKey, Attribute
+
+
+class KDefaults(AppspaceKey):
+
+    '''default settings key'''
+
+
+class KRequired(AppspaceKey):
+
+    '''required settings key'''
+
+
+class NoServiceError(Exception):
+
+    '''no service error'''
+
+
+class KResetType(AppspaceKey):
+
+    '''reset type key'''
+
+    def reset():  # @NoSelf
+        '''reset previously accessed `lazybase` attributes'''
+
+
+class KResetLocal(KResetType):
+
+    '''reset thread local key'''
+
+
+class KSettings(KResetLocal):
+
+    '''settings key'''
+
+
+class KCore(KResetLocal):
+
+    '''core key'''
+
+    G = Attribute('external application global settings')
+
+    def __init__(root):  # @NoSelf
+        '''
+        init
+
+        @param root: root chain
+        '''
+
+
+class KConfig(KCore):
+
+    '''configuration access key'''
+
+    defaults = Attribute('default settings by their lonesome')
+    required = Attribute('required settings by their lonesome')
+
+
+class KRoot(KConfig):
+
+    '''root chain key'''
+
+    def __init__(pattern=None, required=None, defaults=None, **kw):  # @NoSelf
+        '''
+        init
+
+        @param pattern: pattern configuration or appspace label (default: None)
+        @param required: required settings (default: None)
+        @param defaults: default settings (default: None)
+        '''
+
+    def __call__(*args):  # @NoSelf
+        '''new chain session'''
+
+    def back(branch):  # @NoSelf
+        '''
+        handle return from branch chain
+
+        @param branch: branch chain
+        '''
+
+
+class KEventRoot(KRoot):
+
+    '''root event key'''
+
+    def __init__(  # @NoSelf
+        patterns=None,
+        events=None,
+        required=None,
+        defaults=None,
+        *args,
+        **kw
+    ):
+        '''
+        init
+
+        @param patterns: pattern config or eventspace label (default: None)
+        @param events: events configuration (default: None)
+        @param required: required settings (default: None)
+        @param defaults: default settings (default: None)
+        '''
+
+    def event(event):  # @NoSelf
+        '''
+        create or fetch `event`
+
+        @param event: event label
+        '''
+
+    def unevent(event):  # @NoSelf
+        '''
+        drop `event`
+
+        @param event: event label
+        '''
+
+
+class KChain(KResetLocal):
+
+    '''chain key'''
+
+    def chain(call, key=False, *args, **kw):  # @NoSelf
+        '''
+        add `call` or appspaced `call` to call chain, partializing it with any
+        passed arguments
+
+        @param call: call or appspaced call label
+        @param key: appspace key (default: False)
+        '''
+
+    def clear():  # @NoSelf
+        '''clear things'''
+
+    def tap(call, key=False):  # @NoSelf
+        '''
+        add call
+
+        @param call: callable or appspace label
+        @param key: link call chain key (default: False)
+        '''
+
+    def wrap(call, key=False):  # @NoSelf
+        '''build current callable from factory'''
+
+
+class KEvent(KChain):
+
+    '''event chain key'''
+
+    def on(event, call, key=False, *args, **kw):  # @NoSelf
+        '''
+        bind call to `event`
+
+        @param event: event label
+        @param call: label for call or eventspaced thing
+        @param key: key label (default: False)
+        '''
+
+    def off(event):  # @NoSelf
+        '''
+        clear calls bound to `event`
+
+        @param event: event label
+        '''
+
+    def trigger(*events):  # @NoSelf
+        '''
+        extend primary call chain with partials bound to `events`
+
+        @param *events: event labels
+        '''
+
+
+class KCall(KResetLocal):
+
+    '''call key'''
+
+    L = Attribute('local settings extracted')
+    Meta = Attribute('local settings')
+    port = Attribute('python 2.x <-> python 3.x porting helper')
+    space = Attribute('external appspace interface')
+
+    def __enter__():  # @NoSelf
+        '''enter execution context'''
+
+    def __exit__(e, t, b):  # @NoSelf
+        '''exit execution context'''
+
+    def switch(label, key=False):  # @NoSelf
+        '''
+        overt switch to linked chain configured in external appspace
+
+        @param label: linked chain label
+        @param key: linked chain chain key (default: False)
+        '''
+
+    def commit():  # @NoSelf
+        '''consume call chain'''
+
+
+class KEventCall(KCall):
+
+    '''event call key'''
+
+    def fire(*events):  # @NoSelf
+        '''
+        run calls bound to `events` **NOW**
+
+        @param *events: event labels
+        '''
+
+    def queues(*events):  # @NoSelf
+        '''
+        ordered mapping of processing queues for `events`
+
+        @param *events: event labels
+        '''
+
+
+class KBranch(KCore):
+
+    ''''branch key'''
+
+    G = Attribute('root external global settings')
+    M = Attribute('root external appspace manager')
+    _G = Attribute('root internal global settings')
+    _M = Attribute('root internal appspace manager')
+    root = Attribute('root object')
+
+
+class KEventBranch(KBranch):
+
+    '''event branch key'''
+
+    E = Attribute('local event registry')
+
+
+class KLinked(KBranch):
+
+    '''linked chain mixin'''
+
+    def close():  # @NoSelf
+        '''close out linked chain and switch to root chain'''
+
+
+class KChainletKey(KBranch):
+
+    def back():  # @NoSelf
+        '''switch back to root chain'''

callchain/keys/core.py

+# -*- coding: utf-8 -*-
+'''callchain contrib keys'''
+
+from appspace.keys import Attribute, AppspaceKey
+
+
+class KService(AppspaceKey):
+
+    '''service key'''
+
+
+class KThings(KService):
+
+    '''queuing key'''
+
+    incoming = Attribute('incoming queue')
+    outgoing = Attribute('outgoing queue')
+    balanced = Attribute('if incoming and outgoing things are balanced')
+
+    def __len__():  # @NoSelf
+        '''number of incoming things'''
+
+    def outcount():  # @NoSelf
+        '''number of outgoing things'''
+
+    ###########################################################################
+    ## queue clearance ########################################################
+    ###########################################################################
+
+    def clear():  # @NoSelf
+        '''clear every thing'''
+
+    def inclear():  # @NoSelf
+        '''clear incoming things'''
+
+    def outclear():  # @NoSelf
+        '''clear outgoing things'''
+
+    ###########################################################################
+    ## context rotation #######################################################
+    ###########################################################################
+
+    def ctx1(**kw):  # @NoSelf
+        '''swap to one-armed context'''
+
+    def ctx2(**kw):  # @NoSelf
+        '''swap to two-armed context'''
+
+    def ctx3(**kw):  # @NoSelf
+        '''swap to three-armed context'''
+
+    def ctx4(**kw):  # @NoSelf
+        '''swap to four-armed context'''
+
+    def autoctx(**kw):  # @NoSelf
+        '''swap to auto-synchronizing context'''
+
+    def ro():  # @NoSelf
+        '''swap to read-only context'''
+
+    def swap(**kw):  # @NoSelf
+        '''swap contexts'''
+
+    def reswap(self):  # @NoSelfs
+        '''swap to current preferred context'''
+
+    def unswap():  # @NoSelf
+        '''swap to default context'''
+
+    def rw():  # @NoSelf
+        '''swap to default context'''
+
+    ###########################################################################
+    ## current callable management ############################################
+    ###########################################################################
+
+    def args(*args, **kw):  # @NoSelf
+        '''arguments for current callable'''
+
+    def detap():  # @NoSelf
+        '''clear current callable'''
+
+    def wrap(call):  # @NoSelf
+        '''
+        build current callable from factory
+
+        @param call: a callable
+        '''
+
+    def unwrap():  # @NoSelf
+        '''clear factory'''
+
+    ###########################################################################
+    ## things rotation ########################################################
+    ###########################################################################
+
+    def outshift():  # @NoSelf
+        '''shift incoming things to outgoing things'''
+
+    def outsync():  # @NoSelf
+        '''
+        shift incoming things to outgoing things, clearing outgoing things
+        '''
+
+    def reup():  # @NoSelf
+        '''put incoming things in incoming things as one incoming thing'''
+
+    def shift():  # @NoSelf
+        '''shift outgoing things to incoming things'''
+
+    def sync():  # @NoSelf
+        '''
+        shift outgoing things to incoming things, clearing incoming things
+        '''
+
+    ###########################################################################
+    ## things appending #######################################################
+    ###########################################################################
+
+    def append(thing):  # @NoSelf
+        '''
+        append `thing` to right side of incoming things
+
+        @param thing: some thing
+        '''
+
+    def appendleft(thing):  # @NoSelf
+        '''
+        append `thing` to left side of incoming things
+
+        @param thing: some thing
+        '''
+
+    ###########################################################################
+    ## things extension #######################################################
+    ###########################################################################
+
+    def extend(things):  # @NoSelf
+        '''
+        extend right side of incoming things with `things`
+
+        @param thing: some things
+        '''
+
+    def extendleft(things):  # @NoSelf
+        '''
+        extend left side of incoming things with `things`
+
+        @param thing: some things
+        '''
+
+    def outextend(things):  # @NoSelf
+        '''
+        extend right side of outgoing things with `things`
+
+        @param thing: some things
+        '''
+
+    ###########################################################################
+    ## iteration runners ######################################################
+    ###########################################################################
+
+    def __iter__():  # @NoSelf
+        '''yield outgoing things, clearing outgoing things as it iterates'''
+
+    def breakcount(call, length, exception=StopIteration):  # @NoSelf
+        '''
+        rotate through iterator until it reaches its original length
+
+        @param iterable: an iterable to exhaust
+        '''
+
+    def exhaust(iterable, exception=StopIteration):  # @NoSelf
+        '''
+        call next on an iterator until it's exhausted
+
+        @param iterable: iterable to exhaust
+        @param exception: exception marking end of iteration
+        '''
+
+    def exhaustmap(map, call, filter=False, exception=StopIteration):  # @NoSelf @IgnorePep8
+        '''
+        call `next` on an iterator until it's exhausted
+
+        @param mapping: a mapping to exhaust
+        @param call: call to handle what survives the filter
+        @param filter: a filter to apply to mapping (default: `None`)
+        @param exception: exception sentinel (default: `StopIteration`)
+        '''
+
+    def iterexcept(call, exception, start=None):  # @NoSelf
+        '''
+        call a function repeatedly until an exception is raised
+
+        Converts a call-until-exception interface to an iterator interface.
+        Like `iter(call, sentinel)` but uses an exception instead of a sentinel
+        to end the loop.
+
+        Raymond Hettinger, Python Cookbook recipe # 577155
+        '''
+
+
+class KResult(KThings):
+
+    def end():  # @NoSelf
+        '''return outgoing things then clear out everything'''
+
+    def first():  # @NoSelf
+        '''first incoming thing'''
+
+    def last():  # @NoSelf
+        '''last incoming thing'''
+
+    def peek():  # @NoSelf
+        '''results from read-only context'''
+
+    def results():  # @NoSelf
+        '''yield outgoing things, clearing outgoing things as it iterates'''
+
+    def value():  # @NoSelf
+        '''return outgoing things and clear outgoing things'''
+
+
+class KLogger(KService):
+
+    '''logging key'''
+
+    logger = Attribute('the logger')
+
+    def debug(msg):  # @NoSelf
+        '''log debug message'''
+
+    def warning(msg):  # @NoSelf
+        '''log warning message'''
+
+    def info(msg):  # @NoSelf
+        '''log info message'''
+
+    def error(msg):  # @NoSelf
+        '''log error message'''
+
+    def critical(msg):  # @NoSelf
+        '''log critical message'''
+
+    def exception(msg):  # @NoSelf
+        '''log exception message'''

callchain/keys/dumps.py

+# -*- coding: utf-8 -*-
+'''callchain dumping keys'''
+
+from callchain.keys.core import KService
+
+
+class KDumps(KService):
+
+    '''dumping key'''
+
+    def protobuf():  # @NoSelf
+        '''
+        google protocol buffers dumps
+
+        http://code.google.com/p/protobuf/
+
+        http://pypi.python.org/pypi/protobuf/
+        '''
+
+    def thrift():  # @NoSelf
+        '''
+        thrift dumps
+
+        http://thrift.apache.org/
+
+        http://pypi.python.org/pypi/thrift/
+        '''
+
+    def bencode():  # @NoSelf
+        '''
+        bencode dumps
+
+        http://en.wikipedia.org/wiki/Bencode
+
+        http://pypi.python.org/pypi/BitTorrent-bencode/
+        '''
+
+    def bson():  # @NoSelf
+        '''
+        binary JSON dumps
+
+        http://en.wikipedia.org/wiki/BSON
+
+        http://pypi.python.org/pypi/bson/0.3.3
+        '''
+
+    def csv(**kw):  # @NoSelf
+        '''csv serialization'''
+
+    def excel(**kw):  # @NoSelf
+        '''
+        M$ excel dumps
+
+        http://pypi.python.org/pypi/xlrd/
+
+        http://pypi.python.org/pypi/xlwt/
+        '''
+
+    def html(**kw):  # @NoSelf
+        '''
+        html dumps
+
+        http://pypi.python.org/pypi/lxml/
+        '''
+
+    def json(**kw):  # @NoSelf
+        '''JavaScript Object Notation (JSON) dumps'''
+
+    def jsonpickle():  # @NoSelf
+        '''JavaScript Object Notation (JSON) pickle dumps'''
+
+    def marshal():  # @NoSelf
+        '''Python marshal dumps'''
+
+    def message_pack(**kw):  # @NoSelf
+        '''
+        message pack dumps
+
+        http://msgpack.org/
+
+        http://pypi.python.org/pypi/msgpack-python/
+        '''
+
+    def multipart():  # @NoSelf
+        '''form-multipart serialization'''
+
+    def netstring(**kw):  # @NoSelf
+        '''
+        netstring dumps
+
+        http://cr.yp.to/proto/netstrings.txt
+
+        http://pypi.python.org/pypi/netstring
+        '''
+
+    def pickle():  # @NoSelf
+        '''python pickle dumps'''
+
+    def plist():  # @NoSelf
+        '''property list dumps'''
+
+    def tnetstring():  # @NoSelf
+        '''
+        tnetstring dumps
+
+        http://pypi.python.org/pypi/tnetstring/
+        '''
+
+    def urlencode(**kw):  # @NoSelf
+        '''urlencode serialization'''
+
+    def xml(**kw):  # @NoSelf
+        '''eXtensible markup language dumps'''
+
+    def xmlrpc(**kw):  # @NoSelf
+        '''
+        eXtensible markup language remote procedure call dumps
+        '''
+
+    def yaml(**kw):  # @NoSelf
+        '''
+        YaML ain't markup language dumps
+
+        http://en.wikipedia.org/wiki/YAML
+
+        http://pypi.python.org/pypi/PyYAML/
+        '''

callchain/keys/event.py

+# -*- coding: utf-8 -*-
+'''event keys'''
+
+from appspace.keys import AppspaceKey
+
+
+class EEvent(AppspaceKey):
+
+    '''event key'''
+
+
+class EBefore(EEvent):
+
+    '''before event key'''
+
+
+class EWork(EEvent):
+
+    '''work event key'''
+
+
+class EChange(EEvent):
+
+    '''change event key'''
+
+
+class EAny(EEvent):
+
+    '''any events key'''
+
+
+class EAfter(EEvent):
+
+    '''after event key'''
+
+
+class EProblem(EEvent):
+
+    '''problem event key'''
+
+
+class EAnyway(EEvent):
+
+    '''run anyway event key'''

callchain/keys/filter.py

+# -*- coding: utf-8 -*-
+'''filtering services keys'''
+
+from callchain.keys.core import KService
+
+
+class KCollect(KService):
+
+    '''collection key'''
+
+    def deepmembers():  # @NoSelf
+        '''collect object members from incoming things and their bases'''
+
+    def members():  # @NoSelf
+        '''collect object members from incoming things'''
+
+    def pick(*names):  # @NoSelf
+        '''collect object attributes from incoming things by their `*names`'''
+
+    def pluck(*keys):  # @NoSelf
+        '''collect object items from incoming things by item `*keys`'''
+
+
+class KSet(KService):
+
+    '''set uniqueness key'''
+
+    def difference():  # @NoSelf
+        '''difference between incoming things'''
+
+    def symmetric_difference():  # @NoSelf
+        '''symmetric difference between incoming things'''
+
+    def disjointed():  # @NoSelf
+        '''disjoint between incoming things'''
+
+    def intersection():  # @NoSelf
+        '''intersection between incoming things'''
+
+    def subset():  # @NoSelf
+        '''incoming things that are subsets of incoming things'''
+
+    def superset():  # @NoSelf
+        '''incoming things that are supersets of incoming things'''
+
+    def union():  # @NoSelf
+        '''union between incoming things'''
+
+    def unique():  # @NoSelf
+        '''
+        list unique incoming things, preserving order and remember all incoming
+        things ever seen
+        '''
+
+
+class KSlice(KService):
+
+    '''slicing key'''
+
+    def nth(n, default=None):  # @NoSelf
+        '''
+        `nth` incoming thing or default thing
+
+        @param n: number of things
+        @param default: default thing (default: None)
+        '''
+
+    def initial():  # @NoSelf
+        '''all incoming things except the last thing'''
+
+    def rest():  # @NoSelf
+        '''all incoming things except the first thing'''
+
+    def snatch(n):  # @NoSelf
+        '''
+        last `n` things of incoming things
+
+        @param n: number of things
+        '''
+
+    def take(n):  # @NoSelfs
+        '''
+        first `n` things of incoming things
+
+        @param n: number of things
+        '''
+
+
+class KFilter(KService):
+
+    '''filter key'''
+
+    def compact():  # @NoSelf
+        '''strip "untrue" things from incoming things'''
+
+    def filter():  # @NoSelf
+        '''incoming things for which call is `True`'''
+
+    def find():  # @NoSelf
+        '''first incoming thing for which call is `True`'''
+
+    def partition():  # @NoSelf
+        '''
+        split incoming things into `True` and `False` things based on results
+        of call
+        '''
+
+    def reject():  # @NoSelf
+        '''incoming things for which call is `False`'''
+
+    def without(*things):  # @NoSelf
+        '''strip things from incoming things'''

callchain/keys/loads.py

+# -*- coding: utf-8 -*-
+'''callchain loading keys'''
+
+from callchain.keys.core import KService
+
+
+class KLoads(KService):
+
+    '''loading key'''
+
+    def protobuf(**kw):  # @NoSelf
+        '''
+        google protocol buffers loading
+
+        http://code.google.com/p/protobuf/
+
+        http://pypi.python.org/pypi/protobuf/
+        '''
+
+    def thrift(base):  # @NoSelf
+        '''
+        thrift loading
+
+        http://thrift.apache.org/
+
+        http://pypi.python.org/pypi/thrift/
+        '''
+
+    def bencode():  # @NoSelf
+        '''
+        bencode loading
+
+        http://en.wikipedia.org/wiki/Bencode
+
+        http://pypi.python.org/pypi/BitTorrent-bencode/
+        '''
+
+    def bson():  # @NoSelf
+        '''
+        binary JavaScript Object Notation loading
+
+        http://en.wikipedia.org/wiki/BSON
+
+        http://pypi.python.org/pypi/bson/0.3.3
+        '''
+
+    def csv(**kw):  # @NoSelf
+        '''csv serialization'''
+
+    def excel(**kw):  # @NoSelf
+        '''
+        M$ excel loading
+
+        http://pypi.python.org/pypi/xlrd/
+
+        http://pypi.python.org/pypi/xlwt/
+        '''
+
+    def html(**kw):  # @NoSelf
+        '''
+        html loading
+
+        http://pypi.python.org/pypi/lxml/
+        '''
+
+    def json(**kw):  # @NoSelf
+        '''JavaScript Object Notation (JSON) loading'''
+
+    def jsonpickle():  # @NoSelf
+        '''JavaScript Object Notation (JSON) pickle loading'''
+
+    def marshal():  # @NoSelf
+        '''Python marshal loading'''
+
+    def message_pack(**kw):  # @NoSelf
+        '''
+        message pack loading
+
+        http://msgpack.org/
+
+        http://pypi.python.org/pypi/msgpack-python/
+        '''
+
+    def multipart():  # @NoSelf
+        '''form-multipart serialization'''
+
+    def netstring(**kw):  # @NoSelf
+        '''
+        netstring loading
+
+        http://cr.yp.to/proto/netstrings.txt
+
+        http://pypi.python.org/pypi/netstring
+        '''
+
+    def pickle():  # @NoSelf
+        '''python pickle loading'''
+
+    def plist():  # @NoSelf
+        '''property list loading'''
+
+    def tnetstring():  # @NoSelf
+        '''
+        tnetstring loading
+
+        http://pypi.python.org/pypi/tnetstring/
+        '''
+
+    def urlencode(**kw):  # @NoSelf
+        '''urlencode serialization'''
+
+    def xml(**kw):  # @NoSelf
+        '''eXtensible markup language loading'''
+
+    def xmlrpc(**kw):  # @NoSelf
+        '''
+        eXtensible markup language remote procedure call loading
+        '''
+
+    def yaml(**kw):  # @NoSelf
+        '''
+        YaML ain't markup language loading
+
+        http://en.wikipedia.org/wiki/YAML
+
+        http://pypi.python.org/pypi/PyYAML/
+        '''

callchain/keys/map.py

+# -*- coding: utf-8 -*-
+'''mapping services keys'''
+
+from callchain.keys.core import KService
+
+
+class KDelay(KService):
+
+    '''delayed map key'''
+
+    def delay_each(wait):  # @NoSelf
+        '''
+        invoke call with passed arguments, keywords in incoming things after
+        delay `wait`
+
+        @param wait: time in seconds
+        '''
+
+    def delay_invoke(name, wait):  # @NoSelf
+        '''
+        invoke method `name` on each incoming thing with passed arguments,
+        keywords after delay `wait` but return incoming thing instead if method
+        returns `None`
+
+        @param name: name of method
+        @param wait: time in seconds
+        '''
+
+    def delay_map(wait):  # @NoSelf
+        '''
+        invoke call on each incoming thing after delay `wait`
+
+        @param wait: time in seconds
+        '''
+
+
+class KRepeat(KService):
+
+    '''repetition key'''
+
+    def copy():  # @NoSelf
+        '''copy each incoming thing'''
+
+    def padnone():  # @NoSelf
+        '''repeat incoming things and then `None` indefinitely'''
+