How to set up user interpretation for interpreters when running zeppelin in a docker image? - apache-zeppelin

I'm setting up a docker image on the basis of the zeppelin docker image. Now I'm packing my own configuration into my own docker image. I've got it connected to LDAP for logging in and for user impersonation. Like this, overriding the ZEPPELINIMPERSONATECMD in zeppelin-env.sh.
Running whoami with the sh interpreter works fine now. And running id also shows all the correct user information from ldap.
However when I switch the python interpreter to the isolated per user setting and turn on user interpretation it will fail with a ImportError[1] response in the note itself. The server logging looks like this[2], I replaced my user name with user_name.
I've tried not overwriting the the ZEPPELINIMPERSONATECMD in zeppelin-env.sh. That will just result in a runtime exception[3] when running anything.
I've tried copying the /zeppelin/interpreter/python/py4j-0.9.2/src/py4j folder to /tmp but that will just result in python not responding after 10 seconds.
Does anyone have any ideas on how to run the python interpreter as the logged in user?
[1]:
Traceback (most recent call last):
File "/tmp/zeppelin_python-702917387527627656.py", line 20, in <module>
from py4j.java_gateway import java_import, JavaGateway, GatewayClient
ImportError: No module named py4j.java_gateway
Traceback (most recent call last):
File "/tmp/zeppelin_python-702917387527627656.py", line 20, in <module>
from py4j.java_gateway import java_import, JavaGateway, GatewayClient
ImportError: No module named py4j.java_gateway
python is not responding
[2]:
INFO [2019-08-14 15:13:14,716] ({pool-2-thread-2} ShellScriptLauncher.java[launch]:48) - Launching Interpreter: python
INFO [2019-08-14 15:13:14,727] ({pool-2-thread-2} RemoteInterpreterManagedProcess.java[start]:115) - Thrift server for callback will start. Port: 40221
INFO [2019-08-14 15:13:14,738] ({pool-2-thread-2} RemoteInterpreterManagedProcess.java[start]:190) - Run interpreter process [/zeppelin/bin/interpreter.sh, -d, /zeppelin/interpreter/python, -c, 172.17.0.3, -p, 40221, -r, :, -u, user_name, -l, /zeppelin/local-repo/python, -g, python]
INFO [2019-08-14 15:13:16,400] ({pool-7-thread-1} RemoteInterpreterManagedProcess.java[callback]:123) - RemoteInterpreterServer Registered: CallbackInfo(host:172.17.0.3, port:40445)
INFO [2019-08-14 15:13:16,440] ({pool-2-thread-2} RemoteInterpreter.java[call]:168) - Create RemoteInterpreter org.apache.zeppelin.python.PythonInterpreter
INFO [2019-08-14 15:13:16,540] ({pool-2-thread-2} RemoteInterpreter.java[call]:168) - Create RemoteInterpreter org.apache.zeppelin.python.IPythonInterpreter
INFO [2019-08-14 15:13:16,544] ({pool-2-thread-2} RemoteInterpreter.java[call]:168) - Create RemoteInterpreter org.apache.zeppelin.python.PythonInterpreterPandasSql
INFO [2019-08-14 15:13:16,545] ({pool-2-thread-2} RemoteInterpreter.java[call]:168) - Create RemoteInterpreter org.apache.zeppelin.python.PythonCondaInterpreter
INFO [2019-08-14 15:13:16,547] ({pool-2-thread-2} RemoteInterpreter.java[call]:168) - Create RemoteInterpreter org.apache.zeppelin.python.PythonDockerInterpreter
INFO [2019-08-14 15:13:16,549] ({pool-2-thread-2} RemoteInterpreter.java[call]:142) - Open RemoteInterpreter org.apache.zeppelin.python.PythonInterpreter
INFO [2019-08-14 15:13:16,549] ({pool-2-thread-2} RemoteInterpreter.java[pushAngularObjectRegistryToRemote]:436) - Push local angular object registry from ZeppelinServer to remote interpreter group python:user_name:
WARN [2019-08-14 15:13:27,703] ({pool-2-thread-2} NotebookServer.java[afterStatusChange]:2316) - Job 20190814-151311_1784127416 is finished, status: ERROR, exception: null, result: %text Traceback (most recent call last):
File "/tmp/zeppelin_python-4627212054430132450.py", line 20, in <module>
from py4j.java_gateway import java_import, JavaGateway, GatewayClient
ImportError: No module named py4j.java_gateway
%text Traceback (most recent call last):
File "/tmp/zeppelin_python-4627212054430132450.py", line 20, in <module>
from py4j.java_gateway import java_import, JavaGateway, GatewayClient
ImportError: No module named py4j.java_gateway
%text python is not responding
INFO [2019-08-14 15:13:27,713] ({pool-2-thread-2} VFSNotebookRepo.java[save]:196) - Saving note:2EJWQC1Y4
INFO [2019-08-14 15:13:27,715] ({pool-2-thread-2} SchedulerFactory.java[jobFinished]:120) - Job 20190814-151311_1784127416 finished by scheduler org.apache.zeppelin.interpreter.remote.RemoteInterpreter-python:user_name:-shared_session
[3]:
java.lang.RuntimeException: ssh: connect to host localhost port 22: Cannot assign requested address
at org.apache.zeppelin.interpreter.remote.RemoteInterpreterManagedProcess.start(RemoteInterpreterManagedProcess.java:205)
at org.apache.zeppelin.interpreter.ManagedInterpreterGroup.getOrCreateInterpreterProcess(ManagedInterpreterGroup.java:64)
at org.apache.zeppelin.interpreter.remote.RemoteInterpreter.getOrCreateInterpreterProcess(RemoteInterpreter.java:111)
at org.apache.zeppelin.interpreter.remote.RemoteInterpreter.internal_create(RemoteInterpreter.java:164)
at org.apache.zeppelin.interpreter.remote.RemoteInterpreter.open(RemoteInterpreter.java:132)
at org.apache.zeppelin.interpreter.remote.RemoteInterpreter.getFormType(RemoteInterpreter.java:299)
at org.apache.zeppelin.notebook.Paragraph.jobRun(Paragraph.java:407)
at org.apache.zeppelin.scheduler.Job.run(Job.java:188)
at org.apache.zeppelin.scheduler.RemoteScheduler$JobRunner.run(RemoteScheduler.java:315)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

