<commit_before>`Verktyg <verktyg_>`_
=====================

|build-status| |coverage|

Verktyg is a web framework built on `werkzeug`_.

It separates mapping of routes to endpoints and endpoints to handlers and provides a mechanism for dispatching on request content-type and method.

It also includes an optional application base class.
This wraps the routing system and provides a binding mechanism to allow extension.
The request and server context are kept explicit and separate.

Focus is on building api's where support for multiple content types is likely to be important, and where it doesn't make sense to use a form builder and therefore share code between ``GET`` and other methods.
For building html websites flask is probably a better choice.


Components
----------

Router
~~~~~~
Based on werkzeug routing but with method dispatch removed.

Maps from urls to endpoint identifiers


Dispatcher
~~~~~~~~~~
Chooses handler based on endpoint, request accept headers, and request, method.


Application
~~~~~~~~~~~
Wraps dispatcher and router

Binds together request parsing, routing, dispatch, and error handling.


Examples
--------

A slightly overcomplicated Hello World application.
Tries to illustrate separate route configuration and implementation.

.. code:: python

    # hello.py
    from werkzeug import Response
    from verktyg import Dispatcher, Application, expose

    views = Dispatcher()


    @expose(views, 'index')
    def get_index(app, req):
        return Response('Hello world')


    def bind(app):
        app.add_views(views)


.. code:: python

    # root.py
    import os
    import logging

    from werkzeug.serving import run_simple
    from verktyg.routing import Route
    from verktyg import Application


    def create_app(config=os.environ, debug=None, proxy=None):
        if debug is None:
            debug = config.get('DEBUG', False)

        if debug:
            logging.basicConfig(level=logging.DEBUG)
        else:
            logging.basicConfig()

        app = Application(debug=debug)
        app.config = config

        app.add_routes(
            Route('/', endpoint='index'),
        )

        import hello
        hello.bind(app)

        return app


    def run_dev_server():
        app = create_app(debug=True)
        from werkzeug.serving import run_simple
        run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True)


    if __name__ == '__main__':
        run_dev_server()<commit_msg>Improved README<commit_after>`Verktyg <verktyg_>`_
=====================

|build-status| |coverage|

Verktyg is a magic free python web framework focused on making it easy to build large APIs.

It started out as a replacement routing layer for `werkzeug`_ but has slowly developed into a full fork.

Unlike `werkzeug_`, it separates mapping of routes to endpoints and endpoints to handlers and provides a mechanism for dispatching on request content-type and method.

For form based websites, where the coupling of ``GET`` and ``POST`` handlers makes more sense, `werkzeug`_ and `flask`_ will probably always be the better choice.


Components
----------

Verktyg separates the mapping from routes to endpoints from the mapping from the mapping from endpoints to handlers.

This allows handlers to be defined without having to be aware of where they are bound, which means that APIs can be described centrally but have their implementation split out into separate modules.

Router
~~~~~~
Based on werkzeug routing but with method dispatch removed.

Maps from urls to endpoint identifiers.


Dispatcher
~~~~~~~~~~
Chooses a handler for a request based on the endpoint chosen by the router, the request method, and the request accept headers.


Application
~~~~~~~~~~~
Wraps dispatcher and router

Binds together request parsing, routing, dispatch, and error handling.


Examples
--------

A slightly overcomplicated Hello World application.
Tries to illustrate separate route configuration and implementation.

.. code:: python

    # hello.py
    from werkzeug import Response
    from verktyg import Dispatcher, Application, expose

    views = Dispatcher()


    @expose(views, 'index')
    def get_index(app, req):
        return Response('Hello world')


    def bind(builder):
        builder.add_views(views)


.. code:: python

    # root.py
    import os
    import logging

    from werkzeug.serving import run_simple
    from verktyg.routing import Route
    from verktyg import Application


    def create_app(config=os.environ, debug=None):
        if debug is None:
            debug = config.get('DEBUG', False)

        if debug:
            logging.basicConfig(level=logging.DEBUG)
        else:
            logging.basicConfig()

        builder = ApplicationBuilder(debug=debug)

        builder.add_routes(
            Route('/', endpoint='index'),
        )

        import verktyg_sqlalchemy
        verktyg_sqlalchemy.bind(
            builder, database_url=config['APP_DB_URL'],
        )

        import hello
        hello.bind(builder)

        app = builder(config.get('APP_PUBLIC_URL', ''))
        app.debug = debug

        return app


    def _server_main():
        import verktyg_server.argparse

        parser = argparse.ArgumentParser(description="Run the example app")
        verktyg.server.argparse.add_arguments(parser)
        args = parser.parse_args()

        app = create_app(debug=True)

        server = verktyg_server.argparse.make_server(args)
        return server


    if __name__ == '__main__':
        _server_main()
{'fraction_non_alphanumeric': 0.08658865886588658, 'fraction_numerical': 0.0018001800180018, 'mean_word_length': 3.0763022743947177, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '850348', 'n_tokens_mistral': 1535, 'n_tokens_neox': 1441, 'n_words': 568}