Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 96 additions & 23 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
Zeroless
========

.. _badges_start:

|Build Status| |Coverage Status| |Codacy| |PyPi| |Docs| |License|

.. _badges_end:

Yet another ØMQ_ wrapper for Python. However, differing from PyZMQ_, which
tries to stay very close to the C++ implementation, this project aims to
make distributed systems employing ØMQ_ as pythonic as possible.
Expand All @@ -17,63 +21,87 @@ GIL and IPC is unix-only.
Installation
------------

.. _install_content_start:

.. code-block:: bash

$ pip install zeroless

.. _install_content_end:

Python API
----------

In the ``zeroless`` module, two functions can be used to define how
zeroless' sockets are related (i.e. ``bind`` and ``connect``). Both are
able to create a *callable* and/or *iterable* socket, depending on the
message passing pattern.
.. _python_api_content_start:

So that you can iterate over incoming messages and/or call to transmit a
message.
In the ``zeroless`` module, two classes can be used to define how distributed
entities are related (i.e. ``Server`` and ``Client``). To put it bluntly, with
the exception of the pair pattern, a client may be connected to multiple
servers, while a server may accept incoming connections from multiple clients.

Both servers and clients are able to create a *callable* and/or *iterable*,
depending on the message passing pattern. So that you can iterate over incoming
messages and/or call to transmit a message.

.. _python_api_content_end:

All examples assume:

.. code:: python

from zeroless import (connect, bind)
from zeroless import (Server, Client)

Push-Pull
~~~~~~~~~

.. _push_pull_content_start:

Useful for distributing the workload among a set of workers. A common
pattern in the Stream Processing field, being the cornestone of
applications like Apache Storm for instance. Also, it can be seen as a
generalisation of the Map-Reduce pattern.

.. _push_pull_content_end:

.. code:: python

# The pull server binds to port 12345 and waits for incoming messages.
listen_for_push = bind(port=12345).pull()
# Binds the pull server to port 12345
# And assigns an iterable to wait for incoming messages
listen_for_push = Server(port=12345).pull()

for msg in listen_for_push:
print(msg)

.. code:: python

# The push client connects to localhost and sends three messages.
push = connect(port=12345).push()
# Connects the client to as many servers as desired
client = Client()
client.connect_local(port=12345)

# Initiate a push client
# And assigns a callable to push messages
push = client.push()

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
push(msg)

Publisher-Subscriber
~~~~~~~~~~~~~~~~~~~~

.. _pub_sub_content_start:

Useful for broadcasting messages to a set of peers. A common pattern for
allowing real-time notifications at the client side, without having to
resort to inneficient approaches like pooling. Online services like
PubNub or IoT protocols like MQTT are examples of this pattern usage.

.. _pub_sub_content_end:

.. code:: python

# The publisher server connects to localhost and sends three messages.
pub = bind(port=12345).pub(topic=b'sh')
# Binds the publisher server to port 12345
# And assigns a callable to publish messages with the topic 'sh'
pub = Server(port=12345).pub(topic=b'sh')

# Gives publisher some time to get initial subscriptions
sleep(1)
Expand All @@ -83,39 +111,60 @@ PubNub or IoT protocols like MQTT are examples of this pattern usage.

.. code:: python

# The subscriber client binds to port 12345 and waits for incoming messages.
listen_for_pub = connect(port=12345).sub(topics=[b'sh'])
# Connects the client to as many servers as desired
client = Client()
client.connect_local(port=12345)

# Initiate a subscriber client
# Assigns an iterable to wait for incoming messages with the topic 'sh'
listen_for_pub = client.sub(topics=[b'sh'])

for topic, msg in listen_for_pub:
print(topic, ' - ', msg)

.. _pub_sub_appendix_start:

Note: ZMQ's topic filtering capabilities are publisher side since ZMQ 3.0.

Last but not least, SUB sockets that bind will not get any message before they
first ask for via the provided generator, so prefer to bind PUB sockets if
missing some messages is not an option.

.. _pub_sub_appendix_end:

Request-Reply
~~~~~~~~~~~~~

.. _req_rep_content_start:

Useful for RPC style calls. A common pattern for clients to request data
and receive a response associated with the request. The HTTP protocol is
well-known for adopting this pattern, being it essential for Restful
services.

.. _req_rep_content_end:

.. code:: python

# The reply server binds to port 12345 and waits for incoming messages.
reply, listen_for_request = bind(port=12345).reply()
# Binds the reply server to port 12345
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
reply, listen_for_request = Server(port=12345).reply()

for msg in listen_for_request:
print(msg)
reply(msg)

.. code:: python

# The request client connects to localhost and sends three messages.
request, listen_for_reply = connect(port=12345).request()
# Connects the client to as many servers as desired
client = Client()
client.connect_local(port=12345)

# Initiate a request client
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
request, listen_for_reply = client.request()

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
request(msg)
Expand All @@ -125,25 +174,37 @@ services.
Pair
~~~~

.. _pair_content_start:

More often than not, this pattern will be unnecessary, as the above ones
or the mix of them suffices most use cases in distributed computing.
Regarding its capabilities, this pattern is the most similar alternative
to usual posix sockets among the aforementioned patterns. Therefore,
expect one-to-one and bidirectional communication.

.. _pair_content_end:

.. code:: python

# The pair server binds to port 12345 and waits for incoming messages.
pair, listen_for_pair = bind(port=12345).pair()
# Binds the pair server to port 12345
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
pair, listen_for_pair = Server(port=12345).pair()

for msg in listen_for_pair:
print(msg)
pair(msg)

.. code:: python

# The pair client connects to localhost and sends three messages.
pair, listen_for_pair = connect(port=12345).pair()
# Connects the client to a single server
client = Client()
client.connect_local(port=12345)

