Re: [Web-SIG] WSGI and asyncio (tulip)?

2014-10-14 Thread Antoine Pitrou
On Wed, 15 Oct 2014 08:40:05 +1300
Robert Collins
robe...@robertcollins.net wrote:
 On 15 October 2014 07:30, Antoine Pitrou solip...@pitrou.net wrote:
  On Tue, 14 Oct 2014 09:47:35 -0700
  Guido van Rossum gu...@python.org wrote:
 
  I'm wondering if a small extension to the WSGI protocol might be sufficient
  to support this: the special environ variable wsgi.async_input could
  optionally be tied to a standard asyncio stream reader (
  https://docs.python.org/3/library/asyncio-stream.html#streamreader), from
  which bytes can be read using yield from stream.read([nbytes]) or yield
  from stream.readline().
 
  I think it would be frankly better to hook at the transport/protocol
  level, and let people wrap that inside an asyncio stream if that's their
  preference.
 
 For things like mod_wsgi and uwsgi, we're not actually implementing
 the transport or protocol inside of Python at all - its all happening
 in C and often in an entirely separate process.

You may have misunderstood me. I am talking about the Transport and
Protocol abstractions defined in PEP 3156.

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
https://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] WSGI and asyncio (tulip)?

2014-10-14 Thread Antoine Pitrou
On Wed, 15 Oct 2014 09:22:28 +1300
Robert Collins
robe...@robertcollins.net wrote:
 
  You may have misunderstood me. I am talking about the Transport and
  Protocol abstractions defined in PEP 3156.
 
 Lets assume I did. Given say nginx + uwsgi + asyncio, you're proposing
 that there be a uwsgi-asyncio module that listens to the uwsgi socket
 and demuxes packets from that into something that then exposes a
 ReadTransport + WriteTransport pair and a Protocol on top of that.

Let's call it uwsgi-pep3156. It shouldn't be asyncio-specific.

[Note Guido's original remark: However, the situation is different
for reading the request body. The app can read this in dribs and drabs
if it wants to, by reading limited amounts of data from
environ['wsgi.input'], but in an asyncio-driven world reading
operations should really be marked with yield from (or perhaps just
yield -- again, I'm sure an adaptor won't have a problem with this).

Ergo, this is about streaming the request and response bodies. Not
asynchronously receiving the headers, etc.]


The server would implement a Transport for the input body stream +
output body stream. It would accept a Protocol factory from the
application/middleware.

Then when a request comes:

   protocol = protocol_factory()
   transport = Transport(...)
   protocol.connection_made(transport)

and when an input body chunk is available:

   protocol.data_received(chunk)

and when the input body is finished:

   protocol.eof_received()

The protocol would be able to call transport.extra_info(...) to get
HTTP-specific information, e.g. transport.extra_info('headers') perhaps.


(that's for the HTTP part; a websockets layer would probably implement
a separate transport and accept a separate protocol factory; actually,
it could be implemented as a protocol that would parse the websockets
protocol and provide its own transport on top of that... there may
already be such a thing on the Internet :-))

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
https://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] WSGI and asyncio (tulip)?

2014-10-14 Thread Antoine Pitrou
On Wed, 15 Oct 2014 10:48:37 +1300
Robert Collins
robe...@robertcollins.net wrote:
 On 15 October 2014 10:04, Antoine Pitrou solip...@pitrou.net wrote:
 ...
  (that's for the HTTP part; a websockets layer would probably implement
  a separate transport and accept a separate protocol factory; actually,
  it could be implemented as a protocol that would parse the websockets
  protocol and provide its own transport on top of that... there may
  already be such a thing on the Internet :-))
 
 So thats the bit that I'm having conceptual trouble with - servers may
 well implement the framing (and I rather think that they have to do so
 in some deployments), so we need to make sure that we don't do that in
 this context - we're behind an abstraction.

If the new WSGI specifies that the server implements websocket support,
then indeed the application shouldn't redo it.

 The question in mind is whether that is amenable to the same
 unification and layering that WSGI brought to the HTTP synchronous
 case. It looks like you'd make a protocol factory decorator.

I'm not sure why you would need a decorator. In the PEP 3156 mindset, a
protocol factory can be any 0-argument Python callable: a class, a
closure, a bound method, a global function, etc. Just pass that object
it to the server when asking it to listen (or when it tells you it
wants to listen, which is the WSGI approach AFAIU).

 Will it
 be sufficiently flexible and interoperable to be something that
 becomes a lingua franca? I don't know pep-3156 well enough to judge
 that myself.

