{ "info": { "author": "Jim Fulton", "author_email": "jim@zope.com", "bugtrack_url": null, "classifiers": [], "description": "=================================================\nzope.server wrapper that registers with ZooKeeper\n=================================================\n\n``zc.zkzopeserver`` provides a wrapper for the zope.server WSGI runner\nthat registers with ZooKeeper. By registering with ZooKeeper, you can\nlet the operating system assign ports and have clients find your\nserver by looking in ZooKeeper.\n\nBasic Usage\n===========\n\nThe wrapper is used in a past-deploy configuration file::\n\n [server:main]\n use = egg:zc.zkzopeserver\n zookeeper = zookeeper.example.com:2181\n path = /fooservice/providers\n\n.. -> server_config\n\nThe wrapper supports the following options:\n\nzookeeper\n required ZooKeeper connection string\n\npath\n required path at which to register your server\n\n Your server is registered by adding a ZooKeeper ephemeral node as a\n child of the path with the server address as the name.\n\nhost\n host name or ip to listen on, defaulting to ''\n\nport\n The port to listen on, defaulting to 0\n\nsession_timeout\n A ZooKeeper session timeout in milliseconds\n\nthreads\n The size of the thread pool, defaulting to 1\n\nmonitor_server\n A ``zc.monitor`` server address.\n\n The value is an address of the form HOST:PORT. See `Monitor\n server`_ below. (Host can be empty to listen on all interfaces.)\n\nloggers\n Logging configuration.\n\n This can be one of:\n\n - A logging level name (CRITICAL, ERROR, WARNING, INFO, or DEBUG),\n or\n\n - A ZConfig loggers-definition string.\n\n If the configuration includes format strings, you'll need to use\n double dollar signs rather than %, as in::\n\n format $$(message)s\n\n This is necessary due to the use of string formats in the Paste\n Deployment configuration syntax.\n\n.. test\n\n >>> import ConfigParser, StringIO\n >>> parser = ConfigParser.RawConfigParser()\n >>> parser.readfp(StringIO.StringIO(server_config))\n >>> kw = dict(parser.items('server:main'))\n\n >>> import zope.testing.loggingsupport\n >>> loghandler = zope.testing.loggingsupport.InstalledHandler(\n ... 'zc.zkzopeserver')\n\n >>> import pkg_resources\n >>> dist = kw.pop('use').split(':')[1]\n >>> [run] = [v.load()\n ... for v in pkg_resources.get_entry_map(\n ... 'zc.zkzopeserver', 'paste.server_runner'\n ... ).values()]\n\n >>> import wsgiref.simple_server, zc.thread\n >>> @zc.thread.Thread\n ... def server():\n ... run(wsgiref.simple_server.demo_app, {}, **kw)\n\n >>> import zc.zkzopeserver\n >>> zc.zkzopeserver.event_for_testing.wait(1)\n\n >>> import urllib, zc.zk\n >>> zk = zc.zk.ZooKeeper('zookeeper.example.com:2181')\n\n >>> [port] = [int(c.split(':')[1])\n ... for c in zk.get_children('/fooservice/providers')]\n >>> print urllib.urlopen('http://127.0.0.1:%s/' % port).read()\n ... # doctest: +ELLIPSIS\n Hello world!\n ...\n\n >>> zc.zkzopeserver.stop_for_testing(server)\n >>> zk.get_children('/fooservice/providers')\n []\n\n A SIGTERM signal handler is installed:\n\n >>> import signal\n >>> [sig, handler] = signal.signal.call_args[0]\n >>> sig == signal.SIGTERM\n True\n >>> try: handler(sig, None)\n ... except SystemExit, v: print v\n 0\n\n >>> signal.getsignal.return_value = handler\n >>> signal.signal.reset_mock()\n\n The fact that a handler was installed is logged, as is the address:\n\n >>> print loghandler\n zc.zkzopeserver INFO\n Installed SIGTERM handler\n zc.zkzopeserver INFO\n Serving on :35177\n\n >>> loghandler.clear()\n\n Nothing was done w logging:\n\n >>> import logging\n >>> logging.basicConfig.call_args\n >>> import ZConfig\n >>> ZConfig.configureLoggers.call_args\n\nMonitor server\n==============\n\nThe `zc.monitor `_ package\nprovides a simple extensible command server for gathering monitoring\ndata or providing run-time control of servers. If ``zc.monitor`` is\nin the Python path, ``zc.zkzopeserver`` can start a monitor server\nand make it's address available as the ``monitor`` property of a\nserver's ephemeral port. To see how this works, let's update the\nearler example::\n\n [server:main]\n use = egg:zc.zkzopeserver\n zookeeper = zookeeper.example.com:2181\n path = /fooservice/providers\n monitor_server = 127.0.0.1:0\n\n.. -> server_config\n\nWhen our web server is running, the ``/fooservice/providers`` node\nwould look something like::\n\n /providers\n /1.2.3.4:61181\n monitor = u'127.0.0.1:61182'\n pid = 4525\n\n.. -> expected_tree\n\n >>> parser = ConfigParser.RawConfigParser()\n >>> parser.readfp(StringIO.StringIO(server_config))\n >>> kw = dict(parser.items('server:main'))\n >>> del kw['use']\n\n >>> import zope.testing.loggingsupport\n >>> handler = zope.testing.loggingsupport.InstalledHandler('zc.tracelog')\n >>> @zc.thread.Thread\n ... def server():\n ... run(wsgiref.simple_server.demo_app, {}, **kw)\n\n >>> zc.zkzopeserver.event_for_testing.wait(1)\n\n >>> [port] = [int(c.split(':')[1])\n ... for c in zk.get_children('/fooservice/providers')]\n >>> print urllib.urlopen('http://127.0.0.1:%s/' % port).read()\n ... # doctest: +ELLIPSIS\n Hello world!\n ...\n\n >>> import re, zope.testing.renormalizing\n >>> checker = zope.testing.renormalizing.RENormalizing([\n ... (re.compile('pid = \\d+'), 'pid = 999'),\n ... (re.compile('1.2.3.4:\\d+'), '1.2.3.4:99999'),\n ... (re.compile('127.0.0.1:\\d+'), '1.2.3.4:99999'),\n ... ])\n >>> actual_tree = zk.export_tree('/fooservice/providers', True)\n >>> checker.check_output(expected_tree.strip(), actual_tree.strip(), 0)\n True\n\n >>> zc.zkzopeserver.stop_for_testing(server)\n >>> zk.get_children('/fooservice/providers')\n []\n\n >>> print handler\n \n\n >>> handler.uninstall()\n\n The signal handler wasn't set again, as it was already set:\n\n >>> signal.signal.call_args\n >>> print loghandler\n zc.zkzopeserver INFO\n Serving on :46834\n\n >>> loghandler.uninstall()\n\nSome notes on the monitor server:\n\n- A monitor server won't be useful unless you've registered some\n command plugins.\n\n- ``zc.monitor`` isn't a dependency of ``zc.zkzopeserver`` and won't\n be in the Python path unless you install it.\n\n``zc.zservertracslog`` integration\n==================================\n\nThe package ``zc.zservertracelog`` extends zope.server to provide\nsupport for \"trace\" logs that have multiple log entries per web\nrequest as a request goes through various stages.\n\nIf you want to use ``zc.zservertraeslog`` with ``zc.zkzopeserver``,\nmake sure ``zc.zservertracelog`` is in your Python path and include\nthe ``zservertracelog`` option in your server section::\n\n\n [server:main]\n use = egg:zc.zkzopeserver\n zookeeper = zookeeper.example.com:2181\n path = /fooservice/providers\n monitor_server = 127.0.0.1:0\n zservertracelog = true\n\n.. -> server_config\n\n >>> parser = ConfigParser.RawConfigParser()\n >>> parser.readfp(StringIO.StringIO(server_config))\n >>> kw = dict(parser.items('server:main'))\n >>> del kw['use']\n\n >>> handler = zope.testing.loggingsupport.InstalledHandler('zc.tracelog')\n >>> @zc.thread.Thread\n ... def server():\n ... run(wsgiref.simple_server.demo_app, {}, **kw)\n\n >>> zc.zkzopeserver.event_for_testing.wait(1)\n\n >>> [port] = [int(c.split(':')[1])\n ... for c in zk.get_children('/fooservice/providers')]\n >>> print urllib.urlopen('http://127.0.0.1:%s/' % port).read()\n ... # doctest: +ELLIPSIS\n Hello world!\n ...\n\n >>> zc.zkzopeserver.stop_for_testing(server)\n\n >>> print handler\n zc.tracelog INFO\n B 4358585232 2012-01-18 15:31:31.050680 GET /\n zc.tracelog INFO\n I 4358585232 2012-01-18 15:31:31.050887 0\n zc.tracelog INFO\n C 4358585232 2012-01-18 15:31:31.051068\n zc.tracelog INFO\n A 4358585232 2012-01-18 15:31:31.051580 200 ?\n zc.tracelog INFO\n E 4358585232 2012-01-18 15:31:31.051692\n\n >>> handler.uninstall()\n\n\nChange History\n==============\n\n0.3.0 (2012-02-02)\n------------------\n\n- Added logging-configuration support.\n\n- Fixed: servers were registered with the host information returned by\n socket.getsockname(), which was unhelpful.\n\n- Fixed: Killing a server (with SIGTERM) didn't shut down the\n ZooKeeper connection cleanly, causing a delay in removing registered\n ephemeral nodes.\n\n0.2.0 (2012-01-18)\n------------------\n\nAdded optional support for using zc.zservertracelog to generate trace logs.\n\n0.1.0 (2011-12-11)\n------------------\n\nInitial release\n\n\n.. test cleanup\n\n >>> zk.close()", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "UNKNOWN", "keywords": null, "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "zc.zkzopeserver", "package_url": "https://pypi.org/project/zc.zkzopeserver/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/zc.zkzopeserver/", "project_urls": { "Download": "UNKNOWN", "Homepage": "UNKNOWN" }, "release_url": "https://pypi.org/project/zc.zkzopeserver/1.3.2/", "requires_dist": null, "requires_python": null, "summary": "zope.server wrapper that registers with ZooKeeper", "version": "1.3.2" }, "last_serial": 802219, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "527f73af0b5e4e2510f13b84e602fdbb", "sha256": "babc1a6c45bc32761a1b2c28782a4b0292ba8f56caa55169291bc5d4a4a64956" }, "downloads": -1, "filename": "zc.zkzopeserver-0.1.0.tar.gz", "has_sig": false, "md5_digest": "527f73af0b5e4e2510f13b84e602fdbb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5664, "upload_time": "2011-12-11T20:15:44", "url": "https://files.pythonhosted.org/packages/1f/0f/ee480f56f8cdfcc8f8e564c0c0f77c5c07e558f49f2d39842a30a6366b5b/zc.zkzopeserver-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "2c06b3314e2c7f5d5767770379ba64ab", "sha256": "461f9665062820851df7cd784a16e766f5872fa0b8e43bfdee6248b5d44e8d08" }, "downloads": -1, "filename": "zc.zkzopeserver-0.2.0.tar.gz", "has_sig": false, "md5_digest": "2c06b3314e2c7f5d5767770379ba64ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6328, "upload_time": "2012-01-18T21:47:12", "url": "https://files.pythonhosted.org/packages/4a/a2/38fc002537135929f25c06436aed92101f7d7719a2206af25fac4dd73c6c/zc.zkzopeserver-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "ffef36fc3f346a85031d3c9fa556333c", "sha256": "0341639beab1d0887cf95e208127dd44354caace54f8e6d1919ca468c9ca343b" }, "downloads": -1, "filename": "zc.zkzopeserver-0.3.0.tar.gz", "has_sig": false, "md5_digest": "ffef36fc3f346a85031d3c9fa556333c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8114, "upload_time": "2012-02-03T00:19:18", "url": "https://files.pythonhosted.org/packages/eb/24/f37dd0a1f3ceaf8b8d595adaa87a56f6486023d1d82adabf645109894145/zc.zkzopeserver-0.3.0.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "654ff5cccbde325d25a15f517994348b", "sha256": "bfaacb054a6e437dd5ad1dc7e31046f525e91b90d4761ae0ade5e05ade495e26" }, "downloads": -1, "filename": "zc.zkzopeserver-0.3.2.tar.gz", "has_sig": false, "md5_digest": "654ff5cccbde325d25a15f517994348b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7966, "upload_time": "2012-02-03T17:39:17", "url": "https://files.pythonhosted.org/packages/5b/68/d003fbf6c3d461fec2ecfefb1f85914566219d5ea86b8d548bf03d63fd7f/zc.zkzopeserver-0.3.2.tar.gz" } ], "1.3.1": [ { "comment_text": "", "digests": { "md5": "db2b82e075c8f13327eb02816cd3c43a", "sha256": "0b4167630b69ac83f8081f65407aa69dd2b8aa98f3a531d283d9cb13e4e5ac96" }, "downloads": -1, "filename": "zc.zkzopeserver-1.3.1.tar.gz", "has_sig": false, "md5_digest": "db2b82e075c8f13327eb02816cd3c43a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7008, "upload_time": "2012-02-03T17:26:23", "url": "https://files.pythonhosted.org/packages/16/50/b874dfb7bcfcdede526ccbfa0bd85c00cedb3da13b844804bd11734380f8/zc.zkzopeserver-1.3.1.tar.gz" } ], "1.3.2": [ { "comment_text": "", "digests": { "md5": "9f8d715299672a589f0081c8e3c88e1f", "sha256": "4ffa3c3cd58a5af75b82ccfe76cd51cd6d58bae8336ed7f35050a5c93003ab71" }, "downloads": -1, "filename": "zc.zkzopeserver-1.3.2.tar.gz", "has_sig": false, "md5_digest": "9f8d715299672a589f0081c8e3c88e1f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7959, "upload_time": "2012-02-03T17:45:14", "url": "https://files.pythonhosted.org/packages/92/8f/2ed93ed87da087d0df2bc857d410f5df1fc2c5a35b817a507fce31b56451/zc.zkzopeserver-1.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9f8d715299672a589f0081c8e3c88e1f", "sha256": "4ffa3c3cd58a5af75b82ccfe76cd51cd6d58bae8336ed7f35050a5c93003ab71" }, "downloads": -1, "filename": "zc.zkzopeserver-1.3.2.tar.gz", "has_sig": false, "md5_digest": "9f8d715299672a589f0081c8e3c88e1f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7959, "upload_time": "2012-02-03T17:45:14", "url": "https://files.pythonhosted.org/packages/92/8f/2ed93ed87da087d0df2bc857d410f5df1fc2c5a35b817a507fce31b56451/zc.zkzopeserver-1.3.2.tar.gz" } ] }