Pyramid and access to basic useful objects outside of view callables

315 views
Skip to first unread message

Matt Feifarek

unread,
Jun 11, 2011, 1:13:26 PM6/11/11
to pylons-discuss
Hi there.

I'm a relatively long-time Pylons user, starting to work with Pyramid. I like what I see, but am suffering a bit on where to find things.

I'm using traversal and a resource tree in my app (zodb template) and am enjoying this pattern... but I can't seem to find ways to hook onto basic objects like the resource root, the settings, config, etc. I know that these things are attached to the request, but I'm not sure that the best way to go is to pass the request everyplace... if I just want to talk to the database, can I really only do that via a request?

Say I have a utility function that needs to peek in the database (zodb again) to find some elementary thing... how can I do that if it's not in a view callable and I don't explicitly pass request around?

There must be a way to do this for testing if nothing else (I know that there are fake request objects for testing, but do they have root, etc. also?)

OR, how can I grab onto the root, config and other goodies via an import? Maybe that's the question?

-- Matt

Danny Navarro

unread,
Jun 11, 2011, 4:36:45 PM6/11/11
to pylons-...@googlegroups.com
Hi Matt,

I'm not an expert in Pyramid, if I'm wrong I hope someone in the list
corrects me, so take my advice as an opinion from someone who uses
Pyramid sporadically.

I see Pyramid as just an application (a WSGI app) that just takes
requests and returns responses. The rest of Pyramid functionality is
to configure the application in the way it processes the requests and
returns the responses. Well, you have also events that are sent when
the Pyramid application is created but the focus is on
request-response machinery. See:
http://docs.pylonsproject.org/projects/pyramid/1.0/narr/router.html

For things related to the database I use some maintenance I run some
cron jobs with scripts that connect directly to ZODB. Those scripts
connect directly to ZODB, they don't need any Pyramid code. Nothing
stops you from working with ZODB directly from plain Python, you only
have to be careful if you need multiple processes connecting at the
same time, you need to run ZODB with ZEO in that case. See:
http://www.zodb.org/zodbbook/installing.html#setting-up-a-connection
http://docs.repoze.org/zodbconn/

What other things you have mind where you think you it's awkward to
use a request?

--
Danny Navarro | http://dannynavarro.net

> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To post to this group, send email to pylons-...@googlegroups.com.
> To unsubscribe from this group, send email to
> pylons-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.
>

Matt Feifarek

unread,
Jun 11, 2011, 4:58:31 PM6/11/11
to pylons-...@googlegroups.com
On Sat, Jun 11, 2011 at 3:36 PM, Danny Navarro <j...@dannynavarro.net> wrote:
I see Pyramid as just an application (a WSGI app) that just takes
requests and returns responses. The rest of Pyramid functionality is
to configure the application in the way it processes the requests and
returns the responses.

Yes, I see your point. And I agree; I try and configure my apps this way, with most code not inside of view-callables, but called *from* view callables; I hook my code into the events corresponding to requests and responses; I like this way of thinking, and in principle, it would be easier to code and debug, since you can just fire off these bits of code from an interpeter or tests. Needing to have a web request means that I'm stuck talking through a web browser rather than ipython or something nice like WingIDE, which is frustrating.

 
What other things you have mind where you think you it's awkward to
use a request?

Of course I know I can hook into ZODB (or whatever) alone, but there are aspects of the pyramid app that I might need, for example, the settings to determine where the ZODB is (or where ZEO is). One can't grab the configuration without being inside of request either... except that I expect one can, I just don't know how.

I suppose I can make my own plumbing to make this happen, but that seems strange; pyramid has these tools to find, open, expose a ZODB, including transactions, retry, etc... I'd rather just tie into that. I suppose if the "right way" to work is to always have a request or a response, I'll just have to get into the habit of using testing-like stubs... ?

Thanks, Danny.


Danny Navarro

unread,
Jun 11, 2011, 5:15:44 PM6/11/11
to pylons-...@googlegroups.com

