From amk@magnet.com Sun May 11 17:08:57 1997 From: amk@magnet.com (Andrew Kuchling) Date: Sun, 11 May 1997 12:08:57 -0400 (EDT) Subject: [PYTHON DOC-SIG] Documenting frameworks: suggestions? Message-ID: <199705111608.MAA04724@lemur.magnet.com> I've written a first cut at documentation for SocketServer.py, and think it raises some issues that are worth discussing here. The TeX source for the docs is included below. (Comments on the text are welcome, though that's not why I'm posting it.) Most sections in the library reference simply have to document wrappers around a few functions, or an object that won't usually be subclassed. SocketServer is a fairly simple framework for writing servers of various kinds. There are several base classes, and several items to document: * class variables * instance variables * functions for external callers * functions to be overridden by subclasses * functions to be used by those overriding functions, but probably aren't worth overriding themselves. The documentation is thus broken up into sections; right now I've written little fragments of text like "The server classes support the following class variables" and then the class variables are listed and explained. Ditto for instance variables and all the different types of functions. That breaks up the text into a lot of different sections, and makes it difficult to scan through, so a better approach might be in order. Texinfo has special environments for this sort of thing, and I like its rendering; the output looks like: request_queue_size Class variable bla bla bla text goes here bla bla bla server_address Instance variable bla bla bla Perhaps for each function, we could indicate whether it's public or not, overridable or not. Or a tabular format--have a table lists all the attributes and methods, which ones are public, which are overridable, etc, and then just put everything in one big alphabetical list. Or, there could be two subsections; the first is the public interface, and the second is subclassing... Should the documentation be sufficient to use the module, or is it intended that users will look at the code for SocketServer.py? For example, the default implementation of functions like handle_error() is mentioned; should it perhaps be assumed that users will go look at that function's code and decide if it suits them? There are other frameworks, like BaseHTTPServer, that need to be documented for 1.5, so now's the time to improve the structure of the documentation. A.M. Kuchling amk@magnet.com http://people.magnet.com/%7Eamk/ Note to Guido: this isn't finished, so please don't add it to the docs yet. Thanks! ==================================================================== \section{Standard Module \sectcode{SocketServer}} \stmodindex{SocketServer} The \code{SocketServer} module simplifies the task of writing network servers. Classes are available to write servers that use Internet protocols or Unix domain sockets, and to use them as either streams or datagrams. There are four basic server classes: \code{TCPServer} uses the Internet TCP protocol, which provides continuous streams of data between the client and server. \code{UDPServer} uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The more infrequently used \code{UnixStreamServer} and \code{UnixDatagramServer} are similar, but use Unix domain sockets. For more details on network programming, consult a book such as W. Richard Steven's _XXX_ or XXX (Windows version?). These four classes process requests \dfn{synchronously}; each request must be completed before the next request can be started. This isn't suitable if each request takes a long time to complete; this may occur if a request requires a lot of computation, or if the request returns a lot of data and the client has a slow connection. The solution is to create a separate process or thread to handle each request; the \code{ForkingMixIn} and \code{ThreadingMixIn} mix-in classes can be used to support asynchronous behaviour. Creating a server requires several steps. First, you must create a request handler class by subclassing the \code{BaseRequestHandler} class and overriding its \code{handle()} method; this method processes incoming requests. Second, you must instantiate one of the server classes, passing it the server's address and the request handler class. Finally, call the \code{serve_forever()} or \code{handle_request()} method of the server object. Server classes have the same external methods and attributes, no matter what network protocol they use: %XXX should data and methods be intermingled, or separate? % how should the distinction between class and instance variables be % drawn? \begin{funcdesc}{fileno}{} Return a file descriptor for the socket on which the server is listening; this is just an integer. This function is most commonly passed to \code{select.select()}, to allow monitoring multiple servers in the same process. \end{funcdesc} \begin{funcdesc}{handle_request}{} Process a single request. This function calls the following methods, in order: \code{get_request()}, \code{verify_request()}, and \code{process_request()}. If the user-provided \code{handle()} method of the handler class raises an exception, the server's \code{handle_error()} method will be called. \end{funcdesc} \begin{funcdesc}{serve_forever}{} Handle an infinite number of requests. This simply calls \code{handle_request()} inside an infinite loop. \end{funcdesc} % XXX should class variables be covered before instance variables, or % vice versa? % Perhaps it would be more understandable and compact to do something % like Texinfo does? The server classes support the following class variables: \begin{datadesc}{request_queue_size} The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a queue, up to \code{request_queue_size} requests. Once the queue is full, further requests from clients will get a ``Connection denied'' error. The default value is usually 5, but this can be overridden by subclasses. \end{datadesc} \begin{datadesc}{socket_type} The type of socket used by the server; \code{socket.SOCK_STREAM} and \code{socket.SOCK_DGRAM} are possible values. \end{datadesc} Instances of server classes have the following instance variables: \begin{datadesc}{address_family} The family of protocols to which the server's socket belongs. \code{socket.AF_INET} and \code{socket.AF_UNIX} are possible values. \end{datadesc} \begin{datadesc}{RequestHandlerClass} The user-provided request handler class; an instance of this class is created for each request. \end{datadesc} \begin{datadesc}{server_address} The address on which the server is listening. This is a tuple containing a string giving the IP address, and an integer port number: \code{('127.0.0.1', 80)}, for example. \end{datadesc} \begin{datadesc}{socket} The socket object on which the server will listen. \end{datadesc} There are various server methods that can be overridden by subclasses of base server classes like \code{TCPServer}; these methods aren't useful to external users of the server object. % should the default implementations of these be documented, or should % it be assumed that the user will look at SocketServer.py? \begin{funcdesc}{finish_request}{} Actually processes the request by instantiating \code{RequestHandlerClass} and calling its \code{handle()} method. % XXX \end{funcdesc} \begin{funcdesc}{get_request}{} Must accept a request from the socket, and return a 2-tuple containing the \emph{new} socket object to be used to communicate with the client, and the client's address (which is itself a 2-tuple). \end{funcdesc} \begin{funcdesc}{handle_error}{request\, client_address} This function is called if the \code{RequestHandlerClass}'s \code{handle} method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. \end{funcdesc} \begin{funcdesc}{process_request}{request\, client_address} Calls \code{finish_request()} to create an instance of the \code{RequestHandlerClass}. If desired, this function can create a new process or thread to handle the request; the \code{ForkingMixIn} and \code{ThreadingMixIn} classes do this. \end{funcdesc} % Is there any point in documenting the following two functions? % What would the purpose of overriding them be: initializing server % instance variables, adding new network families? \begin{funcdesc}{server_activate}{} Called by the server's constructor to activate the server. May be overridden. \end{funcdesc} \begin{funcdesc}{server_bind}{} Called by the server's constructor to bind the socket to the desired address. May be overridden. \end{funcdesc} \begin{funcdesc}{verify_request}{request\, client_address} Must return a Boolean value; if the value is true, the request will be processed, and if it's false, the request will be denied. This function can be overridden to implement access controls for a server. \end{funcdesc} _______________ DOC-SIG - SIG for the Python Documentation Project send messages to: doc-sig@python.org administrivia to: doc-sig-request@python.org _______________ From amk@magnet.com Sun May 11 20:42:05 1997 From: amk@magnet.com (Andrew Kuchling) Date: Sun, 11 May 1997 15:42:05 -0400 (EDT) Subject: [PYTHON DOC-SIG] Notes on myformat.sty Message-ID: <199705111942.PAA08201@lemur.magnet.com> The hope is to eventually turn the following into a sort of style guide for the TeX documentation. Andrew Kuchling amk@magnet.com Useful typographical things =========================== \ABC The ABC language \UNIX The UNIX operating system \ASCII The ASCII format \Cpp The C++ language \C The C language \EOF The end-of-file condition \sectcode{} Include the text as code; for use only in section headers Macros to highlight small bits of text ====================================== \key, \kbd Indicate a key to be struck (each used only once; do we need them both?) \samp An example of something; \samp{print} or \samp{pass} \var A variable value, like a placeholder for a parameter's value \file A file name \dfn A term being defined for the first time \emph, \strong Emphasizing text that's important (do we need them both?) \varvars{} Define something as being a variable; this escapes chars where \var does not \iftexi, \iflatex Only execute the following code if Texinfo or LaTeX is being used. Indexing ======== Indexing: \index{entry text} is the standard LaTeX indexing macro. ! separates the entry text into sections. Ex.: \index{encoding!base-64}. \indexii{A}{B} creates two entries: A, B and B, A Ex.: \indexii{numeric}{value} \indexiii{A}{B}{C} 3 entries: A, B C -- B, C A -- C, A B Ex.: \indexiii{checksum}{cryptographically}{strong} Indexing special things: statements stindex Ex.: \stindex{pass} operators opindex Ex.: \opindex{**} exceptions exindex Ex.: \exindex{ValueError} objects obindex Ex.: \obindex{code} built-in functions bifuncindex modules modindex built-in modules bimodindex standard modules stmodindex Environments ============ Functions: \begin{funcdesc}{name}{arg1\, arg2\optional{\, optarg1}} Exceptions: \begin{excdesc}{name} Module-level variables (usually constants): \begin{datadesc}{name} \bcode, \ecode Sizable blocks of code should be inside a verbatim environment, and *must* be bracketed by the \bcode and \ecode tags. Ex.: \bcode\begin{verbatim} class foo: pass \end{verbatim}\ecode Tables ====== \tableii{pattern}{column 1 style}{column 1 name}{column 2 name} \tableiii{pattern}{column 1 style}{column 1 name}{column 2 name}{column 3 name} Organization ============ Within a single chapter, modules should be listed in alphabetical order. In each module, all module-level things like functions and variables should also be in alphabetical order. XXX more stylistic comments required! ===================================== Macros used only once: \indexiv Unused LaTeX macros: \itembreak, \itemjoin, \funcitem, \dataitem, \excitem, \kwindex _______________ DOC-SIG - SIG for the Python Documentation Project send messages to: doc-sig@python.org administrivia to: doc-sig-request@python.org _______________