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()
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
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'])
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()
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()
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)
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)
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)
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)
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()