4

I have a fair bit of experience with PHP frameworks and Python for scripting so am now taking the step to Pyramid.

I'd like to know what is the 'correct' way to run a script in Pyramid. That is, how should I set it up so that it is part of the application and has access to config and thus database but does not run through paster (or whatever WSGI).

As an example, say I have a web application which while a user is offline grabs Facebook updates through a web service. I want to write a script to poll that service and store in the database ready for next login.

How should I do this in terms of:

  1. Adding variables in the ini file
  2. Starting the script correctly

I understand the basics of Python modules and packages; however I don't fully understand Configurator/Paster/package setup, wherein I suspect the answer lies.

Thanks

Update:

Thanks, this seems along the lines of what I am looking for. I note that you have to follow a certain structure (eg have summary and parser attributes set) and that the function called command() will always be run. My test code now looks something like this:

class AwesomeCommand(Command):

max_args = 2
min_args = 2

usage = "NAME"
# These are required
summary = "Say hello!"
group_name = "My Package Name"
# Required:
parser = Command.standard_parser(verbose=True)


def command(self):

    # Load the config file/section
    config_file, section_name = self.args
    # What next?

I'm now stuck as to how to get the settings themselves. For example, in init.py you can do this:

 engine = engine_from_config(settings, 'sqlalchemy.')

What do I need to do to transform the config file into the settings?

EDIT: The (simpler) way to do this in Pylons is here: Run Pylons controller as separate app?

Community
  • 1
  • 1
somewhatoff
  • 971
  • 1
  • 11
  • 25
  • did you look at pyramids source code that I linked in my answer to your original question? https://github.com/Pylons/pyramid/blob/master/pyramid/paster.py – Tom Willis Jun 06 '11 at 14:38
  • I have, yes. I have edited in code to try and make it match that as much as possible. The script will run once the get_app functions and so forth are added, but that only seems to get me as far as having a WSGI router application available. Either way, I still can't just access the models or figure out how to get paster to pass the settings in. I still don't really understand why paster has to be involved - sorry, as I say this is new to me. – somewhatoff Jun 06 '11 at 22:24
  • this isn't really something that can be answered here I don't think as this is specific to your application, irc, convore or the news groups might be a better place. if you want to use an ini file, that would be a reason paster is involved. that was the point of my first paragraph. check out the loadapp function docs @ http://pythonpaste.org/deploy/#basic-usage – Tom Willis Jun 06 '11 at 22:35
  • Thanks for your help; I do think that this must be a common requirement for developers (as with the Pylons controller) and I will take it to the lists and post back if I hear anything. Very much appreciate your tips (I have learnt quite a bit about how paster/Pyramids actually works!) – somewhatoff Jun 06 '11 at 23:42
  • no problem glad I could help. paster in and of itself is worth learning. frameworks that use it seem to gloss over it as an implementation detail which is kind of unfortunate because then the web app you create seems more magical than it needs to be. – Tom Willis Jun 07 '11 at 00:31

4 Answers4

2

As of Pyramid 1.1, this is handled by the framework:

http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/commandline.html#writing-a-script

somewhatoff
  • 971
  • 1
  • 11
  • 25
1

paster starts an application given an ini file that describes that application. the "serve" command is a built in command for starting a wsgi application and serving it. BUT, you can write other commands.

from paste.script.command import Command
class AwesomeCommand(Command):
    def command(self):
        print "the awesome thing it does"

and then register them as entry points in your setup.py.

setup(...
entry_points="""
  [paste.app_factory]
  .....

  [paste.global_paster_command]
  myawesome-command = mypackage.path.to.command:AwesomeCommand    """)

pyramid adds it's own commands this way like the pshell command.

Tom Willis
  • 5,250
  • 23
  • 34
  • 1
    The example here requires PasteScript library and the idea is that PasteDeploy executes the command. I suppose you were to run this as `pserve conf.ini#global_paster_command`. It doesn't really initialize/bootstrap the pyramid context, so you'll still need `pyramid.paster.bootstrap()` inside the command but probably the settings file can be digged from `Command` object and passed to bootstrap. Please correct me if wrong. – Tuukka Mustonen Sep 11 '13 at 09:59
1

After going to the pylons discuss list, I came up with an answer. Hope this helps somebody:

 #Bring in pyramid application--------------------------------------

 import pyramid
 from paste.deploy import appconfig
 config_file = '/path_to_config_file/configname.ini'

 name = 'app_name'
 config_name = 'config:%s' % config_file
 here_dir = os.getcwd()

 conf = appconfig(config_name, name, relative_to=here_dir)

 from main_package import main
 app = main(conf.global_conf, **conf.local_conf)

 #--------------------------------------------------------------------------
somewhatoff
  • 971
  • 1
  • 11
  • 25
0

you need to make view for that action and then run it using:

paster request development.ini /url_to_your_view
virhilo
  • 6,568
  • 2
  • 29
  • 26
  • Thanks, but that still has the overhead of the WSGI and so forth. I'm rather looking for something that doesn't involve calling a page but works as a 'normal' script. – somewhatoff Jun 02 '11 at 10:20
  • but it don't need you to have it runned it just run wsgi stuff 'internaly' for that one script – virhilo Jun 02 '11 at 17:32
  • 1
    Sorry, I don't think I am understanding correctly. If I run the above code, it calls a particular URL and returns the result for that URL. Essentially it therefore simulates a browser request. Really, I want to not have a URL or return any results; just to run like a normal Python shell script. Otherwise it feels like I am faking a web request where there is no need to do so. Thanks again for your help – somewhatoff Jun 02 '11 at 23:12