Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Running Pydoc under mod_python

I’ve written about pydoc before. In my opinion it’s one of Python’s best kept secrets: a way of instantly browsing the properties, methods and documentation strings of any module available to the Python environment. It can even run a local HTTP server to allow for easy browsing of available documentation.

That’s all well and good for code running on your local machine, but most developers won’t want to run a Pydoc server on a remote machine. We ran in to this problem recently at work; we wanted to run Pydoc on our development server but didn’t want it exposed to the world at large.

Initially we considered running the regular Pydoc server locally on some random port, blocking that port to external IPs with a firewall rule and then using Apache’s mod_proxy to open it up to outside access in a controlled manner. The downside with this is that we would have to run a special process and a firewall rule just to enable a relatively minor function. Instead, I spent some time working through the pydoc.py source code and came up with a mod_python wrapper for the HTML documentation part of the module.

modpydoc.py

(Aside: Safari will try to render the above as HTML, even though the Content-Type header says text/plain. This is because Safari is brain-dead—it inherited this particular grotesqueness from Internet Explorer. I still use it though.)

Since we were already running mod_python on our development server, adding this extra module required no extra server configuration or additional server processes. It also allowed us to tie authentication for the resulting Pydoc instance to our existing authentication database, using mod_auth_pgsql.

For the inquisitive, here’s a rough approximation of the relevant parts of our httpd.conf file for that server:


LoadModule access_module modules/mod_access.so
LoadModule auth_module modules/mod_auth.so
LoadModule alias_module modules/mod_alias.so
LoadModule auth_pgsql_module modules/mod_auth_pgsql.so
LoadModule python_module modules/mod_python.so

RedirectMatch permanent /pydoc$ /pydoc/

<Location "/pydoc/">
    SetHandler python-program
    PythonHandler utils.modpydoc
    PythonPath "sys.path+['/path/to/our/codebase/']"
    AuthName "Code Browser"
    AuthType basic
    Auth_PG_database ourdb
    Auth_PG_user dbuser
    Auth_PG_pwd_table users
    Auth_PG_uid_field username
    Auth_PG_pwd_field password_md5
    Auth_PG_pwd_whereclause " AND can_browse_code = 't' "
    Auth_PG_hash_type MD5
    require valid-user
</Location>

This is Running Pydoc under mod_python by Simon Willison, posted on 28th September 2004.

View blog reactions

Next: Back in England

Previous: Python2.4 highlights

5 comments

  1. I might be thick here, but you've taken the problem ("We want pydoc available through a browser from server N, but we don't want the internet to be able to see the served pydoc data"), proposed and rejected a solution ("firewall the port off from the internet"), and then proposed and implemented a solution ("require database-backed auth") to a totally different problem! I mean, you don't want people on the net to be able to see if if they've got the password, you just want them not to see it at all, right? Plus, now you have to log in to see python documentation, which is in no way secure? Surely it would have been better to implement some IP-blocking rule within Apache, if you ddn't want to tweak the firewall to cope with this?

    sil - 28th September 2004 06:54 - #

  2. My explanation was lacking. The regular Pydoc server (pydoc -p 8080 runs its own simple Python web server which has no scope for authentication, IP blocking or anything. We wanted to serve it up through Apache so we could use both Apache authentication and Apache access control (ommited from the above configuration example is the fact that we use Allow/Deny to tie down access to the web server to a specific range of IP addresses). Not wanting to bother with firewall rules and a long running pydoc process I implemented a mod_python wrapper instead, which made sense as we already had mod_python up and running on the box. The password stuff is icing on the cake really - it's there mainly to keep people on the internal IP range who aren't one of our three core developers from poking around in the source code.

    Simon Willison - 28th September 2004 15:04 - #

  3. Another option might have been ProxyPass -- you can add restrictions in Apache and only open up pydoc on some random port on 127.0.0.1, so only Apache could access it directly (and other local users, but that's fine too).

    Ian Bicking - 28th September 2004 17:07 - #

  4. For instantly browsing properties etc., give ipython a try. I love it. http://ipython.scipy.org/

    Jean Jordaan - 10th October 2004 21:43 - #

  5. I am broswe err run python and apache in current time.One page is right to browing ,not multiple pages.

    sein nyo - 15th December 2005 06:00 - #

Comments are closed.

Previously hosted at http://simon.incutio.com/archive/2004/09/28/modpydoc

A django site