Commits

Lynn Rees  committed 132e953

- more

  • Participants
  • Parent commits a265891
  • Branches pu

Comments (0)

Files changed (36)

File wire/datalet.py

+# -*- coding: utf-8 -*-
+'''wire datalet'''
+
+from callchain.root.chainlet import chainlet
+
+
+class datalet(chainlet):
+
+    def __init__(self, root):
+        '''
+        init
+
+        @param root: root object
+        '''
+        super(datalet, self).__init__(root)
+        self._data.extend(root._data)
+
+
+class talklet(datalet):
+
+    def encode(self):
+        ''''''

File wire/http/header.py

 
 class CoreHeaders(ResetLocalMixin):
 
-    '''generic HTTP header manager'''
+    '''core HTTP header manager'''
 
     ###########################################################################
     ## header processing definitions ##########################################
             'if-match', 'if-none-match', 'pragma', 'vary', 'via',
         ])
 
-    _hCOMMA_SEP = _COMMA_SEP
-
     @lazy_class
     def _SC_SEP(self):
         '''may have values that split on the semi-colon'''
             'accept', 'accept-charset', 'accept-encoding', 'accept-language',
         ])
 
-    _hSC_SEP = _SC_SEP
-
     @lazy_class
     def _DATES(self):
         '''covert to datetime fields'''
             'if-range', 'last-modified', 'retry-after',
         ])
 
-    _hSC_SEP = _DATES
-
     @lazy_class
     def _ENCODINGS(self):
         '''*CONTENT-ENCODING* compatible values'''
         return self._freeze(['gzip', 'compress', 'deflate'])
 
-    _hENCODINGS = _ENCODINGS
-
     ###########################################################################
     ## header family definitions ####EEEE######################################
     ###########################################################################
             'expires', 'last-modified', 'cookie',
         ])
 
-    _hENTITY = _ENTITY
-
     @lazy_class
     def _GENERAL(self):
         '''general HTTP headers'''
             'transfer-encoding', 'upgrade', 'warning',
         ])
 
-    _hGENERAL = _GENERAL
-
     @lazy_class
     def _HOP_BY_HOP(self):
         '''hop by hop headers'''
             'proxy-authorization', 'te', 'trailer', 'transfer-encoding',
         ])
 
-    _hHOP_BY_HOP = _HOP_BY_HOP
-
     @lazy_class
     def _HTTPIF(self):
         '''HTTP if tests'''
             'if-unmodified-since',
         ])
 
-    _hHTTPIF = _HTTPIF
-
     ###########################################################################
     ## request header definitions #############################################
     ###########################################################################
             'referer',
         ])
 
-    _hREQUEST = _REQUEST
-
     @lazy_class
     def _REQ_HEADERS(self):
         '''combined HTTP request compatible headers'''
         return self.GENERAL | self.REQUEST | self.ENTITY
 
-    _hREQ_HEADERS = _REQ_HEADERS
-
     ###########################################################################
     ## response header definitions ############################################
     ###########################################################################
             'retry-after', 'server', 'set-cookie', 'vary', 'www-authenticate',
         ])
 
-    _hRESPONSE = _RESPONSE
-
     @lazy_class
     def _RES_HEADERS(self):
         '''combined HTTP response compatible headers'''
         return self.GENERAL | self.RESPONSE | self.ENTITY
 
-    _hRES_HEADERS = _RES_HEADERS
-
     ###########################################################################
     ## header validators ######################################################
     ###########################################################################
         )
         return dict((k, re.compile(v, re.U)) for k, v in items(_PATTERNS))
 
-    _hPATTERNS = _PATTERNS
-
     @classmethod
     def _regeval(cls, key, data):
         '''Validates data by key'''
     ## header management ######################################################
     ###########################################################################
 
+    def _key(self, key):
+        '''
+        ensure proper formatting for header `key`
+
+        @param key: key associated with value
+        '''
+        return n(key.lower().replace('_', '-'))
+
+    _hkey = _key
+
     def _parseint(self, value):
         '''
-        parses an integer from a header value.
+        parse integer from header `value`
 
         @param value: integer value
         '''
     ###########################################################################
 
     def dumps(self):
+        '''dump header string'''
         return n('\r\n'.join(': '.join([k, v]) for k, v in self))
 
     _hdumps = dumps

File wire/http/httplet.py

 '''wire httplet'''
 
 from callchain.root.linked import chainlink
-from callchain.root.chainlet import chainlet
 
+from wire.datalet import datalet
 
-class httplet(chainlet):
+
+class httplet(datalet):
 
     def __init__(self, root):
         '''
         '''
         super(httplet, self).__init__(root)
         self._cookies = root._cookies
-        self._data.extend(root._data)
         self._headers = root._headers
         self._params = root._params
         self._files = root._files

File wire/http/request/client.py

 
 import hashlib
 from functools import partial
-from collections import deque
 
+from stuf.six import items
 from appspace.keys import appifies
 from callchain.internal import inside
 from twoq.lazy.mixins import AutoResultMixin
 from wire.support import base64_encode
 from wire.http.request.apps import apps
 from wire.http.request.keys.client import KRequestClient
-from wire.http.errors import OffsetError
 
 
 class Request(ResetTypeMixin):
         self._file = data
 
     def headers(self, headers):
-        self._headers.update(headers.dump())
+        self._headers.update(i for i in items(headers))
 
     def params(self, params):
         self._params = params
         self._headers = OrderedDict()
         # cookies
         self._cookies = None
