You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-dev@quetz.apache.org by Fırat KÜÇÜK <fi...@kucuk.org> on 2006/04/20 10:10:24 UTC

wepy

Hi,
we have been started a project called wepy! it is a modpython based PHP and
Python mix. Here are the some samples about wepy:

--------------- simple hello world script

print "hello world"

--------------- simple redirection script

HEADERS['Location'] = 'http://www.wepy.org/'

--------------- simple image mime type sample

HEADERS['Content-Type'] = 'image/png'

import sys
sys.stdout.write(open('penguin.png', 'rb').read())


--------------------------------------------------------

COOKIES, HEADERS, GET, POST, SERVER, CONFIG, REQUEST

these are the global variables

when you call website/index.py?a=5&a=6&a=12
and
print GET['a']

the output ['5', '6', '12']


for download:
svn co https://svn.gaplan.org/gaplan/trunk/wepy/



please try and send your valuable comments

Regards


Re: wepy

Posted by Fırat KÜÇÜK <fi...@kucuk.org>.
Mike Looijmans yazmış:

> Fırat KÜÇÜK wrote:
>
>> Hi,
>> we have been started a project called wepy! it is a modpython based 
>> PHP and
>> Python mix. Here are the some samples about wepy:
>
>
> It would help a lot if you'd share with us exactly what you are trying 
> to accomplish here. Your examples look a lot like the python CGI 
> handler in mod_python.
>
> A fully implemented "modpython based PHP" already exists and is 
> built-in into mod_python as PSP. So it would help us help you if you 
> told us what is is your project does (or will do) that isn't already 
> in there.
>
>
Hi,

