.. _interfaces: Interfaces -------------- Horetu makes interfaces to Python functions. Let us consider the following Python program, in a file called ``do_something.py``. :: #!/usr/bin/env python3 import horetu def something(input_file, output_file, n_cores: int = 3): ''' Do something to a file with several cores. ''' # Pretend that something happens here. To make it into a horetu interface, call the appropriate interface constructor. Command-line interface ^^^^^^^^^^^^^^^^^^^^^^^^^ Create a command-line interface with the following additional line. :: horetu.cli(something) Then run this. :: chmod +x do_something.py ./do_something.py -help The help text will tell you how your new interface works. .. autofunction:: horetu.cli Web interfaces ^^^^^^^^^^^^^^^^^^^^^^^^^ horetu has two styles of web interface, a more basic style (py:func:`horetu.wsgi_plain`), and a style that produces forms. (py:func:`horetu.wsgi_form`). Add the this additional line to ``do_something.py`` to configure the former interface, :: application = horetu.wsgi_plain(something) or add this next line to configure the form interface. :: application = horetu.wsgi_form(something) Either way, you wind up with a Web Server Gateway Interface (WSGI) application that you can run it with a WSGI server. If you run this, :: uwsgi --wsgi-file print-server.wsgi --plugin python3 --http-socket :9090 then you can open http://127.0.0.1:9090/?help to see how your web interface works. You could also run the application in Apache mod_wsgi; add something like this to your apache configuration. :: WSGIScriptAlias / /srv/do_something.py process-group=something WSGIDaemonProcess something python-path=srv/do_something.py WSGIProcessGroup something ServerName 0.0.0.0 ServerAdmin _@thomaslevine.com Require all granted .. autofunction:: horetu.wsgi_plain .. autofunction:: horetu.wsgi_form Django management command interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Suppose you have a Django application called in the directory "chainsaw". Here is how you could configure the above function to be a management command called "replace-chain". :: mkdir -p chainsaw/management/commands cp do_something.py chainsaw/management/commands/replace-chain.py echo 'Command = horetu.django(something)' >> chainsaw/management/commands/replace-chain.py Once you do that, you can run the command from a Django project that has the chainsaw application installed. :: ./manage.py chainsaw replace-chain .. autofunction:: horetu.django IRC interface ^^^^^^^^^^^^^ The IRC interface is like the command-line interface but over IRC. :: horetu.irc(something, server='irc.freenode.net', channel='##horetu', nick='something') Then you can send messages to user "something" in the ``##horetu`` channel, and that user will respond as if you were typing in a shell and running the same function but with :py:func:``horetu.cli``. This calls :py:func:``horetu.cli`` internally. You may want to configure the server from the command line; you can do that like so. :: horetu.irc(something, server='irc.freenode.net', channel='##horetu', nick='something') cli=True) This starts a command-line interface (:py:func:``horetu.cli``) that accepts arguments for "server", "channel", &c., falling back to the defaults that you provided when an argument is not provided. This interface then runs :py:func:``horetu.irc`` (which internally runs :py:func:``horetu.cli`` again, as I mentioned above). .. autofunction:: horetu.irc Configuration files ^^^^^^^^^^^^^^^^^^^^ The function that you pass to the horetu interface is implicitly converted to a :py:class:`horetu.Program` object. If you set this explicitly, you can also set configuration files. :: application = horetu.wsgi_plain(horetu.Program(something, '~/.something.conf`)) For unspecified arguments, the program falls back, first, to the options set in configuration files, and, second, to any defaults that are set in the Python function. .. autofunction:: horetu.Program .. autofunction:: horetu.Configuration Configuration file interfaces ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can produce a configuration file with the default options implied by the function's keyword arguments. This could be useful in a command that does the initial configuration for your program. :: horetu.config_default(horetu.Program(something, '/etc/something.conf', '~/.something.conf')) You can also do the opposite: Run a program with only the options specified in a configuration file. :: horetu.config_run(horetu.Program(something, '~/.something.conf')) .. autofunction:: horetu.config_default .. autofunction:: horetu.config_run