-        # data
-        self._data = deque()
-        # files
-        self._files = deque()
-        # params
-        self._params = deque()
 
     def __getattr__(self, key):
         return partial(
 
     _hpack = _pack
 
-    def data(self, *data):
-        '''
-        `data` for urls (must equal number of previously passed urls)
-
-        param *data: data for request body
-        '''
-        if len(data) == len(self):
-            self._data.extend(data)
-        else:
-            raise OffsetError(
-                'number of data items does not match number of URLs'
-            )
-        return self
-
-    def files(self, *files):
-        '''
-        `files` for urls (must equal number of previously passed urls)
-
-        param *data: data for request body
-        '''
-        if len(files) == len(self):
-            # files demand multipart as default otherwise go with urlencode
-            self._value = 'multipart'
-            self._files.extend(files)
-        else:
-            raise OffsetError(
-                'number of file items does not match number of URLs'
-            )
-        return self
-
-    def params(self, *params):
-        '''
-        request parameters for all urls
-
-        param **params: parameters
-        '''
-        if len(params) == len(self):
-            self._params.extend(params)
-        else:
-            raise OffsetError(
-                'number of parameter items does not match number of URLs'
-            )
-        return self
-
-    def content_md5(self):
-        '''
-        take MD5 hash of data and set *CONTENT-MD5* HTTP header on items
-
-        @param value: HTTP response data
-        '''
-        self.args(self._headers).invoke('content_md5')
-        return self
-
     ###########################################################################
     ## http configuration #####################################################
     ###########################################################################

File wire/http/request/cookie.py

 # -*- coding: utf-8 -*-
 '''wire HTTP cookie management'''
 
-from functools import partial
-
 from stuf.utils import exhaustmap
-from twoq.support import isstring
 from appspace.keys import appifies
 # pylint: disable-msg=f0401
 from stuf.six.moves import http_cookies  # @UnresolvedImport
 
 from wire.http.httplet import httplet
 from wire.http.request.keys.header import KRequestCookie
+from wire.support import n2b
 
 
 class Cookie(http_cookies.SimpleCookie):
 
-    '''HTTP request specific cookie'''
-
-    def __init__(self, inpt=False):
-        super(Cookie, self).__init__()
-        if inpt:
-            self.load(input)
-
-    def __setitem__(self, key, value):
-        rval, cval = self.value_encode(value)
-        self._set(key, rval, cval)
-
-    def _set(self, k, real_value, coded_value):
-        m = self.get(k, http_cookies.Morsel())
-        m.set(k, real_value, coded_value)
-        dict.__setitem__(self, k, m)
-
-    def _parse(self, cookie, patt=http_cookies._CookiePattern):
-        # our starting point
-        i = 0
-        # length of string
-        n = len(cookie)
-        # current morsel
-        m = None
-        unquote = http_cookies._unquote
-        reserved = http_cookies.Morsel._reserved
-        value_decode = self.value_decode
-        setter = self._set
-        this = self
-        psearch = patt.search
-        while 0 <= i < n:
-            # Start looking for a cookie
-            match = psearch(cookie, i)
-            if not match:
-                break  # no more cookies
-            k, v = match.group('key'), match.group('val').rstrip(', ')
-            i = match.end(0)
-            # parse the key, value just in case it's metainfo
-            if k[0] == '$':
-                if m:
-                    m._morsel[k[1:]] = v
-            elif k.lower() in reserved:
-                if m:
-                    m._morsel[k] = unquote(v)
-            else:
-                rval, cval = value_decode(v)
-                setter(k, rval, cval)
-                m = this[k]
-
-    def loads(self, data):
-        if isstring(data):
-            self._parse(data)
-        else:
-            exhaustmap(data, self.__setitem__)
+    '''HTTP request cookie'''
 
     def set(self, key, field, value):
+        '''
+        set cookie `field`, `value`
+
+        @param key: cookie (or morsel) name
+        @param field: cookie field value
+        @param value: putative header value
+        '''
+        # fetch existing or new cookie morsel
         m = self.get(key, http_cookies.Morsel())
+        # set existing cookie fields
         if key.lower() in m._reserved:
             m[field] = http_cookies._unquote(value)
+        # update existing value
         else:
             real_value, coded_value = self.value_decode(value)
             m.set(field, real_value, coded_value)
+        # save morsel
         dict.__setitem__(self, key, m)
 
+    _cset = set
+
     def dumps(self):
-        return partial(self.output, header='cookie:')
+        '''dump cookie in HTTP header form'''
+        return n2b(self.output(header='cookie:'))
+
+    _cdumps = dumps
 
 
 @appifies(KRequestCookie)
         exhaustmap(values, lambda x, y: setr(key, x, y))
         return self
 
-    _hcookie = cookie
+    _ccookie = cookie

File wire/http/request/data.py

+# -*- coding: utf-8 -*-
+'''wire HTTP data management'''
+
+from collections import deque
+
+from appspace.keys import appifies
+from callchain.internal import inside
+
+from wire.http.httplet import httplet
+from wire.http.request.apps import apps
+from wire.http.errors import OffsetError
+from wire.http.request.keys.data import KRequestData
+
+
+@appifies(KRequestData)
+@inside(apps)
+class RequestData(httplet):
+
+    '''HTTP client call chain'''
+
+    def __init__(self, root):
+        super(RequestData, self).__init__(root)
+        # data
+        self._data = deque() if self._data is None else self._data
+        # files
+        self._files = deque()
+        # params
+        self._params = deque()
+
+    def data(self, *data):
+        '''
+        `data` for urls (must equal number of previously passed urls)
+
+        param *data: data for request body
+        '''
+        if len(data) == len(self):
+            self._data.extend(data)
+        else:
+            raise OffsetError(
+                'number of data items does not match number of URLs'
+            )
+        return self
+
+    def files(self, *files):
+        '''
+        `files` for urls (must equal number of previously passed urls)
+
+        param *data: data for request body
+        '''
+        if len(files) == len(self):
+            # files demand multipart as default otherwise go with urlencode
+            self._value = 'multipart'
+            self._files.extend(files)
+        else:
+            raise OffsetError(
+                'number of file items does not match number of URLs'
+            )
+        return self
+
+    def params(self, *params):
+        '''
+        request parameters for all urls
+
+        param **params: parameters
+        '''
+        if len(params) == len(self):
+            self._params.extend(params)
+        else:
+            raise OffsetError(
+                'number of parameter items does not match number of URLs'
+            )
+        return self
+
+    def content_md5(self):
+        '''
+        take MD5 hash of data and set *CONTENT-MD5* HTTP header on items
+
+        @param value: HTTP response data
+        '''
+        self.args(self._headers).invoke('content_md5')
+        return self

File wire/http/request/header.py

 # -*- coding: utf-8 -*-
-'''wire HTTP management'''
+'''wire HTTP request header management'''
 
 import re
 from random import choice
 from wire.support import n2b
 
 from wire.http.util import httpdate
+from wire.http.httplet import httplet
 from wire.http.header import CoreHeaders
 from wire.http.errors import HTTPHeaderException
 from wire.http.request.keys.header import KRequestHeaders
 n = n2b
 
 
-@appifies(KRequestHeaders)
 class Headers(CoreHeaders):
 
     '''HTTP request header manager'''
 
     def __init__(self):
         super(Headers, self).__init__()
-        # "best practice" sends HTTP headers in order: general, request, entity
+        # "best practice" sends HTTP headers in order: 1. general headers
         self._general = OrderedDict()
+        # 2. request headers
+        self._request = OrderedDict()
+        # 3. entity headers
         self._entity = OrderedDict()
-        self._request = OrderedDict()
+        # 4. custom headers
         self._custom = OrderedDict()
-        # populate headers
-        if self.G.randomua:
-            self.user_agent(self._randomua())
 
     def __iter__(self):
         # cast any header objects as `bytes` (calling `Header.decode`)
-        return ((h[0].lower(), n(h[1])) for h in chain(
+        return ((k, n(v)) for k, v in chain(
+            # "best practice" sends HTTP headers in order: 1. general headers
             items(self._general),
+            # 2. request headers
             items(self._request),
+            # 3. entity headers
             items(self._entity),
+            # 4. custom headers
             items(self._custom),
-        ) if h is not None)
+        ) if k is not None)
 
     ###########################################################################
     ## header definitions #####################################################
 
     @lazy_class
     def _langs(self):
-        '''language set.'''
+        '''language codes'''
         from locale import locale_alias
         return frozenset(n(i.replace('_', '-')) for i in locale_alias)
 
     @staticmethod
     def _randomua():
-        '''random user agent'''
+        '''random user agent value'''
         return choice([
-        n('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) '
-        'Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)'),
-        n('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) '
-        'Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)'),
-        n('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) '
-        'Gecko/20090718 Firefox/3.5.1'),
-        n('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) '
-        'Gecko/20090718 Firefox/4.0.1'),
-        n('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 '
-        '(KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1'),
-        n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; '
-        'Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)'),
-        n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; '
-        'SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; '
-        '.NET CLR 3.0.30729)'),
-        n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; '
-        'Trident/4.0)'),
-        n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; '
-        'SV1; '
-        '.NET CLR 2.0.50727; InfoPath.2)Mozilla/5.0 (Windows; U; MSIE 7.0; '
-        'Windows NT 6.0; en-US)'),
-        n('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)'),
+            n('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) '
+            'Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)'),
+            n('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) '
+            'Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)'),
+            n('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) '
+            'Gecko/20090718 Firefox/3.5.1'),
+            n('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) '
+            'Gecko/20090718 Firefox/4.0.1'),
+            n('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/'
+            '532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1'),
+            n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; '
+            'Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)'),
+            n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0;'
+            ' SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.'
+            '30729; .NET CLR 3.0.30729)'),
+            n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; '
+            'Trident/4.0)'),
+            n('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0;'
+            ' SV1; .NET CLR 2.0.50727; InfoPath.2) Mozilla/5.0 (Windows; U; '
+            'MSIE 7.0; Windows NT 6.0; en-US)'),
+            n('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)'),
         ])
 
