Having trouble calling a get request using Falcon framework - python

I'm following Falcon tutorial for Python.
Everything worked fine until this part:
The response I'm getting when trying this command http localhost:8000/images is:
HTTP/1.1 500 Internal Server Error
Content-Length: 110
Content-Type: text/plain
Date: Sat, 01 Dec 2018 15:50:26 GMT
Server: waitress
Internal Server Error
The server encountered an unexpected internal server error
(generated by waitress)
I read it's a problem in the code but I can't find it, it's exactly as in the tutorial, app.py file:
import falcon
from images import Resource
api = application = falcon.API()
images = Resource()
api.add_route('/images', images)`
images.py:
import json
import falcon
class Resource(object):
def on_get(self, req, resp):
doc = {
'images': [
{
'href': '/images/1eaf6ef1-7f2d-4ecc-a8d5-6e8adba7cc0e.png'
}
]
}
# Create a JSON representation of the resource
resp.body = json.dumps(doc, ensure_ascii=False)
# The following line can be omitted because 200 is the default
# status returned by the framework, but it is included here to
# illustrate how this may be overridden as needed.
resp.status = falcon.HTTP_200
Also, I have an empty file named __init__.py and all the files are in the same folder, C:\look\look.
P.S.
I tried to add an HTTP requests scratch file (using PyCharm IDE) but there is no option to add that kind of a file (after I press Ctrl + Shift + Alt + Insert). I couldn't find how to fix this anywhere.

I see that the question is pretty old, but I found a solution. Just run the server with command:
waitress-serve --port=8000 --call look.app:get_app
since we get the app from calling the function get_app()

Related

"500 Internal Server Error" received when trying to create a .cgi application from a flask application

I have created the following Flask application in python (named simpleflask.py), using the code below:
from flask import Flask
import random
app = Flask(__name__)
app.secret_key = 'This is really unique and secret'
#app.route('/')
def index():
a = random.randrange(2)
if a == 1:
return "<p>the random number selector returned 1</p>"
else:
return "<p>the random number selector returned 0</p>"
if __name__ == "__main__":
app.run()
The Flask app runs fine from my personal computer.
I then tried to create a .cgi application using the instructions provided in the Flask documentation, which features the following code:
from wsgiref.handlers import CGIHandler
from simpleflask import app
CGIHandler().run(app)
However, it does not work as expected. I keep receiving the following error message:
KeyError: 'SERVER_NAME'
Status: 500 Internal Server Error
Content-Type: text/plain
Content-Length: 59
A server error occurred. Please contact the administrator.
I am not quite sure what this is supposed to mean. Any idea why I am receiving this error? What changes would I have to make to be able to create my .cgi application? Any and all suggestions welcome.
Your cgi-script has to write firstly headers. At least 'content-type':
Content-Type: text/html;
with empty line after it.
And then goes your content.

Flask change the server header

I've made a simple flask application:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
host:google.be
HTTP/1.0 404 NOT FOUND
Content-Type: text/html
Content-Length: 233
Server: Werkzeug/0.9.6 Python/2.7.6
Date: Mon, 08 Dec 2014 19:15:43 GMT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
Connection closed by foreign host.
One of the things I would like the change is the server header which at the moment is set as Werkzeug/0.9.6 Python/2.7.6 to something my own chosing. But I can't seem to find anything in the documentation on how to do this.
You can use Flask's make_response method to add or modify headers.
from flask import make_response
#app.route('/index')
def index():
resp = make_response("Hello, World!")
resp.headers['server'] = 'ASD'
return resp
#bcarroll's answer works but it will bypass other processes defined in original process_response method such as set session cookie.
To avoid the above:
class localFlask(Flask):
def process_response(self, response):
#Every response will be processed here first
response.headers['server'] = SERVER_NAME
super(localFlask, self).process_response(response)
return(response)
You can change the Server header for every response by overriding the Flask.process_response() method.
from flask import Flask
from flask import Response
SERVER_NAME = 'Custom Flask Web Server v0.1.0'
class localFlask(Flask):
def process_response(self, response):
#Every response will be processed here first
response.headers['server'] = SERVER_NAME
return(response)
app = localFlask(__name__)
#app.route('/')
def index():
return('<h2>INDEX</h2>')
#app.route('/test')
def test():
return('<h2>This is a test</h2>')
http://flask.pocoo.org/docs/0.12/api/#flask.Flask.process_response
Overriding Server header in code does not work if You use production server like gunicorn. The better way is to use proxy server behind gunicorn and there change Server header.
TL;DR - overwrite /python3.8/http/server.py send_response method. Comment the server header addition line.
Why?
Adding/Manipulating headers in flask (in any way that mentioned above) will fire the response with the configured headers from flask to the web server but the WSGI logic (which happens independently, after & before flask logic) will be the last one to modify those values if any.
In your case(Werkzeug) some headers are hard-coded in python http module which werkzeug depending on. The server header is one of them.
Easy way:
#app.after_request
def changeserver(response):
response.headers['server'] = SERVER_NAME
return response

ProtoRPC App Engine Hello World test app not working

I have been trying to get the rather simple Hello World ProtoRPC App Engine example to work, but to no avail. The code from the website just doesn't seem to work unfortunately. I have looked at a number of possible solutions, but couldn't find a complete working set. Any help would be much appreciated! You can see the error (or lack thereof) below:
app.yaml
application: proto-test
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /hello.*
script: hello.py
hello.py
from protorpc import messages
from protorpc import remote
from protorpc.wsgi import service
package = 'hello'
# Create the request string containing the user's name
class HelloRequest(messages.Message):
my_name = messages.StringField(1, required=True)
# Create the response string
class HelloResponse(messages.Message):
hello = messages.StringField(1, required=True)
# Create the RPC service to exchange messages
class HelloService(remote.Service):
#remote.method(HelloRequest, HelloResponse)
def hello(self, request):
return HelloResponse(hello='Hello there, %s!' % request.my_name)
# Map the RPC service and path (/hello)
app = service.service_mappings([('/hello', HelloService)])
curl command
curl -H 'content-type:application/json' -d '{"my_name":"test1"}' http://proto-test.appspot.com/hello.hello
When I run the above command in the command line, it just returns the prompt without an error. My logs suggest that the curl command sort of worked, but it just didn't provide a response. This is what appears in the logs:
2013-05-08 22:27:07.409 /hello.hello 200 522ms 0kb curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
2620:0:10c8:1007:a800:1ff:fe00:33af - - [08/May/2013:14:27:07 -0700] "POST /hello.hello HTTP/1.1" 200 0 - "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3" "proto-test.appspot.com" ms=523 cpu_ms=133 loading_request=1 app_engine_release=1.8.0 instance=00c61b117c66197ad84ad9bc61485b292e5129
I 2013-05-08 22:27:07.409
This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
An Ajax call through the Chrome JS Console returned the following: SyntaxError: Unexpected token ILLEGAL:
$.ajax({url: ‘/hello.hello’, type: 'POST', contentType: 'application/json', data: ‘{ "my_name": "Bob" }’,dataType: 'json',success: function(response){alert(response.hello);}});
The Java script you posted seems to have syntax errors. Mainly, it looks like you are using the ` character in places instead of the ' character.
The reason why your request is not working is because of how you wrote the app.yaml file. You are using the old Python 2.5 way of calling applications by referring to a script rather than a WSGI application. You can correct it by changing the url handler in app.yaml to:
handlers:
- url: /hello.*
script: hello.app

