Ejemplo n.º 1
0
async def test_nested(client, app):
    @app.middleware
    async def mid(app, req, receive, send):
        response = await app(req, receive, send)
        response.headers['x-app'] = 'OK'
        return response

    from muffin import Application

    subapp = Application()

    @subapp.route('/route')
    def subroute(request):
        return 'OK from subroute'

    @subapp.middleware
    async def mid(app, req, receive, send):
        response = await app(req, receive, send)
        response.headers['x-subapp'] = 'OK'
        return response

    app.route('/sub')(subapp)

    res = await client.get('/sub/route')
    assert res.status_code == 200
    assert await res.text() == 'OK from subroute'
    assert res.headers['x-app'] == 'OK'
    assert res.headers['x-subapp'] == 'OK'
Ejemplo n.º 2
0
async def test_plugin_config(app, client):
    from muffin import Application
    from muffin.plugins import BasePlugin

    class Plugin(BasePlugin):

        name = 'plugin'
        defaults = {
            'debug': True,
            'option': 11,
        }

        after_setup = True

        def setup(self, app, **options):
            super(Plugin, self).setup(app, **options)
            self.after_setup = self.cfg.option

    plugin = Plugin(debug=False)
    assert plugin.cfg
    assert plugin.cfg.debug is False

    app = Application('tests.appcfg')

    plugin = Plugin(app)
    assert plugin.cfg.option == 42  # from application config

    plugin = Plugin(app, option=22)
    assert plugin.cfg.option == 22
    assert plugin.after_setup == 22
Ejemplo n.º 3
0
    def setup(self, app: Application, **options):  # noqa
        """Setup the plugin's commands."""
        super(Plugin, self).setup(app, **options)

        self.__locale_selector: t.Optional[t.Callable[
            [Request],
            t.Awaitable[t.Optional[str]]]] = select_locale_by_request  # noqa

        # Install a middleware for autodetection
        if self.cfg.auto_detect_locale:
            app.middleware(self.__middleware__, insert_first=True)

        @app.manage(lifespan=False)
        def babel_extract_messages(*dirnames: str,
                                   project: str = app.cfg.name,
                                   domain: str = self.cfg.domain,
                                   locations: bool = True,
                                   charset: str = 'utf-8',
                                   locale: str = self.cfg.default_locale):
            """Extract messages from source code.

            :param charset: charset to use in the output
            :param domain:  set domain name for locales
            :param project: set project name in output
            :param version: set project version in output
            :param locations: add message locations
            """
            dirs = [d for d in dirnames if os.path.isdir(d)]

            catalog = Catalog(locale=locale, project=project, charset=charset)
            for dname in dirs:
                for filename, lineno, message, comments, context in extract_from_dir(
                        dname,
                        method_map=self.cfg.sources_map,
                        options_map=self.cfg.options_map):

                    lines = []
                    if locations:
                        filepath = os.path.normpath(
                            os.path.join(dname, filename))
                        lines = [(filepath, lineno)]

                    catalog.add(message,
                                None,
                                lines,
                                auto_comments=comments,
                                context=context)

            locales_dir = self.cfg.locale_folders[0]
            output = os.path.join(locales_dir, locale, 'LC_MESSAGES',
                                  '%s.po' % domain)

            if os.path.exists(output):
                with open(output, 'rb') as f:
                    template = read_po(f, locale=locale, charset=charset)
                    template.update(catalog)
                    catalog = template

            if not os.path.exists(os.path.dirname(output)):
                os.makedirs(os.path.dirname(output))

            logger.info('writing PO template file to %s', output)
            outfile = open(output, 'wb')

            try:
                write_po(outfile,
                         catalog,
                         include_previous=True,
                         sort_output=not locations,
                         sort_by_file=locations)
            finally:
                outfile.close()

        @app.manage(lifespan=False)
        def babel_compile_messages(use_fuzzy=False,
                                   statistics=False,
                                   domain=self.cfg.domain):  # noqa
            """Compile messages for locales.

            :param domain:  set domain name for locales
            """
            for locales_dir in self.cfg.locale_folders:
                for locale in os.listdir(locales_dir):
                    po_file = os.path.join(locales_dir, locale, 'LC_MESSAGES',
                                           domain + '.po')

                    if not os.path.exists(po_file):
                        continue

                    with open(po_file, 'r') as po:
                        catalog = read_po(po, locale)

                    mo_file = os.path.join(locales_dir, locale, 'LC_MESSAGES',
                                           domain + '.mo')

                    with open(mo_file, 'wb') as mo:
                        logger.info('writing MO template file to %s', mo_file)
                        write_mo(mo, catalog, use_fuzzy=use_fuzzy)
