Example #1
0
class MeshServer(Mount):
    configuration = Configuration({
        'bundles':
        Sequence(ObjectReference(notnull=True), required=True, unique=True),
        'mediators':
        Sequence(Text(nonempty=True), nonnull=True, unique=True),
        'server':
        ObjectReference(nonnull=True, default=HttpServer),
    })

    def __init__(self, bundles, server, mediators=None):
        self.mediators = []
        if mediators:
            for mediator in mediators:
                self.mediators.append(getattr(self, mediator))

        super(MeshServer, self).__init__()
        self.server = server(bundles,
                             mediators=self.mediators,
                             context_key='request.context')

    def dispatch(self, environ, start_response):
        ContextLocal.push(environ.get('request.context'))
        try:
            return self.server(environ, start_response)
        finally:
            ContextLocal.pop()
Example #2
0
class MeshClient(Unit):
    configuration = Configuration({
        'bundle':
        ObjectReference(nonnull=True),
        'client':
        ObjectReference(nonnull=True, required=True, default=HttpClient),
        'introspect':
        Boolean(default=False),
        'name':
        Text(nonempty=True),
        'specification':
        ObjectReference(nonnull=True),
        'timeout':
        Integer(default=180),
        'url':
        Text(nonempty=True),
    })

    name = configured_property('name')
    url = configured_property('url')

    def __init__(self, client, url, timeout):
        specification = self.configuration.get('specification')
        if not specification:
            bundle = self.configuration.get('bundle')
            if bundle:
                specification = bundle.specify()
        if not specification and not self.configuration.get('introspect'):
            raise Exception()

        self.cache = {}
        self.instance = construct_mesh_client(url, specification, timeout,
                                              client, self.name)
        self.instance.register()

    def bind(self, name, mixin_modules=None):
        try:
            return self.cache[name]
        except KeyError:
            self.cache[name] = bind(self.instance.specification, name,
                                    mixin_modules)
            return self.cache[name]

    def construct_url(self, path=None):
        url = self.url
        if path:
            url = '%s/%s' % (url.rstrip('/'), path.lstrip('/'))
        return url

    def execute(self, *args, **params):
        return self.instance.execute(*args, **params)

    def prepare(self, *args, **params):
        return self.instance.prepare(*args, **params)

    def ping(self):
        return self.instance.ping()

    def _provide_binding(self):
        return self.instance.specification
Example #3
0
class GenerateDocs(Task):
    name = 'mesh.docs'
    description = 'generate api documentation for a mesh bundle'
    parameters = {
        'bundle':
        ObjectReference(description='module path of bundle', required=True),
        'docroot':
        Path(description='path to docroot', required=True),
        'nocache':
        Boolean(default=False),
        'sphinx':
        Text(default='sphinx-build'),
        'view':
        Boolean(description='view documentation after build', default=False),
    }

    def run(self, runtime):
        from mesh.documentation.generator import DocumentationGenerator
        DocumentationGenerator(self['docroot']).generate(
            self['bundle'].describe(verbose=True))
        runtime.execute('sphinx.html',
                        sourcedir=self['docroot'],
                        view=self['view'],
                        nocache=self['nocache'],
                        binary=self['sphinx'])
Example #4
0
class StartMockServer(Task):
    name = 'mesh.mock'
    description = 'runs a wsgi test server for a mocked mesh bundle'
    parameters = {
        'bundle':
        ObjectReference(description='module path of bundle', required=True),
        'fixtures':
        Path(description='path to fixtures'),
        'hostname':
        Text(description='hostname', default='127.0.0.1:8080'),
        'storage':
        Text(description='path to storage db', default=':memory:'),
    }

    def run(self, runtime):
        from mesh.standard.mock import MockStorage, mock_bundle
        from mesh.transport.wsgiserver import WsgiServer

        storage = MockStorage(self['storage'])
        if self['fixtures']:
            storage.load(self['fixtures'].bytes(), True)

        bundle = mock_bundle(self['bundle'], storage)
        server = WsgiServer(self['hostname'], bundle)

        runtime.info('serving at %s' % self['hostname'])
        server.serve()
Example #5
0
class StartWsgiServer(Task):
    name = 'mesh.wsgi'
    description = 'runs a wsgi test server for a mesh bundle'
    parameters = {
        'bundle':
        ObjectReference(description='module path of bundle', required=True),
        'hostname':
        Text(description='hostname', required=True),
        'detached':
        Boolean(default=False),
        'pidfile':
        Text(),
        'uid':
        Text(),
        'gid':
        Text(),
    }

    def run(self, runtime):
        from mesh.transport.wsgiserver import WsgiServer, DaemonizedWsgiServer
        if self['detached']:
            server = DaemonizedWsgiServer(self['hostname'], self['bundle'])
            runtime.info('serving at %s' % self['hostname'])
            server.serve(self['pidfile'], self['uid'], self['gid'])
        else:
            server = WsgiServer(self['hostname'], self['bundle'])
            runtime.info('serving at %s' % self['hostname'])
            server.serve()