logging errors with flask

I'm trying to log an error in a decorator function using app.logger.error(''), but it just doesn't work. In addition I cant debug this well and I can only see the response from the http client:
(I'm using nginx+uwsgi+flask)
HTTP/1.1 502 Bad Gateway
Server: nginx
Date: Sun, 12 Aug 2012 15:45:09 GMT
Content-Type: text/html
Content-Length: 14
Connection: keep-alive
Everything works great with out the line: app.logger.error('panic !!!')
def mydecorator():
def decorator(f):
def wrapped_function(*args, **kwargs):
try:
ip = Mytable.query.filter_by(ip=request.remote_addr).first()
except:
app.logger.error('panic !!!')
else:
dootherthing()
resp = make_response(f(*args, **kwargs))
h = resp.headers
h['add-this-header'] = ":)"
return resp
return update_wrapper(wrapped_function, f)
return decorator
It seems that it is out of context or something.
in fact, the decorator wasnt able to detect the app instance out of context, i solve this using current_app:
1st. Import the method: from flask import current_app
2nd. append any app class to current_app: current_app.logger.error('panic !!!')
info # http://flask.pocoo.org/docs/api/#flask.current_app
"Points to the application handling the request. This is useful for
extensions that want to support multiple applications running side by
side. This is powered by the application context and not by the
request context, so you can change the value of this proxy by using
the app_context() method."
Is app defined anywhere in the script that you've posted?
Also, to help with debugging, when testing you should consider using the run() method with debug mode.
app.run(debug=True)

Creating a web server with Flask that outputs something available for a GET request

I have a Python script that outputs a piece of text in a string. I am attempting to make that piece of text available online so that I can pull it down to an Arduino Microcontroller. In other words, the work flow goes like this: Text source > Python > ??? > Arduino > Final output.
I've used the sample Flask code from Heroku to begin to experiment with getting this functionality working. Their code for Flask follows:
import os
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return 'Hello World!'
if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
When I attempt to do an HTTP get request on my heroku app, it gives me a 404. I suspect this is because this script doesn't really output anything. For example, when I use this Processing app from the Processing.org website to do a GET request:
import processing.net.*;
Client c;
String data;
void setup() {
size(200, 200);
background(50);
fill(200);
c = new Client(this, "http://freezing-stream-5123.herokuapp.com/", 80); // Connect to server on port 80
c.write("GET / HTTP/1.1\n"); // Use the HTTP "GET" command to ask for a Web page
c.write("Host: my_domain_name.com\n\n"); // Be polite and say who we are
}
void draw() {
if (c.available() > 0) { // If there's incoming data from the client...
data = c.readString(); // ...then grab it and print it
println(data);
}
}
What is returned is this:
HTTP/1.1 200 OK
Date: Sat, 31 Mar 2012 22:27:10 GMT
Server: Apache
Cache-control: no-cache, no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache
Content-Length: 968
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head><meta http- equiv="refresh" content="0;url=http://earthlink-help.com/main?
InterceptSource=0&ClientLocation=us&ParticipantID=xj6e3468k634hy3945zg3zkhfn7zfgf6&FailureMode =1&SearchQuery=&FailedURI=http%3A%2F%2Fmy_domain_name.com%2F&AddInType=4&Version=2.1.8-1.90base&Referer=&Implementation=0"/><script type="text/javascript">url="http://earthlink-help.com/main?InterceptSource=0&ClientLocation=us&ParticipantID=xj6e3468k634hy3945zg3zkhfn7zfgf6&FailureMode=1&SearchQuery=&FailedURI=http%3A%2F%2Fmy_domain_name.com%2F&AddInType=4&Version=2.1.8-1.90base&Referer=&Implementation=0";if(top.location!=location){var w=window,d=document,e=d.documentElement,b=d.body,x=w.innerWidth||e.clientWidth||b.clientWidth,y=w.innerHeight||e.clientHeight||b.clientHeight;url+="&w="+x+"&h="+y;}window.
location.replace(url);</script></head><body></body></html>
AKA: Nothing is there. "Hello world" does show up when I use curl to pull the webpage, but I don't know if that means anything.
So my question is: can anyone point me towards something that will stick my string in something that I can retrieve it from? I realize this is probably a stupid question, but I'm totally lost in a sea of web servers etc and would appreciate some guidance.
Thanks!
"Hello world" does show up when I use curl to pull the webpage, but I don't know if that means anything.
It probably means it's working and the problem is possibly in the Processing code.
It's not very clear if your problem is just with getting the basic Flask app running.
It looks like part of the problem is that you are not returning a response object, look at the API docs. There is a Response object that you should be able to just fill with text, either json or just text. If you plan on using the URL endpoint look at using the function 'jsonify' from Flask.

Categories