How to customize error response in a Turbogears2 controller - python

I'm using Turbogears2 to develop a small web application. And in some of my "controllers", I would like to response the client a json object with error information inside instead of an html page follows the standard error page template, because the ajax client can read the error message and have it's own way to display it.

There are multiple ways you can achieve this. If it is only bound to some controller you can easily register a controller wrapper for them (using tg.hooks.wrap_controller) and return JSON instead of plain error when needed. Controller wrappers are documented on http://turbogears.readthedocs.org/en/latest/turbogears/hooks.html#controller-wrappers
Otherwise another options is to use a decorator on the controller function to catch the error. This is what is also done by tgext.crudwhen reporting json errors through the catch_errors custom decorator: https://github.com/TurboGears/tgext.crud/blob/master/tgext/crud/decorators.py#L114
The controller wrapper solution is usually more powerful as it can be applied also to third party controllers. Otherwise you can even hijack the ErrorController in controllers/error.py to return json using json.dumps (TurboGears returns the response as is when it's a string or a tg.Response instance).

Related

Mocking a helper function in django view test

I have a view function that initiates user login requests
it looks something like this:
def initiate_login(request):
# get request parameters
return check_user_and_send_otp(login_id)
The request is then processed by another function
def check_user_and_send_otp(login_id):
# check if user exits
return send_otp_to_user(phone_number)
And then another function
def send_otp_to_user(phone_number):
# sends a message to user
return response
The problem is while testing my code, I don't want to send messages to a phone number while testing.
My login test function looks somewhat like this, is it possible to mock it without changing my code?
def test_login_initiator(self):
response = self.client.post(self.login_url, data=self.login_data, content_type="application/json", **self.headers)
self.assertEqual(response.status_code, 200)
All these functions that were called by others are located in seperate modules
If you don't want to actually receive the message on a physical phone, you can use online sms receivers. Check out this blog.
Additionally, you can send messages through other free online services like Way2sms. You just have to google them up. To do this from within Python, you need to use web parsing using urllib2/requests and beautifulsoup, which is a totally new question.
Or you can skip this function by simply commenting out the message sender code or returning true from the function.
If you wanna live dangerously, think about making a config file which can help you to make switches that tell whether to execute something or not.
The right thing to do would be use something like magic mock and structure the code into proper classes so that we can create mock objects for each of them.

Is there a better way to access my public api?

I am new to Flask.
I have a public api, call it api.example.com.
#app.route('/api')
def api():
name = request.args.get('name')
...
return jsonify({'address':'100 Main'})
I am building an app on top of my public api (call it www.coolapp.com), so in another app I have:
#app.route('/make_request')
def index():
params = {'name':'Fred'}
r = requests.get('http://api.example.com', params=params)
return render_template('really_cool.jinja2',address=r.text)
Both api.example.com and www.coolapp.com are hosted on the same server. It seems inefficient the way I have it (hitting the http server when I could access the api directly). Is there a more efficient way for coolapp to access the api and still be able to pass in the params that api needs?
Ultimately, with an API powered system, it's best to hit the API because:
It's user testing the API (even though you're the user, it's what others still access);
You can then scale easily - put a pool of API boxes behind a load balancer if you get big.
However, if you're developing on the same box you could make a virtual server that listens on localhost on a random port (1982) and then forwards all traffic to your api code.
To make this easier I'd abstract the API_URL into a setting in your settings.py (or whatever you are loading in to Flask) and use:
r = requests.get(app.config['API_URL'], params=params)
This will allow you to make a single change if you find using this localhost method isn't for you or you have to move off one box.
Edit
Looking at your comments you are hoping to hit the Python function directly. I don't recommend doing this (for the reasons above - using the API itself is better). I can also see an issue if you did want to do this.
First of all we have to make sure the api package is in your PYTHONPATH. Easy to do, especially if you're using virtualenvs.
We from api import views and replace our code to have r = views.api() so that it calls our api() function.
Our api() function will fail for a couple of reasons:
It uses the flask.request to extract the GET arg 'name'. Because we haven't made a request with the flask WSGI we will not have a request to use.
Even if we did manage to pass the request from the front end through to the API the second problem we have is using the jsonify({'address':'100 Main'}). This returns a Response object with an application type set for JSON (not just the JSON itself).
You would have to completely rewrite your function to take into account the Response object and handle it correctly. A real pain if you do decide to go back to an API system again...
Depending on how you structure your code, your database access, and your functions, you can simply turn the other app into package, import the relevant modules and call the functions directly.
You can find more information on modules and packages here.
Please note that, as Ewan mentioned, there's some advantages to using the API. I would advise you to use requests until you actually need faster requests (this is probably premature optimization).
Another idea that might be worth considering, depending on your particular code, is creating a library that is used by both applications.

Run code before url mapping on google app engine

I'd like to check the datastore first, to see if there is any data, and if not, then redirect to another page (most likely /admin). However, I don't want to rewrite the url mapping framework that is already there.
Is there some way to set a handler that will process all requests before they are mapped?
I'm using google app engine with Python 2.7 and webapp2.
Yes, you can override dispatch() with a custom class. In the example shown in the link, the new class name is MyHandler. This means that all of your request classes need to be derived from MyHandler instead of webapp2.RequestHandler. Since this is how you would implement Sessions, you can put your code in dispatch() before it calls webapp2.RequestHandler.dispatch(self). In other words, you probably want to replace webapp2.RequestHandler anyway.

Get Pyramid View callable by it's path (request context)

I am making an app that would translate websocket messages to AJAX requests to the server. Mainly the decision is based on the fact that Pyramid already has a good URL dispatch system and it would be stupid not to use it.
The question is if there is an easy way to dispatch a URL in Pyramid (possibly an instanced Request object) to it's according view callable and get the view callable? Or at least get the output of the view callable related to the request?
I have tried the script from "prequest.py" which basically emulates a whole HTTP client and gives you the response (I have still not managed to get it work, but a look through the sources makes sense anyway) and I wouldn't like to do it that way.
You can reuse the code from the pview command to turn a path into a view reference:
from pyramid.scripts.pviews import PViewsCommand
pvcomm = PViewsCommand([])
view = pvcomm._find_view(path, request.registry)
The actual code to do this is a little involved, but the PViewsCommand does it all for us already.
I have managed to do it using Router.invoke_subrequest in the latest version of Pyramid (1.4a1).
This enables all the features related to routing. URL dispatch, parameter passing, tweens.
You can read about it here: http://docs.pylonsproject.org/projects/pyramid/en/latest/api/request.html#pyramid.request.Request.invoke_subrequest

A minimalist, non-enterprisey approach for a SOAP server in Python

I need to implement a small test utility which consumes extremely simple SOAP XML (HTTP POST) messages. This is a protocol which I have to support, and it's not my design decision to use SOAP (just trying to prevent those "why do you use protocol X?" answers)
I'd like to use stuff that's already in the basic python 2.6.x installation. What's the easiest way to do that? The sole SOAP message is really simple, I'd rather not use any enterprisey tools like WSDL class generation if possible.
I already implemented the same functionality earlier in Ruby with just plain HTTPServlet::AbstractServlet and REXML parser. Worked fine.
I thought I could a similar solution in Python with BaseHTTPServer, BaseHTTPRequestHandler and the elementree parser, but it's not obvious to me how I can read the contents of my incoming SOAP POST message. The documentation is not that great IMHO.
You could write a WSGI function (see wsgiref) and parse inside it an HTTP request body using the xml.etree.ElementTree module.
SOAP is basically very simple, I'm not sure that it deserves a special module. Just use a standard XML processing library you like.
I wrote something like this in Boo, using a .Net HTTPListener, because I too had to implement someone else's defined WSDL.
The WSDL I was given used document/literal form (you'll need to make some adjustments to this information if your WSDL uses rpc/encoded). I wrapped the HTTPListener in a class that allowed client code to register callbacks by SOAP action, and then gave that class a Start method that would kick off the HTTPListener. You should be able to do something very similar in Python, with a getPOST() method on BaseHTTPServer to:
extract the SOAP action from the HTTP
headers
use elementtree to extract the SOAP
header and SOAP body from the POST'ed
HTTP
call the defined callback for the
SOAP action, sending these extracted values
return the response text given by the
callback in a corresponding SOAP
envelope; if the callback raises an
exception, catch it and re-wrap it as
a SOAP fault
Then you just implement a callback per SOAP action, which gets the XML content passed to it, parses this with elementtree, performs the desired action (or mock action if this is tester), and constructs the necessary response XML (I was not too proud to just create this explicitly using string interpolation, but you could use elementtree to create this by serializing a Python response object).
It will help if you can get some real SOAP sample messages in order to help you not tear out your hair, especially in the part where you create the necessary response XML.

Categories

Resources