Return Blank from Python flask API - python

I have an API that must return just blank and status as 200 OK in case there is no data available
I have tried following things and facing these error
if df.empty:
return '' , 200
This returns "" in the browser
if df.empty:
return json.loads('{}'), 200
This return {} in the browser
Send status as 204 (NO CONTENT) makes the previous content to be as it is on the browser
How can i return complete blank with status as 200?

I have found solution after thoroughly exploring Flask documents
from flask import Response
.....
if df.empty:
return Response(status = 200)

Your first example shows in my console, as others have mention in comments:
127.0.0.1 - - [05/Dec/2018 18:46:35] "GET / HTTP/1.1" 200 -
You can also see status of a document in a Network tab in Developers console.
I didn't see 204 - NO CONTENT until I explicitly defined it:
#app.route('/')
def index():
return '', 204
Your second example didn't work for me and gave me an error:
TypeError: 'dict' object is not callable
EDIT:
This is source of a page in opera (and chrome also).
And this is code for your second example, that I get an error from.
from flask import Flask, json
app = Flask(__name__)
#app.route('/')
def index():
return json.loads('{}'), 200

Related

Django test for 404 erroring because Client expects 200?

I am trying to test my 404 page to ensure certain elements are present on it.
My test looks like this:
class TestApp404PageIncludesLink(TestCase):
def setUp(self):
superuser = UserFactory(is_superuser=True, is_staff=True)
self.client.force_login(superuser)
def test_superuser_can_see_link(self):
response = self.client.get("404")
self.assertTrue(response.status_code == 404)
self.assertContains(response, 'href="/special_link/">Specialty</a>')
I am running this test as a logged in user - other tests for other views work fine.
I'm trying to check the 404 page.
It fails with this:
Couldn't retrieve content: Response code was 404 (expected 200)
200 != 404
How do I set up the test so it knows I am trying to get a 404?
The issue had to do with me not reading the documentation thoroughly enough apparently.
The assertContains takes a status_code argument that by default assumes a status of 200, which a 404 is not. Once I added that to the assertion it was resolved.
def test_superuser_can_see_link(self):
response = self.client.get("404")
self.assertTrue(response.status_code == 404)
self.assertContains(response, 'href="/special_link/">Specialty</a>', status_code=404)

how to redirect to a external 404 page python flask

I am trying to redirect my 404 to a external URL like this:
#app.route('404')
def http_error_handler(error):
return flask.redirect("http://www.exemple.com/404"), 404
but it does not work. I keep getting:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
You should try something like this:
from flask import render_template
#app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
Source http://flask.pocoo.org/docs/1.0/patterns/errorpages/
You cannot do this - the user-agent (in most cases, a browser) looks at the status code that is returned to determine what to do. When you return a 404 status code what you are saying to the user-agent is, "I don't know what this thing is you are requesting" and the user-agent can then:
Display what you return in the body of the response
Display its own error message to the end user
Do some combination of the above two options
redirect actually creates a little HTML response (via werkzeug.exceptions), which normally the end user doesn't see because the user-agent follows the Location header when it sees the 302 response. However, you override the status code when you provide your own status code (404).
The fix is to either:
Remove the status code (at the cost of sending the wrong signal to the end user, potentially)
or Send a 404 with a meta:refresh and / or JavaScript redirect (slightly better, still confusing):
return redirect("/where-ever"), 404, {"Refresh": "1; url=/where-ever"}
Try this instead of a route
from flask import request
#app.errorhandler(404)
def own_404_page(error):
pageName = request.args.get('url')
print(pageName)
print(error)
f = open('erreur404.tpl')
return f.read()

How get in real time POST update with django and instagram api?

