<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;

]>

<!-- Module User's Guide -->

<chapter>

    <title>&adminguide;</title>

    <section>
	<title>Overview</title>
	<para>
		This module is a port of the 'app_python' module to Python 3.
		It is based on the work of Maxim Sobolev.
	</para>
	<para>
		<emphasis>This module cannot be loaded together with 'app_python'</emphasis> as global symbols
		have not been renamed. To ease transition, the functions, KEMI exports, and
		RPC commands have the same names as 'app_python', which also means the two modules cannot coexist.
	</para>
	<para>
		This module allows executing Python scripts from the config file,
		exporting functions to access the SIP message from Python.
	</para>
	<para>
		For some basic examples of Python scripts that can be used with
		this module, look at the files inside the source tree located at
		'modules/app_python3/python_examples/'.
	</para>
	<para>
		Note: if symbols exported to KEMI (module or function names) conflict
		with Python's reserved keywords, use the 'getattr()' function or the
		'__dict__' attribute for 'KSR' (e.g., 'KSR.__dict__["async"].task_route("myroute")').
	</para>
    </section>
    <section>
	<title>Dependencies</title>
	<section>
	    <title>&kamailio; Modules</title>
	    <para>
		The following modules must be loaded before this module:
	    	<itemizedlist>
		    <listitem>
			<para>
			    <emphasis>none</emphasis>.
			</para>
		    </listitem>
	    	</itemizedlist>
	    </para>
	</section>
	<section>
	    <title>External Libraries or Applications</title>
	    <para>
		The following libraries or applications must be installed before running
		&kamailio; with this module loaded:
	    	<itemizedlist>
		    <listitem>
			<para>
			    <emphasis>python3</emphasis> - Python 3 runtime.
			</para>
		    </listitem>
	    	</itemizedlist>
	    </para>
	    <para>
		To compile this module the Python 3 development package is needed.
		Requirements:
	    	<itemizedlist>
		    <listitem>
			<para>
			    <emphasis>python3-dev</emphasis> - Python 3 development package.
			</para>
		    </listitem>
		    <listitem>
			<para>
			    <emphasis>python3-config</emphasis> - (part of python3-dev)
				tool to output C includes and library paths.
			</para>
		    </listitem>
	    	</itemizedlist>
	    </para>
	</section>
    </section>
    <section>
	<title>Parameters</title>
	<section id="app_python3.p.load">
	    <title><varname>load</varname> (string)</title>
	    <para>
			The path to the file with Python code to be executed
			from configuration file.
	    </para>
	    <para>
		<emphasis>
		    Default value is <quote>/usr/local/etc/kamailio/handler.py</quote>.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>load</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("app_python3", "load", "/usr/local/etc/kamailio/myscript.py")
...
</programlisting>
	    </example>
	</section>

	<section id="app_python3.p.script_name">
	    <title><varname>script_name</varname> (string)</title>
	    <para>
			This is same as "load" parameter, kept for backward compatibility
			with the older versions of the module.
	    </para>
	</section>

	<section id="app_python3.p.mod_init_function">
	    <title><varname>mod_init_function</varname> (string)</title>
	    <para>
			The Python function to be executed by this module when
			it is initialized by &kamailio;.
	    </para>
	    <para>
		<emphasis>
		    Default value is <quote>mod_init</quote>.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>mod_init_function</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("app_python3", "mod_init_function", "my_mod_init")
...
</programlisting>
	    </example>
	</section>

	<section id="app_python3.p.child_init_method">
	    <title><varname>child_init_method</varname> (string)</title>
	    <para>
			The Python function to be executed by this module when
			a new worker process (child) is initialized by &kamailio;.
	    </para>
	    <para>
		<emphasis>
		    Default value is <quote>child_init</quote>.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>child_init_method</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("app_python3", "child_init_method", "my_child_init")