* can use PHP Session files
* familar global variables such as SERVER, GET, POST, COOKIE ...
* Code and design should be separated (cheetah can be used for this.)
  so coders can write scripts without <%, <?, [[

will a new flavor for modpython.








Re: wepy

Posted by Mike Looijmans <nl...@natlab.research.philips.com>.
Fırat KÜÇÜK wrote:
> Hi,
> we have been started a project called wepy! it is a modpython based PHP and
> Python mix. Here are the some samples about wepy:

It would help a lot if you'd share with us exactly what you are trying 
to accomplish here. Your examples look a lot like the python CGI handler 
in mod_python.

A fully implemented "modpython based PHP" already exists and is built-in 
into mod_python as PSP. So it would help us help you if you told us what 
is is your project does (or will do) that isn't already in there.


-- 
Mike Looijmans
Philips Natlab / Topic Automation



Re: wepy

Posted by Fırat KÜÇÜK <fi...@kucuk.org>.
Mike Looijmans yazmış:

> Your code is perfectly thread safe, yes. But the assignment to 
> sys.stdout IS NOT. There is only one sys.stdout, and all threads use 
> the same one.
>
> Example (two threads):
>
> ##Thread 1:
> - initializes request from client 1
> - sets sys.stdout to StdOut(request ...) object
> - writes "hello1 " to sys.stdout
> ##Thread 2
> - initializes request from client 2
> - sets sys.stdout to StdOut(request ...) object
> - writes "hello2 " to sys.stdout
> ##Thread 1
> - writes "world1" to sys.stdout
> - terminates, and sends sys.stdout.buffer to client
> ##Thread 2
> - writes "world2" to sys.stdout
> - terminates, and sends sys.stdout.buffer to client
>
> Now look at what will happen with your code and a threading apache:
> Client 1 will receive "hello2 world1"
> Client 2 will receive "hello2 world1world2"
>
> Explanation:
>
> ##Thread 1:
> - initializes request from client 1
> - sets sys.stdout to StdOut(request ...) object
> - writes "hello1 " to sys.stdout
> (sys.stdout.buffer == "hello1 ")
> ##Thread 2
> - initializes request from client 2
> - sets sys.stdout to StdOut(request ...) object
> (and thus replaces the buffer that thread 1 put there, its contents 
> are lost)
> - writes "hello2 " to sys.stdout
> (sys.stdout.buffer == "hello2 ")
> ##Thread 1
> - writes "world1" to sys.stdout
> (sys.stdout.buffer == "hello2 world1")
> - terminates, and sends sys.stdout.buffer to client
> ##Thread 2
> - writes "world2" to sys.stdout
> (sys.stdout.buffer == "hello2 world1world2")
> - terminates, and sends sys.stdout.buffer to client
>
>
> Mike Looijmans
> Philips Natlab / Topic Automation
>
> Fırat KÜÇÜK wrote:
>
>> Mike Looijmans yazmış:
>>
>>> Yes,
>>>
>>> the problem is not whatever class or method you use to send the 
>>> output to the client, but the problem is the use of the global 
>>> sys.stdout variable. The is only one such object in your system. If 
>>> there are two threads each handling a request, there is no telling 
>>> to which one the sys.stdout.write or print statement will send its 
>>> output. To prevent this, you'd have to mutex access to it, and leads 
>>> to being able to handle only one request at a time.
>>>
>>> On many unix flavors, apache defaults to 'forking', which runs each 
>>> request in a separate process. In these circumstances, you will not 
>>> detect this problem. On other platforms, or if you modify the 
>>> httpd.conf file, apache uses threading or even a mix of threading 
>>> and forking.
>>>
>>> Important note: Since print sends to sys.stdout, using print is just 
>>> as bad a method to send output to the client as sys.stdout.write.
>>>
>>> The only solution is to use the context in your handler, i.e.
>>> WRITE("hello world\n")
>>>
>>> or the more obvious (like in publisher and PSP):
>>> req.write("Hello world\n")
>>>
>>> Anything that makes use of globals to send back data to the client 
>>> will not work, so "wepi.write" is also out of the question (if wepi 
>>> is a module).
>>>
>>> -- 
>>> Mike Looijmans
>>> Philips Natlab / Topic Automation
>>>
>>>
>>> Fırat KÜÇÜK wrote:
>>>
>>>>>
>>>>>
>>>>>> import sys
>>>>>> sys.stdout.write(open('penguin.png', 'rb').read())
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> NO. NO. NO.
>>>>>
>>>>> sys.stdout is a global variable. If you want sys.stdout.write() to 
>>>>> end up in the user's terminal, your web server will be able to 
>>>>> either serve only one request at a time, or must be forced into 
>>>>> running separate processes for each concurrent request (which will 
>>>>> not happen on windows and many other supported platforms).
>>>>>
>>>>> We made that mistake with cgipython, and we won't make it again. 
>>>>> Learn from the mistakes of others, as you do not have the time to 
>>>>> make them all yourself.
>>>>>
>>>>> Mike
>>>>>
>>>>>
>>>> Hi,
>>>> but i replaced sys.stdout with a StdOut class. is it problem too?
>>>>
>>>> Fırat KÜÇÜK
>>>>
>>>>
>>>
>>>
>> Hi,
>>
>>
>> ###[StdOut 
>> class]###############################################################
>>
>> class StdOut:
>>    "replaces sys.stdout"
>>
>>    buffer = ""
>>
>>    # --------------------------------------------------[overidden 
>> methods]-----
>>
>>    ### [__init__ method]---------------
>>    def __init__(self, req, headers_object):
>>        self.req     = req
>>        self.headers = headers_object
>>
>>    # -----------------------------------------------------[public 
>> methods]-----
>>
>>    ### [write method]---------------
>>    def write(self, text): self.buffer += str(text)
>>
>>
>>
>> this is my sys.stdout replacement class and write method use buffer.
>>
>> and finally after execution of .py file
>>
>> # send buffer
>> req.write(sys.stdout.buffer)
>>
>> I think this is thread safe method for sending data.
>> print or sys.stdout.write indirectly use req.write method.
>>
>>
>> # send buffer
>> req.write(sys.stdout.buffer)
>>
>>
>
>
Hi,
Yes i understood. so we should use an alias or directly req.write for it.
or print operator have to overload.

thanks.


Re: wepy

Posted by Mike Looijmans <nl...@natlab.research.philips.com>.
Your code is perfectly thread safe, yes. But the assignment to 
sys.stdout IS NOT. There is only one sys.stdout, and all threads use the 
same one.

Example (two threads):

##Thread 1:
- initializes request from client 1
- sets sys.stdout to StdOut(request ...) object
- writes "hello1 " to sys.stdout
##Thread 2
- initializes request from client 2
- sets sys.stdout to StdOut(request ...) object
- writes "hello2 " to sys.stdout
##Thread 1
- writes "world1" to sys.stdout
- terminates, and sends sys.stdout.buffer to client
##Thread 2
- writes "world2" to sys.stdout
- terminates, and sends sys.stdout.buffer to client

Now look at what will happen with your code and a threading apache:
Client 1 will receive "hello2 world1"
Client 2 will receive "hello2 world1world2"

Explanation:

##Thread 1:
- initializes request from client 1
- sets sys.stdout to StdOut(request ...) object
- writes "hello1 " to sys.stdout
(sys.stdout.buffer == "hello1 ")
##Thread 2
- initializes request from client 2
- sets sys.stdout to StdOut(request ...) object
(and thus replaces the buffer that thread 1 put there, its contents are 
lost)
- writes "hello2 " to sys.stdout
(sys.stdout.buffer == "hello2 ")
##Thread 1
- writes "world1" to sys.stdout
(sys.stdout.buffer == "hello2 world1")
- terminates, and sends sys.stdout.buffer to client
##Thread 2
- writes "world2" to sys.stdout
(sys.stdout.buffer == "hello2 world1world2")
- terminates, and sends sys.stdout.buffer to client