Ejemplo n.º 4
0
    def setup(self, app: Application, **options):
        """Initialize the application."""
        super().setup(app, **options)
        self.cfg.update(prefix=self.cfg.prefix.rstrip('/'))
        self.api.setup(app, prefix=f"{self.cfg.prefix}/api", openapi=False)

        self.auth['storage'] = self.cfg.auth_storage
        self.auth['storage_name'] = self.cfg.auth_storage_name
        self.auth['loginURL'] = self.cfg.login_url
        self.auth['logoutURL'] = self.cfg.logout_url

        custom_js = self.cfg.custom_js_url
        custom_css = self.cfg.custom_css_url
        title = self.cfg.title
        prefix = self.cfg.prefix

        def authorize(view):
            """Authorization."""
            async def decorator(request):
                """Authorize an user."""
                if self.api.authorize:
                    auth = await self.api.authorize(request)
                    if not auth:
                        if self.cfg.login_url:
                            return ResponseRedirect(self.cfg.login_url)

                return await view(request)

            return decorator

        @authorize
        async def render_admin(_):
            """Render admin page."""
            return TEMPLATE.format(
                prefix=prefix,
                title=title,
                main_js_url=self.cfg.main_js_url.format(prefix=prefix),
                custom_js=f"<script src={custom_js}></script>"
                if custom_js else '',
                custom_css=f"<link rel='stylesheet' href={custom_css} />"
                if custom_css else '',
            )

        app.route(f"/{prefix.lstrip('/')}")(render_admin)

        @authorize
        async def ra(request):
            data = self.to_ra()

            if self.__dashboard__:
                data['dashboard'] = await self.__dashboard__(request)

            return data

        app.route(f"{prefix}/ra.json")(ra)

        async def render_admin_static(_):
            return ResponseFile(PACKAGE_DIR / 'main.js')

        app.route(f"{prefix}/main.js")(render_admin_static)

        async def login(request):
            return await self.__login__(request)

        app.route(f"{prefix}/login")(login)

        async def ident(request):
            return await self.__ident__(request)

        app.route(f"{prefix}/ident")(ident)
Ejemplo n.º 5
0
Archivo: app.py Proyecto: klen/muffin
"""Simple basic app for testing."""

from muffin import Application

app = Application(debug=True, name='muffin')


@app.route('/')
async def index(request):
    return 'OK'


@app.on_startup
async def start():
    app.state = 'started'
Ejemplo n.º 6
0
"""Setup the application and plugins."""

from muffin import Application

from .. import views


# Create Muffin Application named 'example'
app = Application(name='example', debug=True)

app.route('/')(views.index)
app.route('/admin.css')(views.admin_css)

# Import the app's components
app.import_submodules()
Ejemplo n.º 7
0
def app():
    from muffin import Application

    return Application()
