I have a Python program that is run on the command line. It uses raw_input() to read a string from the user's keyboard. I'd like to make the program available on Google App Engine and want to use the App Engine Shell since it has a command prompt.
However, the shell seems to provide a "fake" prompt, and when I use raw_input() in my program, it just returns EOF.
Do you have any tips on what to use instead of raw_input(), or of alternative ways to make interactive console python apps available? (It doesn't have to be fancy curs开发者_如何学Ces stuff or anything, just read-a-buffered-string-stuff.)
EDIT: The program is an online adventure like Zork http://thcnet.net/error/index.php
The Python source for that application is available on Google Code for you to study, or reuse. raw_input() has probably been disabled for security reasons and always returns EOF.
This shell uses an AJAX interface and is simply grabbing the code from the input area and parsing it. See shell.js in the repository:
/**
* This is the prompt textarea's onkeypress handler. Depending on the key that
* was pressed, it will run the statement, navigate the history, or update the
* current statement in the history.
*
* @param {Event} event the keypress event
* @return {Boolean} false to tell the browser not to submit the form.
*/
shell.onPromptKeyPress = function(event) {
var statement = document.getElementById('statement');
if (this.historyCursor == this.history.length - 1) {
// we're on the current statement. update it in the history before doing
// anything.
this.history[this.historyCursor] = statement.value;
}
// should we pull something from the history?
if (event.ctrlKey && event.keyCode == 38 /* up arrow */) {
if (this.historyCursor > 0) {
statement.value = this.history[--this.historyCursor];
}
return false;
} else if (event.ctrlKey && event.keyCode == 40 /* down arrow */) {
if (this.historyCursor < this.history.length - 1) {
statement.value = this.history[++this.historyCursor];
}
return false;
} else if (!event.altKey) {
// probably changing the statement. update it in the history.
this.historyCursor = this.history.length - 1;
this.history[this.historyCursor] = statement.value;
}
// should we submit?
if (event.keyCode == 13 /* enter */ && !event.altKey && !event.shiftKey) {
return this.runStatement();
}
};
Looks like the App Engine shell doesn't bind stdin to the AJAX connection with the browser, which is used to exchange commands and results. In other words you cannot use it to achieve your goal.
Instead of exposing the command line interface over the web (which doesn't sound like a good idea), I would create a simple form-based wrapper which acts as a front-end to the underlying command-line program.
I solved the problem by turning the program into a generator.
Example code can be found at https://github.com/larsr/consoleapp
You can try it out here http://pyconsoleapp.appspot.com/
The program is stored in prog.py and had to be modified a little; replacing the raw_input()
with yields and the prints with a modified print. The App Engine handler sends in the input from an HTML form into the generator with generator.send(input) which is "returned" by the yield statement.
while True:
print "What's your name?"
name = raw_input()
print "Hello "+name+"!"
print
has to be modified into
from appconsole import myprint, printoutput
def prog_gen(namn=""):
while True:
myprint("What's your name?")
name = yield printoutput()
myprint("Hello "+name+"!")
myprint()
精彩评论