Yes, it should. That's the formalism already adopted for serving stuff
on listening connections, e.g. (from PEP 3156):

create_server(protocol_factory, host, port, options). Enters a
serving loop that accepts connections. [...]

Each time a connection is accepted, protocol_factory is called without
arguments(**) to create a Protocol, a bidirectional stream Transport is
created to represent the network side of the connection, and the two
are tied together by calling protocol.connection_made(transport).

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
https://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] WSGI and asyncio (tulip)?

2014-10-14 Thread Antoine Pitrou
On Wed, 15 Oct 2014 11:28:42 +1300
Robert Collins
robe...@robertcollins.net wrote:
 On 15 October 2014 11:10, Antoine Pitrou solip...@pitrou.net wrote:
 
  Each time a connection is accepted, protocol_factory is called without
  arguments(**) to create a Protocol, a bidirectional stream Transport is
  created to represent the network side of the connection, and the two
  are tied together by calling protocol.connection_made(transport).
 
 So where would headers etc be supplied to the protocol for reads (and
 for outputs)? Since the transport isn't the raw socket, its the bodies
 only.

For reads, it could be provided on e.g.
transport.get_extra_info('headers'). Or if you want a flat mapping API,
transport.get_extra_info('http_content_type'), etc.

As for out-bound headers, it's a good question. But I think it's ok for
the transport to have HTTP-specific methods, so
transport.write_header(name, value) could be ok too.

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
https://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] WSGI: allowing short reads

2014-09-27 Thread Antoine Pitrou
On Sun, 28 Sep 2014 10:43:33 +1300
Robert Collins
robe...@robertcollins.net wrote:
 
  It was in the context of improving streamed unpickling, which is
  a problem a bit similar - but less horrible - to JSON unserializing;
  since then, the problem was solved in a different way by adding a
  framing layer to pickle protocol 4 :-).
 
 BufferedReader solves this well though, doesn't it?

Assuming it's the only one accessing the raw stream, yes.

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
https://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] A 'shutdown' function in WSGI

2012-02-21 Thread Antoine Pitrou
Tarek Ziadé ziade.tarek@... writes:
 
 
 On Tue, Feb 21, 2012 at 10:24 AM, Graham Dumpleton
graham.dumple...@gmail.com wrote:
 ...
  But I don't think you can guarantee that everything is still up in memory by
  the time atexit gets called,
  so you can't really call cleanup code there.
 The only thing which is done prior to atexit callbacks being called is
 waiting on threads which weren't marked as daemonised.
 
 
 which can lead to completely lock the shutdown if a lib or the program has a
 thread with a loop that waits for a condition.which it is not the case with
 signals, since you get a chance to properly stop everything beforehand.

That's a buggy lib or program. This has nothing to do with WSGI really. The
snippet Graham showed is run at any interpreter shutdown, even when you simply
run python in your shell.

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] A 'shutdown' function in WSGI

2012-02-21 Thread Antoine Pitrou
Tarek Ziadé ziade.tarek@... writes:
 
 here's a very simple demo: http://tarek.pastebin.mozilla.org/1489505
 
 There are two typos but the effect remains the same since you are locked
 before you reach those lines:
 - atexit call worker.stop() instead 
 of worker.join()
 - in worker.stop(), it calls worker.join() instead of
 worker.join(self)

I find your example convincing. I think that's worth fixing in Python (e.g. by 
offering an atexit() method on Thread objects). Perhaps you can open a bug?

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Declaring PEP 3333 accepted (CGI example)

2011-01-07 Thread Antoine Pitrou
Hello,

P.J. Eby p...@... writes:
 
   if headers_sent:
   # Re-raise original exception if headers sent
 -raise exc_info[0], exc_info[1], exc_info[2]
 +raise 
 exc_info[0](exc_info[1]).with_traceback(exc_info[2])
   finally:
   exc_info = None # avoid dangling circular ref
 
 Can somebody weigh in on what the correct translation here is?  The 
 only real Python 3 coding I've done to date has been experiments to 
 test changes to other aspects of WSGI.  

You don't need the with_traceback. Just raise exc_info[1]. The original
traceback is already attached to the exception instance (major difference from
Python 2).

Oh and by the way:

headers_set = []
headers_sent = []

