Package: grokcore.startup
grokcore.startupThis package provides elements for starting aGrokproject withpasterandWSGI.Contentsgrokcore.startupSetting upgrokcore.startupDetailed DescriptionSetting up Grok projects aspasterserved WSGI applicationsSetting up a project withgrokprojectSetting up a project manuallyAPI Documentationapplication_factory(global_conf, **local_conf)debug_application_factory(global_conf, **local_conf)interactive_debug_prompt(zope_conf_path)Changes4.0 (2023-07-14)3.0.1 (2018-01-12)3.0.0 (2018-01-10)1.2.1 (2016-02-15)1.2 (2012-05-02)1.1 (2010-10-26)1.0.2 (2010-10-05)1.0.1 (2010-08-18)1.0 (2010-05-20)0.4 (2009-10-06)0.3 (2009-10-02)0.2 (2009-02-21)0.1 (2009-01-15)Setting upgrokcore.startupThere is nothing special to setup this package.All you have to do is, to make this package available during runtime.Withzc.buildoutor othersetuptools-related setups this can be
done by simply adding the package namegrokcore.startupto the
required packages of your project insetup.py.Detailed DescriptionSetting up Grok projects aspasterserved WSGI applicationsThe main target of this package is to provide support for enablingGrokapplications to be run aspasterservedWSGIapplications. To make this working some configuration files have to be
set up.Setting up a project withgrokprojectThe most convenient way to setup aGrokproject is usinggrokproject. Once installed, you can a project like this:$ grokproject Samplewhich will generate all configuration files for you.NoteOlder versions ofgrokprojectneed an updateAs older versions ofgrokprojectdo not supportgrokcore.startup, you might want to update your existinggrokprojectinstallation by running:$ easy_install -U grokprojectSetting up a project manuallyBefore we can make use ofgrokcore.startup, we have to setup
several configuration files in the project root:setup.pybuildout.cfg(optional)zope.conf(normally found in theparts/etc/subdirectory of yourGrokproject)site.zcml(normally found in theparts/etc/subdirectory of yourGrokproject)deploy.ini(or any other .ini-file; normally found in theparts/etc/subdirectory of yourGrokproject)When we want to setup a Zope instance aspasterservedWSGIapplication, then we have to set apaste.app_factoryentry point
insetup.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 thepaste.app_factoryentry point pointing togrokcore.startup:application_factoryis important.Furthermore we need at least a minimalbuildout.cfgwhich enableszc.buildoutto create the control scripts for our instance:[buildout]
develop = .
parts = app

[app]
recipe = zc.recipe.egg
eggs = sampleproject
       grokcore.startup
       Paste
       PasteScript
       PasteDeployHere an egg-entry forgrokcore.startupmightbe important, if
it is not required otherwise by your application. Projects generated
bygrokprojectwill automatically include such a dependency and
upcoming versions ofGrokwill pull ingrokcore.startupanyway,
so thatgrokcore.startupwould not be required in this list of
eggs any more.Next we needsite.zcmlandzope.conffiles to define the
Zope instance. These configurations are completely independent from
being served byPasteor not. If you are upgrading an oldGrokproject, you can usesite.zcmlandzope.confof those project
as-is. You only have to take care of the maybe changedsite-definitionentry inzope.conf(see below).The filesite.zcmlcan be quite
short, but for real projects you certainly want to have some useful
content in here:<configure />A shortzope.conffile for use in tests could look like this:site-definition site.zcml

<zodb>
  <mappingstorage />
</zodb>

<eventlog>
  <logfile>
    path STDOUT
   </logfile>
</eventlog>where thesite-definitionentry should point to the location of
the filesite.zcml. In regular Grok projects those files are put
into theetc/subdirectory of your project root.Finally we have to provide adeploy.ini(or another .ini-file),
which tells paster where to find the pieces. This is also put into theetc/subdirectory of your project root in regular Grok projects
created bygrokproject:[app:main]
use = egg:sampleproject

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

[DEFAULT]
zope_conf = %(here)s/zope.confAPI Documentationapplication_factory(global_conf, **local_conf)grokcore.startupprovides a functionapplication_factorywhich delivers aWSGIPublisherApplicationinstance when called
with an appropriate configuration. See thezope.app.wsgi
documentationto learn more about Zope objects supportingWSGI.A call to this function is normally required as entry point insetuptools-drivenpasterenvironments  (seehttp://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 callapplication_factoryto 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 thez3c.evalexceptionmiddleware.When debugging zope is instructed not to handle any raised exceptions
itself. Thez3c.evalexceptionmiddleware 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.Thedebug_application_factoryfunction 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 shouldstillbe
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 IReRaiseExceptionSince theexempt-execptionsconfiguration 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
TrueWhen the option is passed, the adapter will be registered. Calling this
adapter yieldsFalse, 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()
FalseClean 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.startupprovides two different debuggers currently: a
plain one based onzope.app.debugand a more powerfulIPythondebugger. The IPython debugger is automatically enabled if you have
IPython available in the environment.You can explicitly enable theIPythondebugger by stating:grokcore.startup [debug]in the install requirements of yoursetup.py, probably adding only[debug]to an already existing entry forgrokcore.startup. Don’t forget to rerunbuildoutafterwards.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 yourbuildout.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)Changes4.0 (2023-07-14)Add support for Python 3.10, 3.11.Drop support for Python 2.7, 3.5, 3.6.Add support for Python 3.7, 3.8 and 3.9.Drop support for Python 3.4.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 theinteractive_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 adebug_application_factoryfunction that allows for theexempt-exceptionsconfiguration 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)Added support for localzope_confparameter.
Fix bughttps://bugs.launchpad.net/grok/+bug/320644Createdgrokcore.startupin January 2009 by factoring paster
related application code out of grokcore templates.