I'm having some problems accessing http requests' bodies with the CherryPy framework.
I'm using CherryPy 3.2.0 on a x86_64 Arch Linux machine w/ Python3 and Aptana Web Studio IDE.
When I try to access a request's body via the usual cherrypy.request.body.read(), i get the error
File "/usr/lib/python3.2/site-packages/cherrypy/_cpreqbody.py", line 450, in read
return self.fp.read(size, fp_out)
TypeError: read() takes at most 2 positional arguments (3 given)
The code causing the error is:
import cherrypy
class Test:
def index(self):
print(cherrypy.request.body.read())
#print(cherrypy.request.body.readline()) <- this works!
return 'HelloWorld'
index.exposed = True
if __name__ == '__main__':
cherrypy.quickstart(Test())
However, using
cherrypy.request.body.readline() or cherrypy.request.body.readlines(n)
instead of
cherrypy.request.body.read()
i can skim through the request's body just fine. I tried googling for a solution but found none. Considering i'm a total python newbie, there must be something i am doing wrong, but what?
Thanks in advance for your precious help.
The body.read() method works properly only if the request body was processed, which happens only when request.process_request_body is True (it is by default) and when the request method is in request.method_with_bodies which is only PUT and POST by default, but not GET (which you probably used when requesting the page with a browser).
Related
I feel like I'm missing something real basic here, but looking up documentations, references and posts did not get me to any solution, so here goes:
I write Python code, install the functions-framework module and run the command on the terminal to start serving the script
The first curl call returns the expected value of my script ("Hello, World!", for example)
If I make any changes to the code ("Goodbye, World!"), the first values keeps been returned when curl'd
If I re-start the service, it returns the second value as expected
This happens in both Windows command line and Git Bash
I did re-install the module before trying again
Assuming that the module would've been developed to keep track of the source code update and return the last saved version of the code, can anyone help me understand where I'm messing up?
Thanks everybody for the attention!
-- Resources ---
1st code
import functions_framework
#functions_framework.http
def hello(requests):
return 'Hello, World'
2nd code
import functions_framework
#functions_framework.http
def hello(requests):
return 'Goodbye, World'
Framework call command
functions-framework --target=hello
Curl command
curl http://localhost:8080
I feel like I'm running into a brick wall, as I'm not getting anywhere with this, and I believe, simple task.
I'm trying to generate a URL by the likes of '/path/to/url', but upon gazing at multiple StackOverflow Q&A's, the official documentation for cherrypy, I still cannot seem to wrap my head around the issue.
Here's my code so far:
import details
import input_checker as input
import time
import cherrypy
class Index(object):
#cherrypy.expose
def input(self):
return input.check_input()
#cherrypy.expose
def stream(self):
while True:
return 'Hey'
#return input.check_input()
time.sleep(3)
if __name__ == '__main__':
index = Index()
cherrypy.tree.mount(index.stream(), '/input/stream', {})
cherrypy.config.update(
{'server.socket_host': '0.0.0.0'})
cherrypy.quickstart(index)
So essentially, I want to be able to visit http://127.0.0.1:8080/input/stream, and I will be returned with the given result.
After executing this code, and multiple variants of it, I'm still being returned with a 404 not found error, and I'm not sure what I need to do, in order to get it working.
Any tips and/or supporting documentation that I may have skimmed over?
Thanks guys.
So there are couple problems here, why do you use MethodDispatcher do you actually need it?
To serve you stream function on /input/stream you have to mount it as such:
cherrypy.tree.mount(index.stream(), '/input/stream', your_config)
note /input/stream instead of /stream.
But because you're using MethodDispatcher this will likely make your endpoint return 405 as GET is not allowed on this endpoint - to fix that just remove the MethodDispatcher bit.
But if you do require MethodDispatcher you will have to refactor a bit to something like that:
class Stream:
exposed = True # to let cherrypy know that we're exposing all methods in this one
def GET(self):
return something
stream = Stream()
cherrypy.tree.mount(stream , '/index/stream',
{'/':
{'request.dispatch': cherrypy.dispatch.MethodDispatcher()}
}
)
Also make sure to not actually call your methods when mounting them into cherrypy tree, just pass in the name of the function/class
I have some years of solid experience working with asterisk but am new to python.
I want to connect from a python script and receive some events. I have created a manager user with AMIUSERNAME and AMIPASSWORD as credentials and tested working OK. I have also installed StarPy.
Then I run with the command python ami.py USERNAME PASSWORD the following script:
import sys
from starpy import manager
f = manager.AMIFactory(sys.argv[1], sys.argv[2])
df = f.login('127.0.0.1',5038)
While monitoring the asterisk console and nothing happens.
Does anyone know what I am missing?
I would like to send a Ping action and wait for a Pong response.
I suppose that f.login() returns you an AMIProtocol instance that has a ping() method.
I don't know anything about starpy, so some vague advice:
Start Python as an interactive shell. Execute code and examine results on the spot. help function is your friend; try help(df) after the last line of your script.
Look at the examples directory in starpy distribution. Maybe 90% of the code you need is already there.
The following is pulled from the ami module (and a few other places) in the Asterisk Test Suite. We use starpy extensively throughout the Test Suite, so you may want to check it out for some examples. Assume that the following code resides in some class with member method login.
def login(self):
def on_login_success(self, ami):
self.ami_factory.ping().addCallback(ping_response)
return ami
def on_login_error(self, reason):
print "Failed to log into AMI"
return reason
def ping_response(self, ami)
print "Got a ping response!"
return ami
self.ami_factory = manager.AMIFactory("user", "mysecret")
self.ami_factory.login("127.0.0.1", 5038).addCallbacks(on_login_success, on_login_error)
Make sure as well that your manager.conf is configured properly. For the Asterisk Test Suite, we use the following:
[general]
enabled = yes
webenabled = yes
port = 5038
bindaddr = 127.0.0.1
[user]
secret = mysecret
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan,test
write = system,call,agent,user,config,command,reporting,originate
I've mod_python running on Apapche 2 server.
When hello.py contains:
test
Python gives an error:
NameError: name 'test' is not defined
When I replace content above with
from mod_python import apache
def handler(req):
req.content_type = 'text/plain'
req.write("Hello World!")
return apache.OK
I get an 404 - file not found error.
Why is this and how can I get a python script running?
The first error is obvious: there's no variable named "test"... (incidentally, this "silly" error was good for something... see below)
For the second (I'm assuming you're using mod_python), have you tried sending the HTTP header before writing any content?
req.send_http_header()
Also check if your URL is pointing to the right file, that might be the reason for the 404 error (Apache is finding your file correctly, or you wouldn't get the first error, so I'm assuming the script is fine and reachable, you just have to set the path correctly).
In Google App Engine, I have the following code which shows a simple HTML page.
import os
from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
class IndexHandler(webapp.RequestHandler):
def get(self):
template_values = { }
path = os.path.join(os.path.dirname(__file__), '../templates/index.html')
self.response.out.write(template.render(path, template_values))
The issue is that the page isn't always rendered. The index.html is a simple "Hello World!". After a couple of page refresh the page is displayed properly (i.e. the index.html file is found...). I tried to call flush at the end, but it didn't help. I am able to repro this with the SDK and on their server.
Am I missing something? Does someone have an idea of what is going on?
Thanks
Your handler script (the one referenced by app.yaml) has a main() function, but needs this stanza at the end:
if __name__ == '__main__':
main()
What's happening is that the first time your script is run in a given interpreter, it interprets your main script, which does nothing (thus returning a blank response). On subsequent invocations, the interpreter simply executes your main() (a documented optimization), which generates the page as expected. Adding the stanza above will cause it to execute main on initial import, too.
Can't reproduce -- with directory changed to ./templates (don't have a ../templates in my setup), and the usual main function added, and this script assigned in app.yaml to some arbitrary URL, it serves successfully "Hello World" every time. Guess we need more info to help -- log entries (maybe add logging.info calls here?), app.yaml, where's main, etc, etc...