Skip to main content

Paster support for Grok projects.

Project description

grokcore.startup

This package provides elements for starting a Grok project with paster and WSGI.

Setting up grokcore.startup

There is nothing special to setup this package.

All you have to do is, to make this package available during runtime.

With zc.buildout or other setuptools-related setups this can be done by simply adding the package name grokcore.startup to the required packages of your project in setup.py.

Detailed Description

Setting up Grok projects as paster served WSGI applications

The main target of this package is to provide support for enabling Grok applications to be run as paster served WSGI applications. To make this working some configuration files have to be set up.

Setting up a project with grokproject

The most convenient way to setup a Grok project is using grokproject. Once installed, you can a project like this:

$ grokproject Sample

which will generate all configuration files for you.

Setting up a project manually

Before we can make use of grokcore.startup, we have to setup several configuration files in the project root:

  • setup.py

  • buildout.cfg (optional)

  • zope.conf (normally found in the parts/etc/ subdirectory of your Grok project)

  • site.zcml (normally found in the parts/etc/ subdirectory of your Grok project)

  • deploy.ini (or any other .ini-file; normally found in the parts/etc/ subdirectory of your Grok project)

When we want to setup a Zope instance as paster served WSGI application, then we have to set a paste.app_factory entry point in setup.py. A minimal setup could look like this:

# setup.py
from setuptools import setup, find_packages

setup(name='sampleproject',
      version='0.1dev',
      description="A sample project",
      long_description="""Without a long description.""",
      classifiers=[],
      keywords="",
      author="U.N.Owen",
      author_email="",
      url="",
      license="",
      package_dir={'': 'src'},
      packages=find_packages('src'),
      include_package_data=True,
      zip_safe=False,
      install_requires=['setuptools',],
      entry_points = """
      [paste.app_factory]
      main = grokcore.startup:application_factory
      """,
      )

Here the paste.app_factory entry point pointing to grokcore.startup:application_factory is important.

Furthermore we need at least a minimal buildout.cfg which enables zc.buildout to create the control scripts for our instance:

[buildout]
develop = .
parts = app

[app]
recipe = zc.recipe.egg
eggs = sampleproject
       grokcore.startup
       Paste
       PasteScript
       PasteDeploy

Here an egg-entry for grokcore.startup might be important, if it is not required otherwise by your application. Projects generated by grokproject will automatically include such a dependency and upcoming versions of Grok will pull in grokcore.startup anyway, so that grokcore.startup would not be required in this list of eggs any more.

Next we need site.zcml and zope.conf files to define the Zope instance. These configurations are completely independent from being served by Paste or not. If you are upgrading an old Grok project, you can use site.zcml and zope.conf of those project as-is. You only have to take care of the maybe changed site-definition entry in zope.conf (see below).

The file site.zcml can be quite short, but for real projects you certainly want to have some useful content in here:

<configure />

A short zope.conf file for use in tests could look like this:

site-definition site.zcml

<zodb>
  <mappingstorage />
</zodb>

<eventlog>
  <logfile>
    path STDOUT
   </logfile>
</eventlog>

where the site-definition entry should point to the location of the file site.zcml. In regular Grok projects those files are put into the etc/ subdirectory of your project root.

Finally we have to provide a deploy.ini (or another .ini-file), which tells paster where to find the pieces. This is also put into the etc/ subdirectory of your project root in regular Grok projects created by grokproject:

[app:main]
use = egg:sampleproject

