Houdini 18.0 How to use the help

Running a central help server

On this page

Overview

A studio can set up a central help server to serve help to multiple users of Houdini, instead of each instance of Houdini starting up its own help server on each machine. This is useful for sharing site-specific documentation between users.

This document outlines several solutions for running a central server:

  • Small scale: running the default help server. This simply runs the default Python server included with Houdini. This may be sufficient for a few simultaneous users, but for more than few users you probably want to use one of the faster solutions below.

    This solution is easiest to set up and run, but only works for a small number of simultaneous users. This requires a Houdini license (such as an Apprentice license).

  • Faster: use a proxy server. This uses a standalone HTTP server such as nginx to serve most files, while forwarding requests for help page contents to the default Python server.

    This is the most balanced solution. It provides dynamic content, search, and reading help embedding in nodes, while being much faster than the default Python server alone. For a large number of users, it may not be fast enough. This requires a Houdini license (such as an Apprentice license).

  • Even faster: serve the app using a WSGI application server. This uses a WSGI application server to serve static files and handle dynamic page requests.

    This provides dynamic content and search, but cannot read help embedded in nodes. It is faster and scales better than the proxy solution. This does not require a Houdini license.

  • Fastest: serving static help. This pre-generates HTML files from the wiki files in the help, so you can serve them using a plain HTTP server.

    This is the fastest possible solution, and easy to set up, since it’s just serving plain static files. This solution allows you to publish Houdini’s help from an existing web server. This does not provide dynamic content, search, or help embedded in nodes. This does not require a Houdini license.

Note

This document outlines general solutions and configurations. Some of the solutions require installation and configuration of third party software. This document contains some examples, but unfortunately it can’t hope to cover all the possible combinations of platform, software, and configuration options. You may need to do your own research on the software you use, its configuration options, and how your chosen software uses standards such as WSGI.

Licensing

The help server normally requires a Houdini license to run, since it uses HOM to read help embedded in nodes and tools.

You can run hython with any Houdini license, including an Apprentice license. The easiest thing to do is set up a central server machine and install just an Apprentice license on it, so the server process will use that.

(In a future version of Houdini we hope to make it easier to choose to run hython with an Apprentice license through a command-line switch.)

Note that serving static help does not require ongoing use of a license, but has some drawbacks. See serving static help below for more information.

Small scale: running the default help server

The easiest way to set up a central help server is simply to run the default Python help server included with Houdini. The drawback is that the Python server can only uses a single process, and serves all files (images, stylesheets, and so on) using Python code. This may be fast enough for a few people, but for more than a few users you probably need to investigate the faster options below.

  • Easy to set up.

  • Doesn’t scale well to many simultaneous users.

Command line

  1. Open a Houdini shell.

    Windows

    Click Start ▸ All programs ▸ Side Effects Software ▸ Houdini X.X.XXX ▸ Utilities ▸ Command line tools.

    Mac

    In the Finder, open Applications ▸ Houdini ▸ HoudiniX.X.X ▸ Utilities ▸ Houdini Terminal.

    Linux

    In a bash shell, cd to the Houdini install directory and source houdini_setup.

  2. In the Houdini shell, type:

    hhelp serve --bgindex=true
    

    …to start the help server with background indexing.

  3. Open a browser and go to

    http://localhost:8080/
    

hhelp serve

--host=0.0.0.0

The IP address for the server.

  • If your computer has multiple network controllers, you can specify which address you want the server to listen at.

  • Use 0.0.0.0 (the default) to make the server available to other computers.

  • Use localhost or 127.0.0.1 to make the server only available on your computer.

--port=8080

The port number for the server. Default is 8080.

--debug

Run the server with debugging information on.

--bgindex

Re-index changed documents in the background while the server is running.

--config=path

(Optional) a file to read configuration options from.

--logfile=path

(Optional) a file to write server log to.

--loglevel=DEBUG|INFO|WARNING|ERROR

(Optional) log messages at or above this level of severity.

hhelp index

