pyramid_handlers not working - python

I'm currently moving a project from Pylons 1.0 to Pyramid.
My problem so far is how to use restful routes in Pyramid. I'm currently using pyramid_handlers since it seemed like a good start. I'm using Akhet.
So here is the two important lines in my route:
config.add_handler("new_account", "/accounts/new", "sproci2.handlers.accounts:Accounts")
# or
config.add_handler("new_account", "/accounts/new", "sproci2.handlers.accounts:Accounts", action="new")
My action:
#action(name="new_account", renderer='accounts/new.mako', request_method='GET')
The errors:
TypeError: 'Accounts' object is not callable
or
ValueError: Could not convert view return value "{}" into a response Object.
Accounts... so far so good, it is easy to understand that pyramid_handlers doesn't seem to register normally or handle name as it should... that said in request.matched_route, I do have "new_account".
If I add "action='new'" in the route definition, it will find the function but it will not listen to the action definition. In other words, it will fail to find a renderer and expect a response object. The request_method parameter doesn't actually do anything yet, so removing it doesn't change any results.
In short, the #action(name="..." doesn't work. Pyramid fails to find the function by itself and if the function name is defined it fails to execute the action statement.
No idea what I'm doing wrong.
Correct way to do it.
config.add_handler("new_account", "/accounts/new", "sproci2.handlers.accounts:Accounts", action="new_account")
EDIT
route_name is probably going to get used by url generator functions. While action is the actual name in #action. As I understood, #action name was the route_name and not the action name. That makes more sense now.

Well a call to add_handler needs an action pattern. So that's either adding {action} to the url pattern, or setting action= as an argument. Those actions must match the names defined in #action decorators. In your example, you named the action new_account, yet you called add_handler with an action of new. Thus they aren't properly connected.

Related

Is it a good practise to use underscore to ignore a value that is being passed to a function, which we don't need?

I am working on Django rest framework which specifies a set format for function prototype for detail_route in ModelViewSet. Some background: -
The function takes in request object and lookup_field which can be the primary key for a particular table.
#detail_route(methods=["get"], url_path="get-some-data")
def get_some_data(self, request, id=None):
return Response(get_some_data(id))
Now as you can see, I do not need request object here, So should I keep it like this? or change it to
#detail_route(methods=["get"], url_path="get-some-data")
def get_some_data(self, _, id=None):
return Response(get_some_data(id))
Here I changed request to _ to indicate that I do not need this value.
which approach should be followed? Should I let it remain as a request, or change it to an underscore?
For the method arguments I would always use the proper variable name so that in future whether I work on it or my peers if I provide this code to someone else they don't have to struggle to understand what it is.
For now you might think to ignore it but since it is a method argument it would be better to have a name it stands for.
Or, let's say you are adding a docstring where you are including and defining which parameter is what. You would yourself appreciate it if some one had:
#param request: HTTP request object
instead of:
#param _: HTTP request object
If you leave the parameter exist, then give it a meaningful name always do good, even you do not use it.
In addition, _ has special use in python, check it in the following url.
What is the purpose of the single underscore "_" variable in Python?
I'd leave it with a descriptive name. Changing it to underscore or any other non-descriptive name is not beneficial.

Django reverse routes - two optional parameters