I managed to fix this by adding:
export PYTHONPATH=/zeppelin/interpreter/python/py4j-0.9.2/src
in zeppelin-env.sh.
After that the interpreter ran fine.

Related

flask app engine does not work with firestore?

Setup: Run in Google Cloud Shell Standard Env
I tried to access firestore from the flask app using from google.cloud import firestore
I have installed it using pip install --upgrade google-cloud-firestore -t lib. If I run the script manually, it works fine. But when using dev_appserver.py, it fails. Got the error below.
$ dev_appserver.py app.yaml
INFO 2017-10-06 07:34:35,301 devappserver2.py:105] Skipping SDK update check.
INFO 2017-10-06 07:34:35,391 api_server.py:300] Starting API server at: http://0.0.0.0:34796
WARNING 2017-10-06 07:34:35,391 dispatcher.py:312] Your python27 micro version is below 2.7.12, our current production version.
INFO 2017-10-06 07:34:35,440 dispatcher.py:251] Starting module "default" running at: http://0.0.0.0:8080
INFO 2017-10-06 07:34:35,441 admin_server.py:116] Starting admin server at: http://0.0.0.0:8000
ERROR 2017-10-06 07:34:42,266 wsgi.py:263]
Traceback (most recent call last):
File "/google/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/google/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/google/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
obj = __import__(path[0])
File "/home/user1/projects/probfe/main.py", line 10, in <module>
from google.cloud import firestore
File "/google/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/python/runtime/sandbox.py", line 1132, in load_module
raise ImportError('No module named %s' % fullname)
ImportError: No module named google.gax
However, in my lib, I can see them.
$ls lib
builtins future-0.16.0.dist-info itsdangerous.pyc requests-2.18.4.dist-info
cachetools futures-3.1.1.dist-info jinja2 rsa
cachetools-2.0.1.dist-info google Jinja2-2.9.6.dist-info rsa-3.4.2.dist-info
certifi googleapis_common_protos-1.5.3.dist-info libfuturize setuptools
certifi-2017.7.27.1.dist-info googleapis_common_protos-1.5.3-py2.7-nspkg.pth libpasteurize setuptools-36.5.0.dist-info
chardet google_auth-1.1.1.dist-info _markupbase six-1.11.0.dist-info
chardet-3.0.4.dist-info google_auth-1.1.1-py2.7-nspkg.pth markupsafe six.py
click google_cloud_core-0.27.1.dist-info MarkupSafe-1.0.dist-info six.pyc
click-6.7.dist-info google_cloud_core-0.27.1-py3.6-nspkg.pth past socketserver
concurrent google_cloud_firestore-0.27.0.dist-info pkg_resources tests
copyreg google_cloud_firestore-0.27.0-py3.6-nspkg.pth ply _thread
dill google_gax-0.15.15.dist-info ply-3.8.dist-info tkinter
dill-0.2.7.1.dist-info google_gax-0.15.15-py2.7-nspkg.pth protobuf-3.4.0.dist-info urllib3
_dummy_thread grpc protobuf-3.4.0-py2.7-nspkg.pth urllib3-1.22.dist-info
easy_install.py grpcio-1.4.0.dist-info pyasn1 werkzeug
easy_install.pyc html pyasn1-0.3.7.dist-info Werkzeug-0.12.2.dist-info
enum http pyasn1_modules winreg
enum34-1.1.6.dist-info idna pyasn1_modules-0.1.4.dist-info xmlrpc
flask idna-2.6.dist-info queue
Flask-0.12.2.dist-info itsdangerous-0.24.dist-info reprlib
future itsdangerous.py requests
Since you're using dev_appserver.py it means you have a standard env application. And in the standard env all external dependencies need to be installed in your app, not on the local python instalation (which is what you did with your pip invocation).
From Installing a third-party library:
Create a directory to store your third-party libraries, such as lib/.
mkdir lib
Use pip (version 6 or later) with the -t <directory> flag to copy the libraries into the folder you created in the previous
step. For example:
pip install -t lib/ <library_name>