This command lets you manually update the search index (if you're not running a server with the --bgindex option). By default the command will only update changed files, unless you pass the --clean option.

--clean

Re-index all documents from scratch, whether they've changed or not.

--usages

Generate information about what nodes are used by example files.

--config=path

(Optional) a file to read configuration options from.

--logfile=path

(Optional) a file to write server log to.

--loglevel=DEBUG|INFO|WARNING|ERROR

(Optional) log messages at or above this level of severity.

Starting the server from hython

If you want to start the built-in server in code:

from houdinihelp.server import start_server

start_server(
    host="0.0.0.0",         # Network interface to listen to
    port=8080,             # Port to listen to
    debug=False,            # Whether to start the server in debug mode
    bgindex=None ,          # Whether to do background indexing
    config_file=None,       # String path to a config file
    use_houdini_path=True,  # See below
)
  • If config_file is None and use_houdini_path is True, the code will use hou to search the Houdini path for a config/Help/bookish.cfg configuration file (see configuration below). This will use a batch license if hou hasn’t already been imported. If you're specifying a configuration file in the arguments you don’t need worry about this.

  • The bgindex keyword argument can be True, False, or None. None means use the value from the configuration, whereas passing True or False will override the configuration.

Faster: use a proxy server

You can install and run a small web server application such as nginx or uwsgi and use it to serve the help’s static files directly, and "forward" (proxy) requests for help pages to the help server.

  • Relatively easy to set up.

  • Much faster than plain help server, because the standalone server takes care of most files (images, stylesheets, and so on).

  • Can still serve dynamic wiki help out of Houdini path, embedded in nodes, tools, and so on.

  • Throughput is limited because requests for page contents still go through the help server.

Set up central server directories

To set up a proxy server, do the following:

  1. Start the help server process using hhelp serve, as shown above.

  2. Create a directory for your central server, and inside that, a directory for the static files:

    % mkdir central central/files
    % cd central
    
  3. Copy the static help files (such as images and stylesheets) into the central/files directory.

    (Some of the files we want to serve directly are shipped inside .zip files, so the easiest thing is to copy all the files we want into one place.)

    % mkdir files/icons files/images files/static
    % unzip $HFS/houdini/help/icons.zip -d files/icons
    % unzip $HFS/houdini/help/images.zip -d files/images
    % cp -r $HFS/houdini/help/videos videos
    % cp -r $HFS/houdini/python2.7libs/bookish/static/* static
    % cp -r $HFS/houdini/python2.7libs/houdinihelp/static/* static
    

    (Note that we merge the contents of the bookish/static and houdinihelp/static directories from $HFS into a single files/static directory under central.)

  4. Create an environment variable to the absolute path your central directory.

    For example:

    export CENTRAL=/home/username/central
    

    (This is not strictly necessary, but as a convenience will use $CENTRAL in the examples below in place of the central directory’s path.)

Set up a proxy server

  1. Install a standalone HTTP server.

    This step is specific to the HTTP server you want to use. We recommend a lightweight server such as nginx.

    How to install server software on your system is beyond the scope of this document. See the instructions for your chosen server for how to install it on different platforms. In general, on Linux, you can install nginx using your distribution’s package manager. On Mac, you can install it by first installing Homebrew and then using Homebrew to install nginx.

  2. Set up your HTTP server to serve the static files directly, and proxy other requests to the help server.

    This is highly specific to the HTTP server you use and how you want to configure your server. See the example below.

nginx example

Here is an example configuration file for nginx. You can save this file in the central directory.

proxy.nginx configuration file

worker_processes 4;
daemon off;
error_log stderr;
http {
    include /usr/local/etc/nginx/mime.types;
    server {
        listen 0.0.0.0:9090;
        location ~ ^/(images|icons|videos|static)/ {
            root $CENTRAL/files;
        }
        location / {
            proxy_pass http://localhost:8080/;
        }
    }
}
events {
    worker_connections  1024;
}

(See the documentation for nginx for a full list of available configuration.)

  • This example sets daemon off so the server does not immediate fork a separate process and return, so you can see its error messages and other output. Once you have the server set up how you want, you may decide to change this to on so the server runs in the background. You can then instruct it to reload the config file using nginx -s reload, or stop using nginx -s stop.

  • The line include /usr/local/etc/nginx/mime.types; may be specific to your installation. You should to check where nginx’s mime.types file was installed on your system and specify that path.

  • The line listen 0.0.0.0:9090 sets the IP address/port the nginx server will listen on. This must be a different port from the port the help server is listening on (8080 in the examples above).

    Listening on 0.0.0.0 (as opposed to localhost or 127.0.0.1) means that other computers on the network can access this server.

  • The line root $CENTRAL/files; should list the absolute path to the central directory you created above. You cannot use a tilde (~) to represent your home directory in this path.

  • The line proxy_pass http://localhost:8080/; should specify the root URL of the help server.

You can run nginx with this configuration:

% nginx -c $CENTRAL/proxy.nginx

Note that you must specify an absolute path to the configuration file. Otherwise nginx looks for it relative to its install directory, not the current directory. Again, you cannot use a tilde (~) to represent your home directory in this path.

Now you can try the server by pointing a browser to:

http://localhost:9090/

Even faster: serve the app using a WSGI application server

The proxy server example above is relatively easy to set up because you can use hhelp to start Houdini’s help server as usual, then forward requests to the help server as needed.

However, the drawback is that communicating with the help server over HTTP is somewhat inefficient, and the Python help server is still single-process/single-threaded, limiting overall throughput.

Instead of running the help server and forwarding requests to it, this solution uses a WSGI application server such as uwsgi, gunicorn, or Apache with modwsgi, to run the Houdini help’s application code itself, so it can use multiprocessing and multithreading.

WSGI is a protocol that allows standalone HTTP servers to run a Python function to generate dynamic web content. The drawback is that the server usually wants to start the Python interpreter itself, so we can’t rely on hython setting up the path to Houdini’s libraries automatically. The application.py script listed in this section manipulates the Python path so the Houdini help app can run in plain Python.

  • Faster than the plain help server or proxy server solutions.

  • Can serve dynamic wiki help from directories you specify.

  • Doesn’t require any Houdini license.

  • Slightly harder to set up, since we can’t use hython (which sets up the Python path automatically to use Houdini’s libraries).

  • Can’t use hou, so this solution can’t serve help embedded inside assets or tools.

Note

You should still run the server in a Houdini shell environment, so it has environment variables such as $HFS available.

Setting up an application server

  1. First, set up the directory structure as in setting up central server directories above.

    This should give you a directory structure like this:

    central/
        files/
            icons/
                ...
            images/
                ...
            videos/
                ...
            static/
                ...
    
  2. The app server will require a script to create an application() function it will call to serve pages.

    The application server will run the script using Python, not hython, so it won’t automatically have the Houdini libraries available.

    The following example script manipulates the Python path so it can find Houdini’s libraries, and configures the application to find files under $HFS, before creating the application function.

    Save this to a file under central called application.py.

    Example central/application.py script

    import logging
    import sys
    from os.path import expandvars
    
    # Add Houdini libraries to Python path
    sys.path.append(expandvars("$HFS/houdini/python2.7libs"))
    
    # Add Houdini's third-party Python libraries. Unfortunately this path is
    # platform-specific
    if sys.platform in ("linux", "linux2"):
       sys.path.append(expandvars("$HFS/python/lib/python2.7/site-packages-forced"))
    elif sys.platform == "darwin":
        sys.path.append(
            expandvars(
                "$HFS/Frameworks/Python.framework/Versions/Current/lib/python2.7/site-packages-forced"
            )
        )
    elif sys.platform in ("win32", "win64"):
        sys.path.append(expandvars("$HFS/python27/lib/site-packages-forced"))
    
    
    from houdinihelp.hconfig import HoudiniHfsConfig
    from houdinihelp.server import get_houdini_app
    
    
    class MyConfig(HoudiniHfsConfig):
        # The directories you want to serve from
        DOCUMENTS = [
            # "Loose" (unzipped) files under $HFS/houdini/help
            expandvars("$HFS/houdini/help"),
            {
                # This adds ability to read docs out of .zip files in
                # $HFS/houdini/help
                "type": "object",
                "classname": "bookish.stores.ZipTree",
                "args": {
                    "dirpath": expandvars("$HFS/houdini/help"),
                }
            },
            # This adds files under the help dir in your user prefs
            expandvars("$HOUDINI_USER_PREF_DIR/help"),
    
            # Add any other directories you want to add to the server here
            # "/my/dir",
        ]
    
        # Store the cache in the user's prefs dir
        CACHE_DIR = expandvars("$HOUDINI_USER_PREF_DIR/config/Help/cache")
    
        # The full-text index shipped with Houdini. If you want to use background
        # indexing, copy this directory somewhere writable, and set this to the path
        # of the writable directory.
        INDEX_DIR = expandvars("$HFS/houdini/config/Help/index")
    
        # True if the server should run an indexing thread in the background
        ENABLE_BACKGROUND_INDEXING = False
        # Number of seconds between background indexing runs
        BACKGROUND_INDEXING_INTERVAL = 60
    
        # Specify a page manager that doesn't use hou
        PAGES_CLASS = "houdinihelp.hpages.HoudiniPagesWithoutHou"
    
    
    application = get_houdini_app(
        use_houdini_path=False,
        config_obj=MyConfig,
        loglevel=logging.INFO,
        debug=False,
    )
    
  3. Install a WSGI application server.

    This step is specific to the server you want to use. We recommend a lightweight server such as uwsgi.

    How to install server software on your system is beyond the scope of this document. See the instructions for your chosen server for how to install it on different platforms. For uwsgi, you can install it using Python’s pip3 package manager (pip3 install uwsgi). This is the best installation method for uwsgi since it installs all necessary plugins as well as the base program.

  4. Set up your HTTP server to serve the static files directly, and use the application.py script to serve dynamic help pages.

    This is highly specific to the app server you use and how you want to configure the server. See the documentation for your application server for details of how it works with a WSGI function, and how you specify static directories.

uwsgi example

The following command runs uwsgi as an HTTP server, sets the listening address/port, specifies the directory to serve static files from (as set up above), and points to the script that creates the application’s WSGI function:

% uwsgi --http 0.0.0.0:9090 --check-static $CENTRAL/files $CENTRAL/application.py

Fastest: serving static help

  • Fastest, most robust solution

  • Can use any HTTP server, don’t need to configure application

  • Doesn’t require any Houdini license.

  • Only serves static pages, not dynamic wiki pages (that is, you can’t edit a wiki help file and reload to see the results immediately in the browser).

  • No search!

Pre-generate all help files

  1. First, set up the directory structure as in setting up central server directories above.

    This should give you a directory structure like this:

    central/
        files/
            icons/
                ...
            images/
                ...
            videos/
                ...
            static/
                ...
    
  2. In Houdini shell, cd to the central directory.

  3. Run the following command:

    hhelp generate files

    This will generate a static HTML file from every wiki file in the Houdin help. This can take a long time.

  4. Once you have generated the HTML files, you can point any HTTP server to serve the files in central/files.

Configuring the help server

  • You can specify a configuration file in the hhelp command line utility using the --config option, or in code using the config_file parameter of houdinihelp.server.get_houdini_app or houdinihelp.server.start_server.

  • If you don’t specify a configuration file and HOUDINIPATH/config/Help/bookish.cfg exists, the server will load it (unless you pass use_houdini_path=False).

  • The help server is based on Flask. Flask’s configuration files are actually Python.

For example, to add a directory of files at $HOME/myfiles, put the following in the configuration file:

EXTRA_DOCUMENTS = ["$HOME/myfiles/"]

See below for some useful configuration keys.

Useful configuration keys

DOCUMENTS = [...]

The default list of document sources includes help directories from the Houdini path, as well as special sources that allow reading help from inside assets and shelf tools. You can replace this with a list of directory paths to serve only your directories. For example:

DOCUMENTS = ["/my/dir"]

It’s possible to extend this list in your configuration file instead of replacing it, but in that case it’s easier to use EXTRA_DOCUMENTS (see below).

EXTRA_DOCUMENTS = []

A list of "extra" document sources to be added on to the defaults in DOCUMENTS. This is useful when you want the defaults but also want to serve from some additional directories

(Note that the default list includes the HOUDINIPATH/help, so you can extend the Houdini path to achieve the same thing.)

EXTRA_DOCUMENTS = ["/my/dir"]

ENABLE_BACKGROUND_INDEXING = False

Whether to run a thread to re-index changed content in the background. Overridden by the --bgindex option on the command line.

BACKGROUND_INDEXING_INTERVAL = 60

The number of seconds between re-indexes when background indexing is on.

EXTRA_SHORTCUTS = []

CACHE_DIR = "$HOUDINI_USER_PREF_DIR/config/Help"

Where the server caches .json files generated from wiki source files.

INDEX_DIR = "$HFS/houdini/config/Help/index"

Directory containing the search index.

How to use the help

Basics

Documenting nodes

Running a central help server