How to integrate a standalone Python script into a Rails application?
Your index
method does not work because python --version
outputs its version to STDERR, not STDOUT. If you don't need to separate these streams, you may just redirect STDERR to STDOUT:
value = %x(python --version 2>&1)
This call is synchronous, so after running the script (python do_work.py foo bar 2>&1
), you should be able to read the files produced by it.
If the script is not able to create the files for some reason, you will now see the exception in the value
variable because error messages are usually sent to STDERR.
If you want to separate STDERR from STDOUT, use the Open3 module.
Beware that the script takes some time to run, so the calls may overlap. I would use a queue here to prevent this.
And don't forget to check the data the user enters. Never pass it directly to the script.
How to Run a Python Script from a Rails Application?
Here are ways to execute a shell script
`python pythonscript.py`
or
system( "python pythonscript.py" )
or
exec(" python pythonscript.py")
exec replaces the current process by running the given external command.
Returns none, the current process is replaced and never continues.
Run python from a click event in ruby
Check this SO post: Call python script from ruby
ruby provides a variety of methods, exec
, system
that all take the path to the ,py
file along with arguments. Something like
result = exec("python /path/to/script/script.py params")
Or
system 'python /path/to/script/script.py', params1, params2
Or even backquotes
`python /path/to/script/script.py foo bar`
Now, the question is where to put this? I am assuming you have a controller that handles clicks, and it is this controller where you put this code. Check this link out How to integrate a standalone Python script into a Rails application?
Now details depend a lot on your python script. By 'alert script', do you mean a Javascript alert() dialog, a flash msg or anything else? It's always a good idea to refactor your python code to return a string result and the use that in ruby-on-rails. Even better, as far as possible, write the alert-creating-script in ruby itself! It might not be possible in a 3rd-party library setting, but for a simple stand-alone script, it's worth the effort!
Integrating scientific python into an existing Rails webapp
In lieu of substantially hacking apart either codebase to fit the other, I would first propose you evaluate an SOA solution.
e.g. create an API interface to your Python system, and have
the Rails app call that API for what the HR and public-site systems
require.
Call Rails 4 param in Python script
well you could just pass them as command line arguments to your script. %x
does string interpolation, but you need to be careful and verify the input since someone could pass params[:contest_url] = " && rm -rf / "
or something similar into your script and cause you problems(never trust user input) So the Shellwords (http://ruby-doc.org/stdlib-2.0/libdoc/shellwords/rdoc/Shellwords.html) class can help. Perhaps something like.
value = %x(/Users/my/Desktop/rails_test.py #{Shellwords.escape(params[:site])} #{Shellwords.escape(params[:contest_url])} 2>&1)
Then just make your python script read the values via STDIN
#!/usr/bin/env python
import sys
print "Site: ", sys.argv[1]
print "Url: ", sys.argv[2]
I made your python scripts shebang call /usr/bin/env python
, but if python isn't in the path of the user that your rails app is running as you might need the full path. Also you don't need a /bin/bash
at the top of your python script if you are calling it as an argument to the python executable.
Call python script from ruby
One way would be exec.
result = exec("python script.py params")
Creating a standalone HTTP server to invoke a URL
You can write a Flask app, see their hello tutorial:
https://flask.palletsprojects.com/en/1.1.x/tutorial/factory/
with the below code.
import os, requests
from flask import Flask, request
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
@app.route('/')
def hello():
url = request.args.get('url')
response = requests.get(url)
return "Response: " + response.text
return app
Autoloading a bunch of small classes
You can let a particular file be loaded only when a particular module is accessed by using the Kernel#autoload
method.
autoload(:Foo, "foo.rb")
autoload(:Bar, "bar.rb")
...
Related Topics
Variable Assignment and Modification (In Python)
How to Check If Any Value Is Nan in a Pandas Dataframe
Python Script for Minifying CSS
Why Is Ruby More Suitable for Rails Than Python
Why Can't Python Find Shared Objects That Are in Directories in Sys.Path
Possible to Share In-Memory Data Between 2 Separate Processes
What Is the Good Python3 Equivalent for Auto Tuple Unpacking in Lambda
Python Giving Filenotfounderror for File Name Returned by Os.Listdir
How to Refer to Relative Paths of Resources When Working with a Code Repository
How to Get Exit Code When Using Python Subprocess Communicate Method
Python Sockets Error Typeerror: a Bytes-Like Object Is Required, Not 'Str' with Send Function
Why Doesn't This Division Work in Python
Python MySQL Connector Database Query with %S Fails
Moving Balls in Tkinter Canvas
Fast Way of Counting Non-Zero Bits in Positive Integer