gcloud preview app run: "OSError: [Errno 2] No such file or directory"

When running gcloud preview app run from Google Compute Engine, running Ubuntu Trust 14.04 image, I get the following error:
(Note: I fetched the complete gcloud SDK from https://cloud.google.com/sdk/)
$ gcloud preview app run appengine-modules-guestbook/src/main/webapp
Java module found in [/home/yaraju_gmail_com/appengine-modules-sample-java/appengine-modules-guestbook/src/main/webapp]
INFO: Skipping SDK update check.
INFO: Starting API server at: http://localhost:46920
INFO: Starting module "default" running at: http://localhost:8080
INFO: Starting admin server at: http://localhost:8000
Exception in thread Instance Adjustment:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/yaraju_gmail_com/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1492, in _loop_adjusting_instances
self._adjust_instances()
File "/home/yaraju_gmail_com/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1469, in _adjust_instances
self._add_instance(permit_warmup=True)
File "/home/yaraju_gmail_com/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1354, in _add_instance
if not inst.start():
File "/home/yaraju_gmail_com/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/instance.py", line 274, in start
self._runtime_proxy.start()
File "/home/yaraju_gmail_com/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/http_runtime.py", line 270, in start
stderr=subprocess.PIPE)
File "/home/yaraju_gmail_com/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/safe_subprocess.py", line 132, in start_process_file
stderr=stderr)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
What can I do to fix this?
You might be missing one of the dependencies.
Ensure that you have run the following:
sudo apt-get install openjdk-7-jdk
gcloud components update gae-java

fail to execute php-cgi for google app engine under windows

