===================== Quickstart with Grok_ ===================== Goals ===== In this quickstart, we will use zc.async to make a small web application that is a Python Package Index (PyPI, http://pypi.python.org/) helper portal. We'll call it "My PyPI," to be cute. *My PyPI* will let you subscribe to changes of specific packages, rather than the entire package index; and will let you associate external web pages with packages for you and others to see and search on. We'll make a number of "toy app" decisions to keep the story quick, but it should be a good example for how to leverage zc.async. Also for simplicity, we'll assume that we are making several instances on the same machine, such as you might do with a few processors at your disposal. To get the true advantage of high availability in production, you'd want at least two boxes, with a deployment of a ZEO server (or equivalent, for RelStorage), some kind of redundancy for your database (ZRS, or slony for RelStorage plus PostgreSQL) and instructions for each box on how to connect to the ZEO primary. This quickstart is more complex than the :ref:`quickstart-with-virtualenv`. I suggest you read that through before this one. - That previous quickstart introduces |async| through the Python interpreter for a very casual and quick start. - It also is more "pure-Python" with very little understanding needed of additional frameworks to follow and use the examples. This quickstart instead uses the following somewhat "heavier" technologies. - |zc.buildout|_ is a way of producing repeatable software build-outs, for development and conceivably for deployment. It is written in Python, but is not Python-specific, and it has found use as a ``make`` replacement for many projects. - Grok_ is a web framework emerging from "Zope 3" technologies. From their website: Grok is a web application framework for Python developers. It is aimed at both beginners and very experienced web developers. Grok has an emphasis on agile development. Grok is easy and powerful. This guide, then, takes a somewhat slower definition of "quick" for its "quickstart", in exchange for more guidance and care with a view towards production-readiness. .. _Grok: http://grok.zope.org/ .. |async| replace:: ``zc.async`` .. _`async`: http://pypi.python.org/pypi/zc.async .. |zc.buildout| replace:: ``zc.buildout`` .. _`zc.buildout`: http://pypi.python.org/pypi/zc.buildout Prerequisites ============= .. sidebar:: Building Python 2.4.5 on OS X Leopard Unfortunately, building a clean, standalone workable Python 2.4.5 on OS X is not obvious. This is what I recommend, if you are working on that platform. First you need macports. Go to http://www.macports.org/ and download the newest version. It doesn't seem to set up the manual path correctly, so after the installation add this to your ``~/.profile`` (or in a similar place):: export MANPATH=/opt/local/man:$MANPATH You'll need a new terminal session (or other shell magic if you know it) for these changes to take effect. The easiest thing to do is close the shell you are working in and open a new one. Download a source distribution of Python 2.4.5. You may have your own approach as to where to put things, but I go with this pattern: ``~/src`` holds expanded source trees, ``~/opt`` holds our local Python, and I develop in ``~/dev``. We will want readline and need zlib from macports. :: $ sudo port -c install readline $ sudo port -c install zlib Now we'll do the usual dance, with a couple of ugly extra steps. **Note: replace ``/Users/gary/opt/py`` in the below with your own desired location!** :: $ MACOSX_DEPLOYMENT_TARGET=10.5 ./configure \ --prefix=/Users/gary/opt/py \ LDFLAGS=-L/opt/local/lib \ OPT=-I/opt/local/include $ make $ make install Now, given my ``--prefix``, I'll find my python in ``/Users/gary/opt/py/bin/python``. As of this writing, Grok requires Python 2.4. Moreover, for more repeatable installations, many developers strongly recommend using a "clean", non-system Python, to reduce the probability of unnecessary or spurious problems (in your software *or* in your system!). Therefore, consider building your own Python 2.4 for your development. We'll also expect that your Python has |easy_install|_. If it doesn't, you can just download `ez_setup.py`_ and then run it with your local, development Python (e.g., ``~/opt/py/bin/python ez_setup.py``). This will install the easy_install command for your development Python in the same bin directory as your Python (e.g., ``~/opt/py/bin/easy_install``). .. |easy_install| replace:: ``easy_install`` .. _`easy_install`: http://peak.telecommunity.com/DevCenter/EasyInstall .. _`ez_setup.py`: http://peak.telecommunity.com/dist/ez_setup.py grokproject_ ============ .. sidebar:: |zc.buildout| Conveniences You may want to consider the following conveniences if you are building many projects with |zc.buildout|. They make zc.buildout keep two shared collections across all of your zc.buildout projects. This can significantly speed up the time to buildout new applications. One shared collection is a download cache of source distributions and eggs. The other is an egg cache only, for both the downloaded eggs and the eggs generated on your machine. In your home directory, make a ``.buildout`` directory. In that directory, make two sub-directories, ``eggs`` and ``download-cache``. Also in ``.buildout``, create a file named ``default.cfg`` with the following content, where ``/Users/gary`` is replaced with the path to your home directory:: [buildout] eggs-directory=/Users/gary/.buildout/eggs download-cache=/Users/gary/.buildout/download-cache There are many other possible settings to make here (for instance, we could specify the clean Python you built here), but these are all I currently bother with. It is also worth mentioning that, as of this writing, setuptools builds eggs in such a way as to confuse the Python debugger. If you use the Python debugger and discover that you want to see the lines in an egg and can't, the following line (or something like it) will help for non-zipped eggs:: find ~/.buildout/eggs-aside/ -name '*.pyc' -exec rm {} \; Grok has a pleasantly convenient way to start a project. It is called grokproject_. Use your local Python's ``easy_install`` to install it. For instance, I might type ``~/opt/py/bin/easy_install grokproject``. After it runs, it should have installed the ``grokproject`` command in the same bin directory as your local Python (e.g., ``~/opt/py/bin/grokproject``). .. _grokproject: http://pypi.python.org/pypi/grokproject Skeleton ======== Now we will use grokproject_ to make a skeleton of our package. Let's call the project "mypypi". Go to a directory in which you want to develop our package. Then use the newly installed ``grokproject`` command to create XXX - include zc.async in setup.py; mention versions.cfg - set up ZEO - set up multiple instances - zope.app.testing = 3.4.1 -> 3.4.2 - set up interpreter - set up z3monitor - make separate debug instance