I have a question about Django and it's routing system. I believe that it can be powerfull, but right now I am struggling with one issue I don't experience when working in other frameworks and I can't seem to get a grip on it. Worth to mention that I don't have much experience with Django at this point.
The issue is simple - I have a view which takes two optional parameters, defined like this
def test_view(id=None, grid=None):
Both parameters are optional and frequently are not passed. Id can only be an integer and grid will never be an integer (it is a special string to control datagrid when I don't want to use sessions). I have a route defined like this:
url(a(r'^test_view (\/(?P<id>\d+))? (\/(?P<grid>[^\/]+))? \/?$'), views.test_view, name='test_view'),
This works great and I am not having trouble with using one-way routes. But when I try to use the reverse function or url template tag, following error occurs:
Reverse for 'test_view' with arguments '('20~id~desc~1',)' and keyword arguments '{}' not found.
In this example I tried to find reverse without the id, just with the grid parameter. I have tried various methods of passing parameters to the reverse function:
(grid, )
(None, grid)
('', grid)
{id=None, grid=grid}
All of them result in same error or similliar one.
Is there a way to implement this in django? Maybe just disable the cool URL for the grid parameter. That is how I do it in for example Nette framework for PHP, isntead of having an url like this: 'localhost/test_view/1/20~id~desc~1' I have url like this: 'localhost/test_view/1?grid=20~id~desc~1'. This would be completely sufficient, but I have no idea how to achive this in Django.
As you note in your question, the best way to achieve this is to use standard GET query parameters, rather than doing it in the path itself. In Django you do that exclusively in the view; the URL itself is then just
url(r'^test_view$', views.test_view, name='test_view'),
and you request it via localhost/test_view?id=1&grid=20~id~desc~1. You get the params from request.GET, which is a dictionary-like object; you can use .get so that it does not raise a KeyError when the key is not provided.
def test_view(request):
id = request.GET.get('id')
grid = request.GET.get('grid')

AssertionError, altough the expected call looks same as actual call

I made a command in django which calls a function.
That function does a django orm call:
def get_notes():
notes = Note.objects.filter(number=2, new=1)
return [x.note for x in notes]
I want to patch the actual lookup:
#mock.patch('Note.objects.filter', autospec=True)
def test_get_all_notes(self, notes_mock):
get_notes()
notes_mock.assert_called_once_with(number=2, new=1)
I get the following assertion error:
AssertionError: Expected call: filter(number=2, new=1)
Actual call: filter(number=2, new=1)
I search on google and stackoverflow for hours, but I still haven't a clue.
Can anyone point me in the right direction, I think it might be an obvious mistake I'm making...
AFAIK you can't use patch() like this. Patch target should be a string in the form package.module.ClassName. I don't know much about django but I suppose Note is a class so Note.objects.filter is not something you can import and hence use in patch(). Also I don't think patch() can handle attributes. Actually I don't quite understand why the patch works at all.
Try using patch.object() which is specifically designed to patch class attributes. It implies Note is already imported in your test module.
#mock.patch.object(Note, 'objects')
def test_get_all_notes(self, objects_mock):
get_notes()
objects_mock.filter.assert_called_once_with(number=2, new=1)
I've removed autospec because I'm not sure it will work correctly in this case. You can try putting it back if it works.
Another option might be to use patch() on whatever you get with type(Note.objects) (probably some django class).
As I've said I don't know much about django so I'm not sure if these things work.

webapp2: regex in routing

I have such a problem: I want one method of the class to handle different URIs (for URI "/solution/add" and "solution/edit"). So I wrote such routing:
app = webapp2.WSGIApplication([webapp2.Route(r'/solutions/(add|edit)', handler='solution.SolutionPage:add_edit_solution'), ], debug=True)
And webapp2 gives 404 error. Could you please suggest the solution of this problem?
Ofcourse I can write different routes for every URI, but it's not so interesting.)
As the webapp2 docs indicate, you have to put the regex in angle brackets, with a colon separating name and expression. The name is optional, but
everything outside of <> is not interpreted as a regular expression to be matched
So something like this: '/blog/<:\d{4}>/<:\d{2}>' Or in your case, this:
webapp2.Route(r'/solutions/<:(add|edit)>',
handler='solution.SolutionPage:add_edit_solution')
If I can add something.
For my own purpose, I've try to create a handler which perform a little bit similar operation, but the point is that I've used self.request.host or self.request.route instead of arguments.
Doing this, and parsing the result with a switch case or if/elif/else loop, allow me to create a class named URIHandler which is use to route any kind of request to the correct ressources (even 404/500/yyy error pages) dynamicly whithout having to rewrite or add route for each new ressources.
So I'll be interested in comparing the two method to bench them a little bit.

Multiple 'endings' to a function - return an object, return a string, raise an exception?

This one's a structure design problem, I guess. Back for some advice.
To start: I'm writing a module. Hence the effort of making it as usable to potential developers as possible.
Inside an object (let's call it Swoosh) I have a method which, when called, may result in either success (a new object is returned -- for insight: it's an httplib.HTTPResponse) or failure (surprising, isn't it?).
I'm having trouble deciding how to handle failures. There are two main cases here:
user supplied data that was incorrect
data was okay, but user interaction will be needed () - I need to pass back to the user a string that he or she will need to use in some way.
In (1) I decided to raise ValueError() with an appropriate description.
In (2), as I need to actually pass a str back to the user.. I'm not sure about whether it would be best to just return a string and leave it to the user to check what the function returned (httplib.HTTPResponse or str) or raise a custom exception? Is passing data through raising exceptions a good idea? I don't think I've seen this done anywhere, but on the other hand - I haven't seen much.
What would you, as a developer, expect from an object/function like this?
Or perhaps you find the whole design ridiculous - let me know, I'll happily learn.
As much as I like the approach of handling both cases with specifically-typed exceptions, I'm going to offer a different approach in case it helps: callbacks.
Callbacks tend to work better if you're already using an asynchronous framework like Twisted, but that's not their only place. So you might have a method that takes a function for each outcome, like this:
def do_request(on_success, on_interaction_needed, on_failure):
"""
Submits the swoosh request, and awaits a response.
If no user interaction is needed, calls on_success with a
httplib.HTTPResponse object.
If user interaction is needed, on_interaction_needed is
called with a single string parameter.
If the request failed, a ValueError is passed to on_failure
"""
response = sumbit_request()
if response.is_fine():
on_success(response)
elif response.is_partial()
on_interaction_needed(response.message)
else:
on_failure(ValueError(response.message))
Being Python, there are a million ways to do this. You might not like passing an exception to a function, so you maybe just take a callback for the user input scenario. Also, you might pass the callbacks in to the Swoosh initialiser instead.
But there are drawbacks to this too, such as:
Carelessness may result in spaghetti code
You're allowing your caller to inject logic into your function (eg. exceptions raised in the callback will propagate out of Swoosh)
My example here is simple, your actual function might not be
As usual, careful consideration and good documentation should avoid these problems. In theory.
I think raising an exception may actually be a pretty good idea in this case. Squashing multiple signals into a single return value of a function isn't ideal in Python, due to duck typing. It's not very Pythonic; every time you need to do something like:
result = some_function(...)
if isinstance(result, TypeA):
do_something(result)
elif isinstance(result, TypeB):
do_something_else(result)
you should be thinking about whether it's really the best design (as you're doing).
In this case, if you implement a custom exception, then the code that calls your function can just treat the returned value as a HTTPResponse. Any path where the function is unable to return something its caller can treat that way is handled by throwing an exception.
Likewise, the code that catches the exception and prompts the user with the message doesn't have to worry about the exact type of the thing its getting. It just knows that it's been explicitly instructed (by the exception) to show something to the user.
If the user interaction case means the calling code has to show a prompt, get some input and them pass control back to your function, it might be ugly trying to handle that with an exception. Eg,
try:
Swoosh.method()
except UserInteraction, ex:
# do some user interaction stuff
# pass it back to Swoosh.method()?
# did Swoosh need to save some state from the last call?
except ValueError:
pass # whatever
If this user interaction is a normal part of the control flow, it might be cleaner to pass a user-interaction function into your method in the first place - then it can return a result to the Swoosh code. For example:
# in Swoosh
def method(self, userinteractor):
if more_info_needed:
more_info = userinteractor.prompt("more info")
...
ui = MyUserInteractor(self) # or other state
Swoosh.method(ui)
You can return a tuple of (httplib.HTTPResponse, str) with the str being optionally None.
Definitely raise an exception for 1).
If you don't like returning a tuple, you can also create a "response object" i.e. an instance of a new class ( lets say SomethingResponse ) that encapsulates the HTTPResponse with optional messages to the end-user( in the simplest case, just a str).

Categories

Resources