...
</programlisting>
	    </example>
	</section>

	<section id="app_python3.p.threads_mode">
	    <title><varname>threads_mode</varname> (int)</title>
	    <para>
			Control how locking for Python interpreter threads in done. If set
			to 1, use Py_BLOCK_THREADS/Py_UNBLOCK_THREADS (new mode added for
			v6.0.x). If set to 0, use PyGILState_Ensure()/PyGILState_Release()
			(the mode implemented initially).
	    </para>
	    <para>
		If set to 1, Python threading Thread objects created in the KEMI script will be scheduled. Otherwise,
                additional Python threads will not be scheduled (no release of GIL).
	    </para>
	    <para>
		<emphasis>
			Default value is <quote>0</quote>.
		</emphasis>
	    </para>
	    <example>
		<title>Set <varname>threads_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("app_python3", "threads_mode", 1)
...
</programlisting>
	    </example>
	</section>

	</section>

    <section>
	<title>Functions</title>
 	<section id="app_python3.f.python_exec">
	    <title>
		<function moreinfo="none">python_exec(method [, args])</function>
	    </title>
	    <para>
			Execute the Python function with the name given by the parameter 'method'.
			Optionally can be provided a second string with parameters to be passed
			to the Python function.
	    </para>
	    <para>
			Both parameters can contain pseudo-variables.
	    </para>
		<example>
		<title><function>python_exec</function> usage</title>
		<programlisting format="linespecific">
...
python_exec("my_python_function");
python_exec("my_python_function", "my_params");
python_exec("my_python_function", "$rU");
...
</programlisting>
	    </example>
	</section>

    </section>
	<section>
        <title>RPC Commands</title>
        <section id="app_python3.r.reload">
            <title>
            <function moreinfo="none">app_python.reload</function>
            </title>
			<para>
				IMPORTANT: this is not thread-safe. In your Python script
				do not use C extensions with threads that call into
				<varname>apy_exec()</varname>.
			</para>
            <para>
            Marks the need to reload the Python script.
            The actual reload is done in each worker when it next invokes a Python method.
            The module uses a worker process lock to prevent recursive reloads.
            </para>
            <para>
			This function only reloads (re-executes) the user script and creates
			a new script object. It does not reinitialize the interpreter (references
			in the old module remain if not redefined by the new version).
            </para>
            <para>
            Name: <emphasis>app_python.reload</emphasis>
            </para>
            <para>Parameters: <emphasis>none</emphasis></para>
            <para>
            Example:
            </para>
            <programlisting  format="linespecific">
...
&kamcmd; app_python.reload
...
            </programlisting>
			<para>
			Note that reload is done for the Python script provided as parameter
			to this &kamailio; module. To reload the Python libraries imported
			in this script, use something like:
            </para>
            <programlisting  format="linespecific">
...
import mod1
...
import modN
from importlib import reload

def mod_init():
    reload(mod1)
    ...
    reload(modN)
    return kamailio()
...
            </programlisting>
			<para>
				Where "modX" are the modules imported at the top.
            </para>
		</section>
		<section id="app_python3.r.api_list">
            <title>
            <function moreinfo="none">app_python.api_list</function>
            </title>
            <para>
			List the functions available via Kemi framework.
            </para>
            <para>
            Name: <emphasis>app_python.api_list</emphasis>
            </para>
            <para>Parameters: <emphasis>none</emphasis></para>
            <para>
            Example:
            </para>
            <programlisting  format="linespecific">
...
&kamcmd; app_python.api_list
...
            </programlisting>
        </section>
	</section>

	<section id="app_python3.kemi_usage">
        <title>KEMI Usage</title>
            <para>
			The module exports KEMI engine with id "python".
			</para>
            <para>
            Example:
            </para>
            <programlisting  format="linespecific">
...
loadmodule "app_python3.so"
...
cfgengine "python"
...
            </programlisting>
            <para>
			For more details about KEMI, see:
			<ulink url="https://www.kamailio.org/docs/tutorials/devel/kamailio-kemi-framework/">https://www.kamailio.org/docs/tutorials/devel/kamailio-kemi-framework/</ulink>
            </para>
	</section>

</chapter>
