I write integration tests, which go through the whole HTTP stack:
requests library connects to http server
http server routes request to the django application
django application processes the request
If there is an uncaught exception in the django application I get the HTML debug page, since settings.DEBUG is True.
In most cases I like this page, but here want to have a simple ascii traceback which can I can show in our Continuous Application tool (Jenkins).
How to get an ascii traceback if I test my application with an url client library?
Rendering of this page with DEBUG=True is done in BaseHandler. which calls django.views.debug.technical_500_response view for all uncaught exceptions. But when DEBUG=False another view is called django.views.defaults.server_error. So you have 2 options
write custom middleware that will catch all uncaught exceptions and render them as plain text
https://docs.djangoproject.com/en/1.10/topics/http/middleware/#process-exception
Create separate setting file for jenkinks set here DEBUG=False and in your urls.py for if jenkins_env set handler500=custom_technical_500_response
which will render your exceptions the way you need
https://docs.djangoproject.com/en/1.10/ref/views/#http-internal-server-error-view and
https://docs.djangoproject.com/en/1.10/ref/urls/#handler500
Related
I am using Flask and blueprints on IIS. My issue is that when the 500 error is triggered it loads the default IIS 500 template and not what I want.
I've tried several things and this is where I am. I have the following code
from flask import render_template,Blueprint
errorbp = Blueprint("errorbp",__name__)
#errorbp.app_errorhandler(404)
def page_not_found(e):
return "404", 404
#errorbp.app_errorhandler(500)
def internal_server_error(e):
return "500", 500
If I visit a page that does not exist, I get "404" back as intended. If I create an error on purpose, I get the following
Any suggestions as to what to do? I presume I may need to do something with IIS at this point but what? I've edited/remove the 5xx status codes/page and still nothing
What you need to do is, open the error pages module, double-click the 500 status code, set the path of your template in the file path, and IIS will send the content of the file as a custom error response.
In addition, IIS has two other ways to respond to an error: by executing an URL or by redirecting the request.
I have a public cloud VM which has public IP say 160.159.158.157 (this has a domain registered against it).
I have a Django application (backend) which is CORS-enabled and serves data through port 8080.
I have a React app running on the same VIM on a different port (3000), which is accessing the Django app and is supposed to produce a report.
The problem is that, when I use http://<domain-name>:8080/api/ or http://<public-ip>:8080/api/, my application is working fine,
but when I try to fetch data from localhost like http://localhost:8080/api/ or http://127.0.0.1:8080/api/, the React app fails to fetch data with the following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8080/api/. (Reason: CORS request did not succeed). Status code: (null).
Here's what I've tried:
axios.get(baseURL, { headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods':'GET,PUT,POST,DELETE,PATCH,OPTIONS',
}
but it didn't work. What should I do?
Looks like you've gotten confused where those headers need to be. You're setting them on the request to the backend, but they need to be set on the response from the backend. After all, it wouldn't be very good security if someone making a request could simply say "yeah, I'm ok, you should trust me".
The problem is going to be somewhere in your backend Django app, so double check the CORS config over there.
I'm using Selenium to test my Django app's ability to login via Facebook. This works when running my development server (localhost:8000), but not when running the automated test.
When running the automated test, I can get the following error:
Given URL is not allowed by the Application configuration: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains.
I believe this is because LiveServerTestCase is running a test server on port 8081.
Is there a way to configure this such that I can login with both localhost:8000 and 8081? If not, I could always just create another FB app for testing.
I would like to find a way to restrict a view (request handler) to only be called from within the Google App Engine internal network from within my view and not within app.yaml.
For example, I have a view to handle inbound email within my Flask application
#app.route('/_ah/mail/notifications#example.appspotmail.com', methods=['POST'])
def inbound_notification_email():
from google.appengine.api import mail
message = mail.InboundEmailMessage(request.data)
...
return '' # 200 OK
While I know I could put all my mail handlers in their own file / wsgi instance like so:
handlers:
- url: /_ah/mail/.+
script: inbound_mail.app
login: admin
I would prefer not to have to do this as I'm using Flask instead of Webapp. Right now the request works as setup above, but it is exposed to the world.
Inspecting the request to my inbound_notification_email() view, I see X-App-Country in the request header is set to ZZ and the request's remote address is 0.1.0.20. I know the 0.x.x.x IP range is IANA reserved for local networks so it seems logical that checking if request.remote_address starts with "0." would work, but I'm not sure if all internal requests within App Engine are always handled this way (push queues and xmpp come to mind).
One thing I was surprised to see was users.is_current_user_admin() returns False within inbound_notification_mail() even though you're to set login: admin when using Webapp.
I need to read some values from the wsgi request before my flask app is loaded. If I read the url from the wsgi request I can access the file without any issues once the flask app is loaded (after the middleware runs).
But if I attempt to access the params it seems to remove the post data once the flask app is loaded. I even went to the extreme of wrapping the wsgi request with a special Webob Request to prevent this "read once" problem.
Does anyone know how to access values from the wsgi request in middleware without doing any sort of side effect harm to the request so you can get post data / file data in a flask app?
from webob import Request
class SomeMiddleware(object):
def __init__(self, environ):
self.request = Request(environ)
self.orig_environ = environ
def apply_middleware(self):
print self.request.url #will not do any harm
print self.request.params #will cause me to lose data
Here is my flask view
#app.route('/')
def hello_world():
from flask import request
the_file = request.files['file']
print "and the file is", the_file
From what I can tell, this is a limitation of the way that WSGI works. The stream needs only be consumable once (PEP 333 and 3333 only require that the stream support read* calls, tell does not need to be supported). Once the stream is exhausted it cannot be re-streamed to other WSGI applications further "inward". Take a look at these two sections of Werkzeug's documentation for more information:
http://werkzeug.pocoo.org/docs/request_data/
http://werkzeug.pocoo.org/docs/http/#module-werkzeug.formparser
The way to avoid this issue is to wrap the input stream (wsgi.input) in an object that implements the read and readline methods. Then, only when the final application in the chain actually attempts to exhaust the stream will your methods be run. See Flask's documentation on generating a request checksum for an example of this pattern.
That being said, are you sure a middleware is the best solution to your problems? If you need to perform some action (dispatch, logging, authentication) based on the content of the body of the request you may be better off making it a part of your application, rather than a stand-alone application of its own.