Skip to content

Commit

Permalink
Docs (#11)
Browse files Browse the repository at this point in the history
* Add suport to app factory
* new docs
  • Loading branch information
Otoru authored Jul 5, 2020
1 parent 4934725 commit 0346fa6
Show file tree
Hide file tree
Showing 22 changed files with 668 additions and 207 deletions.
11 changes: 11 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
sphinx:
builder: html
configuration: docs/conf.py
formats:
- pdf
- epub
python:
version: 3.7
install:
- requirements: docs/requirements.txt
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ travis = "*"
flake8 = "*"
black = "*"
pytest = "*"
sphinx = "*"
sphinx-rtd-theme = "*"

[packages]
greenswitch = "*"
Expand Down
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
109 changes: 109 additions & 0 deletions docs/cli.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
**********************
Commnad Line Interface
**********************

Let's imagine a simple project, which is all defined in the file ``vanila.py``.

Let's also imagine that the source code looks like this:

.. code-block:: python
:linenos:
from jaspion.sketch import Sketch
poke = Sketch(__name__)
@poke.handle('HEARTBEAT')
def heartbeat(event):
server = event['FreeSWITCH-Hostname']
now = event['Event-Date-Local']
print('[%s] Recived a "heartbeat" from %s' % (now, server))
In cases similar to this (one or more defined and correlated sketches) you can run the project using the Jaspion CLI.

See the example:

.. code-block:: bash
:linenos:
export JASPION_APP=vanila:poke
jaspion runserver
# Try to connect in esl://127.0.0.1:8021
# Listner: Sketch(name=vanila, events='HEARTBEAT')
# [2019-06-04 08:35:12] Recived a "heartbeat" from PABX
Settings
========

To configure the CLI you must use the following environment variables:

+-------------+-------------------------------+-----------+
| Name | Description | Default |
+-------------+-------------------------------+-----------+
| JASPION_APP | Application to be inspected. | N/A |
+-------------+-------------------------------+-----------+
| FSHOST | Address of freeswitch. | 127.0.0.1 |
+-------------+-------------------------------+-----------+
| FSPORT | Port to connect with ESL. | 8021 |
+-------------+-------------------------------+-----------+
| FSPASSWD | Password to connect with ESL. | ClueCon |
+-------------+-------------------------------+-----------+

Special attention should be given to the variable **JASPION_APP**. It identifies the import path of the project master sketch and must be defined using the following syntax:

- ``<package>:<application>``

If application is not defined, its default value will be `app`, that is:

- ``JASPION_APP=vanila``
- ``JASPION_APP=vanila:app``

Are the same thing.

Application Factory
===================

Taking ``vanila:create_app`` as an example, if ``create_app`` is a function, it will be invoked and if its return fosters a ``Sketch``, it will be used.

more about this concept can be seen `here`_.

Example
-------

.. code-block:: python
:linenos:
from jaspion.sketch import Sketch
def create_app():
poke = Sketch(__name__)
return poke
Commands
========

The following is a list of available commands and their parameters.

runserver
---------

Command used to start an application.

Parameters
^^^^^^^^^^

+----------+------------------------------+----------+-----------+
| Name | Description | Required | Default |
+----------+------------------------------+----------+-----------+
| host | Address of freeswitch | yes | $FSHOST |
+----------+------------------------------+----------+-----------+
| port | Port to connect with ESL | yes | $FSPORT |
+----------+------------------------------+----------+-----------+
| password | Password to connect with ESL | yes | $FSPASSWD |
+----------+------------------------------+----------+-----------+

.. _here: https://flask.palletsprojects.com/en/1.1.x/patterns/appfactories/
17 changes: 17 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
project = 'Jaspion'
copyright = '2020, Vitor Hugo de O. Vargas'
author = 'Vitor Hugo de O. Vargas'

extensions = [
'sphinx_rtd_theme'
]

templates_path = ['templates']

exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

html_theme = 'sphinx_rtd_theme'

html_static_path = ['static']

language = 'en'
35 changes: 35 additions & 0 deletions docs/examples/how_to_use_Sketch.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
*****************
How to use Sketch
*****************

.. code-block:: python
:linenos:
from jaspion import Jaspion
from jaspion.sketch import Sketch
# Freeswitch data to connection
freeswitch = {"host": "127.0.0.1", "password": "ClueCon", "port": 8021}
# Create a Sketch instance
default = Sketch("heartbeat")
# Add a handler to Sketch
@default.handle("HEARTBEAT")
def heartbeat(event):
server = event["FreeSWITCH-Hostname"]
now = event["Event-Date-Local"]
print('[%s] Recived a "heartbeat" from %s' % (now, server))
# Create a Jaspion App
app = Jaspion(**freeswitch)
# Add new Sketch to App
app.update(default)
if __name__ == "__main__":
app.run()
39 changes: 39 additions & 0 deletions docs/examples/how_to_use_a_class_handler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
***********************************
How to use a class to handle events
***********************************

.. code-block:: python
:linenos:
from jaspion.abc import AbstractBaseHandler
from jaspion import Jaspion
# Freeswitch data to connection
freeswitch = {"host": "127.0.0.1", "password": "ClueCon", "port": 8021}
# Create a subclass of *AbstractBaseHandler*
class SimpleHandler(AbstractBaseHandler):
def setup(self):
print("Hello, I am a setup.")
def handle(self):
print("event:")
print(self.event)
def finish(self):
print("Finishing the processing.")
# Create a Jaspion App
app = Jaspion(**freeswitch)
# Add Classhandler to event.
app["HEARTBEAT"] = SimpleHandler
# Run Jaspion App
if __name__ == "__main__":
app.run()
77 changes: 77 additions & 0 deletions docs/examples/monitoring_an_extension.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
***********************
Monitoring an Extension
***********************

.. code-block:: python
:linenos:
from jaspion import Jaspion
from jaspion.utils import filtrate
# Freeswitch data to connection
freeswitch = {"host": "127.0.0.1", "password": "ClueCon", "port": 8021}
# Instance of Jaspion
app = Jaspion(**freeswitch)
# Handler to 'pre_register' event and filter to extension 1000.
@app.handle("sofia::pre_register")
@filtrate("from-user", "1000")
def pre_register(event):
domain = event["from-host"]
username = event["from-user"]
date = event["Event-Date-Local"]
print("[{}] {}@{} - Tried to register.".format(date, username, domain))
# Handler to 'register_attempt' event and filter to extension 1000.
@app.handle("sofia::register")
@filtrate("from-user", "1000")
def register(event):
domain = event["from-host"]
username = event["from-user"]
date = event["Event-Date-Local"]
print("[{}] {}@{} - Register.".format(date, username, domain))
# Handler to 'register_attempt' event and filter to extension 1000.
@app.handle("sofia::register_attempt")
@filtrate("from-user", "1000")
def register_attempt(event):
domain = event["from-host"]
username = event["from-user"]
date = event["Event-Date-Local"]
print("[{}] {}@{} - Operation terminated.".format(date, username, domain))
# Handler to 'register_failure' event and filter to extension 1000.
@app.handle("sofia::register_failure")
@filtrate("from-user", "1000")
def register_failure(event):
domain = event["from-host"]
username = event["from-user"]
date = event["Event-Date-Local"]
print("[{}] {}@{} - Failed to register.".format(date, username, domain))
# Handler to 'unregister' and 'expire' event and filter to extension 1000.
@app.handle("sofia::unregister")
@app.handle("sofia::expire")
@filtrate("from-user", "1000")
def unregister(event):
domain = event["from-host"]
username = event["from-user"]
date = event["Event-Date-Local"]
print("[{}] {}@{} - Unregistred.".format(date, username, domain))
if __name__ == "__main__":
# Start Jaspion
app.run()
41 changes: 41 additions & 0 deletions docs/examples/record_registers_in_redis.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
*************************
Record registers on Redis
*************************

.. code-block:: python
:linenos:
from redis import Redis
from jaspion import Jaspion
# Freeswitch data to connection
freeswitch = {"host": "127.0.0.1", "password": "ClueCon", "port": 8021}
# Redis data to connection
redis = {"host": "127.0.0.1", "port": 6379}
# Instance of Jaspion and Redis conn
app = Jaspion(**freeswitch)
conn = Redis(**redis)
# Save all register in redis with expires of sip message.
@app.handle("sofia::register")
def register(event):
key = "registers:%s" % event["call-id"]
ttl = int(event["expires"])
conn.hmset(key, event)
conn.expire(key, ttl)
# Exclude redis register if unregister is recived
@app.handle("sofia::unregister")
def unregister(event):
key = "registers:%s" % event["call-id"]
conn.delete(key)
if __name__ == "__main__":
# Start Jaspion
app.run()
Loading

0 comments on commit 0346fa6

Please sign in to comment.