OS: windows 8
google app engine sdk 1.8.2
C:\google_appengine>dev_appserver.py --php_executable_path=D:\php5417 D:\helloworld
INFO 2013-08-03 16:13:43,874 sdk_update_checker.py:244] Checking for updates to the SDK.
INFO 2013-08-03 16:13:45,128 sdk_update_checker.py:260] Update check failed: HTTP Error 404: Not Found
WARNING 2013-08-03 16:13:45,148 api_server.py:314] Could not initialize images API; you are likely missing the Python "PIL" module.
INFO 2013-08-03 16:13:45,164 api_server.py:138] Starting API server at: http://localhost:9024
INFO 2013-08-03 16:13:45,171 dispatcher.py:164] Starting module "default" running at: http://localhost:8080
ERROR 2013-08-03 16:13:45,176 php_runtime.py:216] The PHP runtime is not available
Traceback (most recent call last):
File "C:\google_appengine\google\appengine\tools\devappserver2\php_runtime.py", line 212, in new_instance
self._check_environment(php_executable_path)
File "C:\google_appengine\google\appengine\tools\devappserver2\php_runtime.py", line 156, in _check_environment
env={})
File "C:\google_appengine\google\appengine\tools\devappserver2\safe_subprocess.py", line 61, in start_process
stdin=subprocess.PIPE)
File "C:\python\lib\subprocess.py", line 711, in __init__
errread, errwrite)
File "C:\python\lib\subprocess.py", line 948, in _execute_child
startupinfo)
WindowsError: [Error 5] 存取被拒。
INFO 2013-08-03 16:13:45,177 admin_server.py:117] Starting admin server at: http://localhost:8000
--php_executable_path should point to the actual executable file. So you probably want something like:
--php_executable_path=D:\php5417\php-cgi.exe

Google App Engine PHP running on mac

Trying to run WordPress on Google App Engine.
Following the installation I am missing where the "path to php-cgi" is?
I can find some php54-cgi under macport/software/php54-cgi, but setting the path to this gives permission errors.
Also the installation missed saying anything about installing python sdk in order to run the dev_appserver.py.
Question is can you even run the hello world on mac and if so how to start the dev_appserver.py?
https://developers.google.com/appengine/docs/php/gettingstarted/helloworld
Error message:
dev_appserver.py --php_executable_path=/opt/local/var/macports/software/php54-cgi /Users/name/GAE/PHPTest
WARNING 2013-05-21 22:31:10,600 api_server.py:329] Could not initialize images API; you are likely missing the Python "PIL" module.
WARNING 2013-05-21 22:31:10,606 simple_search_stub.py:962] Could not read search indexes from /var/folders/6w/2nmsznqj3d7310_lp70p34s00000gn/T/appengine.helloworld/search_indexes
INFO 2013-05-21 22:31:10,609 api_server.py:153] Starting API server at: http://localhost:49390
INFO 2013-05-21 22:31:10,614 dispatcher.py:164] Starting server "default" running at: http://localhost:8080
INFO 2013-05-21 22:31:10,619 admin_server.py:117] Starting admin server at: http://localhost:8000
Exception in thread Thread-6:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/server.py", line 1232, in _loop_adjusting_instances
self._adjust_instances()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/server.py", line 1209, in _adjust_instances
self._add_instance(permit_warmup=True)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/server.py", line 1087, in _add_instance
expect_ready_request=perform_warmup)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/php_runtime.py", line 195, in new_instance
self._check_environment(php_executable_path)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/php_runtime.py", line 138, in _check_environment
env={})
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/safe_subprocess.py", line 61, in start_process
stdin=subprocess.PIPE)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 13] Permission denied
Thanks
Regards
I used macports to get it running, /opt/local/bin/php-cgi54.
./google_appengine/dev_appserver.py --php_executable_path=/opt/local/bin/php-cgi54 --php_remote_debugging=yes ~/apps/minishell/
However, I'm not sure that your permission denied error is related to not being able to find the php-cgi executable.

Fatal devappserver2 error: PYTHON_EGG_CACHE in Appengine 1.7.6 and 1.7.5 python 2.7, win7