Example #6
0
class Application(Mount):
    """A WSGI application."""

    configuration = Configuration({
        'mediators':
        Sequence(Text(nonempty=True), unique=True),
        'templates':
        Sequence(Tuple((Text(nonempty=True), Text(nonempty=True)))),
        'urls':
        ObjectReference(nonnull=True, required=True),
        'views':
        Sequence(ObjectReference(nonnull=True), unique=True),
    })

    def __init__(self, urls, views=None, templates=None, mediators=None):
        super(Application, self).__init__()
        if isinstance(urls, (list, tuple)):
            urls = Map(list(urls))
        if not isinstance(urls, Map):
            raise Exception()

        self.urls = urls
        self.views = self._collect_views(views)

        self.environment = None
        if templates:
            self.environment = TemplateEnvironment(templates)

        self.mediators = []
        if mediators:
            for mediator in mediators:
                attr = getattr(self, mediator)
                self.mediators.append(attr)

    def contribute_params(self):
        return {'application': self}

    def dispatch(self, environ, start_response):
        try:
            return self._dispatch_request(environ)(environ, start_response)
        except HTTPException, error:
            return error(environ, start_response)
Example #7
0
class GenerateSpecification(Task):
    name = 'mesh.specification'
    description = 'generate the specification for a bundle'
    parameters = {
        'bundle': ObjectReference(required=True),
        'path': Path(required=True),
        'targets': Sequence(Text()),
    }

    def run(self, runtime):
        description = self['bundle'].describe(self['targets'])
        content = StructureFormatter().format(description)
        self['path'].write_bytes(content)
Example #8
0
class GeneratePythonBindings(Task):
    name = 'mesh.python'
    description = 'generate python bindings for a mesh bundle'
    parameters = {
        'binding_module': Text(default='mesh.standard.python'),
        'bundle': ObjectReference(required=True),
        'mixin_modules': Sequence(Text()),
        'path': Path(description='path to target directory', required=True),
    }

    def run(self, runtime):
        from mesh.binding.python import BindingGenerator
        generator = BindingGenerator(binding_module=self['binding_module'],
                                     mixin_modules=self['mixin_modules'])
        filename, source = generator.generate(self['bundle'])

        root = self['path']
        if not (root.exists() and root.isdir()):
            raise TaskError('path is not an existing directory')

        (root / filename).write_bytes(source)
Example #9
0
class GenerateJavascriptBindings(Task):
    name = 'mesh.javascript'
    description = 'generate javascript bindings for a mesh bundle'
    parameters = {
        'bundle':
        ObjectReference(description='module path of bundle', required=True),
        'mimetype':
        Text(description='mimetype'),
        'path':
        Path(description='path to target directory', required=True),
        'templates':
        Path(description='path to templates directory'),
    }

    def run(self, runtime):
        from mesh.binding.javascript import Generator
        generator = Generator(template_dir=self['templates'],
                              mimetype=self['mimetype'])

        root = self['path']
        if not root.exists():
            root.makedirs_p()
        if not root.isdir():
            raise TaskError('path is not a directory')

        files = generator.generate(self['bundle'])
        self._create_files(root, files)

    def _create_files(self, root, files):
        for name, content in files.iteritems():
            if isinstance(content, dict):
                directory = root / name
                directory.mkdir()
                self._create_files(directory, content)
            else:
                (root / name).write_bytes(content)
Example #10
0
class SessionMiddleware(Unit, Middleware):
    """A session middleware."""

    configuration = Configuration({
        'enabled':
        Boolean(default=True, required=True),
        'cookie':
        Structure(
            {
                'name': Text(nonnull=True, min_length=1, default='sessionid'),
                'max_age': Integer(minimum=0),
                'secure': Boolean(default=False),
            },
            generate_default=True,
            required=True),
        'store':
        Structure(
            structure={
                FilesystemSessionStore: {
                    'path': Text(default=None),
                },
            },
            polymorphic_on=ObjectReference(name='implementation',
                                           nonnull=True),
            default={'implementation': FilesystemSessionStore},
            required=True,
        )
    })

    enabled = configured_property('enabled')

    def __init__(self, store):
        self.store = store['implementation'](session_class=Session,
                                             **pruned(store, 'implementation'))

    def dispatch(self, application, environ, start_response):
        session = None
        if self.enabled:
            session = self._get_session(environ)

        environ['request.session'] = session
        if session is None:
            return application(environ, start_response)

        def injecting_start_response(status, headers, exc_info=None):
            if session.expired:
                headers.append(
                    ('Set-Cookie', self._construct_cookie(session, True)))
                self.store.delete(session)
            elif session.should_save:
                self.store.save(session)
                headers.append(('Set-Cookie', self._construct_cookie(session)))
            return start_response(status, headers, exc_info)

        return ClosingIterator(application(environ, injecting_start_response),
                               lambda: self.store.save_if_modified(session))

    def _construct_cookie(self, session, unset=False):
        params = self.configuration['cookie']
        expires = (LONG_AGO if unset else params.get('expires'))

        return dump_cookie(params['name'], session.sid, params.get('max_age'),
                           expires, params.get('path', '/'),
                           params.get('domain'), params.get('secure'),
                           params.get('httponly', True))

    def _get_session(self, environ):
        cookie = parse_cookie(environ.get('HTTP_COOKIE', ''))
        id = cookie.get(self.configuration['cookie']['name'], None)
        if id is not None:
            return self.store.get(id)
        else:
            return self.store.new()