I have a pyramid API which has basically three layers.
View -> validates the request and response
Controller -> Does business logic and retrieves things from the DB.
Services -> Makes calls to external third party services.
The services are a class for each external API which will have things like authentication data. This should be a class attribute as it does not change per instance. However, I cannot work out how to make it a class attribute.
Instead I extract the settings in the view request.registry.settings pass it to the controller which then passes it down in the init() for the service. This seems unnecessary.
Obviously I could hard code them in code but that's an awful idea.
Is there a better way?
Pyramid itself does not use global variables, which is what you are asking for when you ask for settings to be available in class-level or module-level attributes. For instance-level stuff, you can just pass the settings from Pyramid into the instance either from the view or from the config.
To get around this, you can always pass data into your models at config-time for your Pyramid app. For example, in your main just pull settings = config.get_settings() and pass some of them to where they need to be. As a general rule, you want to try to pass things around at config-time once, instead of from the view layer all the time.
Finally, a good way to do that without using class-level or module-level attributes is to register instances of your services with your app. pyramid_services library provides one approach to this, but the idea is basically to instantiate an instance of a service for your app, add it to your pyramid registry config.registry.foo = ... and when you do that you can pass in the settings. Later in your view code you can grab the service from there using request.registry.foo and it's already setup for you!
Related
I'm trying to unit test Django REST Framework view set permissions for two reasons: speed and simplicity. In keeping with these goals I would also like to avoid using any mocking frameworks. Basically I want to do something like this:
request = APIRequestFactory().post(…)
view = MyViewSet.as_view(actions={"post": "create"})
self.assertTrue(MyPermission().has_permission(request, view))
The problem with this approach is that view is not actually a View instance but rather a function which does something with a View instance, and it does not have certain properties which I use in has_permission, such as action. How do I construct the kind of View instance which can be passed to has_permission?
The permission is already tested at both the integration and acceptance level, but I would like to avoid creating several complex and time-consuming tests to simply check that each of the relevant actions are protected.
I've been able to work around this by monkeypatching a view set instance and manually dispatching it:
view_set = MyViewSet()
view_set.action_map = {"post": "create"}
view_set.dispatch(request)
You can do something like below.
request = APIRequestFactory().post(…)
view_obj = MyViewSet()
self.assertTrue(MyPermission().has_permission(request, view_obj))
This is more of a conceptual question. While learning the Django class-based view, I am wondering if it is possible to make a call to a Django view as an initiation call. I mean, after the first call, the following calls from the templates can share the instance variables created by the first one. This avoids passing variables back and forth between the template and server.
No. Django views are specifically designed to prevent this. It would be a very bad idea; any instance variables set would be shared by all future users of that process, leading to potential information leakage and other thread-safety bugs.
If you want to store information between requests, use the session.
I'm currently writing a Flask app. One of my views has very complex business logic so I moved that to a class declared outside the view. In the constructor of that class I create several instances of flask_wtf.form.Form objects.
My problem is that at runtime I get the following error:
*** RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in a way. To solve
this set up an application context with app.app_context(). See the
documentation for more information.
(ipdb is mine)
I assume the form objects need to be in the view? But I want to move the work of creating them into a separate class so the view won't get too complex, otherwise it's unmanageable.
You can't. flask_wtf.Form requires the application context to set up CSRF.
It doesn't really make sense to instantiate a form outside of where it will be used, because you need to instantiate it with the data that is submitted to do anything useful.
Move creating the form instances to a method that you call on that class, rather than in it's __init__ method.
I am trying to share an object between two GAE apps. The first will have the class's file, and will offer up an instance of that object. The second, using a given url, will access the first app, get the object and then use is. Is this actually possible? If so what am I not doing right in the code below?
As a small side note I tried a solution with pickle, but both apps are required to have the class in its name space, but I will be working with a number of these. I thought about trying to imitate something like Java's abstract class by using inheritance, but that didn't work out. I can provide that code too if you want to see it.
I understand the possible Terms of Service, that is not a issue.
I know cloud computing is out there, I don't know how to work with it, and I would
prefer to avoid the costs because I am developing this as a class project.
I have seen some suggestions to use remote_api, but I have seen no good example
of how it can be used, let alone used to allow two applications to interact.
I have seen the solution to use multiple versions, but each student will have
an app, it would be incredibly messy, but possibly doable.
First.Py:
class SampleCritter():
def move():
...
class Access(webapp2.RequestHandler):
def post(self):
CritStore(stats=self.request.body).put()
def get(self):
creature = CritStore.all().order('-date').get()
if creature:
stats = loads(creature.stats)
return SampleCritter(stats)
else:
return SampleCritter()
Second.py:
class Out(webapp2.RequestHandler):
def post(self):
url = self.request.POST['url']
critter = urllib2.urlopen(url)
critter.move()
The short answer is, you can't share objects between apps.
The longer answer is, your first app can expose objects using an HTTP based API. Any client can access the HTTP API, including app 2.
App 2 will have to manipulate objects via the HTTP API. You won't be able to call critter.move() from app 2, though if you create a handler say, critter\move, you can have the handler pull up the appropriate Critter instance and call move() on it. You'll have to pass all the appropriate params via HTTP POST as well.
I am a beginner in Web2Py. I wish to develop a simple application, where the user should log in with a username and a password (no fancy stuff like login with facebook or OpenID etc.). Upon successful login, the user sees some interface, and performs certain operations. I imagined a User class and a JobStore class (which has certain methods defined, which the user should be able to call). There will be only one JobStore object for all users and sessions. When a user logs in, an User object gets created with a reference to the JobStore. The User class has methods like GetRights(), RequestJob(), MarkAsFinished(), etc. and JobStore has methods like GetUnfinished(), RemoveJobs(), etc. Structurally speaking, where am I supposed to have these classes, so that based on certain actions the user performs on the view, certain methods get called? Are these classes supposed to inherit from some standard classes used in Web2Py? I am trying to find an example, where some kind of object oriented approach is used in the controller, but have not found any so far. Also, is this the wrong approach in Web2Py app development? I am not trying to implement any complex business logic through these functions as of now; I am just trying to understand how traditional programming approach would map to Web2Py approach somehow.
You can define classes in model or controller files, but it would probably make most sense to put them in the app's /modules folder and import them where needed in your models and controllers. There is no need for your classes to inherit from web2py classes, though they can do so if desired. For more on using modules and importing, see here and here.
For an example of a heavily object-oriented approach, see the Movuca CMS. Most of the code is in the /modules folder.