I attempted to use Appengine SDK version 1.7.6 but was receiving fatal errors (same as outlined below) so reverted to 1.7.5, where my app works fine. However, the errors I saw in 1.7.6 recur when I attempt to run the experimental devappserver in 1.7.5. I am running Python 2.7 on a win 7 machine. Standard install selections for AppEngine.
These error messages refer to permissions relating to the PYTHON_EGG_CACHE, but...
- 1) They do not occur for the 'old' dev_appserver
- 2) The application can successfully extract files to the location noted. In fact, I changed the path of the PYTHON_EGG_CACHE to another location, gave it wide open permissions, and still received the error.
- 3) I have pyyaml in my site-packages, so am not sure why it would need to do a temporary extract anyway.
Any help looking for a resolution to this would be appreciated, since I'll be forced to use the new devappserver in a couple of releases time.
Command line error dump below:
python "C:\Program Files (x
86)\Google\google_appengine\devappserver2.py" .
WARNING 2013-03-25 19:10:41,029 devappserver2.py:497] devappserver2.py is curre
ntly experimental but will eventually replace dev_appserver.py in the App Engine
Python SDK. For more information and to report bugs, please see: http://code.go
ogle.com/p/appengine-devappserver2-experiment/
INFO 2013-03-25 19:10:41,171 appcfg.py:618] Checking for updates to the SDK.
WARNING 2013-03-25 19:10:44,525 simple_search_stub.py:975] Could not read searc
h indexes from c:\users\ben\appdata\local\temp\appengine.dev~upskillme-main.Ben\
search_indexes
INFO 2013-03-25 19:10:44,539 api_server.py:148] Starting API server at: http
://localhost:49302
INFO 2013-03-25 19:10:44,555 dispatcher.py:96] Starting server "default" run
ning at: http://localhost:8080
INFO 2013-03-25 19:10:44,571 admin_server.py:112] Starting admin server at:
http://localhost:8000
Traceback (most recent call last):
File "C:\Program Files (x86)\Google\google_appengine\_python_runtime.py", line
150, in <module>
run_file(__file__, globals())
File "C:\Program Files (x86)\Google\google_appengine\_python_runtime.py", line
146, in run_file
execfile(script_path, globals_)
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\de
vappserver2\python\runtime.py", line 39, in <module>
from google.appengine.ext.remote_api import remote_api_stub
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\remo
te_api\remote_api_stub.py", line 75, in <module>
import yaml
File "C:\Program Files (x86)\Google\google_appengine\lib\yaml-3.10\yaml\__init
__.py", line 14, in <module>
from cyaml import *
File "C:\Program Files (x86)\Google\google_appengine\lib\yaml-3.10\yaml\cyaml.
py", line 5, in <module>
from _yaml import CParser, CEmitter
File "C:\Python27\lib\site-packages\pyyaml-3.10-py2.7-win32.egg\_yaml.py", lin
e 7, in <module>
File "C:\Python27\lib\site-packages\pyyaml-3.10-py2.7-win32.egg\_yaml.py", lin
e 4, in __bootstrap__
File "C:\Python27\lib\site-packages\pkg_resources.py", line 882, in resource_f
ilename
self, resource_name
File "C:\Python27\lib\site-packages\pkg_resources.py", line 1351, in get_resou
rce_filename
self._extract_resource(manager, self._eager_to_zip(name))
File "C:\Python27\lib\site-packages\pkg_resources.py", line 1406, in _extract_
resource
manager.extraction_error() # report a user-friendly error
File "C:\Python27\lib\site-packages\pkg_resources.py", line 928, in extraction
_error
raise err
pkg_resources.ExtractionError: Can't extract file(s) to egg cache
The following error occurred while trying to extract file(s) to the Python egg
cache:
[Error 5] Access is denied: 'C:\\Users\\Ben\\AppData\\Roaming\\Python-Eggs\\py
yaml-3.10-py2.7-win32.egg-tmp\\_yaml.pyd'
The Python egg cache directory is currently set to:
C:\Users\Ben\AppData\Roaming\Python-Eggs
Perhaps your account does not have write access to this directory? You can
change the cache directory by setting the PYTHON_EGG_CACHE environment
variable to point to an accessible directory.
Exception in thread Thread-4:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 551, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\de
vappserver2\server.py", line 1045, in _loop_adjusting_instances
self._adjust_instances()
If anyone comes along with the same issue, the resolution that worked for me was as follows:
Unzip the PyYAML-3.10-py2.7-win32.egg in your python27 site-packages
directory into a new directory within site-packages. You'll need to
unzip it to into a directory name like NEWPyYAML-3.10-py2.7-win32.egg
to avoid name conflicts.
Rename your original egg. to something else (e.g., OLDPyYAML-3.10-py2.7-win32.egg).
Rename your new directory to PyYAML-3.10-py2.7-win32.egg
All references to the egg will now actually point to a directory in your site-packages containing the unzipped python files. The new devappserver should be able to work with this.
Unsure how to unzip an egg in windows? See here (presuming you have Winzip or similar installed):
http://mail.python.org/pipermail/chicago/2007-July/002301.html

Resources