Mike Looijmans
Philips Natlab / Topic Automation

Fırat KÜÇÜK wrote:
> Mike Looijmans yazmış:
> 
>> Yes,
>>
>> the problem is not whatever class or method you use to send the output 
>> to the client, but the problem is the use of the global sys.stdout 
>> variable. The is only one such object in your system. If there are two 
>> threads each handling a request, there is no telling to which one the 
>> sys.stdout.write or print statement will send its output. To prevent 
>> this, you'd have to mutex access to it, and leads to being able to 
>> handle only one request at a time.
>>
>> On many unix flavors, apache defaults to 'forking', which runs each 
>> request in a separate process. In these circumstances, you will not 
>> detect this problem. On other platforms, or if you modify the 
>> httpd.conf file, apache uses threading or even a mix of threading and 
>> forking.
>>
>> Important note: Since print sends to sys.stdout, using print is just 
>> as bad a method to send output to the client as sys.stdout.write.
>>
>> The only solution is to use the context in your handler, i.e.
>> WRITE("hello world\n")
>>
>> or the more obvious (like in publisher and PSP):
>> req.write("Hello world\n")
>>
>> Anything that makes use of globals to send back data to the client 
>> will not work, so "wepi.write" is also out of the question (if wepi is 
>> a module).
>>
>> -- 
>> Mike Looijmans
>> Philips Natlab / Topic Automation
>>
>>
>> Fırat KÜÇÜK wrote:
>>
>>>>
>>>>
>>>>> import sys
>>>>> sys.stdout.write(open('penguin.png', 'rb').read())
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> NO. NO. NO.
>>>>
>>>> sys.stdout is a global variable. If you want sys.stdout.write() to 
>>>> end up in the user's terminal, your web server will be able to 
>>>> either serve only one request at a time, or must be forced into 
>>>> running separate processes for each concurrent request (which will 
>>>> not happen on windows and many other supported platforms).
>>>>
>>>> We made that mistake with cgipython, and we won't make it again. 
>>>> Learn from the mistakes of others, as you do not have the time to 
>>>> make them all yourself.
>>>>
>>>> Mike
>>>>
>>>>
>>> Hi,
>>> but i replaced sys.stdout with a StdOut class. is it problem too?
>>>
>>> Fırat KÜÇÜK
>>>
>>>
>>
>>
> Hi,
> 
> 
> ###[StdOut 
> class]###############################################################
> 
> class StdOut:
>    "replaces sys.stdout"
> 
>    buffer = ""
> 
>    # --------------------------------------------------[overidden 
> methods]-----
> 
>    ### [__init__ method]---------------
>    def __init__(self, req, headers_object):
>        self.req     = req
>        self.headers = headers_object
> 
>    # -----------------------------------------------------[public 
> methods]-----
> 
>    ### [write method]---------------
>    def write(self, text): self.buffer += str(text)
> 
> 
> 
> this is my sys.stdout replacement class and write method use buffer.
> 
> and finally after execution of .py file
> 
> # send buffer
> req.write(sys.stdout.buffer)
> 
> I think this is thread safe method for sending data.
> print or sys.stdout.write indirectly use req.write method.
> 
> 
> # send buffer
> req.write(sys.stdout.buffer)
> 
> 


Re: wepy

Posted by Fırat KÜÇÜK <fi...@kucuk.org>.
Mike Looijmans yazmış:

> Yes,
>
> the problem is not whatever class or method you use to send the output 
> to the client, but the problem is the use of the global sys.stdout 
> variable. The is only one such object in your system. If there are two 
> threads each handling a request, there is no telling to which one the 
> sys.stdout.write or print statement will send its output. To prevent 
> this, you'd have to mutex access to it, and leads to being able to 
> handle only one request at a time.
>
> On many unix flavors, apache defaults to 'forking', which runs each 
> request in a separate process. In these circumstances, you will not 
> detect this problem. On other platforms, or if you modify the 
> httpd.conf file, apache uses threading or even a mix of threading and 
> forking.
>
> Important note: Since print sends to sys.stdout, using print is just 
> as bad a method to send output to the client as sys.stdout.write.
>
> The only solution is to use the context in your handler, i.e.
> WRITE("hello world\n")
>
> or the more obvious (like in publisher and PSP):
> req.write("Hello world\n")
>
> Anything that makes use of globals to send back data to the client 
> will not work, so "wepi.write" is also out of the question (if wepi is 
> a module).
>
> -- 
> Mike Looijmans
> Philips Natlab / Topic Automation
>
>
> Fırat KÜÇÜK wrote:
>
>>>
>>>
>>>> import sys
>>>> sys.stdout.write(open('penguin.png', 'rb').read())
>>>
>>>
>>>
>>>
>>>
>>> NO. NO. NO.
>>>
>>> sys.stdout is a global variable. If you want sys.stdout.write() to 
>>> end up in the user's terminal, your web server will be able to 
>>> either serve only one request at a time, or must be forced into 
>>> running separate processes for each concurrent request (which will 
>>> not happen on windows and many other supported platforms).
>>>
>>> We made that mistake with cgipython, and we won't make it again. 
>>> Learn from the mistakes of others, as you do not have the time to 
>>> make them all yourself.
>>>
>>> Mike
>>>
>>>
>> Hi,
>> but i replaced sys.stdout with a StdOut class. is it problem too?
>>
>> Fırat KÜÇÜK
>>
>>
>
>
Hi,


