python/ruby question..

3 views
Skip to first unread message

bruce

unread,
Jun 18, 2008, 11:33:38 PM6/18/08
to pytho...@python.org
hi...

can someone point me to where/how i would go about calling a ruby app from a
python app, and having the python app being able to get a returned value
from the ruby script.

something like

test.py
a = os.exec(testruby.rb)


testruby.py
foo = 9
return foo


i know this doesn't work... but i've been searching for hours on this with
no luck.... (and yeah, i'm relatively new to both ruby/python!!)

thanks


Mensanator

unread,
Jun 19, 2008, 12:11:27 AM6/19/08
to

Well, I don't know anything about Ruby, but here's
how I do it for C programs (compiled to .exe that
write to stdout).


import os
factor_program = 'factor! -d200 ' # factor!.exe from MIRACL

n =
'50818429800343305993022114330311033271249313957919046352679206262204589342623811236647989889145173098650749'

# call external program and capture stdout
the_output = os.popen(factor_program+n).readlines()

print 'n: %s' % n
for i in the_output:
print i,

## n:
50818429800343305993022114330311033271249313957919046352679206262204589342623811236647989889145173098650749
## PRIME_FACTOR 37
## PRIME_FACTOR 43
## PRIME_FACTOR 167
## COMPOSITE_FACTOR 507787751
## PRIME_FACTOR 69847
## PRIME_FACTOR 30697
## PRIME_FACTOR 89017
## PRIME_FACTOR 3478697
## PRIME_FACTOR 434593
## PRIME_FACTOR 49998841
## PRIME_FACTOR 161610704597143
## PRIME_FACTOR 14064370273
## COMPOSITE_FACTOR 963039394703598565337297
## PRIME_FACTOR 11927295803

Matt Nordhoff

unread,
Jun 19, 2008, 6:14:11 AM6/19/08
to pytho...@python.org

<snip output>

You're supposed to use the subprocess module.

In this case, something like:

import subprocess
factor_program = ['factor!', '-d200']

...

p = subprocess.Popen(factor_program + [n], stdout=subprocess.PIPE)
p.wait() # wait for it to finish; not sure how necessary it is
the_output = p.stdout.readlines()

See subprocess's documentation [1], which includes guides on replacing
os.popen* and other functions with it.

[1] <http://docs.python.org/lib/module-subprocess.html>
--

Aahz

unread,
Jun 19, 2008, 12:49:52 PM6/19/08
to
In article <mailman.634.1213870...@python.org>,

Matt Nordhoff <mnor...@mattnordhoff.com> wrote:
>
>You're supposed to use the subprocess module.

Really? Sez who?

$ python
Python 2.3.4 (#1, Feb 2 2005, 12:11:53)
[GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ImportError: No module named subprocess
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"as long as we like the same operating system, things are cool." --piranha

Giampaolo Rodola'

unread,
Jun 19, 2008, 2:36:14 PM6/19/08
to
On 19 Giu, 18:49, a...@pythoncraft.com (Aahz) wrote:
> In article <mailman.634.1213870465.1044.python-l...@python.org>,

> Matt Nordhoff  <mnordh...@mattnordhoff.com> wrote:
>
>
>
> >You're supposed to use the subprocess module.
>
> Really?  Sez who?
>
> $ python
> Python 2.3.4 (#1, Feb  2 2005, 12:11:53)
> [GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.>>> import subprocess
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> ImportError: No module named subprocess
> --
> Aahz (a...@pythoncraft.com)           <*>        http://www.pythoncraft.com/

>
> "as long as we like the same operating system, things are cool." --piranha

That's because you're using a too old python version.


--- Giampaolo
http://code.google.com/p/pyftpdlib/

Mike Driscoll

unread,
Jun 19, 2008, 2:50:19 PM6/19/08
to
On Jun 19, 11:49 am, a...@pythoncraft.com (Aahz) wrote:
> In article <mailman.634.1213870465.1044.python-l...@python.org>,
> Matt Nordhoff  <mnordh...@mattnordhoff.com> wrote:
>
>
>
> >You're supposed to use the subprocess module.
>
> Really?  Sez who?
>
> $ python
> Python 2.3.4 (#1, Feb  2 2005, 12:11:53)
> [GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.>>> import subprocess
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> ImportError: No module named subprocess
> --
> Aahz (a...@pythoncraft.com)           <*>        http://www.pythoncraft.com/

>
> "as long as we like the same operating system, things are cool." --piranha

The subprocess module supercedes os.popen*, os.system, commands and a
few others in Python 2.4+. Thus, those others are deprecated. See the
docs here:

http://docs.python.org/lib/module-subprocess.html

Mike

Mensanator

unread,
Jun 19, 2008, 4:47:13 PM6/19/08
to
On Jun 19, 5:14 am, Matt Nordhoff <mnordh...@mattnordhoff.com> wrote:
> Mensanator wrote:

> You're supposed to use the subprocess module.

Yeah, I know, but I couldn't get it to work the last
time I tried it.

>
> In this case, something like:
>
> import subprocess
> factor_program = ['factor!', '-d200']
>
> ...
>
> p = subprocess.Popen(factor_program + [n], stdout=subprocess.PIPE)
> p.wait() # wait for it to finish; not sure how necessary it is
> the_output = p.stdout.readlines()

Just like how this doesn't work either:

Traceback (most recent call last):

File "C:\Program Files\PyGTK\Python\user\factor_timing.py", line 26,
in <module>
p = subprocess.Popen(factor_program + [the_comp[1]],
stdout=subprocess.PIPE)
File "C:\Program Files\PyGTK\Python\lib\subprocess.py", line 586, in
__init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Program Files\PyGTK\Python\lib\subprocess.py", line 681, in
_get_handles
p2cread = self._make_inheritable(p2cread)
File "C:\Program Files\PyGTK\Python\lib\subprocess.py", line 722, in
_make_inheritable
DUPLICATE_SAME_ACCESS)
TypeError: an integer is required

>
> See subprocess's documentation [1], which includes guides on replacing
> os.popen* and other functions with it.

I have seen it - it's utterly incomprehensible.

What do you suppose you did wrong?

The complete program (with the deprecated code commented out -
which works, BTW):


#import os
import time
import subprocess

#factor_program = 'factor! -d200 '


factor_program = ['factor!','-d200']

the_composites =
[['COMPOSITE_FACTOR','50818429800343305993022114330311033271249313957919046352679206262204589342623811236647989889145173098650749']]

the_primes = []
the_intractables = []

phase = 1
the_times = []
while the_composites:
print "="*40
print 'Phase',phase
the_comp = the_composites.pop(0)
print the_comp
print
the_times.append(time.time()) # time how long it takes to run
factor!.exe

#the_output = os.popen(factor_program+the_comp[1]).readlines()
# change to subprocess
p = subprocess.Popen(factor_program + [the_comp[1]],
stdout=subprocess.PIPE)
p.wait()
the_output = p.stdout.readlines()

the_times.append(time.time())
new_factors = [i.split() for i in the_output]
for i in new_factors: print i
print
if len(new_factors) == 1:
if new_factors[0][0] == 'PRIME_FACTOR':
the_primes.append([new_factors[0][0],long(new_factors[0][1])])
else:
the_intractables.append([new_factors[0][0],long(new_factors[0]
[1])])
new_factors.pop()
while new_factors:
j = new_factors.pop(0)
if j[0] == 'PRIME_FACTOR':
the_primes.append([j[0],long(j[1])])
else:
the_composites.append(j)
print the_times[phase] - the_times[phase-1],'seconds'
phase += 1

print "="*40
print
print 'Factoring complete'
print

the_primes.sort()
the_intractables.sort()
the_primes.extend(the_intractables)

for i in the_primes:
print i[0],i[1]
print
print "="*40

When working, it produces:


## ========================================
## Phase 1
## ['COMPOSITE_FACTOR',
'50818429800343305993022114330311033271249313957919046352679206262204589342623811236647989889145173098650749']
##
## ['PRIME_FACTOR', '37']
## ['PRIME_FACTOR', '43']
## ['PRIME_FACTOR', '167']
## ['COMPOSITE_FACTOR', '507787751']
## ['PRIME_FACTOR', '69847']
## ['PRIME_FACTOR', '30697']
## ['PRIME_FACTOR', '89017']
## ['PRIME_FACTOR', '3478697']
## ['PRIME_FACTOR', '434593']
## ['PRIME_FACTOR', '49998841']
## ['PRIME_FACTOR', '161610704597143']
## ['PRIME_FACTOR', '14064370273']
## ['COMPOSITE_FACTOR', '963039394703598565337297']
## ['PRIME_FACTOR', '11927295803']
##
## 0.860000133514 seconds
## ========================================
## Phase 2
## ['COMPOSITE_FACTOR', '507787751']
##
## ['PRIME_FACTOR', '29819']
## ['PRIME_FACTOR', '17029']
##
## 0.0780000686646 seconds
## ========================================
## Phase 3
## ['COMPOSITE_FACTOR', '963039394703598565337297']
##
## ['PRIME_FACTOR', '518069464441']
## ['PRIME_FACTOR', '1858900129817']
##
## 0.0469999313354 seconds
## ========================================
##
## Factoring complete
##


## PRIME_FACTOR 37
## PRIME_FACTOR 43
## PRIME_FACTOR 167

## PRIME_FACTOR 17029
## PRIME_FACTOR 29819
## PRIME_FACTOR 30697
## PRIME_FACTOR 69847
## PRIME_FACTOR 89017
## PRIME_FACTOR 434593
## PRIME_FACTOR 3478697
## PRIME_FACTOR 49998841
## PRIME_FACTOR 11927295803
## PRIME_FACTOR 14064370273
## PRIME_FACTOR 518069464441
## PRIME_FACTOR 1858900129817
## PRIME_FACTOR 161610704597143
##
## ========================================

Matimus

unread,
Jun 19, 2008, 7:00:13 PM6/19/08
to

Both Ruby and Python appear to support XMLRPC. I haven't used XMLRPC
in Ruby, but in general you create a server and expose some functions.
On the client end (Python) you would do something like this (assuming
you are serving on port 8050):

import xmlrpclib

rubyserver = xmlrpclib.Server("http://localhost:8050")
x = rubyserver.foo(1,2,3)

where 'foo' is a function served by the ruby server and x is its
return value.

some links:

http://www.ruby-doc.org/stdlib/libdoc/xmlrpc/rdoc/index.html

Good python server and client examples on this page:

http://docs.python.org/lib/simple-xmlrpc-servers.html

I can't be of much help for ruby, and that link doesn't seem to help
much other than to say 1. it exists and 2. its easy.

Matt

Matimus

unread,
Jun 19, 2008, 7:23:57 PM6/19/08
to

Here is a more complete example.

The ruby server code:

require "xmlrpc/server"

s = XMLRPC::Server.new(8080)

s.add_handler("add") do |a,b|
a + b
end

s.add_handler("div") do |a,b|
if b == 0
raise XMLRPC::FaultException.new(1, "division by zero")
else
a / b
end
end

s.set_default_handler do |name, *args|
raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
" or wrong number of parameters!")
end

s.serve

I put the above code into a file xmlrpctest.rb and ran it at the
command line. Then I opened the python interpreter in a separate
window and did this:

>>> s = xmlrpclib.Server("http://localhost:8080")
>>> s.div(100,2.0)
50.0
>>> s.add(100000, 2)
100002
>>>

In the long run you may still want to use the subprocess module to
launch the ruby xmlrpc server, but once you do that communicating
between the two processes should be pretty simple.

Matt

Paul McGuire

unread,
Jun 19, 2008, 9:27:05 PM6/19/08
to
On Jun 18, 10:33 pm, "bruce" <bedoug...@earthlink.net> wrote:
> hi...
>
> can someone point me to where/how i would go about calling a ruby app from a
> python app, and having the python app being able to get a returned value
> from the ruby script.
>

I'm betting that Ruby is similar to Python in that a Ruby interpreter
can be embedded within other applications. Why not implement
something like ruby_exec(), similar to Python's exec, which takes a
string containing Ruby code, and a dict of variables that can be
accessed and updated from the executed Ruby? Then no messing around
with subprocess, XMLRPC, firing up processes, etc. - just create the
string and call it.

(Implementation left as an exercise for the reader.)

-- Paul

bruce

unread,
Jun 19, 2008, 10:10:06 PM6/19/08
to Paul McGuire, pytho...@python.org
hey guys...

i managed to solve what i was attempting.. my goal was rather simple, to be
able to have a python script, call a ruby app, and be able to return a
value from the ruby (child) app to the parent.. blocking/unblocking wasn't
on my radar for now.

ultimately, my goal is to have an app on a master server, with that app
calling the ruby app using the remote functions (rsh/rexec for now).

so, on the master python, i have:
#!/usr/bin/python

#test python script
import re
import os
import sys, string
import os.path
import subprocess

#print "foo"
pp="http://siteanalytics.compete.com/xxxx/?metrics=uv"

a = subprocess.Popen(["/test1/test.rb",pp], stdout=subprocess.PIPE)
aa=a.communicate()[0]
qq=aa.split("\n")
print "qq[8] = ",qq[8]
print "qq[9] = ",qq[9]
print "qq[10] = ",qq[10]
#exit()

and on the child/ruby app:
#! /usr/local/bin/ruby

require 'rubygems'
require '/usr/local/lib/ruby/gems/1.8/gems/firewatir-1.1.1/firewatir'
include FireWatir

a1=ARGV[0]

ff=Firefox.new
ff.goto(a1)
table = ff.table(:id, "dataTable").to_a
#puts table
#puts "blah...."
aa = table[1][1]
puts table[1][1]

#ff.text_field(:name, "q").set("ruby")
#ff.button(:value,"Google Search").click
#puts ff.element_by_xpath("//a[@class='l']").text
#ff.close
#puts "hi there"
#return (33)


this pretty much works as it needs to for now...

like i said.. rather simple, as it should be.

so thanks for the help/suggestions from everyone!

-- Paul
--
http://mail.python.org/mailman/listinfo/python-list

Aahz

unread,
Jun 19, 2008, 11:52:15 PM6/19/08
to
In article <86781600-4100-4413...@f24g2000prh.googlegroups.com>,

Giampaolo Rodola' <gne...@gmail.com> wrote:
>On 19 Giu, 18:49, a...@pythoncraft.com (Aahz) wrote:
>> In article <mailman.634.1213870465.1044.python-l...@python.org>,
>> Matt Nordhoff =A0<mnordh...@mattnordhoff.com> wrote:
>>
>>>You're supposed to use the subprocess module.
>>
>> Really? =A0Sez who?
>>
>> $ python
>> Python 2.3.4 (#1, Feb =A02 2005, 12:11:53)

>> [GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)] on linux2
>> Type "help", "copyright", "credits" or "license" for more information.>>>=

> import subprocess
>>
>> Traceback (most recent call last):
>> =A0 File "<stdin>", line 1, in ?

>> ImportError: No module named subprocess
>
>That's because you're using a too old python version.

Who died and made you BDFL to decree that?
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

Reply all
Reply to author
Forward
0 new messages