• Python Идут мысли по поводу слияния WebOb и Werkzeug. Армин Ронашер написал всё, что думает (в списке рассылки paste-users-list). Не знаю как туда ссылку дать, потому в комментарии
    ♡ recommended by @Kxepal

Replies (6)

  • @kb, Hi,


    Sorry it took me so long to reply to this thread. Both
    university and my game hacking obsession came in the way of
    replying earlier to this. I spend some time now on getting
    my design defense of Werkzeug written, so without further
    ado: here it is.


    Werkzeug Recap
    --------------

    TLDR: I would love to see a new library for both Python 2 and Python
    3 which implements functions for parsing cookies, form data, urls and
    a bunch of other things as well as a read-only request object and a
    read-write response object.

    I personally am not too stubborn on having that library my way, I
    would just like to present my view the status of Werkzeug and WebOb
    that you have some understanding of how I approached Werkzeug and why
    it's different to WebOb.
  • @kb, Why Werkzeug
    ````````````

    Why the hell was Werkzeug written in the first place? When I started
    working on my blogging engine zine I wanted to start without an actual
    framework and had the component architecture of trac in mind. With
    that I started working with Paste originally but dropped that plan
    along the way because I ended up wrapping all of the Paste utilities
    in order to get unicode support going. I found out that I barely need
    anything in there and like so many I wrote my own minimal request
    object based on the cgi module and a bunch of other things.

    For that matter I recycled code I wrote for Colubrid earlier,
    thankfully a project that no longer exists (it basically was my
    introduction to both Python web development and actual real web
    development in general).

    Unfortunately at the time I unbundled the code from the unreleased
    textpress into a separate package, Ian Bicking already released WebOb
    which in many parts is what I was actually aiming at.

    With WebOb there and WebOb building up on cgi and a bunch of standard
    library stuff as well I went into a different direction with Werkzeug
    and removed magic (except for the stupid import hack I wrote) from the
    interfaces and instead wrote parsing functions.

    I mainly did this because I missed these functions in Django projects
    a lot and it was easy to just import the required header parsing
    function from werkzeug and using it in combination with the Django
    request objects (eg: parsing accept headers and stuff like that).

    Over the time a bunch of other things entered the Werkzeug code base:

    — secure cookie, a hash protected cookie (unfortunatley with a
    terrible implementation to later implementations by other people).
    This was based on the ideas I saw in Ruby on Rails and suffers
    from using Pickle internally and trying different protocols on a
    per-key basis to get the smallest output possible. In hindsight,
    urlencoded JSON would have been a smarter choice.

    — a bunch of read-only and writable data structures. Among other
    things a MultiDict that stores more than one value per key with
    the same access times as the standard dict. Later another dict
    that additionally keeps the values linked with a double linked
    list to preserve the same access complexity for all operations by
    also preserving the ordering.

    — Basic session support

    — A WSGI test application

    — A basic WSGI server that fixes some of the problems that wsgiref
    has (like emitting the wrong value for wsgi.multithreaded)

    — A debugger middleware that drops the user into an interactive
    Python session right in the browser when an error occurs.

    — A routing system with smart ordering of rules and strict trailing
    slash behavior.

    For me Werkzeug was (as the name means) a toolkit used to write web
    applications and frameworks in Python.
  • @kb, Why Werkzeug
    ````````````

    Why the hell was Werkzeug written in the first place? When I started
    working on my blogging engine zine I wanted to start without an actual
    framework and had the component architecture of trac in mind. With
    that I started working with Paste originally but dropped that plan
    along the way because I ended up wrapping all of the Paste utilities
    in order to get unicode support going. I found out that I barely need
    anything in there and like so many I wrote my own minimal request
    object based on the cgi module and a bunch of other things.

    For that matter I recycled code I wrote for Colubrid earlier,
    thankfully a project that no longer exists (it basically was my
    introduction to both Python web development and actual real web
    development in general).

    Unfortunately at the time I unbundled the code from the unreleased
    textpress into a separate package, Ian Bicking already released WebOb
    which in many parts is what I was actually aiming at.

    With WebOb there and WebOb building up on cgi and a bunch of standard
    library stuff as well I went into a different direction with Werkzeug
    and removed magic (except for the stupid import hack I wrote) from the
    interfaces and instead wrote parsing functions.

    I mainly did this because I missed these functions in Django projects
    a lot and it was easy to just import the required header parsing
    function from werkzeug and using it in combination with the Django
    request objects (eg: parsing accept headers and stuff like that).

    Over the time a bunch of other things entered the Werkzeug code base:

    — secure cookie, a hash protected cookie (unfortunatley with a
    terrible implementation to later implementations by other people).
    This was based on the ideas I saw in Ruby on Rails and suffers
    from using Pickle internally and trying different protocols on a
    per-key basis to get the smallest output possible. In hindsight,
    urlencoded JSON would have been a smarter choice.

    — a bunch of read-only and writable data structures. Among other
    things a MultiDict that stores more than one value per key with
    the same access times as the standard dict. Later another dict
    that additionally keeps the values linked with a double linked
    list to preserve the same access complexity for all operations by
    also preserving the ordering.

    — Basic session support
  • @kb, — A WSGI test application

    — A basic WSGI server that fixes some of the problems that wsgiref
    has (like emitting the wrong value for wsgi.multithreaded)

    — A debugger middleware that drops the user into an interactive
    Python session right in the browser when an error occurs.

    — A routing system with smart ordering of rules and strict trailing
    slash behavior.

    For me Werkzeug was (as the name means) a toolkit used to write web
    applications and frameworks in Python.

    What's Bad
    ``````````

    Of course I learned along the way and Werkzeug is not perfect, far
    from it.

    1. Exceptions. They suck. Because with 2.4 you could not raise new
    style objects they are emulating part of the response API but not
    all. Not that we do not have to care about 2.4 that much any more
    it would make sense to make the exceptions actual response
    objects.

    2. Too much stuff in there. Really, that's too much for being a
    reference implementation.

    3. The demand import system. Do not look into __init__.py, do not
    ever attempt to make something like that. I took the inspiration
    from the py package and that was not a clever idea.

    4. Most of the stuff in contrib should have gone to a separate
    package. Inspired by the flaskext system I will probably try to
    move them into separate packages if they make sense or deprecate
    in favor of other things. I did unbundle the markup class from
    Jinja2 recently into a separate package and that turned out to be
    a good decision which encourages me to try that more.

    5. utf-8 Header encoding. I decided to use utf-8 as default encoding
    for headers and that was not the best decision in hindsight due to
    the encoding in Python 3 being latin1. As it only affects the
    cookie header in practice I might be able to change this even in
    Werkzeug itself without causing havor.
  • @kb, 6. Missing support for byte ranges. I never thought they were useful
    until I found out that it's a commonly used feature on GAE for
    their blobstore.

    7. Special key errors. Sounded like a good idea at the time and I
    still use it, but it's a bad idea for a general library. The idea
    is that a MultiDict does not just raise a key error, it raises a
    key error that is also a bad request error. That means if a user
    does not catch it down, it's automatically converted into a bad
    request response. I would love to see an API where this would
    still be sortof possible though. It makes for very concicse code
    that does not result in 500 internal server errors.

    8. ignore as default error handling for decoding for incoming data.
    It would have been nicer if this was chosen to be 'replace' and
    was a huge mistake. I was not yet man enough to make this
    transition in Werkzeug itself but I should.


    Why I would like to see
    ```````````````````````

    I think both webob and Werkzeug made enough mistakes in the past that
    it would be amazing to learn from both and come up with a small and
    useful core library that can be used as the basis for frameworks.
    It's without question that WebOb and Werkzeug will both have to be
    independently maintained for a while because nobody of us wants to
    force people to do another hard upgrade without much value.

    My ideal upgrade path would be starting to subclass from the new core
    request class and adapt the interface to match the old one.
  • @kb, I know that Werkzeug has the lower adoption compared to WebOb which
    inherited many of the former paste users, but I still think that it
    would make sense to look at what worked in Werkzeug for some input.

    Keep in mind that the Python web ecosystem is larger than just WebOb /
    Werkzeug and we also should keep the requirements for Django and other
    frameworks in mind. Django is special because they don't want to
    depend on stuff :) However Django in general leads the way in many
    regards. The Python packaging world is now in the hands of Tarek, but
    virtualenv and pip are mostly in the hands of Django people which
    means good things. First of all they are not only willing to
    reconsider their decisions eventually, but also that they are working
    on making the infrastructure better.

    Also, a common request base implementation might just be shipped with
    Django hidden somewhere like they are currently shipping simplejson
    and pydispatch as well as a bunch of stdlib backports.


    GSOC as a Chance
    ````````````````

    Google Summer of Code is here and it would be amazing to have a
    student working on having a look how a merge of WebOb and Werkzeug
    with best intentions in mind could look like. Porting to Python 3
    alone is probably not worth GSOC, but also merging these two libs
    might be an amazing GSOC project and for the best of the whole Python
    community.



    Regards,
    Armin