+    _hrandom = _randomua
+
     ###########################################################################
     ## header validation ######################################################
     ###########################################################################
 
     @lazy_class
     def _rules(self):
-        '''Validation rules for individual HTTP header fields'''
+        '''validation rules for individual HTTP header fields'''
         return {
-            # "Allow" values must be valid HTTP methods
+            # "ALLOW" values must be valid HTTP methods
             'allow': (
                 lambda v: v.upper() not in self._METHODS,
                 '"Allow" value must be valid HTTP method'
             ),
-            # "Content-Encoding" value must be zip, compress, or deflate
+            # "CONTENT-ENCODING" value must be zip, compress, or deflate
             'content-encoding': (
                 lambda v: v.lower() not in self._ENCODINGS,
                 '"Content-Encoding" must be gzip, compress, deflate',
             ),
-            # "Content-Language" values must be valid language codes
+            # "CONTENT-LANGUAGE" values must be valid language codes
             'content-language': (
                 lambda v: v.lower() not in self._langs,
                 'Unknown language code'
             ),
-            # "Content-Length" value must be an integer
+            # "CONTENT-LENGTH" value must be an integer
             'content-length': (
                 lambda v: not v.isdigit(),
                 '"Content-Length" must be integer'
             ),
-            # "Content-Range" value must be in the proper format
+            # "CONTENT-RANGE" value must be in the proper format
             'content-range': (
                 lambda v: not self._iscontentrange(v),
                 'Invalid format for "Content-Range"'
     @classmethod
     def _validate(self, key, value):
         '''
-        validate header value
+        validate HTTP header `value`
 
         @param key: HTTP header name
         @param value: putative header value
         '''
-        err_msg = None
         if not isstring(value):
             return True
-        # Don't allow request headers
+        err_msg = None
+        # don't allow response headers
         if key in self._RESPONSE:
             err_msg = '"%s" is HTTP response-only header' % key
-        # Don't allow unicode header names
+        # don't allow unicode header names
         if isunicode(key):
             err_msg = 'HTTP header name must be non-Unicode string'
-        # Don't allow unicode header values outside RFC2822
+        # don't allow unicode header values outside RFC 2822
         elif isunicode(value):
-            err_msg = 'use "rfc2822" to set Unicode HTTP header values'
-        # Don't allow "status" to be set in headers
+            err_msg = 'use `rfc2822` to set Unicode HTTP header values'
+        # don't allow "status" to be set in headers
         elif key == 'status':
             err_msg = 'HTTP status code cannot be set on HTTP request'
-        # Don't allow newline or colon in header name
+        # don't allow newline or colon in header name
         elif '\n' in key or ':' in key:
             err_msg = 'HTTP header names may not contain ":" or "\\n"'
-        # Do not allow invalid characters in header name
+        # do not allow invalid characters in header name
         elif not self._ishttpname(key):
             err_msg = 'Bad HTTP header name: %r' % key
-        # Do not allow dash or underscore at end of header name
+        # do not allow dash or underscore at end of header name
         elif key.endswith('-') or key.endswith('_'):
             err_msg = 'HTTP header name may not end in "-" or "_"'
-        # No control characters in header name
+        # no control characters in header name
         elif isstring(value) and self._badheaders.search(value):
             err_msg = 'Bad character %r in HTTP header value %r' % (
                 self._badheaders.search(value).group(0), value
             )
-        # Validate RFC 1123 compliance
+        # validate RFC 1123 compliance
         elif key in self._DATES and not self._isrfc1123(value):
             err_msg = 'Date is not RFC 1123 compliant'
-        # Validate individual header
+        # validate individual header
         else:
             rule = self._rules.get(key)
             if rule is not None and rule[0](value):
         if err_msg is not None:
             raise HTTPHeaderException(err_msg)
 
+    _hvalidate = _validate
+
     ###########################################################################
     ## header retrieval #######################################################
     ###########################################################################
 
     def _getheaders(self, key):
         '''
-        gets list tracker for a header's category.
+        fetch tracker associated with header `key` category
 
-        @param: key Header key
+        @param key: header key
         '''
+        # "best practice" sends HTTP headers in order: 1. general headers
         if key in self._GENERAL:
             return self._general
+        # 2. request headers
         elif key in self._REQUEST:
             return self._request
+        # 3. entity headers
         elif key in self._ENTITY:
             return self._entity
+        # 4. custom headers
         return self._custom
 
+    _hgetheaders = _getheaders
+
     def get(self, key):
         '''
         get HTTP request header value
 
-        @param key HTTP header key
+        @param key: header key
         '''
         key = self._key(key)
         return self._getheaders(key).get(key)
 
+    _hget = get
+
     ###########################################################################
     ## header manipulation ####################################################
     ###########################################################################
 
-    def _key(self, key):
-        '''
-        Ensure proper formatting for header key
-
-        @param key: Key associated with value
-        '''
-        return n(key.lower().replace('_', '-'))
-
     def _value(self, key, value):
         '''
-        Ensure proper formatting for header value
+        properly format for HTTP header `value`
 
-        @param key: Key associated with value
-        @param value: Value to format
+        @param key: key associated with value
+        @param value: value to format
         '''
-        # Keep nulls out of the pipeline
+        # keep nulls out of the pipeline
         if value is None or not value:
             return value
-        # Join with any existing value if header allows multiple values
+        key = self._key(key)
+        # join with any existing value if header allows multiple values
         if key in self._DATES and isinstance(value, datetime):
             value = httpdate(value)
-        return n(value)
+        return key, n(value)
+
+    _hvalue = _value
 
     def rfc2822(self, key, value, charset=None):
         '''
-        set header value with a specific charset encoded following RFC 2822.
+        set HTTP header `value` with `charset` encoded following RFC 2822
 
-        @param key HTTP header key
-        @param value HTTP header value
-        @param charset HTTP charset (default: None)
+        @param key: header key
+        @param value: header value
+        @param charset: charset (default: None)
         '''
-        # Use an existing email.Header instance
+        # use an existing email.Header instance
         existing = self.get(key)
         if existing is not None:
             try:
             except AttributeError:
                 pass
         else:
-            # Override existing value if not Header instance or add new value
+            # override existing value if not Header instance or add new value
             self.set(key, Header(value, charset))
 
+    _hrfc2822 = rfc2822
+
     def set(self, key, value):
         '''
-        set HTTP request header
+        set HTTP request header `value`
 
         @param key: header key
         @param value: header value
         '''
         fmt = self._value
-        key = self._key(key)
-        value = fmt(key, value)
+        # format key, value
+        key, value = fmt(key, value)
+        # validate
         self._validate(key, value)
+        # fetch header dict
         headers = self._getheaders(key)
-        prev = headers.get(key)
-        if prev is not None:
+        previous = headers.get(key)
+        # if previous value exists
+        if previous is not None:
             # try to assign as email.Header instance
             try:
-                prev.append(value)
+                previous.append(value)
             except AttributeError:
-                # join with any existing value if header allows multiple values
+                # join with existing values if multiple values allowed
                 if key in self._COMMA_SEP:
                     headers[key] = fmt(', '.join([headers[key], value]))
-                # replace value on headers allowing only single values
+                # replace value in headers allowing only single values
                 elif key in self._SC_SEP:
                     headers[key] = fmt('; '.join([headers[key], value]))
                 else:
                     headers[key] = value
-        # add new value if not present
         else:
+            # add value if not present
             headers[key] = value
 
+    _hset = set
+
     def delete(self, key):
         '''
-        delete HTTP request header value
+        delete HTTP request header value associated with `key`
 
-        @param key HTTP header key
+        @param key: header key
         '''
         del self.get(key)[self._key(key)]
 
+    _hdelete = delete
+
 
 @appifies(KRequestHeaders)
-class RequestHeaders(CoreHeaders):
+class RequestHeaders(httplet):
 
-    '''request header chainlet'''
+    '''HTTP request header chainlet'''
 
     def __init__(self, root):
         '''
         self._headers = self._synchback(
             '_headers', Headers() if self._headers is None else self._headers,
         )
+        if self.G.randomua:
+            # set random user agent
+            self.user_agent(self._randomua())
 
     def __getattr__(self, key):
         try:
             return object.__getattribute__(self, key)
         except AttributeError:
-            tkey = self._headattr.get(key)
+            tkey = self._headmap.get(key)
             # cast to native string to cast email.Header to native string type
             if tkey is not None:
                 value = self._headers.get(tkey)
                 # don't make `None` a string
                 if value is not None:
                     return partial(self.bheader, key)
-            raise AttributeError(key)
+            return self._fgetr(key)
+
+    _hgetattr = __getattr__
 
     @lazy_class
-    def _headattr(self):
+    def _headmap(self):
         '''python name -> header name mapping'''
         return dict((checkname(h), h) for h in self._headers.REQ_HEADERS)
 
         @param length: instance length
         '''
         if length == '*':
-            self._headers.set('Content-Range', 'bytes %d-%d/*' % (first, last))
+            self._headers.set('content-range', 'bytes %d-%d/*' % (first, last))
         else:
             self._headers.set(
-                'Content-Range', 'bytes %d-%d/%d' % (first, last, length)
+                'content-range', 'bytes %d-%d/%d' % (first, last, length)
             )
         return self
 
+    _hcontent_range = content_range
+
     def bheader(self, key, value):
         '''
-        set HTTP request header with `bytes` (native string) value
+        set HTTP request header to `bytes` (native string) `value`
 
         @param key: header key
         @param value: header value
         self._headers.set(key, value)
         return self
 
-    header = bheader
+    header = _hheader = bheader
 
     def uheader(self, key, value, charset=None):
         '''
-        set HTTP request header with `unicode` value
+        set HTTP request header to `unicode` `value`
 
         @param key: header key
         @param value: header value
         '''
         self._headers.rfc2822(key, value, charset)
         return self
+
+    _huheader = uheader

File wire/http/request/keys/cookie.py

+# -*- coding: utf-8 -*-
+#@PydevCodeAnalysisIgnore
+#pylint: disable-msg=e0211,e0213
+'''http request cookie keys'''
+
+from appspace.keys import AppspaceKey
+
+
+class KRequestCookie(AppspaceKey):
+    
+    '''HTTP request cookie setter'''
+
+    def cookie(key, **values):
+        '''
+        cookie setter
+        
+        @param key: cookie key
+        @param **values: cookie field names, values
+        '''

File wire/http/request/keys/data.py

+# -*- coding: utf-8 -*-
+#@PydevCodeAnalysisIgnore
+#pylint: disable-msg=e0211,e0213
+'''http request client keys'''
+
+from appspace.keys import AppspaceKey
+
+
+class KRequestClient(AppspaceKey):
+
+    '''HTTP client key'''
+
+    def __call__(*urls, **config):
+        '''
+        load urls
+    
+        @param urls: Uniform Resource Locations (URLs)
+        '''
+
+    def data(*data):
+        '''
+        `data` for urls (must equal number of previously passed urls)
+        
+        param *data: data for request body
+        '''
+    
+    def files(*files):
+        '''
+        `files` for urls (must equal number of previously passed urls)
+        
+        param *data: data for request body
+        '''
+        
+    def params(**params):
+        '''
+        request parameters for all urls
+        
+        param **params: parameters
+        '''
+
+    def get():
+        '''
+        *GET* HTTP method
+    
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3
+        '''
+
+    def post():
+        '''
+        *POST* HTTP method
+    
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5
+        '''
+
+    def delete():
+        '''
+        *DELETE* HTTP method
+    
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7
+        '''
+
+    def put():
+        '''
+        *PUT* HTTP method
+    
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
+        '''
+
+    def head():
+        '''
+        *HEAD* HTTP method
+    
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
+        '''
+
+    def options():
+        '''
+        *OPTIONS* HTTP method
+    
+        http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2
+        '''
+        
+    def auth(username, password):
+        '''
+        set authentication settings
+        
+        @param username: username credential
+        @param password: password credential
+        '''
+
+    def proxy(server, host):
+        '''
+        proxy settings
+        
+        @param server: proxy server
+        @param host: proxy host
+        '''
+        
+    def content_md5():
+        '''
+        take MD5 hash of data and set *CONTENT-MD5* HTTP header.
+
+        @param value: HTTP response data
+        '''
+
+class KAPI(AppspaceKey):
+    
+    '''HTTP API key'''
+        
+    def api():
+        '''switch to HTTP API chain'''

File wire/http/response/client.py

 from wire.http.util import statuscode
 
 
-class CoreResponse(chainlink):
+class Response(chainlink):
 
     '''Core HTTP response manager'''
 
     def __init__(self, **kw):
-        super(CoreResponse, self).__init__()
+        super(Response, self).__init__()
         self._options = kw
 
     def code(self):
         return int(self._code)
 
     def good(self):
-        '''True if HTTP was successful enough'''
+        '''true if HTTP was successful enough'''
         return self._code.startswith('20')
 
     def fail(self):
-        '''True if HTTP request failed'''
+        '''true if HTTP request failed'''
         return self._code.startswith('40') or self._code.startswith('50')
 
     def noop(self):
-        '''True if HTTP request was more or less harmless'''
+        '''true if HTTP request was more or less harmless'''
         return self._code.startswith('30') or self._code.startswith('10')
 
     def ok(self):
-        '''True if HTTP request was successful'''
+        '''true if HTTP request was successful'''
         return self._code == '200'
 
     def status(self):

File wire/http/response/cookie.py

-class Morsel(Immutable):
+#
+#
+#class Morsel(Immutable):
+#
+#    '''HTTP response specific morsel'''
+#
+#    def __init__(self):
+#        super(Morsel, self).__init__()
+#        self._hset('_morsel', CoreMorsel())
+#
+#    def __getattr__(self, key):
+#        try:
+#            return object.__getattribute__(self, key)
+#        except AttributeError:
+#            try:
+#                return self._morsel.__getitem__(key)
+#            except KeyError:
+#                try:
+#                    return self._morsel.__getitem__(key.replace('_', '-'))
+#                except KeyError:
+#                    raise AttributeError(key)
+#
+#    def __getitem__(self, key):
+#        return self._morsel.__getitem__(key)
+#
+#    def _set(self):
+#        return self._morsel.set
+#
+#    def output(self):
+#        return self._morsel.output
+#
+#    def value(self):
+#        return self._morsel.value
+#
+#
+#class Cookie(object):
+#
+#    '''HTTP response specific cookie'''
+#
+#    __slots__ = ('_cookie')
+#
+#    def __init__(self, cookie):
+#        self._cookie = self._class()(cookie)
+#
+#    def __getattr__(self, key):
+#        try:
+#            return object.__getattribute__(self, key)
+#        except AttributeError:
+#            try:
+#                return self.__getitem__(key)
+#            except KeyError:
+#                raise AttributeError(key)
+#
+#    def __getitem__(self, key):
+#        return self._cookie.__getitem__(key)
+#
+#    def __iter__(self):
+#        return self._cookie.__iter__()
+#
+#    def __str__(self):
+#        return self._cookie.output()
+#
+#    def __setitem__(self, key, value):
+#        rval, cval = self.value_encode(value)
+#        self._set(key, rval, cval)
+#
+#    def _set(self, k, real_value, coded_value):
+#        m = self.get(k, http_cookies.Morsel())
+#        m.set(k, real_value, coded_value)
+#        dict.__setitem__(self, k, m)
 
-    '''HTTP response specific morsel'''
-
-    def __init__(self):
-        super(Morsel, self).__init__()
-        self._hset('_morsel', CoreMorsel())
-
-    def __getattr__(self, key):
-        try:
-            return object.__getattribute__(self, key)
-        except AttributeError:
-            try:
-                return self._morsel.__getitem__(key)
-            except KeyError:
-                try:
-                    return self._morsel.__getitem__(key.replace('_', '-'))
-                except KeyError:
-                    raise AttributeError(key)
-
-    def __getitem__(self, key):
-        return self._morsel.__getitem__(key)
-
-    def _set(self):
-        return self._morsel.set
-
-    def output(self):
-        return self._morsel.output
-
-    def value(self):
-        return self._morsel.value
-
-
-class Cookie(object):
-
-    '''HTTP response specific cookie'''
-
-    __slots__ = ('_cookie')
-
-    def __init__(self, cookie):
-        self._cookie = self._class()(cookie)
-
-    def __getattr__(self, key):
-        try:
-            return object.__getattribute__(self, key)
-        except AttributeError:
-            try:
-                return self.__getitem__(key)
-            except KeyError:
-                raise AttributeError(key)
-
-    def __getitem__(self, key):
-        return self._cookie.__getitem__(key)
-
-    def __iter__(self):
-        return self._cookie.__iter__()
-
-    def __str__(self):
-        return self._cookie.output()
-
-    @classmethod
-    def _class(cls):
-        class _ResponseCookie(CoreCookie):
-            def _set(self, k, real_value, coded_value):
-                '''invisible setters'''
-                m = self.get(k, Morsel())
-                m._set(k, real_value, coded_value)
-                dict.__setitem__(self, k, m)
-        return _ResponseCookie
+#    def _parse(self, cookie, _patt=http_cookies._CookiePattern):
+#         our starting point
+#        i = 0
+#         length of string
+#        n = len(cookie)
+#         current morsel
+#        m = None
+#        unquote = http_cookies._unquote
+#        reserved = http_cookies.Morsel._reserved
+#        value_decode = self.value_decode
+#        setter = self._set
+#        this = self
+#        psearch = _patt.search
+#        while 0 <= i < n:
+#             Start looking for a cookie
+#            match = psearch(cookie, i)
+#            if not match:
+#                break  # no more cookies
+#            k, v = match.group('key'), match.group('val').rstrip(', ')
+#            i = match.end(0)
+#             parse the key, value just in case it's metainfo
+#            if k[0] == '$':
+#                if m:
+#                    m._morsel[k[1:]] = v
+#            elif k.lower() in reserved:
+#                if m:
+#                    m._morsel[k] = unquote(v)
+#            else:
+#                rval, cval = value_decode(v)
+#                setter(k, rval, cval)
+#                m = this[k]
+#
+#    def loads(self, data):
+#        '''
+#        load cookie value
+#
+#        @param data: cookie data
+#        '''
+#        if isstring(data):
+#            self._parse(data)
+#        else:
+#            exhaustmap(data, self.__setitem__)
+#
+#    @classmethod
+#    def _class(cls):
+#        class _ResponseCookie(CoreCookie):
+#            def _set(self, k, real_value, coded_value):
+#                '''invisible setters'''
+#                m = self.get(k, Morsel())
+#                m._set(k, real_value, coded_value)
+#                dict.__setitem__(self, k, m)
+#        return _ResponseCookie

File wire/http/response/header.py

-'''wire core HTTP response'''
+'''wire HTTP response headers'''
 
 from stuf.utils import lazy_class
 from twoq.support import isstring, items
         '''
         # Keep nulls out of the pipeline
         if isstring(value):
-            
             # HTTP variables to cast to integers
             if key in set(['accept-ranges', 'age', 'content-length']):
                 value = cls._parseint(value)
         return value
 
     @lazy_class
-    def _headattr(self):
+    def _headmap(self):
         '''Python name -> header name mapping'''
         return dict((self._checkname(h), h) for h in self.RES_HEADERS)
 
         date values are returned as datetime objects
         '''
         k = key.lower()
-        tk = self._headattr.get(k)
+        tk = self._headmap.get(k)
         v = self._headers.get(tk)
         # Format value
         self._headers[k] = v = self._set(k, v)

File wire/keys/__init__.py

+# -*- coding: utf-8 -*-
+'''wire keys'''

File wire/keys/talk.py

+# -*- coding: utf-8 -*-
+#@PydevCodeAnalysisIgnore
+#pylint: disable-msg=e0211,e0213
+
+'''talk keys'''
+
+from wire.keys.talkers import (
+    KDumps, KYaml, KXmlRpc, KXml, KUrlEncode, KTNetString, KThrift, KProtobuf,
+    KPlist, KPickle, KNetString, KMultiPart, KMarshal, KMessagePack, KJson, 
+    KHtml, KExcel, KCsv, KBson, KBencode)
+
+  
+class KBencodeDumps(KDumps, KBencode):
+    
+    '''bencode serialize key'''
+        
+
+class KBsonDumps(KDumps, KBson):
+    
+    '''bson serialize key'''
+        
+        
+class KCsvDumps(KDumps, KCsv):
+    
+    '''csv serialize key'''
+        
+        
+class KExcelDumps(KDumps, KExcel):
+    
+    '''excel serialize key'''
+        
+
+class KHtmlDumps(KDumps, KHtml):
+    
+    '''html serialize key'''
+        
+        
+class KJsonDumps(KDumps, KJson):
+    
+    '''json serialize key'''
+        
+        
+class KMarshalDumps(KDumps, KMarshal):
+    
+    '''Python marshal serialize key'''
+        
+        
+class KMessagePackDumps(KDumps, KMessagePack):
+    
+    '''message pack serialize key'''
+        
+
+class KMultiPartDumps(KDumps, KMultiPart):
+    
+    '''form multipart serialize key'''
+        
+        
+class KNetStringDumps(KDumps, KNetString):
+    
+    '''netstring serialize key'''
+        
+        
+class KPickleDumps(KDumps, KPickle):
+    
+    '''python pickle serialize key'''
+        
+        
+class KPlistDumps(KDumps, KPlist):
+    
+    '''property list serialize key'''
+        
+        
+class KProtobufDumps(KDumps, KProtobuf):
+    
+    '''google protocol buffers serialize key'''
+    
+    def protobuf():
+        '''protocol buffers serialization'''
+
+        
+class KThriftDumps(KDumps, KThrift):
+    
+    '''thrift serialize key'''
+    
+    def thrift():
+        '''thrift deserialization'''
+        
+        
+class KTNetStringDumps(KDumps, KTNetString):
+    
+    '''tnetstring serialize key'''
+        
+        
+class KUrlEncodeDumps(KDumps, KUrlEncode):
+    
+    '''urlencode serialize key'''
+        
+        
+class KXmlDumps(KDumps, KXml):
+    
+    '''extensible markup language serialize key'''
+        
+        
+class KXmlRpcDumps(KDumps, KXmlRpc):
+    
+    '''extensible markup language remote procedure call serialize key'''
+
+
+class KYamlDumps(KDumps, KYaml):
+    
+    '''YAML ain't markup language serialize key'''

File wire/keys/talkers.py

+# -*- coding: utf-8 -*-
+#@PydevCodeAnalysisIgnore
+#pylint: disable-msg=e0211,e0213
+'''http client data keys'''
+
+from appspace.keys import AppspaceKey
+
+
+class KTalk(AppspaceKey):
+
+    '''talker key'''
+
+
+class KDumps(AppspaceKey):
+    
+    '''serializer key'''
+
+
+class KLoads(AppspaceKey):
+    
+    '''deserializer key'''
+
+class KBencode(KTalk):
+    
+    '''
+    bencode serialization key
+    
+    http://en.wikipedia.org/wiki/Bencode
+    
+    http://pypi.python.org/pypi/BitTorrent-bencode/
+    '''
+    
+    def bencode():
+        '''bencode serialization'''
+
+
+class KBson(KTalk):
+    
+    '''
+    binary JSON serialization key
+    
+    http://en.wikipedia.org/wiki/BSON
+    
+    http://pypi.python.org/pypi/bson/0.3.3
+    '''
+    
+    def bson():
+        '''bson serialization'''
+        
+
+
+class KCsv(KTalk):
+    
+    '''comma separated values (CSV) serialization key'''
+        
+    def csv(**kw):
+        '''csv serialization'''
+
+
+class KExcel(KTalk):
+    
+    '''
+    M$ excel serialization key
+    
+    http://pypi.python.org/pypi/xlrd/
+    
+    http://pypi.python.org/pypi/xlwt/
+    '''
+        
+    def excel(**kw):
+        '''excel serialization'''
+
+
+class KHtml(KTalk):
+    
+    '''
+    html serialization key
+
+    http://pypi.python.org/pypi/lxml/
+    '''
+        
+    def html(**kw):
+        '''html serialization'''
+        
+
+class KJson(KTalk):
+
+    '''JavaScript Object Notation (JSON) serialization key'''
+
+    def json(**kw):
+        '''json serialization'''
+
+        
+class KMarshal(KTalk):
+    
+    '''Python marshal serialization key'''
+        
+    def marshal():
+        '''marshal serialization'''
+        
+
+class KMessagePack(KTalk):
+    
+    '''
+    message pack serialization key
+    
+    http://msgpack.org/
+    
+    http://pypi.python.org/pypi/msgpack-python/
+    '''
+        
+    def message_pack(**kw):
+        '''message pack serialization key'''
+
+
+class KMultiPart(KTalk):
+
+    '''form multipart serialization'''
+        
+    def multipart():
+        '''form-multipart serialization'''
+
+        
+class KNetString(KTalk):
+    
+    '''
+    netstring serialization key
+    
+    http://cr.yp.to/proto/netstrings.txt
+    
+    http://pypi.python.org/pypi/netstring
+    '''
+        
+    def netstring(**kw):
+        '''netstring serialization'''
+        
+
+class KPickle(KTalk):
+    
+    '''python pickle serialization key'''
+        
+    def pickle():
+        '''pickle serialization'''
+
+
+class KPlist(KTalk):
+    
+    '''property list serialization key'''
+
+    def plist():
+        '''pickle serialization'''
+
+
+class KProtobuf(KTalk):
+    
+    '''
+    google protocol buffers serialization key
+
+    http://code.google.com/p/protobuf/
+
+    http://pypi.python.org/pypi/protobuf/
+    '''
+        
+        
+class KThrift(KTalk):
+    
+    '''
+    thrift serialization key
+    
+    http://thrift.apache.org/
+    
+    http://pypi.python.org/pypi/thrift/
+    '''
+
+
+class KTNetString(KTalk):
+    
+    '''
+    tnetstring serialization key
+    
+    http://pypi.python.org/pypi/tnetstring/
+    '''
+        
+    def tnetstring():
+        '''tnetstring serialization'''
+
+
+class KUrlEncode(KTalk):
+    
+    '''urlencode serialization key'''  
+
+    def urlencode(**kw):
+        '''urlencode serialization'''
+        
+
+class KXml(KTalk):
+    
+    '''extensible markup language serialization key'''
+
+    def xml(**kw):
+        '''xml serialization'''
+
+
+class KXmlRpc(KTalk):
+    
+    '''extensible markup language remote procedure call serialization key'''
+        
+    def xmlrpc(**kw):
+        '''xml-rpc serialization'''
+        
+
+class KYaml(KTalk):
+    
+    '''
+    YAML ain't markup language serialization key
+    
+    http://en.wikipedia.org/wiki/YAML
+    
+    http://pypi.python.org/pypi/PyYAML/
+    '''
+        
+    def yaml(**kw):
+        '''yaml serialization'''

File wire/keys/untalk.py

+# -*- coding: utf-8 -*-
+#@PydevCodeAnalysisIgnore
+#pylint: disable-msg=e0211,e0213
+'''untalk keys'''
+
+from wire.keys.talkers import (
+    KLoads, KYaml, KXmlRpc, KXml, KUrlEncode, KTNetString, KThrift, KProtobuf,
+    KPlist, KPickle, KNetString, KMultiPart, KMarshal, KMessagePack, KJson,
+    KHtml, KExcel, KCsv, KBson, KBencode)
+
+
+class KBencodeLoads(KLoads, KBencode):
+
+    '''bencode deserialize key'''
+
+
+class KBsonLoads(KLoads, KBson):
+
+    '''bson deserialize key'''
+
+
+class KCsvLoads(KLoads, KCsv):
+
+    '''csv deserialize key'''
+
+
+class KExcelLoads(KLoads, KExcel):
+
+    '''excel deserialize key'''
+
+
+class KHtmlLoads(KLoads, KHtml):
+
+    '''html deserialize key'''
+
+
+class KJsonLoads(KLoads, KJson):
+
+    '''json deserialize key'''
+
+
+class KMarshalLoads(KLoads, KMarshal):
+
+    '''Python marshal deserialize key'''
+
+
+class KMessagePackLoads(KLoads, KMessagePack):
+
+    '''message pack deserialize key'''
+
+
+class KMultiPartLoads(KLoads, KMultiPart):
+
+    '''form multipart deserialize key'''
+
+
+class KNetStringLoads(KLoads, KNetString):
+
+    '''netstring deserialize key'''
+
+
+class KPickleLoads(KLoads, KPickle):
+
+    '''python pickle deserialize key'''
+
+
+class KPlistLoads(KLoads, KPlist):
+
+    '''property list deserialize key'''
+
+
+class KProtobufLoads(KLoads, KProtobuf):
+
+    '''google protocol buffers deserialize key'''
+
+    def protobuf(**kw):
+        '''protocol buffers serialization'''
+
+
+class KThriftLoads(KLoads, KThrift):
+
+    '''thrift deserialize key'''
+
+    def thrift(**kw):
+        '''thrift deserialization'''
+
+
+class KTNetStringLoads(KLoads, KTNetString):
+
+    '''tnetstring deserialize key'''
+
+
+class KUrlEncodeLoads(KLoads, KUrlEncode):
+
+    '''urlencode deserialize key'''
+
+
+class KXmlLoads(KLoads, KXml):
+
+    '''extensible markup language deserialize key'''
+
+
+class KXmlRpcLoads(KLoads, KXmlRpc):
+
+    '''extensible markup language remote procedure call deserialize key'''
+
+
+class KYamlLoads(KLoads, KYaml):
+
+    '''YAML ain't markup language deserialize key'''

File wire/talk/bencodew.py

     raise ImportError('requires "BitTorrent-bencode" library')
 from callchain.mixin.reset import ResetLocalMixin
 
-from wire.talk.keys import KBencodeLoads, KBencodeDumps
+from wire.keys.talk import KBencodeDumps
+from wire.keys.untalk import KBencodeLoads
 
 
 class Bencode(ResetLocalMixin):

File wire/talk/bsonw.py

     raise ImportError('requires "bson" library')
 from callchain.mixin.reset import ResetLocalMixin
 
-from wire.talk.keys import KBsonDumps
+from wire.keys.talk import KBsonDumps
+from wire.keys.untalk import KBsonLoads
 
 
 class BSON(ResetLocalMixin):
         return self
 
 
-@appifies(KBsonDumps)
+@appifies(KBsonLoads)
 class Loads(BSON):
 
     '''unbson data'''

File wire/talk/csvw.py

 from appspace.keys import appifies
 from callchain.mixin.reset import ResetLocalMixin
 
-from wire.talk.keys import KCsvDumps, KCsvLoads
+from wire.keys.talk import KCsvDumps
+from wire.keys.untalk import KCsvLoads
 
 
 class CSV(ResetLocalMixin):

File wire/talk/excelw.py

 # pylint: enable-msg=f0401
 from callchain.mixin.reset import ResetLocalMixin
 
-from wire.talk.keys import KExcelDumps, KExcelLoads
+from wire.keys.talk import KExcelDumps
+from wire.keys.untalk import KExcelLoads
 
 
 class Excel(ResetLocalMixin):

File wire/talk/htmlw.py

     raise ImportError('requires "lxml" library')
 from callchain.mixin.reset import ResetLocalMixin
 
-from wire.talk.keys import KHtmlDumps, KHtmlLoads
+from wire.keys.talk import KHtmlDumps
+from wire.keys.untalk import KHtmlLoads
 
 
 class HTML(ResetLocalMixin):

File wire/talk/jsonw.py

 from appspace.keys import appifies
 from callchain.mixin.reset import ResetLocalMixin
 
-from wire.talk.keys import KJsonDumps, KJsonLoads
+from wire.keys.talk import KJsonDumps
+from wire.keys.untalk import KJsonLoads
 
 
 class JSON(ResetLocalMixin):

File wire/talk/keys.py

-# -*- coding: utf-8 -*-
-#@PydevCodeAnalysisIgnore
-#pylint: disable-msg=e0211,e0213
-'''http client data keys'''
-
-from appspace.keys import AppspaceKey
-
-
-class KTalk(AppspaceKey):
-
-    '''talker key'''
-
-
-class KDumps(AppspaceKey):
-    
-    '''serializer key'''
-
-
-class KLoads(AppspaceKey):
-    
-    '''deserializer key'''
-        
-        
-###############################################################################
-## Bencode ####################################################################
-###############################################################################
-
-
-class KBencode(KTalk):
-    
-    '''
-    bencode serialization key
-    
-    http://en.wikipedia.org/wiki/Bencode
-    
-    http://pypi.python.org/pypi/BitTorrent-bencode/
-    '''
-    
-    def bencode():
-        '''bencode serialization'''
-
-        
-class KBencodeDumps(KDumps, KBencode):
-    
-    '''bencode serialize key'''
-    
-    
-class KBencodeLoads(KLoads, KBencode):
-    
-    '''bencode deserialize key'''
-
-
-###############################################################################
-## BSON #######################################################################
-###############################################################################
-
-
-class KBson(KTalk):
-    
-    '''
-    binary JSON serialization key
-    
-    http://en.wikipedia.org/wiki/BSON
-    
-    http://pypi.python.org/pypi/bson/0.3.3
-    '''
-    
-    def bson():
-        '''bson serialization'''
-        
-
-class KBsonDumps(KDumps, KBson):
-    
-    '''bson serialize key'''
-    
-    
-class KBsonLoads(KLoads, KBson):
-    
-    '''bson deserialize key'''
-
-
-###############################################################################
-## CSV ########################################################################
-###############################################################################
-
-
-class KCsv(KTalk):
-    
-    '''comma separated values (CSV) serialization key'''
-        
-    def csv(**kw):
-        '''csv serialization'''
-        
-        
-class KCsvDumps(KDumps, KCsv):
-    
-    '''csv serialize key'''
-    
-    
-class KCsvLoads(KLoads, KCsv):
-    
-    '''csv deserialize key'''
-  
-        
-###############################################################################
-## Excel ######################################################################
-###############################################################################
-
-
-class KExcel(KTalk):
-    
-    '''
-    M$ excel serialization key
-    
-    http://pypi.python.org/pypi/xlrd/
-    
-    http://pypi.python.org/pypi/xlwt/
-    '''
-        
-    def excel(**kw):
-        '''excel serialization'''
-        
-        
-class KExcelDumps(KDumps, KExcel):
-    
-    '''excel serialize key'''
-    
-    
-class KExcelLoads(KLoads, KExcel):
-    
-    '''excel deserialize key'''
-    
-    
-###############################################################################
-## HTML #######################################################################
-###############################################################################
-
-
-class KHtml(KTalk):
-    
-    '''
-    html serialization key
-
-    http://pypi.python.org/pypi/lxml/
-    '''
-        
-    def html(**kw):
-        '''html serialization'''
-        
-
-class KHtmlDumps(KDumps, KHtml):
-    
-    '''html serialize key'''
-    
-    
-class KHtmlLoads(KLoads, KHtml):
-    
-    '''html deserialize key'''
-    
-    
-###############################################################################
-## JSON #######################################################################
-###############################################################################
-
-
-class KJson(KTalk):