This is really a recipe for disaster. Please give these two variables clearly
distinct names. Your example is very confusing to read because of this.

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] PEP 444 / WSGI 2 Async

2011-01-07 Thread Antoine Pitrou
Alice Bevan–McGregor al...@... writes:
 
  I don't understand why you want a yield at this level. IMHO, WSGI 
  needn't involve generators. A higher-level wrapper (framework, 
  middleware, whatever) can wrap fd-waiting in fancy generator stuff if 
  so desired. Or, in some other environments, delegate it to a reactor 
  with callbacks and deferreds. Or whatever else, such as futures.
 
 WSGI already involves generators: the response body.

Wrong. The response body is an arbitrary iterable, which means it can be a
sequence, a generator, or something else. WSGI doesn't mandate any specific
feature of generators, such as coroutine-like semantics, and the server doesn't
have to know about them.

 Everyone has their own idea of what a deferred is, and there is only 
 one definition of a future, which (in a broad sense) is the same as 
 the general idea of a deferred.

A Twisted deferred is as well defined as a Python stdlib future; actually,
deferreds have been in use by the Python community for much, much longer than
futures. But that's besides the point, since I'm proposing that your spec
doesn't rely on a high-level abstraction at all.

 Ratification of PEP 444 is a long way off itself.

Right, that's why I was suggesting you drop your concern for Python 2
compatibility.


Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] PEP 444 / WSGI 2 Async

2011-01-07 Thread Antoine Pitrou
Alice Bevan–McGregor al...@... writes:
 
 On 2011-01-07 09:04:07 -0800, Antoine Pitrou said:
  Alice Bevan–McGregor al...@... writes:
  I don't understand why you want a yield at this level. IMHO, WSGI 
  needn't involve generators. A higher-level wrapper (framework, 
  middleware, whatever) can wrap fd-waiting in fancy generator stuff if 
  so desired. Or, in some other environments, delegate it to a reactor 
  with callbacks and deferreds. Or whatever else, such as futures.
  
  WSGI already involves generators: the response body.
  
  Wrong.
 
 I'm aware that it can be any form of iterable, [snip]

Ok, so, WSGI doesn't already involve generators. QED.

  Right, that's why I was suggesting you drop your concern for Python 2 
  compatibility.
 
 -1
 
 There is practically no reason for doing so;

Of course, there is one: a less complex PEP without any superfluous
compatibility language sprinkled all over. And a second one: a simpler PEP is
probably easier to get contructive comments about, and (perhaps some day)
consensus on.

 esp. considering that I've 
 managed to write a 2k/3k polygot server that is more performant out of 
 the box than any other WSGI HTTP server I've come across and is far 
 simpler in implementation than most of the ones I've come across with 
 roughly equivelant feature sets.

Just because you managed to write some piece of code for a *particular* use
case doesn't mean that cross-compatibility is a solved problem. If you think
it's easy, then I'm sure the authors of various 3rd-party libs would welcome
your help achieving it.

 Python 2.x will be around for a long time.

And so will PEP  and even PEP 333. People who value legacy compatibility
will favour these old PEPs over your new one anyway. People who don't will
progressively jump to 3.x.

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] PEP 444 / WSGI 2 Async

2011-01-07 Thread Antoine Pitrou

Alice Bevan–McGregor al...@... writes:
 
 On 2011-01-07 13:21:36 -0800, Antoine Pitrou said:
  Ok, so, WSGI doesn't already involve generators. QED.
 
 This can go around in circles; by allowing all forms of iterable, it 
 involves generators.  Geneators are a type of iterable.  QED right 
 back.  ;)

Please read back in context.

 There isn't any compatibility language sprinkled within the PEP.[...]
 
 Using native strings where possible encourages compatibility, [snip]

The whole native strings thing *is* compatibility cruft. A Python 3 PEP would 
only need two string types: bytes and unicode (str).

  Just because you managed to write some piece of code for a 
  *particular* use case doesn't mean that cross-compatibility is a solved 
  problem.
 
 The particular use case happens to be PEP 444 as implemented using an 
 async and multi-process (some day multi-threaded) HTTP server, so I'm 
 not quite sure what you're getting at, here.

It's becoming to difficult to parse. You aren't sure yet what the async part of 
PEP 444 should look like but you have already implemented it?

  If you think it's easy, then I'm sure the authors of various 3rd-party 
  libs would welcome your help achieving it.
 
 I helped proof a book about Python 3 compatibility and am giving a 
 presentation in March that contains information on Python 3 
 compatibility from the viewpoint of implementing the Marrow suite.