###[StdOut class]###############################################################

class StdOut:
    "replaces sys.stdout"

    buffer = ""

    # --------------------------------------------------[overidden methods]-----

    ### [__init__ method]---------------
    def __init__(self, req, headers_object):
        self.req     = req
        self.headers = headers_object

    # -----------------------------------------------------[public methods]-----

    ### [write method]---------------
    def write(self, text): self.buffer += str(text)



this is my sys.stdout replacement class and write method use buffer.

and finally after execution of .py file

# send buffer
req.write(sys.stdout.buffer)

I think this is thread safe method for sending data.
print or sys.stdout.write indirectly use req.write method.


# send buffer
req.write(sys.stdout.buffer)


Re: wepy

Posted by Mike Looijmans <nl...@natlab.research.philips.com>.
Yes,

the problem is not whatever class or method you use to send the output 
to the client, but the problem is the use of the global sys.stdout 
variable. The is only one such object in your system. If there are two 
threads each handling a request, there is no telling to which one the 
sys.stdout.write or print statement will send its output. To prevent 
this, you'd have to mutex access to it, and leads to being able to 
handle only one request at a time.

On many unix flavors, apache defaults to 'forking', which runs each 
request in a separate process. In these circumstances, you will not 
detect this problem. On other platforms, or if you modify the httpd.conf 
file, apache uses threading or even a mix of threading and forking.

Important note: Since print sends to sys.stdout, using print is just as 
bad a method to send output to the client as sys.stdout.write.

The only solution is to use the context in your handler, i.e.
WRITE("hello world\n")

or the more obvious (like in publisher and PSP):
req.write("Hello world\n")

Anything that makes use of globals to send back data to the client will 
not work, so "wepi.write" is also out of the question (if wepi is a module).

--
Mike Looijmans
Philips Natlab / Topic Automation


Fırat KÜÇÜK wrote:
>>
>>
>>> import sys
>>> sys.stdout.write(open('penguin.png', 'rb').read())
>>
>>
>>
>>
>> NO. NO. NO.
>>
>> sys.stdout is a global variable. If you want sys.stdout.write() to end 
>> up in the user's terminal, your web server will be able to either 
>> serve only one request at a time, or must be forced into running 
>> separate processes for each concurrent request (which will not happen 
>> on windows and many other supported platforms).
>>
>> We made that mistake with cgipython, and we won't make it again. Learn 
>> from the mistakes of others, as you do not have the time to make them 
>> all yourself.
>>
>> Mike
>>
>>
> Hi,
> but i replaced sys.stdout with a StdOut class. is it problem too?
> 
> Fırat KÜÇÜK
> 
> 


Re: wepy

Posted by Fırat KÜÇÜK <fi...@kucuk.org>.
>
>
>> import sys
>> sys.stdout.write(open('penguin.png', 'rb').read())
>
>
>
> NO. NO. NO.
>
> sys.stdout is a global variable. If you want sys.stdout.write() to end 
> up in the user's terminal, your web server will be able to either 
> serve only one request at a time, or must be forced into running 
> separate processes for each concurrent request (which will not happen 
> on windows and many other supported platforms).
>
> We made that mistake with cgipython, and we won't make it again. Learn 
> from the mistakes of others, as you do not have the time to make them 
> all yourself.
>
> Mike
>
>
Hi,
but i replaced sys.stdout with a StdOut class. is it problem too?

Fırat KÜÇÜK


Re: wepy

Posted by Mike Looijmans <nl...@natlab.research.philips.com>.
> import sys
> sys.stdout.write(open('penguin.png', 'rb').read())


NO. NO. NO.

sys.stdout is a global variable. If you want sys.stdout.write() to end 
up in the user's terminal, your web server will be able to either serve 
only one request at a time, or must be forced into running separate 
processes for each concurrent request (which will not happen on windows 
and many other supported platforms).

We made that mistake with cgipython, and we won't make it again. Learn 
from the mistakes of others, as you do not have the time to make them 
all yourself.

Mike