Ejemplo n.º 8
0
async def test_plugin(app, client):
    from muffin import Application, TestClient
    from muffin.plugins import BasePlugin

    with pytest.raises(TypeError):
        BasePlugin()

    start = mock.MagicMock()
    finish = mock.MagicMock()
    assert BasePlugin.middleware is None
    assert BasePlugin.startup is None
    assert BasePlugin.shutdown is None

    class Plugin(BasePlugin):

        name = 'plugin'
        defaults = {
            'debug': True,
            'option': 42,
        }

        async def middleware(self, handler, request, receive, send):
            response = await handler(request, receive, send)
            response.headers['x-plugin'] = '42'
            return response

        async def startup(self):
            return start()

        def shutdown(self):
            return finish()

    plugin = Plugin(DEBUG=False)
    assert plugin.cfg
    assert plugin.cfg.debug is False

    app = Application('muffin', DEBUG=True, PLUGIN_DEBUG=True)
    plugin.setup(app, option=43)
    assert plugin.app is app
    assert app.plugins['plugin'] is plugin

    assert plugin.cfg.debug is True
    assert plugin.cfg.option == 43

    @app.route('/')
    async def index(request):
        return 'OK'

    assert not start.called
    assert not finish.called

    client = TestClient(app)

    async with client.lifespan():

        assert start.called
        assert not finish.called

        res = await client.get('/')
        assert res.status_code == 200
        assert res.headers['x-plugin'] == '42'
        assert await res.text() == 'OK'

    assert finish.called
Ejemplo n.º 9
0
import time
from pathlib import Path
from uuid import uuid4

from muffin import Application, ResponseHTML, ResponseText, ResponseError

upload_dir = Path(__file__).parent.parent
app = Application(debug=True)


# first add ten more routes to load routing system
# ------------------------------------------------
async def req_ok(request):
    return 'ok'


for n in range(5):
    app.route(f"/route-{n}", f"/route-dyn-{n}/{{part}}")(req_ok)


# then prepare endpoints for the benchmark
# ----------------------------------------
@app.route('/html')
async def html(request):
    """Return HTML content and a custom header."""
    content = "<b>HTML OK</b>"
    headers = {'x-time': f"{time.time()}"}
    return ResponseHTML(content, headers=headers)


@app.route('/upload', methods=['POST'])
Ejemplo n.º 10
0
    @coroutine
    def middleware(request):
        if hasattr(request, 'user'):
            response = None
        else:
            response = token_auth_handler(request,
                                          get_authorization_header(request),
                                          not_auth_token, set_user, Token)
        if not response:
            response = yield from handler(request)
        return response

    return middleware


app = application = Application('noteit', **options)
app._middlewares.extend(
    [token_middleware_factory, baseauth_middleware_factory])

for model in [Note, Report, User, Token, NoteBook]:
    app.ps.peewee.register(model)


class SuperHandler(Handler):
    @abcoroutine
    def make_response(self, request, response):
        while iscoroutine(response):
            response = yield from response

        status = 200
Ejemplo n.º 11
0
def app():
    return Application(debug=True)
Ejemplo n.º 12
0
import time
import datetime

#import trio
from muffin import Application, Request, ResponseJSON

app = Application()

origin_clock_start = datetime.datetime.now().timestamp() - time.perf_counter()


def pretty_time(seconds: float) -> str:
    present = time.localtime(origin_clock_start + seconds)
    return str(
        datetime.datetime(present.tm_year, present.tm_mon, present.tm_mday,
                          present.tm_hour, present.tm_min, present.tm_sec))


@app.route("/")
async def timed_api(request: Request):  # Callable?
    received = time.perf_counter()  # trio.current_time()
    scheduled = received + 5

    print(
        f"Request received @ {pretty_time(received)} scheduled to reply @ {pretty_time(scheduled_response)}."
    )
    #trio.sleep_until(scheduled_response)
    time.sleep(5)
    handled = time.perf_counter()  # trio.current_time()
    response = {
        'received': received,
Ejemplo n.º 13
0
"""The example uses muffin-grpc plugin to setup a GRPC server/client."""

from pathlib import Path

from muffin import Application
from muffin_grpc import Plugin as GRPC
from muffin_jinja2 import Plugin as Jinja2


app = Application('grpc-example', debug=True, root=Path(__file__).parent)
jinja2 = Jinja2(app, template_folders=[app.cfg.root / 'templates'], auto_reload=True)
grpc = GRPC(app, server="[::]:50051", build_dir=app.cfg.root / 'proto')
grpc.add_proto(grpc.cfg.build_dir / 'src/helloworld.proto')

from .rpc import *      # noqa
from .views import *    # noqa