[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 8080

[DEFAULT]
zope_conf = %(here)s/zope.conf

API Documentation

application_factory(global_conf, **local_conf)

grokcore.startup provides a function application_factory which delivers a WSGIPublisherApplication instance when called with an appropriate configuration. See the zope.app.wsgi documentation to learn more about Zope objects supporting WSGI.

A call to this function is normally required as entry point in setuptools-driven paster environments (see http://pythonpaste.org/deploy/#paste-app-factory).

We have to create our own site definition file – which will simply be empty – to provide a minimal test:

>>> import os, tempfile
>>> temp_dir = tempfile.mkdtemp()
>>> sitezcml = os.path.join(temp_dir, 'site.zcml')
>>> out = open(sitezcml, 'w')
>>> _ = out.write('<configure />')
>>> out.close()

Furthermore we create a Zope configuration file, which is also quite plain:

>>> zope_conf = os.path.join(temp_dir, 'zope.conf')
>>> out = open(zope_conf, 'w')
>>> _ = out.write('''
... site-definition %s
...
... <zodb>
...   <mappingstorage />
... </zodb>
...
... <eventlog>
...   <logfile>
...     path STDOUT
...   </logfile>
... </eventlog>
... ''' % sitezcml)
>>> out.close()

Now we can call application_factory to get a WSGI application:

>>> from grokcore.startup import application_factory
>>> app_factory = application_factory({'zope_conf': zope_conf})
>>> app_factory
<zope.app.wsgi.WSGIPublisherApplication object at 0x...>

debug_application_factory(global_conf, **local_conf)

There’s a second application factory that can be used when debugging the application, especially when using the z3c.evalexception middleware.

When debugging zope is instructed not to handle any raised exceptions itself. The z3c.evalexception middleware then catches the exceptions and provides an user interfaces for debugging in the webbrowser.

As a result also the IUnauthorized execption would not be handled by zope and the authentication mechanisms of zope are not triggered. As a result, when debugging one cannot login.

The debug_application_factory function accepts the “exempt-exceptions” configuration option. The value for this option should be a comma seperated list of dotted names for each of the execptions that should still be handled by zope and not re-raised to be catched by the middleware.

>>> from grokcore.startup import debug_application_factory
>>> app_factory = debug_application_factory({'zope_conf': zope_conf})
>>> app_factory
<zope.app.wsgi.WSGIPublisherApplication object at 0x...>
>>> from zope.interface import implementer
>>> from zope.security.interfaces import IUnauthorized
>>> @implementer(IUnauthorized)
... class UnauthorizedException(object):
...     pass
>>>
>>> from zope.component import queryAdapter
>>> from zope.publisher.interfaces import IReRaiseException

Since the exempt-execptions configuration option was not passed, there’s no IReRaiseException adapter registered for any type of exceptions including IUnauthorized:

>>> error = UnauthorizedException()
>>> reraise = queryAdapter(error, IReRaiseException, default=None)
>>> reraise is None
True

When the option is passed, the adapter will be registered. Calling this adapter yields False, telling zope not to reraise this particular exception.

>>> app_factory = debug_application_factory(
...     {'zope_conf': zope_conf},
...     **{'exempt-exceptions': 'zope.security.interfaces.IUnauthorized'})
>>>
>>> reraise = queryAdapter(error, IReRaiseException, default=None)
>>> reraise is None
False
>>> reraise()
False

Clean up the temp_dir

>>> import shutil
>>> shutil.rmtree(temp_dir)

interactive_debug_prompt(zope_conf_path)

Get an interactive console with a debugging shell started.

grokcore.startup provides two different debuggers currently: a plain one based on zope.app.debug and a more powerful IPython debugger. The IPython debugger is automatically enabled if you have IPython available in the environment.

You can explicitly enable the IPython debugger by stating:

grokcore.startup [debug]

in the install requirements of your setup.py, probably adding only [debug] to an already existing entry for grokcore.startup. Don’t forget to rerun buildout afterwards.

You can explicitly require one or the other debugger by calling:

grokcore.startup.startup.interactive_debug_prompt(zope_conf)

or:

grokcore.startup.debug.ipython_debug_prompt(zope_conf)

in the [interactive_debugger] section of your buildout.cfg.

>>> import zope.app.appsetup.appsetup
>>> zope.app.appsetup.appsetup._configured = False
>>> temp_dir = tempfile.mkdtemp()
>>> sitezcml = os.path.join(temp_dir, 'site.zcml')
>>> out = open(sitezcml, 'w')
>>> _ = out.write(
...    """<configure xmlns="http://namespaces.zope.org/zope">
...   <include package="zope.component" file="meta.zcml"/>
...   <include package="zope.component"/>
...   <include package="zope.traversing"/>
...   <include package="zope.security" file="meta.zcml"/>
...   <include package="zope.security"/>
...   <include package="zope.container"/>
...   <include package="zope.site"/>
...   <include package="zope.app.appsetup"/>
... </configure>""")
>>> out.close()
>>>
>>> zopeconf = os.path.join(temp_dir, 'zope.conf')
>>> out = open(zopeconf, 'w')
>>> _ = out.write("""
...     site-definition %s
...     <zodb>
...       <filestorage>
...         path %s
...       </filestorage>
...     </zodb>
...     <eventlog>
...       <logfile>
...         path STDOUT
...         formatter zope.exceptions.log.Formatter
...       </logfile>
...     </eventlog>
...     """ % (sitezcml, os.path.join(temp_dir, 'Data.fs')))
>>> out.close()
>>>
>>> import sys
>>> old_argv = sys.argv[:]
>>>
>>> script = os.path.join(temp_dir, 'script.py')
>>> out = open(script, 'w')
>>> _ = out.write(
...    """import sys
... from pprint import pprint
... pprint(debugger)
... pprint(app)
... pprint(root)
... pprint(sys.argv)
... pprint(__file__)
... pprint(__name__)""")
>>>
>>> out.close()
>>>
>>> sys.argv = ['interactive_debugger', script]
>>> from grokcore.startup import interactive_debug_prompt
>>> try:
...     interactive_debug_prompt(zopeconf)
... except SystemExit:
...     # Catch the exit from the interactive prompt as it would
...     # exit this test as well.
...     pass
------
...WARNING zope.app.appsetup Security policy is not configured.
Please make sure that securitypolicy.zcml is included in site.zcml
immediately before principals.zcml
...
<zope.app.debug.debug.Debugger object at ...>
<zope.app.debug.debug.Debugger object at ...>
<zope.site.folder.Folder object at ...>
['...script.py']
'...script.py'
'__main__'

Clean up the temp_dir

>>> sys.argv = old_argv
>>> import shutil
>>> shutil.rmtree(temp_dir)

Changes

4.1 (2024-05-22)

  • Add support for Python 3.12.

  • Update debug.py to run with IPython >= 8. Also requiring at least that version of IPython.

4.0 (2023-07-14)

  • Drop support for Python 2.7, 3.4, 3.5, 3.6.

  • Add support for Python 3.7, 3.8, 3.9, 3.10, 3.11.

3.0.1 (2018-01-12)

  • Rearrange tests such that Travis CI can pick up all functional tests too.

3.0.0 (2018-01-10)

  • Python 3 compatibility.

1.2.1 (2016-02-15)

  • Update tests.

1.2 (2012-05-02)

  • Added new IPython-based interactive debugger which is used automatically when IPython is available. Otherwise the gdb-style debugger is provided.

1.1 (2010-10-26)

  • Drop zdaemon support.

  • Close the database explicitely when execing a script through the interactive_debug_prompt. This came to light in tests on Windows, as the tests would try to delete the temp directory it created with the still unclosed database file in there.

1.0.2 (2010-10-05)

  • Somehow the intended fix in 1.0.1 did not actually get included in that release. We make the fix again.

1.0.1 (2010-08-18)

  • When passing a script to the interactive_debug_prompt command, one would expect to be able to do: if __name__ == ‘__main__’:, however __name__ would be “__builtin__”. This is fixed.

1.0 (2010-05-20)

  • Amend the interactive_debug_prompt function to behave more or less like the “old” zopectl command. Whenever there’s commandline arguments passed to the command, the first one is assumed to be a python script that is ‘execfile’d. This allows ad hoc scripts to run against the setup application.

  • Make package comply to zope.org repository policy.

  • The upgrade notes will be moved to the Grok upgrade notes.

  • Define entry points for main and debug application factories in grokcore.startup.

  • Use the groktoolkit.

0.4 (2009-10-06)

  • Fix documentation bugs.

0.3 (2009-10-02)

  • Add a debug_application_factory function that allows for the exempt-exceptions configuration option. The value for this option should be a comma seperated list of dotted names for each of the exceptions that should not be re-raised during debugging.

    This for one allow the IUnauthorized exception to still be handled by zope and thus have the normal authentication mechanisms still work.

  • Bring versions.cfg in line with current grok versions.cfg.

0.2 (2009-02-21)

  • Made main functions available package wide.

0.1 (2009-01-15)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

grokcore.startup-4.1.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

grokcore.startup-4.1-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file grokcore.startup-4.1.tar.gz.

File metadata

  • Download URL: grokcore.startup-4.1.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.9

File hashes

Hashes for grokcore.startup-4.1.tar.gz
Algorithm Hash digest
SHA256 b69f2bce2b54c522fa2c3705d73b59c1a9eeeb10642110e88b4edc447d92d8e0
MD5 19203c3bf622dfac2f8b6f757bd3afc6
BLAKE2b-256 92b08904e6a59df59bd9fa1beb35b1cb74f4cb9425f9ab974e096f45fc0a5b36

See more details on using hashes here.

File details

Details for the file grokcore.startup-4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for grokcore.startup-4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5446fb2519ea4f84c2a9b45cabd31425b18ddbede48d76d98228f9dd7ebb588d
MD5 af014cfc781640bdf8ddfa74c1e817da
BLAKE2b-256 ce1b11a6e1ea7a717405385bdaa563df9962d11bd5136a70e28ac97e2589e731

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page