43 comments

[ 2.3 ms ] story [ 107 ms ] thread
This looks like a whole lot of work for a 0.0.1 release so I must ask... why might I choose Ice over Flask?
Or Bottle, CherryPy, and others? I'm sure there's room for another framework, but it would be good to elaborate what Ice's raison d'être is, and what it's strengths and weaknesses are.
Following text quoted from the README[1]:

"This microframework was born as a result of experimenting with WSGI framework. Since what started as a small experiment turned out to be several hundred lines of code, it made sense to share the source code on the web, just in case anyone else benefits from it.

This microframework has a very limited set of features currently. It may be used to develop small web applications. For large web applications, it may make more sense to use a more wholesome framework such as Flask or Django.

It is possible that you may find that this framework is missing a useful API that another major framework provides. In such a case, you have direct access to the WSGI internals to do what you want via the documented API.

If you believe that a missing feature or a bug fix would be useful to others, you may report an issue, or even better, fork this project on GitHub, develop the missing feature or the bug fix, and send a patch or a pull request. In fact, you are very welcome to do so, and turn this experimental project into a matured one by contributing your code and expertise."

[1]: https://github.com/susam/ice#why-ice

Bottle is faster and simpler.
What is Bottle faster and simpler than? CherryPy? Flask? Ice?

Do you have benchmarking results to support your claim?

What aspects of Bottle are simpler? Writing code using it? Deploying it? Can you elaborate with some concrete examples?

Even more: why WSGI ?

We need a django of the async world. We need something in Python to compete with nodejs, or even meteor, with async/await as primary tool. And maybe a aWSGI support.

But WSGI ? We have everything we need. They are proven tools. They work. Have great ecosystems and documentations. They do the job perfectly for non real time oriented web site. We don't need another one.

Seen Sanic[1] yet? I've become a fan... works well with asyncpg[2] too.

[1]: https://github.com/channelcat/sanic

[2]: https://github.com/MagicStack/asyncpg

It's very limited. We are far, far away from what django or meteor can provide. The API, while using async, is kinda old school (no plugins, namespaces, conf hooks...) and low level for some stuff (where is my task queue ?), and yet too high level for others (you give up control of the even loop policy completely).

It's a nice attempt, but it's barely a draft IMO.

When did you last use sanic? It's far from limited, and advancing quickly. However, it's a microframework, so it's true that you'll not get a full Django-like experience (and Meteor isn't even in the same class of web framework as Django or microframeworks like Sanic, so there's nothing to compare there either).

But with respect to microframeworks, Sanic is getting pretty close to feature parity with Flask, only asynchronously. I'm not sure what kind of plugin architecture you're looking for, but you can do middleware with Sanic. Also custom protocols. Also decorators (e.g., for auth). And for namespacing, there are blueprints. I'm not sure what you mean by "conf hooks".

It does help with Sanic if you're already familiar with Flask. Sanic is very close to an async version of Flask.

For a task queue, you can run async tasks with Sanic alone using `app.add_task(some_async_function)`.

It's also simple to use apscheduler if you want a more full-feature async scheduler. Example:

    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from sanic import Sanic

    app = Sanic()

    async def tick():
        print('Work!')

    @app.listener('before_server_start')
    async def initialize_scheduler(app, loop):
        scheduler = AsyncIOScheduler({'event_loop': loop})
        scheduler.add_job(tick, 'interval', seconds=1)
        scheduler.start()

    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8000, debug=True)
Finally, unless things have changed, you should be able to set event loop policy with `asyncio.set_event_loop_policy`, have you tried it?
> We need a django of the async world

