468,549 Members | 1,974 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,549 developers. It's quick & easy.

Return a string result with out breaking loop

Hi I was wondering if there is anyway with XML RPC to send a string of
text from the server to the client with out calling return thus breaking
my loop

for example

def somefunc():
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
out2 = str(full_filename) + " " + str(theact)
return out2

the return statement will return a result breaking my loop. My goal is
to have it continue looping and updating the client

any ideas?

Cheers

Andrew

Thanks in advance

Pyhon 2.5.2

Windows XP
Aug 25 '08 #1
13 2086
Andrew wrote:
Hi I was wondering if there is anyway with XML RPC to send a string of
text from the server to the client with out calling return thus breaking
my loop

for example

def somefunc():
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
out2 = str(full_filename) + " " + str(theact)
return out2

the return statement will return a result breaking my loop. My goal is
to have it continue looping and updating the client

any ideas?
Yes, use yield instead of return. It turns the function into a generator.

Christian

Aug 26 '08 #2
Hi Ive been trying with yield all day and other different things :D

but I always get the same result using yield

Fault: <Fault 1: "<type 'exceptions.TypeError'>:cannot marshal <type
'generator'
objects">
I'm not sure exactly what I am doing wrong as this is the first time Ive
used yield

Any suggestions on how to fix this error

Cheers

Andrew
Christian Heimes wrote:
Andrew wrote:
>Hi I was wondering if there is anyway with XML RPC to send a string of
text from the server to the client with out calling return thus
breaking my loop

for example

def somefunc():
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
out2 = str(full_filename) + " " + str(theact)
return out2

the return statement will return a result breaking my loop. My goal is
to have it continue looping and updating the client

any ideas?

Yes, use yield instead of return. It turns the function into a generator.

Christian
Aug 26 '08 #3
cnb
def somefunc():
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
yield str(full_filename) + " " + str(theact)

?
Here is an example if that doesn't work, using yield, to show how to
use yield:
def yi(x):
while x 0:
yield str(x)
x -= 1

>>yi(4)
<generator object at 0x01FA3C88>
>>a=yi(4)
a.next()
'4'
>>a.next()
'3'
>>a.next()
'2'
>>a.next()
'1'
>>a.next()
Traceback (most recent call last):
File "<pyshell#151>", line 1, in <module>
a.next()
StopIteration
>>>
Aug 26 '08 #4
cnb
On Aug 26, 2:50*am, cnb <circularf...@yahoo.sewrote:
def somefunc():
* * * *for action, files in results:
* * * * * * * *full_filename = os.path.join(path_to_watch, files)
* * * * * * * *theact = ACTIONS.get(action, "Unknown")
* * * * * * * *yield *str(full_filename) + *" " + str(theact)

?

Here is an example if that doesn't work, using yield, to show how to
use yield:
def yi(x):
* * * * while x 0:
* * * * * * * * yield str(x)
* * * * * * * * x -= 1
>yi(4)

<generator object at 0x01FA3C88>
>a=yi(4)
a.next()
'4'
>a.next()
'3'
>a.next()
'2'
>a.next()
'1'
>a.next()

Traceback (most recent call last):
* File "<pyshell#151>", line 1, in <module>
* * a.next()
StopIteration


you can also do:
def yi(x):
while x 0:
yield str(x)
x -= 1
>>a = yi(10)
for x in a:
print x
10
9
8
7
6
5
4
3
2
1
>>>
Aug 26 '08 #5
Yes I found many examples similiar to that but Yield still produces that
error

Sorry if I sound Novice but I have no formal education in programming so
understanding something takes me a bit longer than most of you guys :-D

Ive included a bit more of the function

How ever unimportant it may be
def watchos(self, path_to_watch="C:\\"):
FILE_LIST_DIRECTORY = 0x0001
try: path_to_watch or "."
except: path_to_watch = "."
path_to_watch = os.path.abspath(path_to_watch)

out1 = "Watching %s at %s" % (path_to_watch, time.asctime()) + "\n\n"
while 1:

#INSERT MORE CODE HERE

results = change_handle
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
yield str(full_filename) + " " + str(theact)

But I am having a hard time wrapping my head around yield... perhaps if
it produced more than the same error no matter what I did. I could try
and get a bit further

Anyway once again I appreciate the help cheers

:-)
Aug 26 '08 #6
cnb
ok post exactly what you do when this hapens:
ault: <Fault 1: "<type 'exceptions.TypeError'>:cannot marshal <type
'generator'
objects">
it complains you are trying to marshal a generator object rather than
the file you are yielding.

also, something I am not sure about:
>>def f(x):
try: open("C:/ruby/progs/blandat/infixtoprefix.rb") or open(str(x))
except:print "hello"