Well, I hope not too many people will waste time trying to write code
cross-compatible code rather than solely target Python 3. The whole point of
Python 3 is to make developers' life better, not worse.

  Python 2.x will be around for a long time.
  
  And so will PEP  and even PEP 333. People who value legacy 
  compatibility will favour these old PEPs over your new one anyway. 
  People who don't will progressively jump to 3.x.
 
 Yup.  Not sure how this is really an issue.  PEP 444 is the /future/, 
 333[3] is /now/ [-ish].

Please read back in context (instead of stripping it), *again*.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] PEP 444 / WSGI 2 Async

2011-01-06 Thread Antoine Pitrou
Alice Bevan–McGregor al...@... writes:
 
 agronholm: what new features does pep 444 propose to add to pep ? \ 
 async, filters, no buffering?
 
 GothAlice: Async, filters, no server-level buffering, native string 
 usage, the definition of byte string as the format returned by 
 socket read (which, on Java, is unicode!), and the allowance for 
 returned data to be Latin1 Unicode.

Regardless of the rest, I think the latter would be a large step backwards.
Clear distinction between bytes and unicode is a *feature* of Python 3.
Unicode-ignorant programmers should use frameworks which do the encoding work
for them.

(by the way, why you are targeting both Python 2 and 3?)

 agronholm: I'm not very comfortable with the idea of wsgi.input in 
 async apps \ I'm just thinking what would happen when you do 
 environ['wsgi.input'].read()
 
 GothAlice: One of two things: in a sync environment, it blocks until it 
 can read, in an async environment [combined with yield] it 
 pauses/shelves your application until the data is available.

Er, for the record, in Python 3 non-blocking file objects return None when
read() would block. For example:

 r, w = os.pipe()
 flags = fcntl.fcntl(r, fcntl.F_GETFL, 0); fcntl.fcntl(r, fcntl.F_SETFL,
flags | os.O_NONBLOCK)
0
 os.read(r, 1)
Traceback (most recent call last):
  File stdin, line 1, in module
OSError: [Errno 11] Resource temporarily unavailable
 f = open(r, rb)
 f.read(1) is None
True

 agronholm: the requirements of async apps are a big problem
 
 agronholm: returning magic values from the app sounds like a bad idea
 
 agronholm: the best solution I can come up with is to have 
 wsgi.async_input or something, which returns an async token for any 
 given read operation

The idiomatic abstraction for non-blockingness under POSIX is file descriptors.
So, at the low level (the WSGI level), exchanging fds between server and app
could be enough to allow both to wake up each other (perhaps two fds: one the
server can wait on, one the app can wait on). Similarly to what signalfd() does.
Then higher-level tools can wrap inside Futures or whatever else.

However, this also means Windows compatibility becomes more complicated, unless
the fds are sockets.

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


[Web-SIG] CGI in PEP 444

2011-01-04 Thread Antoine Pitrou
Alice Bevan–McGregor al...@... writes:
 
 [1] http://bit.ly/e7rtI6

So, while we are at it, could we get rid of the CGI server example in this new
SWGI spec?
This is 2011, and we should promote modern idioms, not encourage people to do
1995 Web programming. 10 years ago, CGI was already frown upon.
(and even the idea that WSGI should provide some kind of CGI compatibility
sounds a bit ridiculous to me)

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


[Web-SIG] decoding environ

2010-07-17 Thread Antoine Pitrou
Ian Bicking i...@... writes:
 
 So... there's been some discussion of WSGI on Python 3 lately.
 I'm not feeling as pessimistic as some people, I feel like we were close
 but just didn't *quite* get there.
 Here's my thoughts:
 * Everyone agrees keys in the environ should be native strings

I don't know how that related to WSGI but it should be noted that Python 3.2
comes with two synchronized views of the environment: os.environ (str - str
mapping) and os.environb (bytes - bytes mapping).

See http://docs.python.org/dev/library/os.html#os.environ

Also, the way os.environ is decoded from bytes values involves the
surrogateescape error handler, which ensures that non-decodeable bytes get
their own unicode escape sequences, and can get re-encoded losslessly:

http://www.python.org/dev/peps/pep-0383/

Regards

Antoine.


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com