I would love to see this, BUT I don't think it's needed to compete with Node.js. Async is mostly interesting for networking, and you can get that now with Django Channels (https://channels.readthedocs.io/) or Pushpin (http://pushpin.org (disclosure: I'm the author)).

Yeah they rely on separate processes which is a bit of a dodge, but IMHO the separation is good architecture.

I tried the django channels, and the way it works is a pita.

Currently to setup a Django website you usually need a wsgi server, and a font-end server like nginx, then maybe a task queue and now your django channel server. None of them being well integrated.

It's crazy. You should have one process that pops and manage the other ones, and allow them to integrate and communicate transparently, with not even a need for nginx/apache for small to medium websites.

You should not have to setup a task queue manually, a thread/process pool and the like. You should have a way to communicate real time between the client code, the tasks in your queues, endpoints in your servers and all your workers.

You should have synchronization primitives, a common configuration system (with live settings that propagates) and a clean way to build a hierarchy of components.

The closest I get is crossbar.io serving django + celery and some custom code to hook them using the WAMP protocol. It's very, very nice, but far away from the integration we should have for those things in 2017.

I have been starting to work on something (https://github.com/Tygs) but since it's a VERY hard problem, I struggle find continuity by working on it only here and there. This is something you need a few months full time to really dig deep. Especially since with async, the HTTP part is actually the easiest part. The hard part is to make it easily usable, configurable and debugable.

Maybe there is a kickstarter to build for this.

what about aiohttp? Doesn't it fit to the job of flask/django. A complete stack is one cookiecutter away.
Tygs is based on aiohttp. But again, aiohttp is very minimalist. You gain very little in productivity if you use only that, and if you don't, well, that's a hell of glue code to write.

Being async and capable of dealing with http requests are only the very beginning of the story. With what async allows, we should be able of doing more. Way, way more.

Aren't Flask, Django and Bottle also built on top of WSGI?
I think that's what your parent is saying. There are good solutions built on WSGI, and WSGI itself is restrictive. Not to take anything away from this project.
This project too is a solution built on WSGI like Bottle and others. I agree plain WSGI is too restrictive and tedious to work with. So I don't understand how the parent comment's concerns about WSGI applies to this project but not to other WSGI-based frameworks.
There are already good solutions for WSGI. There are less for non-WSGI async options. The parents point is that if you now create something new, yet another WSGI solution doesn't add much to the general ecosystem, where a new async thing very well might.
That makes sense. Thanks for explaining.
Exactly. If you build an async project, but do the same things than WSGI frameworks we gain nothing. We already have perfectly capable and productive frameworks. We use them everyday, we make money with it. They work.

Async allows to maintain low latency permanent connections between each clients, being it a web page, a task queue, a server worker, etc. We finally can have it all connected. We can broadcast setting changes, propagate cache invalidation, push action notifications, update task completions to subscribers, allow everybody to react to stuff on the file system or the db instead of polling, all in soft real time.

The potential is amazing.

We all can do HTTP req / resp. The question now is: how good the tooling around this cycle is.

You may have already seen this but uWSGI allows you operate with asyncio too.

http://uwsgi-docs.readthedocs.io/en/latest/asyncio.html

Your point ?
Sorry, it was a vague attempt to foster discussion about the options of moving out of WSGI without throwing it out completely (I was really ill yesterday and couldn't quite formulate any logic thoughts around it myself).

Have you looked at the options there / if there would be an easy way to bolt on a more async driven framework? Obviously, it doesn't solve the missing framework issue, but maybe there's some clever tricks you can do because uwsgi is allowing you to bend the rules.

What about apistar[1]? It recently added support for async/await and asyncio[2].

[1] https://github.com/encode/apistar [2] https://github.com/encode/apistar#asyncio

Again it's very old school. You have async, you can do something incredible. You can setup real time RPC, propagate pub/sub accross all client and server nodes, provide a transparent tasks queue, enable live settings, etc.

What you are doing here is just "what sync frameworks do, but async". There is no use for that. I can already do it with WSGI frameworks. It works well. It's robust, proven and productive.

If you don't use async to provide novel features that only async enables, what's the point ?

I just use CherryPy. It can run under WSGI, be a host for WSGI applications (and is usually used to host Flask applications) and runs it's own web server as well. CherryPy is pretty decent and performant, both Hulu and Netflix use it internally or have in the past. I do know one of the main devs is trying to make it support more of the asyncio stuff, though that might be a while.

To answer your question as to "why WSGI?" the point is that if you write code that targets WSGI, no matter what you can put your Python code behind any WSGI compliant server. You wont be screwed because you picked a dying framework.

Yes but we have plenty of solutions for those. It's 2017, we got WSGI right. It's a done deal. Like trying to create another CGI framework.
I'm for WSGI, just stating that there are frameworks that fully support it properly as both hosts and end points for it.
The minimal implementation for the application side in Python is "flipflop". It calls your function, and you return a HTML string as a result. That's enough to hook up a Python program as a web server.

Anything beyond that, such as input data parsing or generating HTML from a template or tree, should be a library, not a "framework". You might want multiple libraries from different sources.

Reading this reminds me of the Clojure style of code... anyone else?
Yeah, my first thought as well. The Rich Hickey spirit is leaking..
It seems the entire Python community disagree, and made the monolithic Django the most popular framework. No the minimalist flask. Not the very composable pyramid.

Django.

And the reasons for that are:

- choosing tools takes time and resources. - integrating them takes time and resources.

- keep up to update the stack so it works well together takes time and resources.

- multiple tools mean multiple docs.

- you need to train your newcomers to your whole whole stack.

- when you change project, you have to learn a new stack.

- multiple tools won't be nearly as well integrated or full featured than the big framework. Have you tried flask-admin ? It's very far away from django-admin.

- ecosystems build on common grounds. They assume they have tools, configurations, conventions. If you just use anything and everything, no third party tool car easily fit in your stack. E.G: django has a lot of nice libs around authentication because 3rd parties can rely on having a central User model. It's terribly unperfect, but it's really productive.

- JS has this philosophy, and it's a terrible horrible no good messy pain.

(comment deleted)
Express has way more devs than all of the Python frameworks combined. JS is past, present, and future. This is what the job market looks like: https://www.dynatrace.com/blog/node-js-is-hitting-the-big-ti...

On npm, expesss had 538,945 downloads in the last day https://www.npmjs.com/package/express

http://blog.builtinnode.com/post/most-installed-packages-acc... "Express is a very popular package with 160,809,503 downloads so far. It has a very steady growth, peaking in March with a little over 12 million downloads."

Express was released November 16, 2010; Django was released July 21st 2005.

https://trends.builtwith.com/framework shows PHP with 53 million sites, Express with 217K, and Django right under Visual Studio (wat) and ColdFusion with 59k.

It really depends on what you're trying to do. Because so many JS frameworks for the browser integrate so nicely with Node, you can use stuff like Axios on both ends and only learn one API. Meteor is even nicer in this (write models once and use on both ends).

Out of topic man. We are talking about integration vs lib based.
I took that comment as meaning "the entire NodeJS community disagrees", in response to your opening statement.
I think both integrated monolithic framework as well as microframework + library based web development have their place in software development. Most of my career, I have seen Flask to be popular wherever I worked, but I am well aware that Django is the most popular Python web development framework out there. It shows that there are all kinds of developers with their own preferences. Therefore both kinds of web development would remain popular.

There is no one way framework or paradigm that can be the past, present and future. There are always multiple of them.

Django preceding Flask (by 5 years) and Pyramid (by 2 months) surely made a difference.
We had zope, plone, turbogear and pylon before that.
Why invent a new string matching format, instead of just using regular expressions?
They allow regular expression.

But having use Django's regex matching a lot, and the one provided with werkzeug, I can tell you the second one is much more productive: 99% of the case you don't need a complex pattern and you are very happy to be able to just say "hey gime 'stuff' here" instead of crafting things like "(?P<stuff>\d+)" . For the rare use case, you just fall back on regexes.

(comment deleted)