# Initiate a pair client
# And assigns a callable and an iterable
# To both transmit and wait for incoming messages
pair, listen_for_pair = client.pair()

for msg in [b"Msg1", b"Msg2", b"Msg3"]:
pair(msg)
Expand All @@ -153,6 +214,8 @@ expect one-to-one and bidirectional communication.
Logging
-------

.. _logging_content_start:

The ``zeroless`` module allows logging via a global `Logger object <https://docs.python.org/3/library/logging.html#logger-objects>`__.

.. code:: python
Expand All @@ -161,9 +224,13 @@ The ``zeroless`` module allows logging via a global `Logger object <https://docs

To enable it, just add an `Handler object <https://docs.python.org/3/library/logging.html#handler-objects>`__ and set an appropriate `logging level <https://docs.python.org/3/library/logging.html#logging-levels>`__.

.. _logging_content_end:

Testing
-------

.. _testing_content_start:

To run individual tests:

.. code-block:: bash
Expand All @@ -182,6 +249,8 @@ Alternatively, you can use tox:

$ tox

.. _testing_content_end:

Need help?
----------

Expand All @@ -190,6 +259,8 @@ For more information, please see our documentation_.
License
-------

.. _license_content_start:

Copyright 2014 Lucas Lira Gomes x8lucas8x@gmail.com

This library is free software; you can redistribute it and/or modify it
Expand All @@ -205,6 +276,8 @@ General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library. If not, see http://www.gnu.org/licenses/.

.. _license_content_end:

.. |Build Status| image:: https://img.shields.io/travis/zmqless/zeroless.svg?style=flat
:target: https://travis-ci.org/zmqless/zeroless
.. |Coverage Status| image:: https://img.shields.io/coveralls/zmqless/zeroless.svg?style=flat
Expand Down
26 changes: 19 additions & 7 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,36 @@ Contributing
We welcome contributions of any kind (ideas, code, tests, documentation,
examples, ...).

Getting started with contributing to Zeroless
---------------------------------------------

General contribution guidelines
-------------------------------
General Contribution Guidelines
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Any non-trivial change must contain tests.
* All the functions and methods must contain Sphinx docstrings which are
used to generate the API documentation.
* If you are adding a new feature, make sure to add a corresponding
documentation.

Code style guide
----------------
Code Style Guide
~~~~~~~~~~~~~~~~

* We follow `PEP8 Python Style Guide`_.
* Use 4 spaces for a tab.
* Use 79 characters in a line.
* Make sure edited file doesn't contain any trailing whitespace.

.. _`PEP8 Python Style Guide`: http://www.python.org/dev/peps/pep-0008/

Testing
-------

Tests make use of the ``py.test`` framework and are located in the tests/
folder. However, we recommend the usage of ``tox`` as it will test our
codebase against both Python 2.7 and 3.0.

.. include:: ../README.rst
:start-after: _testing_content_start:
:end-before: _testing_content_end:

All functionality (including new features and bug fixes) must include a
test case to check that it works as expected, so please include tests
for your patches if you want them to get accepted sooner.
32 changes: 29 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Zeroless
========

.. include:: ../README.rst
:start-after: _badges_start:
:end-before: _badges_end:

This documentation contains notes on some important aspects of developing Zeroless
and an overview of Zeroless' API. For information on how to use ØMQ_ in general,
see the many examples in the excellent ØMQGuide_. It can give a better understanding
Expand Down Expand Up @@ -32,9 +36,9 @@ Installing

Install stable releases of Zeroless with ``pip``.

.. code-block:: bash

$ pip install zeroless
.. include:: ../README.rst
:start-after: _install_content_start:
:end-before: _install_content_end:

See the :doc:`install` for more detail.

Expand Down Expand Up @@ -82,9 +86,31 @@ Links
* Zeroless on PyPy_
* Issue Tracker_

License
=======

.. include:: ../README.rst
:start-after: _license_content_start:
:end-before: _license_content_end:

.. |Build Status| image:: https://img.shields.io/travis/zmqless/zeroless.svg?style=flat
:target: https://travis-ci.org/zmqless/zeroless
.. |Coverage Status| image:: https://img.shields.io/coveralls/zmqless/zeroless.svg?style=flat
:target: https://coveralls.io/r/zmqless/zeroless?branch=master
.. |Docs| image:: https://readthedocs.org/projects/zeroless/badge/?version=latest
:target: https://readthedocs.org/projects/zeroless/?badge=latest
.. |License| image:: https://img.shields.io/pypi/l/zeroless.svg?style=flat
:target: https://www.gnu.org/licenses/lgpl-2.1.html
.. |Codacy| image:: https://img.shields.io/codacy/116ada408f3c45709197e0e5d2fe46ba.svg?style=flat
:target: https://www.codacy.com/p/4364
.. |PyPi| image:: https://img.shields.io/pypi/v/zeroless.svg?style=flat
:target: https://pypi.python.org/pypi/zeroless

.. _ØMQ: http://www.zeromq.org
.. _ØMQGuide: http://zguide.zeromq.org
.. _PyZMQ: https://www.github.com/zeromq/pyzmq
.. _GitHub: https://github.com/zmqless/zeroless
.. _Tracker: https://github.com/zmqless/zeroless/issues
.. _PyPy: https://pypi.python.org/pypi/zeroless


6 changes: 3 additions & 3 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Install Guide

Install stable releases of Zeroless with ``pip``.

.. code-block:: bash

$ pip install zeroless
.. include:: ../README.rst
:start-after: _install_content_start:
:end-before: _install_content_end:

.. _install_dependencies:

Expand Down
Loading