{ "info": { "author": "Jim Fulton", "author_email": "jim@zope.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Buildout", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "***********************************************\nZope3 Application, Instance and Offline Recipes\n***********************************************\n\nRecipes for creating Zope 3 instances with distinguishing features:\n\n- Don't use a skeleton\n\n- Separates application and instance definition\n\n- Don't support package-includes\n\n- Support offline instance.\n\nUnfortunately, partial Windows support at this time. It works but it's alpha.\n\n.. contents::\n\n\n==========\n Releases\n==========\n\n0.19.0 (2019-07-12)\n===================\n\n- Fix TypeError: () takes no arguments (1 given) on Windows\n with zdaemon >= 3.0.0.\n\n- Support Python 3.5 through 3.7.\n\n\n0.18.0 (2013/02/05)\n===================\n\n- For the offline recipe, check the effective UID instead of the actual UID.\n- Make the tests pass with modern buildouts, including buildout 2.\n\n\n0.17.0 (2012/02/07)\n===================\n\n- Added \"location\" value as output of the zopeconf recipe to make it\n easier to use in place of ``zc.recipe.deployment:configuration``.\n\n\n0.16.0 (2012/01/15)\n===================\n\n- Added support for using Paste Deployment to specify a WSGI stack\n over a zope.app-based application.\n\n\n0.15.0 (2011/12/12)\n===================\n\n- Added zopeconf recipe to produce decently-formatted zope.conf files,\n without constructing an instance.\n\n\n0.14.1 (2011/12/08)\n===================\n\n- Fixed ReST on pypi page.\n\n\n0.14.0 (2011/12/08)\n===================\n\n- Execute $PYTHONSTARTUP in the environment that the user will interact\n with in zc.zope3recipes.debugzope; this mirrors how $PYTHONSTARTUP is\n used with an interactive interpreter.\n- Added a recipe for offline instance.\n- Fixed tests to pass with zc.buildout >= v1.5\n\n\n0.13.0 (2010/11/24)\n===================\n\n- Support inserting additional code into the runzope & debugzope scripts\n using ``initialization`` and ``debug-initialization``.\n\n\n0.12.0 (2010/11/22)\n===================\n\n- Provide control for generation of the logrotate configuration, include the\n ability to suppress it when not desired.\n\n\n0.11.1 (2010/11/12)\n===================\n\n- Added an environment hook to enable logging for debugzope\n\n\n0.11.0 (2009/10/01)\n===================\n\n- Added support and tests for relative paths buildout option.\n- Changed the dependency requirements to >=1.2.0 for zc.buildout and\n zc.recipe.egg because relative paths are added in these releases.\n- Added missing release date for the previous release (0.10.0).\n\n\n0.10.0 (2009/09/16)\n===================\n\nRemoved support for creating a logrotate script for the access.log because it\nis not possible to reopen the log with ZDaemons ``reopen_transacript``. Note\nhowever that is is possible to declare ``when`` and ``interval`` in a logfile\nsection to rotate logfiles internally.\n\n\n0.9.0 (2009/07/21)\n==================\n\nUpdated tests to work with latest package versions.\n\n\n0.8.0 (2009/04/03)\n==================\n\nAdded the \"newest=false\" option in the SetUp to prevent upgrade during tests\n\nAdded support for creating logrotate scripts when using a deployment recipe.\n\n\n0.7.0 (2008/02/01)\n==================\n\nUse the deployment name option (as provided by zc.recipe.deployment\n0.6.0 and later) if present when generating instance file names.\n\nYou can now specify an instance name option that overrides the part\nname for generated files.\n\n\n0.6.1 (2007/12/17)\n==================\n\nFixed bug: The zope.conf site-definition option could not be overridden.\n\n\n0.6.0 (2007/11/03)\n==================\n\nFinal release with Windows support.\n\n\n0.6b1 (2007/08/21)\n==================\n\nWindows support was added.\n\n\n0.5.5 (2007/07/26)\n==================\n\nNow debugzope takes the servers key of the application into account.\n\n\n0.5.3 (2007/07/14)\n==================\n\nCreated another recipe called 'application' that installs Zope 3\nsolely from eggs. The 'app' recipe is just an extension that also\nsupports Zope 3 from checkout or tarball.\n\n\n0.5.2 (2007/06/21)\n==================\n\nUse ZConfig's schema-free configuration parsing gain support for\n%import.\n\n\n0.5.1 (2007/05/22)\n==================\n\nSupport repeated keys in ZConfig sections.\n\n\n0.5.0 (2007/03/21)\n==================\n\nSupport building Zope 3 application solely from eggs.\n\n========================\n Detailed Documentation\n========================\n\nThe Zope 3 recipes allow one to define Zope applications and instances\nof those applications. A Zope application is a collection of software\nand software configuration, expressed as ZCML. A Zope instance\ninvokes the application with a specific instance configuration. A\nsingle application may have many instances.\n\n\nBuilding Zope 3 applications (from eggs)\n========================================\n\nThe 'application' recipe can be used to define a Zope application. It\nis designed to work with with Zope solely from eggs. The app recipe\ncauses a part to be created. The part will contain the scripts runzope\nand debugzope and the application's site.zcml. Both of the scripts\nwill require providing a -C option and the path to a zope.conf file\nwhen run. The debugzope script can be run with a script name and\narguments, in which case it will run the script, rather than starting\nan interactive session.\n\nThe 'application' recipe accepts the following options:\n\nsite.zcml\n The contents of site.zcml.\n\neggs\n The names of one or more eggs, with their dependencies that should\n be included in the Python path of the generated scripts.\n\n\nLets define some (bogus) eggs that we can use in our application:\n\n >>> mkdir('demo1')\n >>> write('demo1', 'setup.py',\n ... '''\n ... from setuptools import setup\n ... setup(name = 'demo1')\n ... ''')\n\n >>> mkdir('demo2')\n >>> write('demo2', 'setup.py',\n ... '''\n ... from setuptools import setup\n ... setup(name = 'demo2', install_requires='demo1')\n ... ''')\n\n.. Please note that the \"newest=false\" option is set in the test SetUp to\n prevent upgrades\n\nWe'll create a buildout.cfg file that defines our application:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\nNow, Let's run the buildout and see what we get:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nThe runzope script runs the Web server:\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n ]\n \n import zope.app.twisted.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.twisted.main.main())\n\nHere, unlike the above example the location path is not included\nin ``sys.path``. Similarly debugzope script is also changed:\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zc.zope3recipes',\n ]\n \n import zope.app.twisted.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.twisted.main))\n\nThe ``initialization`` setting can be used to provide a bit of\nadditional code that will be included in the runzope and debugzope\nscripts just before the server's main function is called:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo2\n ... initialization =\n ... print(\"Starting application server.\")\n ... ''')\n\nNow, Let's run the buildout and see what we get:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nThe runzope and debugzope scripts now include the additional code just\nbefore server is started:\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n ]\n \n print(\"Starting application server.\")\n \n import zope.app.twisted.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.twisted.main.main())\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zc.zope3recipes',\n ]\n \n print(\"Starting application server.\")\n import zope.app.twisted.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.twisted.main))\n\nIf the additional initialization for debugzope needs to be different\nfrom that of runzope, the ``debug-initialization`` setting can be used.\nIf set, that is used for debugzope *instead* of the value of\n``initialization``.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo2\n ... initialization =\n ... print(\"Starting application server.\")\n ... debug-initialization =\n ... print(\"Starting debugging interaction.\")\n ... ''')\n\nNow, Let's run the buildout and see what we get:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zc.zope3recipes',\n ]\n \n print(\"Starting debugging interaction.\")\n import zope.app.twisted.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.twisted.main))\n\nThe runzope script still uses the ``initialization`` setting::\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n ]\n \n print(\"Starting application server.\")\n \n import zope.app.twisted.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.twisted.main.main())\n\nSetting ``debug-initialization`` to an empty string suppresses the\n``initialization`` setting for the debugzope script:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo2\n ... initialization =\n ... print(\"Starting application server.\")\n ... debug-initialization =\n ... ''')\n\nNow, Let's run the buildout and see what we get:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zc.zope3recipes',\n ]\n \n import zope.app.twisted.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.twisted.main))\n\n\nRelative paths\n--------------\n\nIf requested in a buildout configuration, the scripts will be generated\nwith relative paths instead of absolute.\n\nLet's change a buildout configuration to include ``relative-paths``.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ... relative-paths = true\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nWe get runzope script with relative paths.\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import os\n \n join = os.path.join\n base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))\n base = os.path.dirname(base)\n base = os.path.dirname(base)\n \n import sys\n sys.path[0:0] = [\n join(base, 'demo2'),\n join(base, 'demo1'),\n ]\n \n import zope.app.twisted.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.twisted.main.main())\n\nSimilarly, debugzope script has relative paths.\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import os\n \n join = os.path.join\n base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))\n base = os.path.dirname(base)\n base = os.path.dirname(base)\n \n import sys\n sys.path[0:0] = [\n join(base, 'demo2'),\n join(base, 'demo1'),\n '/zc.zope3recipes',\n ]\n \n import zope.app.twisted.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.twisted.main))\n\n\nBuilding Zope 3 Applications (from Zope 3 checkouts/tarballs)\n=============================================================\n\nThe 'app' recipe works much like the 'application' recipe. It takes\nthe same configuration options plus the following one:\n\nzope3\n The name of a section defining a location option that gives the\n location of a Zope installation. This can be either a checkout or a\n distribution. If the location has a lib/python subdirectory, it is\n treated as a distribution, otherwise, it must have a src\n subdirectory and will be treated as a checkout. This option defaults\n to \"zope3\". And if location is empty, the application will run solely\n from eggs.\n\nLet's look at an example. We'll make a faux zope installation:\n\n >>> zope3 = tmpdir('zope3')\n >>> mkdir(zope3, 'src')\n\nNow we'll create a buildout.cfg file that defines our application:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\nNote that our site.zcml file is very small. It expect the application\nzcml to define almost everything. In fact, a site.zcml file will often\ninclude just a single include directive. We don't need to include the\nsurrounding configure element, unless we want a namespace other than\nthe zope namespace. A configure directive will be included for us.\n\nLet's run the buildout and see what we get:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nA directory is created in the parts directory for our application\nfiles. Starting with zc.buildout >= v1.5, and distribute, a \"buildout\"\ndirectory is created in the parts folder. Since the minimum version we support\nfor zc.buildout is lower than v1.5, we use a custom \"ls\" functional called\n\"ls_optional\" to which we pass a list of folders that may be present. These are\nignore by the function.\n\n >>> from zc.zope3recipes.tests import ls_optional\n >>> ls_optional('parts', ignore=('buildout',))\n d myapp\n\n >>> ls('parts', 'myapp')\n - debugzope\n - runzope\n - site.zcml\n\nWe get 3 files, two scripts and a site.zcml file. The site.zcml file\nis just what we had in the buildout configuration:\n\n >>> cat('parts', 'myapp', 'site.zcml')\n \n \n \n \n \n\nUnfortunately, the leading whitespace is stripped from the\nconfiguration file lines. This is a consequence of the way\nConfigParser works.\n\nThe runzope script runs the Web server:\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zope3/src',\n ]\n \n import zope.app.twisted.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.twisted.main.main())\n\nIt includes in it's path the eggs we specified in the configuration\nfile, along with their dependencies. Note that we haven't specified a\nconfiguration file. When runzope is run, a -C option must be used to\nprovide a configuration file. -X options can also be provided to\noverride configuration file options.\n\nThe debugzope script provides access to the object system. When\ndebugzope is run, a -C option must be used to provide a configuration\nfile. -X options can also be provided to override configuration file\noptions. If run without any additional arguments, then an interactive\ninterpreter will be started with databases specified in the\nconfiguration file opened and with the variable root set to the\napplication root object. The debugger variable is set to a Zope 3\ndebugger. If additional arguments are provided, then the first\nargument should be a script name and the remaining arguments are\nscript arguments. The script will be run with the root and debugger\nvariables available as global variables.\n\n..\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zope3/src',\n '/zc.zope3recipes',\n ]\n \n import zope.app.twisted.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.twisted.main))\n\nNote that the runzope shown above uses the default, twisted-based\nserver components. It's possible to specify which set of server\ncomponents is used: the \"servers\" setting can be set to either\n\"zserver\" or \"twisted\". For the application, this affects the runzope\nscript; we'll see additional differences when we create instances of\nthe application.\n\nLet's continue to use the twisted servers, but make the selection\nexplicit:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... servers = twisted\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Updating myapp.\n\nNote that this is recognized as not being a change to the\nconfiguration; the messages say that myapp was updated, not\nuninstalled and then re-installed.\n\nThe runzope script generated is identical to what we saw before:\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zope3/src',\n ]\n \n import zope.app.twisted.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.twisted.main.main())\n\nWe can also specify the ZServer servers explicitly:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... servers = zserver\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nThe part has been re-installed, and the runzope script generated is\ndifferent now. Note that the main() function is imported from a\ndifferent package this time:\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zope3/src',\n ]\n \n import zope.app.server.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.server.main.main())\n\nThe debugzope script has also been modified to take this into account.\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/zope3/src',\n '/zc.zope3recipes',\n ]\n \n import zope.app.server.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.server.main))\n\n\nRelative paths\n--------------\n\nWe can also request relative paths.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ... relative-paths = true\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... servers = zserver\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nThe runzope script has relative paths.\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/bin/python2.4\n \n import os\n \n join = os.path.join\n base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))\n base = os.path.dirname(base)\n base = os.path.dirname(base)\n \n import sys\n sys.path[0:0] = [\n join(base, 'demo2'),\n join(base, 'demo1'),\n '/zope3/src',\n ]\n \n import zope.app.server.main\n \n if __name__ == '__main__':\n sys.exit(zope.app.server.main.main())\n\nThe debugzope script also has relative paths.\n\n >>> cat('parts', 'myapp', 'debugzope')\n #!/usr/local/bin/python2.4\n \n import os\n \n join = os.path.join\n base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))\n base = os.path.dirname(base)\n base = os.path.dirname(base)\n \n import sys\n sys.path[0:0] = [\n join(base, 'demo2'),\n join(base, 'demo1'),\n '/zope3/src',\n '/zc.zope3recipes',\n ]\n \n import zope.app.server.main\n \n \n import zc.zope3recipes.debugzope\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.debugzope.debug(main_module=zope.app.server.main))\n\n\nLegacy Functional Testing Support\n---------------------------------\n\nZope 3's functional testing support is based on zope.testing test\nlayers. There is a default functional test layer that older functional\ntests use. This layer loads the default configuration for the Zope\napplication server. It exists to provide support for older functional\ntests that were written before layers were added to the testing\ninfrastructure. The default testing layer has a number of\ndisadvantages:\n\n- It loads configurations for a large number of packages. This has\n the potential to introduce testing dependency on all of these\n packages.\n\n- It required a ftesting.zcml file and makes assumptions about where\n that file is. In particular, it assumes a location relative to the\n current working directory when the test is run.\n\nNewer software and maintained software should use their own functional\ntesting layers that use test-configuration files defined in packages.\n\nTo support older packages that use the default layer, a ftesting.zcml\noption is provided. If it is used, then the contents of the option\nare written to a ftesting.zcml file in the application. In addition,\nan ftesting-base.zcml file is written that includes configuration\ntraditionally found in a Zope 3 ftesting-base.zcml excluding reference\nto package-includes.\n\nIf we modify our buildout to include an ftesting.zcml option:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = myapp\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... ftesting.zcml =\n ... \n ... \n ... \n ... eggs = demo2\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n\nWe'll get ftesting.zcml files and ftesting-base.zcml files created in\nthe application:\n\n >>> cat('parts', 'myapp', 'ftesting.zcml')\n \n \n \n \n \n \n\n >>> cat('parts', 'myapp', 'ftesting-base.zcml')\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\nDefining Zope3 instances\n========================\n\nHaving defined an application, we can define one or more instances of\nthe application. We do this using the zc.zope3recipes instance\nrecipe. The instance recipe has 2 modes, a development and a\nproduction mode. We'll start with the development mode. In\ndevelopment mode, a part directory will be created for each instance\ncontaining the instance's configuration files. This directory will\nalso contain run-time files created by the instances, such as log\nfiles or zdaemon socket files.\n\nWhen defining an instance, we need to specify a zope.conf file. The\nrecipe can do most of the work for us. Let's look at a a basic\nexample:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\nThe application option names an application part. The application\npart will be used to determine the location of the site.zcml file and\nthe name of the control script to run.\n\nWe specified a zope.conf option which contains a start at our final\nzope.conf file. The recipe will add some bits we leave out. The one\nthing we really need to have is a database definition. We simply\ninclude the zconfig option from the database section, which we provide\nas a file storage part using the zc.recipe.filestorage recipe. The\nfilestorage recipe will create a directory to hold our database and\ncompute a zconfig option that we can use in our instance section.\n\nNote that we've replaced the myapp part with the instance part. The\nmyapp part will be included by virtue of the reference from the\ninstance part.\n\nLet's run the buildout, and see what we get:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling myapp.\n Installing database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\nWe see that the database and myapp parts were included by virtue of\nbeing referenced from the instance part.\n\nWe get new directories for our database and instance:\n\n >>> ls_optional('parts', ignore=('buildout',))\n d database\n d instance\n d myapp\n\nThe instance directory contains zdaemon.conf and zope.conf files:\n\n >>> ls('parts', 'instance')\n - zdaemon.conf\n - zope.conf\n\nLet's look at the zope.conf file that was generated:\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8080\n type HTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nThis uses the twisted server types, since that's the default\nconfiguration for Zope 3. If we specify use of the ZServer servers,\nthe names of the server types are adjusted appropriately:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... servers = zserver\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Uninstalling myapp.\n Updating database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\nThe generated zope.conf file now uses the ZServer server components\ninstead:\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8080\n type WSGI-HTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nThe Twisted-based servers can also be specified explicitly:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... servers = twisted\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Uninstalling myapp.\n Updating database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\nThe generated zope.conf file now uses the Twisted server components\nonce more:\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8080\n type HTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nIt includes the database definition that we provided in the zope.conf\noption. It has a site-definition option that names the site.zcml file\nfrom our application directory.\n\nWe didn't specify any server or logging ZConfig sections, so some were\ngenerated for us.\n\nNote that, by default, the event-log output goes to standard output.\nWe'll say more about that when we talk about the zdaemon\nconfiguration later.\n\nIf we specify a server section ourselves:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... \n ... type PostmortemDebuggingHTTP\n ... address 8080\n ... \n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\nThen the section (or sections) we provide will be used and new ones\nwon't be added:\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8080\n type PostmortemDebuggingHTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nIf we just want to specify alternate ports or addresses, we can use\nthe address option which accepts zero or more address specifications:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081 foo.com:8082\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8081\n type HTTP\n \n \n \n address foo.com:8082\n type HTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nWe can specify our own accesslog and eventlog configuration. For\nexample, to send the event-log output to a file and suppress the\naccess log:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... \n ... \n ... path ${buildout:parts-directory}/instance/event.log\n ... formatter zope.exceptions.log.Formatter\n ... \n ... \n ... \n ... \n ...\n ... address = 8081\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path /sample-buildout/parts/instance/event.log\n \n \n \n \n \n \n \n address 8081\n type HTTP\n \n\nLet's look at the zdaemon.conf file:\n\n >>> cat('parts', 'instance', 'zdaemon.conf')\n \n daemon on\n directory /sample-buildout/parts/instance\n program /sample-buildout/parts/myapp/runzope -C /sample-buildout/parts/instance/zope.conf\n socket-name /sample-buildout/parts/instance/zdaemon.sock\n transcript /sample-buildout/parts/instance/z3.log\n \n \n \n \n path /sample-buildout/parts/instance/z3.log\n \n \n\nHere we see a fairly ordinary zdaemon.conf file. The program option\nrefers to the runzope script in our application directory. The socket\nfile, used for communication between the zdaemon command-line script\nand the zademon manager is placed in the instance directory.\n\nIf you want to override any part of the generated zdaemon output,\nsimply provide a zdaemon.conf option in your instance section:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n >>> cat('parts', 'instance', 'zdaemon.conf')\n \n daemon off\n directory /sample-buildout/parts/instance\n program /sample-buildout/parts/myapp/runzope -C /sample-buildout/parts/instance/zope.conf\n socket-name /sample-buildout/parts/instance/sock\n transcript /dev/null\n \n \n \n \n\nIn addition to the configuration files, a control script is generated\nin the buildout bin directory:\n\n >>> ls('bin')\n - buildout\n - instance\n\n..\n\n >>> cat('bin', 'instance')\n #!/usr/local/bin/python2.4\n \n import sys\n sys.path[0:0] = [\n '/site-packages',\n '/zc.zope3recipes',\n ]\n \n import zc.zope3recipes.ctl\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.ctl.main([\n '/sample-buildout/parts/myapp/debugzope',\n '/sample-buildout/parts/instance/zope.conf',\n '-C', '/sample-buildout/parts/instance/zdaemon.conf',\n ]+sys.argv[1:]\n ))\n\nSome configuration sections can include a key multiple times; the ZEO\nclient section works this way. When a key is given multiple times,\nall values are included in the resulting configuration in the order in\nwhich they're give in the input::\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf =\n ... \n ... \n ... server 127.0.0.1:8001\n ... server 127.0.0.1:8002\n ... \n ... \n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Uninstalling database.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n server 127.0.0.1:8001\n server 127.0.0.1:8002\n \n \n \n \n address 8081\n type HTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nInstance names\n--------------\n\nThe instance recipe generates files or directories based on its name,\nwhich defaults to the part name. We can specify a different name\nusing the name option. This doesn't effect which parts directory is\nused, but it does affect the name of the run script in bin:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... name = server\n ... application = myapp\n ... zope.conf =\n ... \n ... \n ... server 127.0.0.1:8001\n ... server 127.0.0.1:8002\n ... \n ... \n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/server'.\n\n\nSpecifying an alternate site definition\n---------------------------------------\n\nIdeally, ZCML is used to configure the software used by an application\nand zope.conf is used to provide instance-specific configuration. For\nhistorical reasons, there are ZCML directives that provide process\nconfiguration. A good example of this is the smtpMailer directive\nprovided by the zope.sendmail package. We can override the\nsite-definition option in the zope.conf file to specify an alternate\nzcml file. Here, we'll update out instance configuration to use an\nalternate site definition:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf =\n ... site-definition ${buildout:directory}/site.zcml\n ... \n ... \n ... server 127.0.0.1:8001\n ... server 127.0.0.1:8002\n ... \n ... \n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/site.zcml\n \n \n \n server 127.0.0.1:8001\n server 127.0.0.1:8002\n \n \n \n \n address 8081\n type HTTP\n \n \n \n \n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\n(Note that, in practice, you'll often use the\nzc.recipe.deployment:configuration recipe,\nhttp://pypi.python.org/pypi/zc.recipe.deployment#configuration-files,\nto define a site.zcml file using the buildout.)\n\nLog files\n---------\n\nThe log file settings deserver some explanation. The Zope event log\nonly captures output from logging calls. In particular, it doesn't\ncapture startup errors written to standard error. The zdaemon\ntranscript log is very useful for capturing this output. Without it,\nerror written to standard error are lost when running as a daemon.\nThe default Zope 3 configuration in the past was to write the Zope\naccess and event log output to both files and standard output and to\ndefine a transcript log. This had the effect that the transcript\nduplicated the contents of the event log and access logs, in addition\nto capturing other output. This was space inefficient.\n\nThis recipe's approach is to combine the zope and zdaemon event-log\ninformation as well as Zope error output into a single log file. We\ndo this by directing Zope's event log to standard output, where it is\nuseful when running Zope in foreground mode and where it can be\ncaptured by the zdaemon transcript log.\n\nUnix Deployments\n----------------\n\nThe instance recipe provides support for Unix deployments, as provided\nby the zc.recipe.deployment recipe. A deployment part defines a number of\noptions used by the instance recipe:\n\netc-directory\n The name of the directory where configuration files should be\n placed. This defaults to /etc/NAME, where NAME is the deployment\n name.\n\nlog-directory\n The name of the directory where application instances should write\n their log files. This defaults to /var/log/NAME, where NAME is\n the deployment name.\n\nrun-directory\n The name of the directory where application instances should put\n their run-time files such as pid files and inter-process\n communication socket files. This defaults to /var/run/NAME, where\n NAME is the deployment name.\n\nrc-directory\n The name of the directory where run-control scripts should be\n installed.\n\nlogrotate-directory\n The name of the directory where logrotate configuration files should be\n installed.\n\nuser\n The name of a user that processes should run as.\n\nThe deployment recipe has to be run as root for various reasons, but\nwe can create a faux deployment by providing a section with the needed\ndata. Let's update our configuration to use a deployment. We'll first\ncreate a faux installation root:\n\n >>> root = tmpdir('root')\n >>> mkdir(root, 'etc')\n >>> mkdir(root, 'etc', 'myapp-run')\n >>> mkdir(root, 'etc', 'init.d')\n >>> mkdir(root, 'etc', 'logrotate.d')\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081\n ... deployment = myapp-deployment\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ...\n ... [myapp-deployment]\n ... name = myapp-run\n ... etc-directory = %(root)s/etc/myapp-run\n ... rc-directory = %(root)s/etc/init.d\n ... logrotate-directory = %(root)s/etc/logrotate.d\n ... log-directory = %(root)s/var/log/myapp-run\n ... run-directory = %(root)s/var/run/myapp-run\n ... user = zope\n ... ''' % globals())\n\nHere we've added a deployment section, myapp-deployment, and added a\ndeployment option to our instance part telling the instance recipe to\nuse the deployment. If we rerun the buildout:\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Installing database.\n Updating myapp.\n Installing instance.\n Generated script '/root/etc/init.d/myapp-run-instance'.\n\nThe installer files will move. We'll no-longer have the instance part:\n\n >>> ls_optional('parts', ignore=('buildout',))\n d database\n d myapp\n\nor the control script:\n\n >>> ls('bin')\n - buildout\n\nRather, we'll get our configuration files in the /etc/myapp-run directory:\n\n >>> ls(root, 'etc', 'myapp-run')\n - instance-zdaemon.conf\n - instance-zope.conf\n\nNote that the instance name was added as a prefix to the file names,\nsince we'll typically have additional instances in the deployment.\n\nThe control script is in the init.d directory:\n\n >>> ls(root, 'etc', 'init.d')\n - myapp-run-instance\n\nNote that the deployment name is added as a prefix of the control\nscript name.\n\nThe logrotate file is in the logrotate.d directory:\n\n >>> ls(root, 'etc', 'logrotate.d')\n - myapp-run-instance\n\n\nThe configuration files have changed to reflect the deployment\nlocations:\n\n >>> cat(root, 'etc', 'myapp-run', 'instance-zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8081\n type HTTP\n \n \n \n \n path /root/var/log/myapp-run/instance-access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\n >>> cat(root, 'etc', 'myapp-run', 'instance-zdaemon.conf')\n \n daemon on\n directory /root/var/run/myapp-run\n program /sample-buildout/parts/myapp/runzope -C /root/etc/myapp-run/instance-zope.conf\n socket-name /root/var/run/myapp-run/instance-zdaemon.sock\n transcript /root/var/log/myapp-run/instance-z3.log\n user zope\n \n \n \n \n path /root/var/log/myapp-run/instance-z3.log\n \n \n\n >>> cat(root, 'etc', 'logrotate.d', 'myapp-run-instance')\n /root/var/log/myapp-run/instance-z3.log {\n rotate 5\n weekly\n postrotate\n /root/etc/init.d/myapp-run-instance reopen_transcript\n endscript\n }\n\n\nIf we provide an alternate instance name, that will be reflected in\nthe generated files:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... name = server\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081\n ... deployment = myapp-deployment\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ...\n ... [myapp-deployment]\n ... name = myapp-run\n ... etc-directory = %(root)s/etc/myapp-run\n ... rc-directory = %(root)s/etc/init.d\n ... logrotate-directory = %(root)s/etc/logrotate.d\n ... log-directory = %(root)s/var/log/myapp-run\n ... run-directory = %(root)s/var/run/myapp-run\n ... user = zope\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/root/etc/init.d/myapp-run-server'.\n\n >>> cat(root, 'etc', 'myapp-run', 'server-zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8081\n type HTTP\n \n \n \n \n path /root/var/log/myapp-run/server-access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\n >>> cat(root, 'etc', 'myapp-run', 'server-zdaemon.conf')\n \n daemon on\n directory /root/var/run/myapp-run\n program /sample-buildout/parts/myapp/runzope -C /root/etc/myapp-run/server-zope.conf\n socket-name /root/var/run/myapp-run/server-zdaemon.sock\n transcript /root/var/log/myapp-run/server-z3.log\n user zope\n \n \n \n \n path /root/var/log/myapp-run/server-z3.log\n \n \n\n\nControlling logrotate configuration\n-----------------------------------\n\nSome applications control their own log rotation policies. In these\ncases, we don't want the logrotate configuration to be generated.\n\nSetting the logrotate.conf setting affects the configuration. Setting\nit explicitly controls the content of the logrotate file for the\ninstance; setting it to an empty string causes it not to be generated at\nall.\n\nLet's take a look at setting the content to a non-empty value directly:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081\n ... deployment = myapp-deployment\n ... logrotate.conf =\n ... /root/var/log/myapp-run/instance-z3.log {\n ... rotate 10\n ... daily\n ... postrotate\n ... /root/etc/init.d/myapp-run-instance reopen_transcript\n ... endscript\n ... }\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ...\n ... [myapp-deployment]\n ... name = myapp-run\n ... etc-directory = %(root)s/etc/myapp-run\n ... rc-directory = %(root)s/etc/init.d\n ... logrotate-directory = %(root)s/etc/logrotate.d\n ... log-directory = %(root)s/var/log/myapp-run\n ... run-directory = %(root)s/var/run/myapp-run\n ... user = zope\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Uninstalling myapp.\n Updating database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/root/etc/init.d/myapp-run-instance'.\n\n >>> cat(root, 'etc', 'logrotate.d', 'myapp-run-instance')\n /root/var/log/myapp-run/instance-z3.log {\n rotate 10\n daily\n postrotate\n /root/etc/init.d/myapp-run-instance reopen_transcript\n endscript\n }\n\nIf we set ``logrotate.conf`` to an empty string, the file is not generated:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081\n ... deployment = myapp-deployment\n ... logrotate.conf =\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ...\n ... [myapp-deployment]\n ... name = myapp-run\n ... etc-directory = %(root)s/etc/myapp-run\n ... rc-directory = %(root)s/etc/init.d\n ... logrotate-directory = %(root)s/etc/logrotate.d\n ... log-directory = %(root)s/var/log/myapp-run\n ... run-directory = %(root)s/var/run/myapp-run\n ... user = zope\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/root/etc/init.d/myapp-run-instance'.\n\n >>> ls(root, 'etc', 'logrotate.d')\n\n\nDefining multiple similar instances\n-----------------------------------\n\nOften you want to define multiple instances that differ only by one or\ntwo options (e.g. an address). The extends option lets you name a\nsection from which default options should be loaded. Any options in\nthe source section not defined in the extending section are added to\nthe extending section.\n\nLet's update our buildout to add a new instance:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance instance2\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ... address = 8081\n ... deployment = myapp-deployment\n ...\n ... [instance2]\n ... recipe = zc.zope3recipes:instance\n ... extends = instance\n ... address = 8082\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ...\n ... [myapp-deployment]\n ... name = myapp-run\n ... etc-directory = %(root)s/etc/myapp-run\n ... rc-directory = %(root)s/etc/init.d\n ... logrotate-directory = %(root)s/etc/logrotate.d\n ... log-directory = %(root)s/var/log/myapp-run\n ... run-directory = %(root)s/var/run/myapp-run\n ... user = zope\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Uninstalling myapp.\n Updating database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/root/etc/init.d/myapp-run-instance'.\n Installing instance2.\n Generated script '/root/etc/init.d/myapp-run-instance2'.\n\nNow, we have the new instance configuration files:\n\n >>> ls(root, 'etc', 'myapp-run')\n - instance-zdaemon.conf\n - instance-zope.conf\n - instance2-zdaemon.conf\n - instance2-zope.conf\n\n >>> cat(root, 'etc', 'myapp-run', 'instance2-zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n address 8082\n type HTTP\n \n \n \n \n path /root/var/log/myapp-run/instance2-access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\n\nRelative paths\n--------------\n\nRelative paths will be used in the control script if they are requested\nin a buildout configuration.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ... relative-paths = true\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf = ${database:zconfig}\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance2.\n Uninstalling instance.\n Uninstalling myapp.\n Updating database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n Both ``sys.path`` and arguments to the `ctl` are using relative\n paths now.\n\n >>> cat('bin', 'instance')\n #!/usr/local/bin/python2.4\n \n import os\n \n join = os.path.join\n base = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))\n base = os.path.dirname(base)\n \n import sys\n sys.path[0:0] = [\n '/site-packages',\n '/zc.zope3recipes',\n ]\n \n import zc.zope3recipes.ctl\n \n if __name__ == '__main__':\n sys.exit(zc.zope3recipes.ctl.main([\n join(base, 'parts/myapp/debugzope'),\n join(base, 'parts/instance/zope.conf'),\n '-C', join(base, 'parts/instance/zdaemon.conf'),\n ]+sys.argv[1:]\n ))\n\n\nzope.conf recipe\n================\n\nThe zope.conf recipe handles filling in the implied bits of a zope.conf\nfile that the instance recipe performs, without creating the rest of an\ninstance.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1\n ... parts = some.conf\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo1\n ...\n ... [some.conf]\n ... recipe = zc.zope3recipes:zopeconf\n ... application = myapp\n ... text =\n ... \n ... \n ... server 127.0.0.1:8001\n ... \n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Uninstalling instance.\n Uninstalling myapp.\n Uninstalling database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing some.conf.\n\n >>> cat('parts', 'some.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n server 127.0.0.1:8001\n \n \n \n \n address 8080\n type HTTP\n \n \n \n \n path /sample-buildout/parts/some-access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nWe can specify the location of the access log directly in the part:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1\n ... parts = some.conf\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo1\n ...\n ... [some.conf]\n ... recipe = zc.zope3recipes:zopeconf\n ... application = myapp\n ... access-log = ${buildout:directory}/access.log\n ... text =\n ... \n ... \n ... server 127.0.0.1:8001\n ... \n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/tmp/tmp2eRRw1buildoutSetUp/_TEST_/sample-buildout/demo1'\n Uninstalling some.conf.\n Updating myapp.\n Installing some.conf.\n\n >>> cat('parts', 'some.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n server 127.0.0.1:8001\n \n \n \n \n address 8080\n type HTTP\n \n \n \n \n path /sample-buildout/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nThe address of the server can be set using the \"address\" setting:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1\n ... parts = some.conf\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo1\n ...\n ... [some.conf]\n ... recipe = zc.zope3recipes:zopeconf\n ... address = 4242\n ... application = myapp\n ... text =\n ... \n ... \n ... server 127.0.0.1:8001\n ... \n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/tmp/tmp2eRRw1buildoutSetUp/_TEST_/sample-buildout/demo1'\n Uninstalling some.conf.\n Updating myapp.\n Installing some.conf.\n\n >>> cat('parts', 'some.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n server 127.0.0.1:8001\n \n \n \n \n address 4242\n type HTTP\n \n \n \n \n path /sample-buildout/parts/some-access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\nThe location of the file is made available as the \"location\" setting.\nThis parallels the zc.recipe.deployment:configuration recipe, making\nthis a possible replacement for that recipe where appropriate.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1\n ... parts = another.conf\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... site.zcml = \n ... eggs = demo1\n ...\n ... [some.conf]\n ... recipe = zc.zope3recipes:zopeconf\n ... application = myapp\n ... text =\n ... \n ... \n ... server 127.0.0.1:8001\n ... \n ... \n ...\n ... [another.conf]\n ... recipe = zc.zope3recipes:zopeconf\n ... application = myapp\n ... text =\n ... ${some.conf:text}\n ... \n ... config ${some.conf:location}\n ... \n ...\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/tmp/tmp2eRRw1buildoutSetUp/_TEST_/sample-buildout/demo1'\n Uninstalling some.conf.\n Updating myapp.\n Installing some.conf.\n Installing another.conf.\n\n >>> cat('parts', 'another.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n ...\n \n config /sample-buildout/parts/some.conf\n \n ...\n\n\nOffline recipe\n==============\n\nThe offline recipe creates a script that in some ways is a syntactic sugar for\n\"bin/instance debug\" or \"bin/instance run \". This script doesn't\ncreate additional folders like the ``Instance`` recipe; it expects two options:\n\"application\" and \"zope.conf\" that must be sections for a Zope3 application and\na configuration file (that supports a \"location\" option) to exist.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance offline\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... name = server\n ... application = myapp\n ... zope.conf =\n ... \n ... \n ... server 127.0.0.1:8001\n ... server 127.0.0.1:8002\n ... \n ... \n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... [offline.conf]\n ... location = %(zope3)s\n ...\n ... [offline]\n ... recipe = zc.zope3recipes:offline\n ... application = myapp\n ... zope.conf = offline.conf\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling another.conf.\n Uninstalling some.conf.\n Uninstalling myapp.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/sample-buildout/bin/server'.\n Installing offline.\n\n >>> cat('bin', 'offline')\n #!/usr/local/bin/python2.4\n \n import os\n import sys\n import logging\n \n argv = list(sys.argv)\n env = {}\n restart = False\n \n if None:\n import pwd\n if pwd.getpwnam(None).pw_uid != os.geteuid():\n restart = True\n argv[:0] = [\"sudo\", \"-u\", None]\n # print(\"switching to user %s\" % None)\n del pwd\n \n for k in env:\n if os.environ.get(k) != env[k]:\n os.environ[k] = env[k]\n restart = True\n del k\n \n if restart:\n # print(\"restarting\")\n os.execvpe(argv[0], argv, dict(os.environ))\n \n del argv\n del env\n del restart\n \n sys.argv[1:1] = [\n \"-C\",\n '/zope3',\n \n ]\n \n debugzope = '/sample-buildout/parts/myapp/debugzope'\n globals()[\"__file__\"] = debugzope\n \n zeo_logger = logging.getLogger('ZEO.zrpc')\n zeo_logger.addHandler(logging.StreamHandler())\n \n \n # print(\"starting debugzope...\")\n with open(debugzope) as f:\n exec(f.read())\n\n\ninitialization option\n---------------------\n\nThe recipe also accepts an \"initialization\" option:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance offline\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... name = server\n ... application = myapp\n ... zope.conf =\n ... \n ... \n ... server 127.0.0.1:8001\n ... server 127.0.0.1:8002\n ... \n ... \n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... [offline.conf]\n ... location = %(zope3)s\n ...\n ... [offline]\n ... recipe = zc.zope3recipes:offline\n ... initialization =\n ... os.environ['ZC_DEBUG_LOGGING'] = 'on'\n ... application = myapp\n ... zope.conf = offline.conf\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling offline.\n Updating myapp.\n Updating instance.\n Installing offline.\n\n >>> cat('bin', 'offline')\n \n import os\n import sys\n import logging\n \n argv = list(sys.argv)\n env = {}\n restart = False\n \n if None:\n import pwd\n if pwd.getpwnam(None).pw_uid != os.geteuid():\n restart = True\n argv[:0] = [\"sudo\", \"-u\", None]\n # print(\"switching to user %s\" % None)\n del pwd\n \n for k in env:\n if os.environ.get(k) != env[k]:\n os.environ[k] = env[k]\n restart = True\n del k\n \n if restart:\n # print(\"restarting\")\n os.execvpe(argv[0], argv, dict(os.environ))\n \n del argv\n del env\n del restart\n \n sys.argv[1:1] = [\n \"-C\",\n '/zope3',\n \n ]\n \n debugzope = '/sample-buildout/parts/myapp/debugzope'\n globals()[\"__file__\"] = debugzope\n \n zeo_logger = logging.getLogger('ZEO.zrpc')\n zeo_logger.addHandler(logging.StreamHandler())\n \n os.environ['ZC_DEBUG_LOGGING'] = 'on'\n \n # print(\"starting debugzope...\")\n with open(debugzope) as f:\n exec(f.read())\n\n\nscript option\n-------------\n\nas well as a \"script\" option.\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance run-foo\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:app\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... name = server\n ... application = myapp\n ... zope.conf =\n ... \n ... \n ... server 127.0.0.1:8001\n ... server 127.0.0.1:8002\n ... \n ... \n ... address = 8081\n ... zdaemon.conf =\n ... \n ... daemon off\n ... socket-name /sample-buildout/parts/instance/sock\n ... transcript /dev/null\n ... \n ... \n ... \n ...\n ... [offline.conf]\n ... location = %(zope3)s\n ...\n ... [run-foo]\n ... recipe = zc.zope3recipes:offline\n ... initialization =\n ... os.environ['ZC_DEBUG_LOGGING'] = 'on'\n ... application = myapp\n ... zope.conf = offline.conf\n ... script = %(zope3)s/foo.py\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling offline.\n Updating myapp.\n Updating instance.\n Installing run-foo.\n\n >>> cat('bin', 'run-foo')\n \n import os\n import sys\n import logging\n \n argv = list(sys.argv)\n env = {}\n restart = False\n \n if None:\n import pwd\n if pwd.getpwnam(None).pw_uid != os.geteuid():\n restart = True\n argv[:0] = [\"sudo\", \"-u\", None]\n # print(\"switching to user %s\" % None)\n del pwd\n \n for k in env:\n if os.environ.get(k) != env[k]:\n os.environ[k] = env[k]\n restart = True\n del k\n \n if restart:\n # print(\"restarting\")\n os.execvpe(argv[0], argv, dict(os.environ))\n \n del argv\n del env\n del restart\n \n sys.argv[1:1] = [\n \"-C\",\n '/zope3',\n '/zope3/foo.py'\n ]\n \n debugzope = '/sample-buildout/parts/myapp/debugzope'\n globals()[\"__file__\"] = debugzope\n \n zeo_logger = logging.getLogger('ZEO.zrpc')\n zeo_logger.addHandler(logging.StreamHandler())\n \n os.environ['ZC_DEBUG_LOGGING'] = 'on'\n \n # print(\"starting debugzope...\")\n with open(debugzope) as f:\n exec(f.read())\n\n\nPaste-deployment support\n========================\n\nYou can use paste-deployment to control WSGI servers and middleware.\nYou indicate this by specifying ``paste`` in the ``servers`` option:\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... servers = paste\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf =\n ... threads 1\n ... ${database:zconfig}\n ...\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\nWhen we run the buildout, we'll get a paste-based runzope script and\npaste-based instance start scripts.\n\n.. test\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling run-foo.\n Uninstalling instance.\n Uninstalling myapp.\n Installing database.\n Installing myapp.\n Generated script '/sample-buildout/parts/myapp/runzope'.\n Generated script '/sample-buildout/parts/myapp/debugzope'.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\n\n >>> cat('parts', 'myapp', 'runzope')\n #!/usr/local/python/2.6/bin/python2.6\n \n import sys\n sys.path[0:0] = [\n '/sample-buildout/demo2',\n '/sample-buildout/demo1',\n '/site-packages',\n ]\n \n import paste.script.command\n \n if __name__ == '__main__':\n sys.exit(paste.script.command.run(['serve']+sys.argv[1:]))\n\n\n >>> cat('parts', 'instance', 'zope.conf')\n site-definition /sample-buildout/parts/myapp/site.zcml\n \n \n \n path /sample-buildout/parts/database/Data.fs\n \n \n \n \n level info\n name accesslog\n propagate false\n \n \n format %(message)s\n path /sample-buildout/parts/instance/access.log\n \n \n \n \n \n formatter zope.exceptions.log.Formatter\n path STDOUT\n \n \n\n >>> cat('parts', 'instance', 'zdaemon.conf')\n \n daemon on\n directory /sample-buildout/parts/instance\n program /sample-buildout/parts/myapp/runzope /sample-buildout/parts/instance/paste.ini\n socket-name /sample-buildout/parts/instance/zdaemon.sock\n transcript /sample-buildout/parts/instance/z3.log\n \n \n \n \n path /sample-buildout/parts/instance/z3.log\n \n \n\nWe also get a paste.ini file in the instance directory, which defines\nthe application and server and is used when running paste::\n\n >>> cat('parts', 'instance', 'paste.ini')\n [app:main]\n use = egg:zope.app.wsgi\n config_file = /sample-buildout/parts/instance/zope.conf\n filter-with = translogger\n \n [filter:translogger]\n use = egg:Paste#translogger\n setup_console_handler = False\n logger_name = accesslog\n \n [server:main]\n use = egg:zope.server\n host = \n port = 8080\n threads = 1\n\nNote that the threads setting made in zope.conf was moved to paste.ini\n\nNote too that past:translogger was used to provide an access log.\n\nIf you don't want to use zope.server, or if you want to control the\nserver configuration yourself, you can provide a paste.init option::\n\n >>> write('buildout.cfg',\n ... '''\n ... [buildout]\n ... develop = demo1 demo2\n ... parts = instance\n ...\n ... [zope3]\n ... location = %(zope3)s\n ...\n ... [myapp]\n ... recipe = zc.zope3recipes:application\n ... servers = paste\n ... site.zcml = \n ... \n ... \n ... eggs = demo2\n ...\n ... [instance]\n ... recipe = zc.zope3recipes:instance\n ... application = myapp\n ... zope.conf =\n ... threads 1\n ... ${database:zconfig}\n ... paste.ini = test and not working :)\n ...\n ...\n ... [database]\n ... recipe = zc.recipe.filestorage\n ... ''' % globals())\n\n.. test\n\n >>> print(system(join('bin', 'buildout')))\n Develop: '/sample-buildout/demo1'\n Develop: '/sample-buildout/demo2'\n Uninstalling instance.\n Updating database.\n Updating myapp.\n Installing instance.\n Generated script '/sample-buildout/bin/instance'.\n\nIn this example, we gave useless text in the paste.ini option and we\ngot a nonsense paste.ini file::\n\n >>> cat('parts', 'instance', 'paste.ini')\n [app:main]\n use = egg:zope.app.wsgi\n config_file = /sample-buildout/parts/instance/zope.conf\n \n test and not working :)\n\nThis illustrates that the recipe doesn't care what you provide. It\nuses it with the application definition instead of supplying\nzope.server and paste.translogger definition.", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/zopefoundation/zc.zope3recipes", "keywords": "zope3 buildout", "license": "ZPL 2.1", "maintainer": "", "maintainer_email": "", "name": "zc.zope3recipes", "package_url": "https://pypi.org/project/zc.zope3recipes/", "platform": "", "project_url": "https://pypi.org/project/zc.zope3recipes/", "project_urls": { "Homepage": "https://github.com/zopefoundation/zc.zope3recipes" }, "release_url": "https://pypi.org/project/zc.zope3recipes/0.19.0/", "requires_dist": null, "requires_python": "", "summary": "ZC Buildout recipe for defining Zope 3 applications", "version": "0.19.0" }, "last_serial": 5523897, "releases": { "0.10.0": [ { "comment_text": "", "digests": { "md5": "0aae88bc2191e4d18ba2de6edd5f475b", "sha256": "2b66cad4f3c1093185a398cd48229c8109560b4e74c234d0dc35c9308acf9cad" }, "downloads": -1, "filename": "zc.zope3recipes-0.10.0.tar.gz", "has_sig": false, "md5_digest": "0aae88bc2191e4d18ba2de6edd5f475b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45212, "upload_time": "2009-09-16T10:57:04", "url": "https://files.pythonhosted.org/packages/33/3b/9401cb3daa0358bef6a97e427df8df3e21052d3ce0849d7ac12567fe5191/zc.zope3recipes-0.10.0.tar.gz" } ], "0.11.0": [ { "comment_text": "", "digests": { "md5": "294c9f20a60a1e41d3ea584bc07ff5c3", "sha256": "1dd29917aa01ef9203d340cae627246b4ff7f6986cb17f27cb1231569f459ab8" }, "downloads": -1, "filename": "zc.zope3recipes-0.11.0.tar.gz", "has_sig": false, "md5_digest": "294c9f20a60a1e41d3ea584bc07ff5c3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47190, "upload_time": "2009-10-01T16:37:32", "url": "https://files.pythonhosted.org/packages/ed/14/ce527d3765dc69963e7adcac3c2fc3052e6de11cb578e56e6341db1203a6/zc.zope3recipes-0.11.0.tar.gz" } ], "0.11.1": [], "0.12.0": [ { "comment_text": "", "digests": { "md5": "47446acd5c1f486e582756fba4e98529", "sha256": "2fdfedc9230d48b577ac872df089957e7a4ed3ff97a84f9be71ebfd3e968cfa9" }, "downloads": -1, "filename": "zc.zope3recipes-0.12.0.tar.gz", "has_sig": false, "md5_digest": "47446acd5c1f486e582756fba4e98529", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49784, "upload_time": "2010-11-22T23:39:26", "url": "https://files.pythonhosted.org/packages/20/4f/cfd92380afd565a5390b251ae83d1ab671a2bf62808d16a9dc60cabe3658/zc.zope3recipes-0.12.0.tar.gz" } ], "0.13.0": [ { "comment_text": "", "digests": { "md5": "346b8b1783206cac952fbc8f0078e101", "sha256": "e923fe1a27c2ab4920789a9babe5224960239fc3913600e94464f4fa3b428940" }, "downloads": -1, "filename": "zc.zope3recipes-0.13.0.tar.gz", "has_sig": false, "md5_digest": "346b8b1783206cac952fbc8f0078e101", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51062, "upload_time": "2010-11-24T18:23:16", "url": "https://files.pythonhosted.org/packages/22/71/f17a65a75be24be299e8023564b45f1361a0ccd1b2602a4d3570623b7043/zc.zope3recipes-0.13.0.tar.gz" } ], "0.14.0": [ { "comment_text": "", "digests": { "md5": "8b8125a4d7bc42f2508acdfd9450380b", "sha256": "0c7a9885c379f4c8935be0368acf572f4abd13b1f0644aa729773e2a892c0b49" }, "downloads": -1, "filename": "zc.zope3recipes-0.14.0.tar.gz", "has_sig": false, "md5_digest": "8b8125a4d7bc42f2508acdfd9450380b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55024, "upload_time": "2011-12-08T18:08:32", "url": "https://files.pythonhosted.org/packages/92/11/a6e2a52cacd3b47ea02a3ef167b4092145a52fc3ddf4d2a494108422e6fd/zc.zope3recipes-0.14.0.tar.gz" } ], "0.14.1": [ { "comment_text": "", "digests": { "md5": "c6f752ebfc2cd8584ca3aee150ca058f", "sha256": "e878f2c1b10bf9aa92608efe6523ec0ec63bcfcc03008518792ec46208b1209f" }, "downloads": -1, "filename": "zc.zope3recipes-0.14.1.tar.gz", "has_sig": false, "md5_digest": "c6f752ebfc2cd8584ca3aee150ca058f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55047, "upload_time": "2011-12-09T00:02:19", "url": "https://files.pythonhosted.org/packages/bc/b4/6236a3667c06f130f35953d03d29c4138433cbf2853da9b6c8a8ba1b7b55/zc.zope3recipes-0.14.1.tar.gz" } ], "0.15.0": [ { "comment_text": "", "digests": { "md5": "6efe799d701cdc01564aa3df383f1301", "sha256": "bde0304f5ae042b0cc53ab03baee3774c73510da2654c887355a9e353a01fdfd" }, "downloads": -1, "filename": "zc.zope3recipes-0.15.0.tar.gz", "has_sig": false, "md5_digest": "6efe799d701cdc01564aa3df383f1301", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 57796, "upload_time": "2011-12-12T14:25:14", "url": "https://files.pythonhosted.org/packages/3f/03/ad446848f09f9012da3ffe2fec4581794672bb1865b3ba8368d06806c810/zc.zope3recipes-0.15.0.tar.gz" } ], "0.16.0": [ { "comment_text": "", "digests": { "md5": "ecfa85f40aebccf20418ec18d8591336", "sha256": "48d0087c1d137ad95748523fb4cf1a98bc098461ccef15b65ed770cf5c5ee9c5" }, "downloads": -1, "filename": "zc.zope3recipes-0.16.0.tar.gz", "has_sig": false, "md5_digest": "ecfa85f40aebccf20418ec18d8591336", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 60930, "upload_time": "2012-01-15T17:18:54", "url": "https://files.pythonhosted.org/packages/cf/e4/2ea0e7e28cce9d5ffd323e67fcc850db1a5f593e52ddc2e9e6e843cc0fc4/zc.zope3recipes-0.16.0.tar.gz" } ], "0.17.0": [ { "comment_text": "", "digests": { "md5": "7be093f3f08020c471d39c9f5200b695", "sha256": "1f978e275bb6a4bd5e336387d42697f76ae5a9f89f63211661416dc104156d9a" }, "downloads": -1, "filename": "zc.zope3recipes-0.17.0.tar.gz", "has_sig": false, "md5_digest": "7be093f3f08020c471d39c9f5200b695", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 61972, "upload_time": "2012-02-08T04:33:36", "url": "https://files.pythonhosted.org/packages/d5/d9/f6a6a2a047aa497e12df2b8a1112efefd3e834fc65907d75832ca58d4cc3/zc.zope3recipes-0.17.0.tar.gz" } ], "0.18.0": [ { "comment_text": "", "digests": { "md5": "4f5a82781ebb790cf4a1ff5846c67ca9", "sha256": "66fb37651aea2359fdf62329c3798b0942269567da24389db4d82464112d0d0d" }, "downloads": -1, "filename": "zc.zope3recipes-0.18.0.tar.gz", "has_sig": false, "md5_digest": "4f5a82781ebb790cf4a1ff5846c67ca9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 61846, "upload_time": "2013-02-05T20:43:44", "url": "https://files.pythonhosted.org/packages/67/4e/c9c5c872a8a94c1587d0b7bd301ce800b905f073359cb61cfbec05e712fa/zc.zope3recipes-0.18.0.tar.gz" } ], "0.19.0": [ { "comment_text": "", "digests": { "md5": "7dab2f67b8e51fe46ed3bce479b807c0", "sha256": "b69fa18c9c27ebc493451bbf7fae292f2f9e7afc0ca5a6e4e662ae9291509d13" }, "downloads": -1, "filename": "zc.zope3recipes-0.19.0.tar.gz", "has_sig": false, "md5_digest": "7dab2f67b8e51fe46ed3bce479b807c0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 63187, "upload_time": "2019-07-12T16:19:05", "url": "https://files.pythonhosted.org/packages/dd/4c/7d67f6a4bdf6d985aea060e1fb80e5140021a7459d63d1a305f25a934a5e/zc.zope3recipes-0.19.0.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "0ad17882f02fa86f19cf5b8f048e3fa3", "sha256": "b700401c8580f93b9b90a26223c862bf052a0b43db3ba16c68739a4ceed23996" }, "downloads": -1, "filename": "zc.zope3recipes-0.3-py2.4.egg", "has_sig": false, "md5_digest": "0ad17882f02fa86f19cf5b8f048e3fa3", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 32985, "upload_time": "2007-02-28T19:12:34", "url": "https://files.pythonhosted.org/packages/68/f6/4b3a0fb855bd7d7d9f18f7e9a000b333cbb4bec47dc52eee49d6ee94c5f7/zc.zope3recipes-0.3-py2.4.egg" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "b54de024dcc2d1ca3507e94bc57b9564", "sha256": "909815146f812c68756e956d62239467b233b997c62ef001fce80c6a2aed7cb1" }, "downloads": -1, "filename": "zc.zope3recipes-0.4-py2.4.egg", "has_sig": false, "md5_digest": "b54de024dcc2d1ca3507e94bc57b9564", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 27282, "upload_time": "2007-03-02T23:37:18", "url": "https://files.pythonhosted.org/packages/56/be/95e751548fdd9545e447e40f1ca1590632c52e814809cc9d7c9a9293e4f0/zc.zope3recipes-0.4-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "366f5a328a870a45ad04a68a6b530543", "sha256": "8c200d48ee64b03ebdfcd418b7bf546242aaaf7c3b6ab4b6406d0a37458d2611" }, "downloads": -1, "filename": "zc.zope3recipes-0.4.tar.gz", "has_sig": false, "md5_digest": "366f5a328a870a45ad04a68a6b530543", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14047, "upload_time": "2007-03-02T23:36:56", "url": "https://files.pythonhosted.org/packages/42/77/a876553e56598f4052ecfb23ff061fd3ea710ee78fd9fcd63b6b1cae6755/zc.zope3recipes-0.4.tar.gz" }, { "comment_text": "", "digests": { "md5": "918d0cef9059952a2653e8b201c8b3fc", "sha256": "aa3530d1e1cafa0c2d1acec7c1aa8bfe16ea8fdfd5d2bee72b0bf6735617ce17" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.0-py2.4.egg", "has_sig": false, "md5_digest": "918d0cef9059952a2653e8b201c8b3fc", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 35253, "upload_time": "2007-03-21T13:38:27", "url": "https://files.pythonhosted.org/packages/34/17/c2ce6ba7f2e907326ab0aac31121046b1e4207fa675601637002cadaade3/zc.zope3recipes-0.5.0-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "80da33c8a7d7640756623c43c5d051c7", "sha256": "6628e449882a1d9bd59d3743a46397a43e4169659e9b63206194fa40eab92f57" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.0.tar.gz", "has_sig": false, "md5_digest": "80da33c8a7d7640756623c43c5d051c7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30012, "upload_time": "2007-03-21T13:42:35", "url": "https://files.pythonhosted.org/packages/37/a0/2b717299ee4dcd66cc06dff3d217d699f7d82792281c269767ff4d232fec/zc.zope3recipes-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "4db171644da80f00bdfcd694f5d60cf8", "sha256": "39d4324235e79b9e1f4a07371bc6add1fce9b671fde47ab4243d22bc21dcd859" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.1-py2.4.egg", "has_sig": false, "md5_digest": "4db171644da80f00bdfcd694f5d60cf8", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 36130, "upload_time": "2007-05-22T21:41:15", "url": "https://files.pythonhosted.org/packages/8f/5b/b7eb1af43a55bb15ae53eb8905c2993f567d05f1d7b45733465b1ef0339c/zc.zope3recipes-0.5.1-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "304631947e2a0399e41d74edc303d8c4", "sha256": "84ba3c2e778bc189733be6507ec850164c8e08d2109f252c00283021e9f5cb41" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.1.tar.gz", "has_sig": false, "md5_digest": "304631947e2a0399e41d74edc303d8c4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31028, "upload_time": "2007-05-22T21:41:13", "url": "https://files.pythonhosted.org/packages/f6/ce/31dfb826544bb2caf6b160f67b02e03f47756afbe026f74796e63c89e7bd/zc.zope3recipes-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "140578a5cbefa79d0a2799a3765a8fa6", "sha256": "e6c1b8fcb27eefd82340980da1c9e7dbc5cc07d5e7d67e3da9822f35c8d65b5b" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.2-py2.4.egg", "has_sig": false, "md5_digest": "140578a5cbefa79d0a2799a3765a8fa6", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 34451, "upload_time": "2007-06-21T18:06:23", "url": "https://files.pythonhosted.org/packages/d9/a5/5437a4c1fe7e191bb2a45792085c0fc0cf5c5b4f01c150b49974df46dcfb/zc.zope3recipes-0.5.2-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "38fe3678f246c783ff019b703984beef", "sha256": "3e5705d6a83fff7545c878e7ba480e1ce3568d527a42c37f66854cb1d6c65717" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.2.tar.gz", "has_sig": false, "md5_digest": "38fe3678f246c783ff019b703984beef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30545, "upload_time": "2007-06-21T18:06:17", "url": "https://files.pythonhosted.org/packages/3c/b9/b5be8c3bb5e317069a83a95afa2b491bacc6b768d828b30d3285b767bba5/zc.zope3recipes-0.5.2.tar.gz" } ], "0.5.3": [ { "comment_text": "", "digests": { "md5": "40a12fcf7e7df9621d13d0e2f8117e2b", "sha256": "9f6b3894d51348a2b9116d53336eaa679073f9096ebc156001fd6a6c7a01b15b" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.3-py2.4.egg", "has_sig": false, "md5_digest": "40a12fcf7e7df9621d13d0e2f8117e2b", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 34834, "upload_time": "2007-07-14T15:11:05", "url": "https://files.pythonhosted.org/packages/e8/a6/f836c306607acb7efa8fee28e8dd16f42117ad578658e2a2cc63b5e80350/zc.zope3recipes-0.5.3-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "23d6d521a39c08a500fa07b9e5ce2da0", "sha256": "97b02274c4a1ef59dcd0950298b6e1cf9c05ece4d34c8d7333be8e3bf3fddc9d" }, "downloads": -1, "filename": "zc.zope3recipes-0.5.3.tar.gz", "has_sig": false, "md5_digest": "23d6d521a39c08a500fa07b9e5ce2da0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31099, "upload_time": "2007-07-14T15:11:05", "url": "https://files.pythonhosted.org/packages/72/7d/a3589232744f41e94c329c89f53516c57b69623222043b40233c9d6f190a/zc.zope3recipes-0.5.3.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "f4520915fc2e242c8804d1aa5da4e960", "sha256": "e3946ba51a03c48900521c20c75f03dbbbb6159965d1688267e654c4400bdcff" }, "downloads": -1, "filename": "zc.zope3recipes-0.6.0.tar.gz", "has_sig": false, "md5_digest": "f4520915fc2e242c8804d1aa5da4e960", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41012, "upload_time": "2007-11-04T00:20:59", "url": "https://files.pythonhosted.org/packages/28/96/779f5338e0397260bf9f5490c6284fa000fc27cbd7e42fbd15e6f29c8d0f/zc.zope3recipes-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "efa2ca0df3b3b4e924fccac84ff411ed", "sha256": "d7c88c518e278d28faa2ff9bad932bc70a962b5bb1f954cbb5b67567e732b33d" }, "downloads": -1, "filename": "zc.zope3recipes-0.6.1.tar.gz", "has_sig": false, "md5_digest": "efa2ca0df3b3b4e924fccac84ff411ed", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41964, "upload_time": "2007-12-17T20:29:13", "url": "https://files.pythonhosted.org/packages/af/e2/45adb199dc8b0cbe5cb0f56aea03ae25e8ab2f168e84b9d1144c936d22e6/zc.zope3recipes-0.6.1.tar.gz" } ], "0.6.2": [ { "comment_text": "", "digests": { "md5": "8be48b1a6d560c6b5d68ba8593571145", "sha256": "83fe4d994cef3c3530ca43e92e250634e24add20d21fbef38af80fd86f6e4e88" }, "downloads": -1, "filename": "zc.zope3recipes-0.6.2.tar.gz", "has_sig": false, "md5_digest": "8be48b1a6d560c6b5d68ba8593571145", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43271, "upload_time": "2008-08-17T22:49:42", "url": "https://files.pythonhosted.org/packages/48/c5/8a19f1d1698474e168f46301021571c5d7f6dd38113d7f1d364a92adaa0a/zc.zope3recipes-0.6.2.tar.gz" } ], "0.6b1": [ { "comment_text": "", "digests": { "md5": "373b36dc442003434f5a4c5decd904d3", "sha256": "e41dcecf6e629cd70dd7fe4413ccaa3f19432608a759231564f1da5f6e5927d6" }, "downloads": -1, "filename": "zc.zope3recipes-0.6b1-py2.4.egg", "has_sig": false, "md5_digest": "373b36dc442003434f5a4c5decd904d3", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 51983, "upload_time": "2007-08-21T19:25:17", "url": "https://files.pythonhosted.org/packages/36/c5/211b72794df630da54f04fde8b2ef2730dda65e3a05550298af3e70ced22/zc.zope3recipes-0.6b1-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "5a99d682f6994edd9c9ddca5b963e4cb", "sha256": "c5ad04e50de2f60ee52ad83492ef64d46f961aa2f032a1aeee7f91469a896369" }, "downloads": -1, "filename": "zc.zope3recipes-0.6b1.tar.gz", "has_sig": false, "md5_digest": "5a99d682f6994edd9c9ddca5b963e4cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40996, "upload_time": "2007-10-11T12:19:57", "url": "https://files.pythonhosted.org/packages/21/8f/90a7db45e3a64666fcf3a256227c4be0247b42976df8bbf3bec332936a6b/zc.zope3recipes-0.6b1.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "b495d414b4a829e6ff187ffa070604ee", "sha256": "40b0c334f1fa285a98a71c26da7ed5322ff459537cbb20a022737f5c3df2f915" }, "downloads": -1, "filename": "zc.zope3recipes-0.7.0.tar.gz", "has_sig": false, "md5_digest": "b495d414b4a829e6ff187ffa070604ee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 44101, "upload_time": "2008-02-01T16:43:05", "url": "https://files.pythonhosted.org/packages/cf/b1/fcc127c75ebd6c9cc43e79454b741cd7b751d9a70dd2313967dd6deae526/zc.zope3recipes-0.7.0.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "940a0e7e67e5054a14a968752a516f57", "sha256": "eaf1eaf6381f13c4e12e478bb806b41f4b5e6572d2e0738b3347149384c0aa3e" }, "downloads": -1, "filename": "zc.zope3recipes-0.8.0.tar.gz", "has_sig": false, "md5_digest": "940a0e7e67e5054a14a968752a516f57", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45475, "upload_time": "2009-04-03T08:52:17", "url": "https://files.pythonhosted.org/packages/35/88/03cf0802a9ab3b064853a0a43237d332b23c8a8d28ebb4f1bdcd7790087c/zc.zope3recipes-0.8.0.tar.gz" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "e745a22c8675add17262e821b12a9271", "sha256": "d769a0f2dd9a94031f0f691a66956197f23967b40bd025313473818bb83dc09d" }, "downloads": -1, "filename": "zc.zope3recipes-0.9.0.tar.gz", "has_sig": false, "md5_digest": "e745a22c8675add17262e821b12a9271", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45489, "upload_time": "2009-07-23T21:36:51", "url": "https://files.pythonhosted.org/packages/a5/c4/ee6444d71b8b433463c4f9d744d340dbcf1016e4ddd11e23d8c26ad78d7b/zc.zope3recipes-0.9.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7dab2f67b8e51fe46ed3bce479b807c0", "sha256": "b69fa18c9c27ebc493451bbf7fae292f2f9e7afc0ca5a6e4e662ae9291509d13" }, "downloads": -1, "filename": "zc.zope3recipes-0.19.0.tar.gz", "has_sig": false, "md5_digest": "7dab2f67b8e51fe46ed3bce479b807c0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 63187, "upload_time": "2019-07-12T16:19:05", "url": "https://files.pythonhosted.org/packages/dd/4c/7d67f6a4bdf6d985aea060e1fb80e5140021a7459d63d1a305f25a934a5e/zc.zope3recipes-0.19.0.tar.gz" } ] }