>>f(12)
def f(x):
try: (open(str(x)) or open("C:/ruby/progs/blandat/infixtoprefix.rb"))
except:print "hello"

>>f(12)
hello
>>>
the or doesnt seem to work as expected. but thats not the problem youa
re experienceing
Aug 26 '08 #7
I run the server then execute the client. From the client I execute the
function key.watchos()

My goal is an administration tool

and this is just a function in my goal :-)

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Maboroshi>python C:\software\mabssystem\client.py
Use the keyword, "key" to interact with the server
>>key.watchos()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python25\lib\xmlrpclib.py", line 1147, in __call__
return self.__send(self.__name, args)
File "C:\Python25\lib\xmlrpclib.py", line 1437, in __request
verbose=self.__verbose
File "C:\Python25\lib\xmlrpclib.py", line 1201, in request
return self._parse_response(h.getfile(), sock)
File "C:\Python25\lib\xmlrpclib.py", line 1340, in _parse_response
return u.close()
File "C:\Python25\lib\xmlrpclib.py", line 787, in close
raise Fault(**self._stack[0])
Fault: <Fault 1: "<type 'exceptions.TypeError'>:cannot marshal <type
'generator'
objects">
>>>
the function watchos is basically based off of Tim Goldens Directory
watching app

the function is as follows in entirety

def watchos(self, path_to_watch="C:\\"):
#get path or maintain current path of app
FILE_LIST_DIRECTORY = 0x0001
try: path_to_watch or "."
except: path_to_watch = "."
path_to_watch = os.path.abspath(path_to_watch)

out1 = "Watching %s at %s" % (path_to_watch, time.asctime()) +
"\n\n"
# FindFirstChangeNotification sets up a handle for watching
# file changes.
while 1:

hDir = win32file.CreateFile (
path_to_watch,
FILE_LIST_DIRECTORY,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
win32con.FILE_FLAG_BACKUP_SEMANTICS,
None
)

change_handle = win32file.ReadDirectoryChangesW (
hDir,
1024,
True,#Heap Size include_subdirectories,
win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
win32con.FILE_NOTIFY_CHANGE_SIZE |
win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
win32con.FILE_NOTIFY_CHANGE_SECURITY,
None,
None
)

# Loop forever, listing any file changes. The WaitFor... will
# time out every half a second allowing for keyboard
interrupts
# to terminate the loop.
ACTIONS = {
1 : "Created",
2 : "Deleted",
3 : "Updated",
4 : "Renamed from something",
5 : "Renamed to something"
}

results = change_handle
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
yield str(full_filename) + " " + str(theact)
and the rpc client is as follows

import xmlrpclib, code

# Specify IP of Server here defualt port is 9000
url = "http://127.0.0.1:8888"
sock = xmlrpclib.ServerProxy(url, allow_none=True, verbose=0)
# use the interactive console to interact example "key.keyit()" will
start the logger
interp = code.InteractiveConsole({'key': sock})
interp.interact("Use the keyword, \"key\" to interact with the server")

Sorry if I posted to much code :-)

Thank you in advance
Aug 26 '08 #8
On Aug 26, 12:14*pm, Andrew <nob...@yahoo.comwrote:
I run the server then execute the client. From the client I execute the
function key.watchos()
Sorry if I posted to much code :-)
The problem is the Python implementation of XML-RPC _can't_ send
generators (which is what the 'unable to marshal' error is telling
you). From the docs:

"Types that are conformable (e.g. that can be marshalled through XML),
include the following (and except where noted, they are unmarshalled
as the same Python type): [boolean, integers, floating-point numbers,
strings, arrays, structures (dicts), dates, binary dates]"

I'm not sure how to easily fix this to achieve what you want, though.
Aug 26 '08 #9
On Aug 25, 6:37*pm, Andrew <nob...@yahoo.comwrote:
Hi I was wondering if there is anyway with XML RPC to send a string of
text from the server to the client with out calling return thus breaking
* my loop

for example

* def somefunc():
* * * *for action, files in results:
* * * * * * * *full_filename = os.path.join(path_to_watch, files)
* * * * * * * *theact = ACTIONS.get(action, "Unknown")
* * * * * * * *out2 = *str(full_filename) + *" " + str(theact)
* * * * * * * *return out2

the return statement will return a result breaking my loop. My goal is
to have it continue looping and updating the client

any ideas?

Cheers

Andrew

Thanks in advance

Pyhon 2.5.2

Windows XP
Andrew,

I have generators working on both sides of a SimpleXMLRPCServer
instance. You ask for a server-side generator, and I won't post the
whole program, as it's long, so here's an important part:

server = SimpleXMLRPCServer(("localhost", 8000))
server.register_introspection_functions()

def gen( ):
while 1:
yield 1
yield 2
yield 3

servg= gen( )
server.register_function( servg.next, 'gen' )

Called 's.gen( )' four times, output:

localhost - - [25/Aug/2008 23:08:28] "POST /RPC2 HTTP/1.0" 200 -
1
localhost - - [25/Aug/2008 23:08:29] "POST /RPC2 HTTP/1.0" 200 -
2
localhost - - [25/Aug/2008 23:08:30] "POST /RPC2 HTTP/1.0" 200 -
3
localhost - - [25/Aug/2008 23:08:31] "POST /RPC2 HTTP/1.0" 200 -
1

As expected. I guess that your problem was on this line:

server.register_function( servg.next, 'gen' )

where instead you just wrote

server.register_function( servg, 'gen' ) #wrong

or perhaps even

server.register_function( gen, 'gen' ) #wrong

I'll offer an explanation of the difference too, for the asking.
Aug 26 '08 #10
Hi I have done this without error

:D

Yield returns the result I am looking for... however it does not
continue looping. It does the same thing as return would

any suggestions

my code is as follows

serveraddr = ('', 8888)
srvr = ThreadingServer(serveraddr, SimpleXMLRPCRequestHandler,
allow_none=True)

srvr.register_instance(theApp())

srvr.register_introspection_functions()

def watchos(path_to_watch="C:\\"):
#get path or maintain current path of app
FILE_LIST_DIRECTORY = 0x0001
try: path_to_watch or "."
except: path_to_watch = "."
path_to_watch = os.path.abspath(path_to_watch)

out1 = "Watching %s at %s" % (path_to_watch, time.asctime()) + "\n\n"
# FindFirstChangeNotification sets up a handle for watching
# file changes.
while 1:

hDir = win32file.CreateFile (
path_to_watch,
FILE_LIST_DIRECTORY,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
win32con.FILE_FLAG_BACKUP_SEMANTICS,
None
)

change_handle = win32file.ReadDirectoryChangesW (
hDir,
1024,
True,#Heap Size include_subdirectories,
win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
win32con.FILE_NOTIFY_CHANGE_SIZE |
win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
win32con.FILE_NOTIFY_CHANGE_SECURITY,
None,
None
)

# Loop forever, listing any file changes. The WaitFor... will
# time out every half a second allowing for keyboard interrupts
# to terminate the loop.
ACTIONS = {
1 : "Created",
2 : "Deleted",
3 : "Updated",
4 : "Renamed from something",
5 : "Renamed to something"
}

results = change_handle
for action, files in results:
full_filename = os.path.join(path_to_watch, files)
theact = ACTIONS.get(action, "Unknown")
out2 = str(full_filename) + " " + str(theact)
yield str(out2)

servg = watchos()
srvr.register_function(servg.next, 'watchos')

srvr.register_multicall_functions()
srvr.serve_forever()
Aug 26 '08 #11
Andrew wrote:
Yield returns the result I am looking for... however it does not
continue looping. It does the same thing as return would
the XML-RPC protocol doesn't really support your use case; for each
call, the client issues a complete request package, and the server
produces a complete response in return.

</F>

Aug 26 '08 #12
mmk guess I will have to look for alternate solutions for this project.
Thank you all for your help

cheers Andrew!

Fredrik Lundh wrote:
Andrew wrote:
>Yield returns the result I am looking for... however it does not
continue looping. It does the same thing as return would

the XML-RPC protocol doesn't really support your use case; for each
call, the client issues a complete request package, and the server
produces a complete response in return.

</F>
Aug 27 '08 #13
On Aug 26, 11:46*am, Andrew <nob...@yahoo.comwrote:
...
* * * * *results = change_handle
* * * * *for action, files in results:
* * * * * * *full_filename = os.path.join(path_to_watch, files)
* * * * * * *theact = ACTIONS.get(action, "Unknown")
* * * * * * *out2 = str(full_filename) + *" " + str(theact)
* * * * *yield str(out2)
I think you have the yield in the wrong place. Should you tab it over
one?
Aug 27 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Mike Copeland | last post: by
30 posts views Thread by John Bailo | last post: by
4 posts views Thread by OutdoorGuy | last post: by
3 posts views Thread by Dominique Vandensteen | last post: by
18 posts views Thread by Pedro Pinto | last post: by
18 posts views Thread by terminator(jam) | last post: by
11 posts views Thread by =?Utf-8?B?Um9nZXIgVHJhbmNoZXo=?= | last post: by
12 posts views Thread by Matt B | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by UniDue | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.