If you mean accessing the settings, the database configuration
settings, have a look at repoze.zodbconn, you can reuse the same
configuration for ZEO/ZODB that you have for Pyramid, just use the
script the same URL you use in your paster ini file to configure
ZEO/ZODB.

Testing is another story. You can use
``pyramid.threadlocal.get_current_request`` anywhere in your
application to get the current request. It's not recommended in a real
application but it's OK while testing.
http://docs.pylonsproject.org/projects/pyramid/1.0/api/threadlocal.html

``pyramid.testing`` offers you many helpers to ease the creation of
dummy requests and for the activation of a dummy registry so that the
request runs as if it were within pyramid.
http://docs.pylonsproject.org/projects/pyramid/1.0/narr/testing.html
http://docs.pylonsproject.org/projects/pyramid/1.0/api/testing.html

> Thanks, Danny.


>
> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To post to this group, send email to pylons-...@googlegroups.com.
> To unsubscribe from this group, send email to
> pylons-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.
>

--
Danny Navarro  |  http://dannynavarro.net

Thomas G. Willis

unread,
Jun 11, 2011, 6:47:16 PM6/11/11
to pylons-...@googlegroups.com
Assuming that "application.ini" defines all your settings for your pyramid app...

one way that could work for you is this....

    from paste.deploy import loadapp
    import os
    here = os.getcwd()
    app = loadapp("config:application.ini", relative_to=here)

at this point any initialization that was needed should be done. you should be able to do things like import your models and perform queries and such

   from myapplication.model import User, DBSession
   [u.email for u in DBSession().query(User)]

This assumes your models are defined in model.py and youre session factory is named DBSession

or to get your resource root assuming its defined in resource.py as Root and this is what's passed to the configurator as the root_factory

    from myapplication.resource import Root
    root = Root()



Mike Orr

unread,
Jun 11, 2011, 7:22:43 PM6/11/11
to pylons-...@googlegroups.com
On Sat, Jun 11, 2011 at 1:58 PM, Matt Feifarek <matt.f...@gmail.com> wrote:
> On Sat, Jun 11, 2011 at 3:36 PM, Danny Navarro <j...@dannynavarro.net> wrote:
>>
>> I see Pyramid as just an application (a WSGI app) that just takes
>> requests and returns responses. The rest of Pyramid functionality is
>> to configure the application in the way it processes the requests and
>> returns the responses.
>
> Yes, I see your point. And I agree; I try and configure my apps this way,
> with most code not inside of view-callables, but called *from* view
> callables; I hook my code into the events corresponding to requests and
> responses; I like this way of thinking, and in principle, it would be easier
> to code and debug, since you can just fire off these bits of code from an
> interpeter or tests. Needing to have a web request means that I'm stuck
> talking through a web browser rather than ipython or something nice like
> WingIDE, which is frustrating.

There are about four patterns for accessing application state/request
state. One is to import a global object, as Pylons and CherryPy do.
Another is to call a global function, as Quixote does. Another is to
pass the request object through to every utility function, as Pyramid
does. Another is to save it in an instance variable in the view
handler, as Pyramid applications often do.

Part of the transition from Pylons to Pyramid was an intentional move
away from magic globals. They work but they depend on complex
threadlocals or StackedObjectProxies, which violate the principle of
encapsulation. They create complex interdependencies between the
modules in the application and the framework, which in turn makes it
more difficult to use the features outside of a request.
``pylons.app_globals`` was the most obvious example of this. People
would put a db connection or data structure into app_globals, and then
their model would depend on it, and then suddenly they'd discover in a
standalone script or a test, that app_globals wasn't initialized. So
then the had to research and write custom code to initialize it, and
that code would be different from how you normally access it. It's
better to just create objects explicitly and pass them through as
arguments, then you'll know that they'll work and how they work,
without depending on something behind the scenes in the framework,
something that might break.

--
Mike Orr <slugg...@gmail.com>

Reply all
Reply to author
Forward
0 new messages