Skip to content

Commit

Permalink
Merge pull request #1 from AGTGreg/release-0.1.7
Browse files Browse the repository at this point in the history
Release 0.1.7
  • Loading branch information
AGTGreg committed Jul 22, 2019
2 parents a88c4a5 + 4a67264 commit 25cb79f
Show file tree
Hide file tree
Showing 24 changed files with 1,127 additions and 170 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ venv.bak/

# mypy
.mypy_cache/

# VS Code
.vscode/
7 changes: 0 additions & 7 deletions .vscode/settings.json

This file was deleted.

22 changes: 0 additions & 22 deletions README.md

This file was deleted.

94 changes: 94 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
Runium
======

Runium is a Python library that makes it easy to write non-blocking,
asynchronous tasks.

You can add new tasks as you please, choose when and how to execute them as
**Threads** or **Processes** and attach callbacks to be executed as soon as the
task is finished running. Run those tasks once or periodically or schedule to
run them at a specific time.

The purpose of Runium is to do these simple, easy and clean with minimum to
no changes to your code. Just one line of code is all it takes.

So if you want to run a long-running method without blocking your code, instead
of doing this:

.. code-block:: python
send_email()
...you can use Runium and run it asynchronously like this:

.. code-block:: python
runium.run(send_email)
And now this method will run in the background without blocking your entire
app. It's that simple!

Features
========
* **Concurrency**: Run a task once or many times in its own Thread or Process.
* **Repetition**: Run tasks periodically on even time intervals. Optionally for a certain amount of times.
* **Scheduling**: Run tasks at a certain date and time.
* **Callbacks**: Runium tasks can accept callback functions which are executed when the task is finished running.
* **Simplicity and Readability**: Do all the above in a single line of code that is easy to read.


Installation
============

Runium is distributed on PyPI. The best way to install it is with pip:

.. code-block:: console
$ pip install runium
Quickstart
==========

.. code-block:: python
from runium.core import Runium
# Initialize Runium
rn = Runium()
# Or you may want to run your tasks in Processes
rn = Runium(mode='multiprocessing')
# Create a task
async_task = rn.new_task(task)
# Attach callbacks (Check the documentation for callbacks)
async_task.on_finished(callback)
# or you can be more flexible...
async_task.on_success(s_callback).on_error(e_callback)
# Run it. This will return a future object.
future = async_task.run()
# Or if you want to run it multiple times
future = async_task.run(times=3)
# Or maybe run it 3 times every 1 hour
future = async_task.run(every='1 hour', times=3)
# Or tell Runium to start the task in a specific time
future = async_task.run(start_in='5 hours')
# Then you can wait for the result.
future.result()
# Of course you can do all these in one line :)
rn.new_task(task).run(every='1 second', times=3).result()
Links
=====

**Github:** `https://github.com/AGTGreg/runium <https://github.com/AGTGreg/runium>`_

**Pypi:** `https://pypi.org/project/runium/ <https://pypi.org/project/runium/>`_
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 = source
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)
35 changes: 35 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

if "%1" == "" goto help

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
182 changes: 182 additions & 0 deletions docs/source/callbacks.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
Callbacks
=========

A callback is a function that is attached to a ``runium.core.Task`` object and
gets executed as soon as the task finishes.

Callbacks are executed in the same Thread/Process as the Task that calls them.
As a result they are non-blocking.


***********
on_finished
***********
``Task.on_finished(fn, updates_result=False)``

Accepts a callable with the task's success and error results as its only
arguments.

If the task was successfull (no exceptions were raised) then the success
argument will contain the task's return and the error argument will be
``None``.

If the task is unsuccessfull (an exception was raised) then the error argument
will contain the exception object and success will be ``None``.

Runs the callback after the task has been executed successfully or after an
exception was raised.

**Parameters**
- **fn** -- The callable to be executed with success and error as its only arguments.
- **updates_result** -- If this is True then the task's result will be replaced with whatever is returned by the callable.

**Example:**

.. code-block:: python
def send_email():
print("Sending email...")
return "Email sent."
# The callback must have the success and error arguments.
def callback(success, error):
if success:
return True
elif error:
return "An error occurred."
# Attach the callback like this
async_task = runium.new_task(send_email).on_finished(callback).run()
# You may also choose to get the result of the callback instead of the task
# by setting the parameter updates_result to True.
async_task = runium.new_task(send_email).on_finished(
callback, updates_result=True).run()
# This will return True
async_task.result()
**********
on_success
**********
``Task.on_success(fn, updates_result=False)``

Accepts a callable with the task's result as its only argument.
Runs the callback after the task has been executed successfully and no
exceptions were raised.

**Parameters**
- **fn** -- The callable to be executed with success as its only argument.
- **updates_result** -- If this is True then the task's result will be replaced with whatever is returned by the callable.

**Example:**

.. code-block:: python
def send_email():
print("Sending email...")
return "Email sent."
# The callback must have the success argument.
def callback(success):
return ("Success!")
# Attach the callback like this
async_task = runium.new_task(send_email).on_success(callback).run()
# This callback is often used together with on_error callback:
async_task = runium.new_task(
send_email
).on_success(
callback
).on_error(
error_callback
).run()
********
on_error
********
``Task.on_error(fn, updates_result=False)``

Accepts a callable with the task’s exception object as its only argument. Runs
the callback after an exception was raised by the task.

**Parameters**
- **fn** -- The callable to be executed with error as its only argument.
- **updates_result** -- If this is True then the task’s result will be replaced with whatever is returned by the callable.

**Example:**

.. code-block:: python
def send_email():
raise Exception("Email was not sent.)
# The callback must have the error argument.
def callback(error):
resend_email()
# Attach the callback like this
async_task = runium.new_task(send_email).on_error(callback).run()
# This callback is often used together with on_success callback:
async_task = runium.new_task(
send_email
).on_success(
callback
).on_error(
error_callback
).run()
*******
on_iter
*******
``Task.on_iter(fn, updates_result=False)``
Accepts a callable with the task's success and error results as its only
arguments.
If the task was successfull (no exceptions were raised) then the
success argument will contain the task's return and the error
argument will be ``None``.
If the task is unsuccessfull (an exception was raised) then the error
argument will contain the exception object and success will be ``None``.
Runs the callback after the task has been executed successfully or after an
exception was raised.
The difference between this type of callback and all the others is that
the other callbacks will run only once after the task has been executed
no matter how many times we've set it to run. But an on_iter callback
will run on every iteration if the task is to be executed many times.
**Parameters**
- **fn** -- The callable to be executed with success and error as its only arguments: fn(success, error)
- **updates_result** -- If this is True then the task's result will be replaced with whatever is returned by the callable.
**Example:**
.. code-block:: python
# The callback must have the success and error arguments.
def callback(success, error):
if success:
print(success)
return True
elif error:
print(error)
return "An error occurred."
# The callback will be executed 3 times.
async_task = runium.new_task(send_email).on_iter(callback).run(times=3)

0 comments on commit 25cb79f

Please sign in to comment.