I try to use python-instagram for get in real time instagram's media.
I use api.create_subscription with tag. And my callback url is a django web page on a distant web server.
My python script (I run it on my local computer):
api = InstagramAPI(client_id='my_id', client_secret='my_secret')
sub = api.create_subscription(object='tag', object_id='test', aspect='media', callback_url=my_url/insta)
print sub
while 1:
pass
My django view call by the callback url (I run it on distant web server):
def getInstagramPicture(request):
if request.method == "GET":
mode = request.GET.get("hub.mode")
challenge = request.GET.get("hub.challenge")
verify_token = request.GET.get("hub.verify_token")
return HttpResponse(challenge)
if request.method == "POST":
print "post"
I think the subscription works well. Web server terminal logs:
[20/Jan/2015 13:30:11] "GET /insta?hub.challenge=1aed90578d1743a3afb865cc2a6b69cc&hub.mode=subscribe HTTP/1.1" 301 0
[20/Jan/2015 13:30:11] "GET /insta/?hub.challenge=1aed90578d1743a3afb865cc2a6b69cc&hub.mode=subscribe HTTP/1.1" 200 32
And local terminal log:
sub {'meta': {'code': 200}, 'data': {'object': 'tag', 'object_id': 'test', 'aspect': 'media', 'callback_url': 'my_url/insta', 'type': 'subscription', 'id': '15738925'}}
But my problem it's when I try to post on Instagram a picture with tag "test" my view it's not call and I have in my web server terminal:
[20/Jan/2015 13:31:24] "POST /insta HTTP/1.1" 500 65563
Why my view is not call when I post instagram picture?
You need to correct your callback url to match what is defined in your urlconf. You currently tell Instagram that your callback url is <server>/insta but from the request logs it seems your urlconf is expecting <server>/insta/ (with a trailing slash)
This works ok for GET requests, as seen below
[20/Jan/2015 13:30:11] "GET /insta?hub.challenge=1aed90578d1743a3afb865cc2a6b69cc&hub.mode=subscribe HTTP/1.1" 301 0
[20/Jan/2015 13:30:11] "GET /insta/?hub.challenge=1aed90578d1743a3afb865cc2a6b69cc&hub.mode=subscribe HTTP/1.1" 200 32
(note the first line is a 301 redirect)
Django's default APPEND_SLASH setting ensures that the request for /insta is automatically redirected to the /insta/ view that you have defined.
However Django can't do that for a POST request... an HTTP redirect is always a GET request so the POST data would be lost. This is why you see a 500 error in your logs when a POST request is made to the non-existent url /insta:
[20/Jan/2015 13:31:24] "POST /insta HTTP/1.1" 500 65563
See also: https://stackoverflow.com/a/9739046/202168
The code shown does not appear to handle POST requests at all. It merely prints out "post" and returns nothing.
The web server log shows a HTTP 500 error (Internal Server Error) and a 64KiB error page that probably tells you exactly why.
You need to implement a handler for POST requests, and this handler would probably be similar to the GET handler that you already have.
Seems like instagram uses POST method to access to your callback url.
Try this:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def getInstagramPicture(request):
if request.method == "GET":
mode = request.GET.get("hub.mode")
challenge = request.GET.get("hub.challenge")
verify_token = request.GET.get("hub.verify_token")
return HttpResponse(challenge)
if request.method == "POST":
mode = request.POST.get("hub.mode")
challenge = request.POST.get("hub.challenge")
verify_token = request.POST.get("hub.verify_token")
return HttpResponse(challenge)

How do I get the different parts of a Flask request's url?

I want to detect if the request came from the localhost:5000 or foo.herokuapp.com host and what path was requested. How do I get this information about a Flask request?
You can examine the url through several Request fields:
Imagine your application is listening on the following application root:
http://www.example.com/myapplication
And a user requests the following URI:
http://www.example.com/myapplication/foo/page.html?x=y
In this case the values of the above mentioned attributes would be the following:
path /foo/page.html
full_path /foo/page.html?x=y
script_root /myapplication
base_url http://www.example.com/myapplication/foo/page.html
url http://www.example.com/myapplication/foo/page.html?x=y
url_root http://www.example.com/myapplication/
You can easily extract the host part with the appropriate splits.
An example of using this:
from flask import request
#app.route('/')
def index():
return request.base_url
another example:
request:
curl -XGET http://127.0.0.1:5000/alert/dingding/test?x=y
then:
request.method: GET
request.url: http://127.0.0.1:5000/alert/dingding/test?x=y
request.base_url: http://127.0.0.1:5000/alert/dingding/test
request.url_charset: utf-8
request.url_root: http://127.0.0.1:5000/
str(request.url_rule): /alert/dingding/test
request.host_url: http://127.0.0.1:5000/
request.host: 127.0.0.1:5000
request.script_root:
request.path: /alert/dingding/test
request.full_path: /alert/dingding/test?x=y
request.args: ImmutableMultiDict([('x', 'y')])
request.args.get('x'): y
you should try:
request.url
It suppose to work always, even on localhost (just did it).
If you are using Python, I would suggest by exploring the request object:
dir(request)
Since the object support the method dict:
request.__dict__
It can be printed or saved. I use it to log 404 codes in Flask:
#app.errorhandler(404)
def not_found(e):
with open("./404.csv", "a") as f:
f.write(f'{datetime.datetime.now()},{request.__dict__}\n')
return send_file('static/images/Darknet-404-Page-Concept.png', mimetype='image/png')

How to I return JSON in flask python fetched from another url to the browser?

I want to use flask to return JSON to the brower with or without simplejson (with appropriate headers) here is what I have so far for my flask application:
#app.route('/')
def hello_world():
QUERY_URL="http://someappserver:9902/myjsonservlet"
result = simplejson.load(urllib.urlopen(QUERY_URL))
return result;
Assuming the JSON output returned is:
{"myapplication":{"system_memory":21026160640.0,"percent_memory":0.34,
"total_queue_memory":4744,"consumers":1,"messages_unacknowledged":0,
"total_messages":0,"connections":1}
When I visit the page http://localhost:5000 however, I get a Internal Server Error. What must I do with "result" to get it to display appropriately? Or is there some way I can tell it to return with json headers?
When I add a print statement to print the result I can see the JSON, but in the browser it gives me an Internal Server Error.
import requests
r = requests.get(QUERY_URL)
return r.json
#normal return
return jsonify(username=g.user.username,
email=g.user.email,
id=g.user.id)
jsonify is available in flask. Here is the docs

Categories

Resources