├── .coveragerc
├── .gitattributes
├── .gitignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── docs
├── Makefile
├── _static
│ └── css
│ │ ├── colors.css
│ │ └── types.css
├── code
│ ├── demo.py
│ ├── demo_basic.py
│ ├── demos
│ │ ├── advanced.py
│ │ ├── basic.py
│ │ ├── intermediate.py
│ │ ├── minimal.py
│ │ └── monitor.py
│ ├── execution.py
│ ├── parameter
│ │ ├── parameters.py
│ │ └── pipelining.py
│ ├── schedule
│ │ ├── fixed_period.py
│ │ ├── fixed_period_with_args.py
│ │ ├── logic.py
│ │ └── time_of.py
│ └── snippets
│ │ ├── parallelization.py
│ │ ├── parametrize.py
│ │ ├── pipeline.py
│ │ └── scheduling.py
├── condition_syntax
│ ├── dependence.rst
│ ├── execution.rst
│ ├── fixed_interval.rst
│ ├── index.rst
│ ├── task_status.rst
│ └── timedelta.rst
├── conf.py
├── contributing.rst
├── examples
│ └── index.rst
├── favicon.ico
├── how_it_works.rst
├── index.rst
├── logo.svg
├── make.bat
├── s5defs.txt
├── scheduling.png
├── task_execution.png
├── tutorial
│ ├── advanced.rst
│ ├── basic.rst
│ ├── index.rst
│ ├── intermediate.rst
│ └── quick_start.rst
└── versions.rst
├── redengine
├── __init__.py
├── _base.py
├── _setup.py
├── _version.py
├── application.py
├── args
│ ├── __init__.py
│ ├── builtin.py
│ └── secret.py
├── conditions
│ ├── __init__.py
│ ├── func.py
│ ├── meta.py
│ ├── parameter.py
│ ├── scheduler.py
│ ├── task
│ │ ├── __init__.py
│ │ ├── task.py
│ │ └── utils.py
│ └── time.py
├── core
│ ├── __init__.py
│ ├── condition
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── statement.py
│ │ └── utils.py
│ ├── hook.py
│ ├── log
│ │ ├── __init__.py
│ │ └── adapter.py
│ ├── meta.py
│ ├── parameters
│ │ ├── __init__.py
│ │ ├── arguments.py
│ │ └── parameters.py
│ ├── schedule.py
│ ├── task.py
│ ├── time
│ │ ├── __init__.py
│ │ ├── anchor.py
│ │ ├── base.py
│ │ └── utils.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── meta.py
│ │ ├── pickle.py
│ │ └── process.py
├── exc.py
├── log
│ ├── __init__.py
│ ├── defaults.py
│ ├── handlers.py
│ └── log_record.py
├── parameters
│ ├── __init__.py
│ └── func.py
├── parse
│ ├── __init__.py
│ ├── _condition
│ │ ├── __init__.py
│ │ ├── condition_item.py
│ │ └── string.py
│ ├── _time
│ │ ├── __init__.py
│ │ ├── string.py
│ │ └── time_item.py
│ ├── condition.py
│ ├── time.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── cond.py
│ │ ├── exception.py
│ │ ├── parser.py
│ │ ├── string_parser.py
│ │ └── utils.py
├── pybox
│ ├── __init__.py
│ ├── container
│ │ ├── __init__.py
│ │ └── visitor.py
│ ├── pkg
│ │ ├── __init__.py
│ │ └── path.py
│ ├── query
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── parse.py
│ │ └── string.py
│ └── string
│ │ ├── __init__.py
│ │ └── parse
│ │ ├── __init__.py
│ │ └── closure.py
├── session.py
├── tasks
│ ├── __init__.py
│ ├── code.py
│ ├── command.py
│ ├── func.py
│ └── maintain
│ │ ├── __init__.py
│ │ └── os.py
├── test
│ ├── __init__.py
│ ├── app
│ │ ├── __init__.py
│ │ └── test_app.py
│ ├── condition
│ │ ├── __init__.py
│ │ ├── task
│ │ │ ├── __init__.py
│ │ │ ├── test_basic.py
│ │ │ ├── test_compare.py
│ │ │ ├── test_set_default.py
│ │ │ ├── test_time.py
│ │ │ ├── test_time_executable.py
│ │ │ └── test_time_optimized.py
│ │ ├── test_alchemy.py
│ │ ├── test_core.py
│ │ ├── test_create.py
│ │ ├── test_env.py
│ │ ├── test_equal.py
│ │ ├── test_meta.py
│ │ ├── test_parse.py
│ │ ├── test_parse_clause.py
│ │ └── test_scheduler.py
│ ├── conftest.py
│ ├── helpers
│ │ ├── __init__.py
│ │ ├── io_helpers.py
│ │ ├── log_helpers.py
│ │ └── task_helpers.py
│ ├── parameters
│ │ ├── __init__.py
│ │ ├── test_construct.py
│ │ └── test_params.py
│ ├── pybox
│ │ ├── __init__.py
│ │ └── query
│ │ │ ├── __init__.py
│ │ │ ├── test_core.py
│ │ │ ├── test_from.py
│ │ │ ├── test_query.py
│ │ │ └── test_to.py
│ ├── pytest.ini
│ ├── schedule
│ │ ├── __init__.py
│ │ ├── process
│ │ │ ├── __init__.py
│ │ │ └── test_core.py
│ │ ├── test_core.py
│ │ ├── test_failure.py
│ │ ├── test_from_scripts.py
│ │ ├── test_methods.py
│ │ ├── test_params.py
│ │ ├── test_piping.py
│ │ ├── test_scheduler_conditions.py
│ │ ├── test_terminate.py
│ │ └── test_traceback.py
│ ├── session
│ │ ├── __init__.py
│ │ ├── params
│ │ │ ├── __init__.py
│ │ │ ├── test_func.py
│ │ │ ├── test_params.py
│ │ │ └── test_return.py
│ │ ├── test_construct.py
│ │ ├── test_control.py
│ │ ├── test_core.py
│ │ ├── test_logs.py
│ │ ├── test_run.py
│ │ └── test_utils.py
│ ├── task
│ │ ├── __init__.py
│ │ ├── code
│ │ │ ├── __init__.py
│ │ │ └── test_construct.py
│ │ ├── command
│ │ │ ├── test_construct.py
│ │ │ └── test_run.py
│ │ ├── func
│ │ │ ├── __init__.py
│ │ │ ├── test_construct.py
│ │ │ ├── test_export.py
│ │ │ ├── test_logging.py
│ │ │ ├── test_run.py
│ │ │ └── test_run_delayed.py
│ │ ├── misc
│ │ │ ├── __init__.py
│ │ │ ├── test_restart.py
│ │ │ └── test_shutdown.py
│ │ ├── test_core.py
│ │ └── test_pickle.py
│ ├── test_files
│ │ ├── __init__.py
│ │ ├── failing_script.py
│ │ ├── parameterized_kwargs_script.py
│ │ ├── parameterized_script.py
│ │ ├── succeeding_script.py
│ │ └── syntax_error_script.py
│ ├── test_hooks.py
│ └── time
│ │ ├── __init__.py
│ │ ├── delta
│ │ ├── __init__.py
│ │ ├── test_construct.py
│ │ ├── test_contains.py
│ │ └── test_roll.py
│ │ ├── interval
│ │ ├── __init__.py
│ │ ├── test_construct.py
│ │ ├── test_core.py
│ │ ├── timeofday
│ │ │ ├── __init__.py
│ │ │ ├── test_contains.py
│ │ │ └── test_roll.py
│ │ └── timeofweek
│ │ │ ├── __init__.py
│ │ │ ├── test_contains.py
│ │ │ └── test_core.py
│ │ ├── logic
│ │ ├── __init__.py
│ │ └── test_roll.py
│ │ ├── test_contains.py
│ │ ├── test_core.py
│ │ └── test_parse.py
├── time
│ ├── __init__.py
│ ├── construct.py
│ └── interval.py
└── utils
│ ├── __init__.py
│ └── dependencies.py
├── requirements.txt
├── requirements
├── build.txt
├── ci.txt
├── coverage.txt
└── docs.txt
├── scripts
└── systest
│ ├── flask_api.py
│ ├── load_test.py
│ ├── pipelined.py
│ └── timing.py
├── setup.cfg
├── setup.py
├── tox.ini
└── versioneer.py
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | source = redengine
3 | branch = False
4 | omit =
5 | test/*
6 | _version.py
7 |
8 | data_file = cov_data/.coverage
9 |
10 | [report]
11 |
12 | omit =
13 | redengine/test/*
14 | redengine/_version.py
15 | redengine/__main__.py
16 |
17 | # Regexes for lines to exclude from consideration
18 | exclude_lines =
19 | pragma: no cover
20 |
21 | # Don't complain about abstract methods, they aren't run:
22 | @(abc\.)?abstractmethod
23 |
24 | # Ignore type checking imports
25 | if TYPE_CHECKING
26 |
27 | ignore_errors = True
28 |
29 | [html]
30 | directory = htmlcov
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | redengine/_version.py export-subst
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | *pyx
6 |
7 | # Build & packaging
8 | build/*
9 | dist/*
10 | *egg-info/*
11 |
12 | # Jupyter Notebook
13 | .ipynb_checkpoints
14 | prototype*
15 |
16 | # Scrapy stuff:
17 | .scrapy
18 |
19 | draft/
20 | private/
21 |
22 | # Environments
23 | .env
24 | .venv
25 | env/
26 | env_linux/
27 | venv/
28 | ENV/
29 | env.bak/
30 | venv.bak/
31 |
32 | # IDE
33 | .vscode/
34 | .idea/
35 |
36 | # Testing
37 | .pytest_cache/
38 |
39 | # Packaging
40 | build/
41 | dist/
42 |
43 | # Prototyping files & manual testing
44 | proto/
45 |
46 | # Data & logs
47 | *.csv
48 |
49 | # Private configurations
50 | private.yaml
51 |
52 | # Some other random stuff
53 | bash.exe.stackdump
54 |
55 | # Sphinx documentation
56 | docs/_build/
57 |
58 | # tox
59 | .tox/
60 |
61 | # Coverage
62 | cov_data/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Mikael Koli
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include redengine/test/test_files/*.ipynb
2 | include redengine/test/test_files/*.py
3 | include redengine/config/defaults/*.json
4 | include versioneer.py
5 | include redengine/_session.py
6 | include redengine/_setup.py
7 | include redengine/_pkg.py
8 | include redengine/_version.py
9 | recursive-include redengine/templates *
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Red Engine
3 | > Powering your Python Apps
4 |
5 |
6 | ## NOTE: Red Engine has been renamed as Rocketry: https://github.com/Miksus/rocketry
7 |
8 | -----------------
9 |
10 | [](https://pypi.org/project/redengine/)
11 | [](https://github.com/Miksus/red-engine/actions/workflows/main.yml)
12 | [](https://codecov.io/gh/Miksus/red-engine)
13 | [](https://red-engine.readthedocs.io/en/latest/?badge=latest)
14 | [](https://pypi.org/project/redengine/)
15 |
16 | ## What is it?
17 |
18 | Red Engine is a modern scheduling framework for Python
19 | applications. It is simple, clean and extensive. It is
20 | the engine that sets your Python programs alive.
21 |
22 | The library is minimal on the surface but extensive
23 | and customizable underneath. The syntax very clean:
24 |
25 | ```python
26 | from redengine import RedEngine
27 |
28 | app = RedEngine()
29 |
30 | @app.task('daily')
31 | def do_daily():
32 | ...
33 |
34 | if __name__ == '__main__':
35 | app.run()
36 | ```
37 |
38 | Compared to alternatives, Red Engine has perhaps the most elegant syntax and is the most productive. It offers more features than Crontab or APScheduler but is much
39 | easier to work with than Airflow. It does not make assumptions of your project.
40 |
41 | Read more from the documentations: [Red Engine, documentations](https://red-engine.readthedocs.io/en/stable/)
42 |
43 | ## Installation
44 |
45 | Install Red Engine from [PyPI](https://pypi.org/project/redengine/):
46 |
47 | ```shell
48 | pip install redengine
49 | ```
50 |
51 |
52 | ## More Examples?
53 |
54 | **Scheduling:**
55 |
56 | ```python
57 | @app.task("every 10 seconds")
58 | def do_continuously():
59 | ...
60 |
61 | @app.task("daily after 07:00")
62 | def do_daily_after_seven():
63 | ...
64 |
65 | @app.task("hourly & time of day between 22:00 and 06:00")
66 | def do_hourly_at_night():
67 | ...
68 |
69 | @app.task("(weekly on Monday | weekly on Saturday) & time of day after 10:00")
70 | def do_twice_a_week_after_ten():
71 | ...
72 | ```
73 |
74 | **Pipelining tasks:**
75 |
76 | ```python
77 | from redengine.args import Return
78 |
79 | @app.task("daily after 07:00")
80 | def do_first():
81 | ...
82 | return 'Hello World'
83 |
84 | @app.task("after task 'do_first'")
85 | def do_second(arg=Return('do_first')):
86 | # arg contains the value of the task do_first's return
87 | ...
88 | return 'Hello Python'
89 | ```
90 |
91 | **Parallelizing tasks:**
92 |
93 | ```python
94 | @app.task("daily", execution="main")
95 | def do_unparallel():
96 | ...
97 |
98 | @app.task("daily", execution="thread")
99 | def do_on_separate_thread():
100 | ...
101 |
102 | @app.task("daily", execution="process")
103 | def do_on_separate_process():
104 | ...
105 | ```
106 |
107 | ---
108 |
109 | ## Author
110 |
111 | * **Mikael Koli** - [Miksus](https://github.com/Miksus) - koli.mikael@gmail.com
112 |
113 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/_static/css/colors.css:
--------------------------------------------------------------------------------
1 |
2 | .red {
3 | color: red;
4 | }
--------------------------------------------------------------------------------
/docs/_static/css/types.css:
--------------------------------------------------------------------------------
1 |
2 | .py.class {
3 | padding-bottom: 20px;
4 | }
--------------------------------------------------------------------------------
/docs/code/demo.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 | from redengine.args import Return
3 |
4 | app = RedEngine()
5 |
6 | @app.task('daily')
7 | def do_daily():
8 | "This function runs once a day"
9 | ...
10 |
11 | @app.task('daily between 07:00 and 10:00 | daily between 16:00 and 20:00')
12 | def do_twice_a_day():
13 | "This function runs twice a day (in the morning and in the afternoon)"
14 | # The '|' means OR operator. Fully supports logical operations.
15 | ...
16 |
17 | @app.task("after task 'do_daily'")
18 | def do_after_another(arg=Return('do_daily')):
19 | "Run after 'do_daily' task"
20 | # The parameter 'arg' has the return value of the function 'do_daily'
21 | ...
22 |
23 | if __name__ == "__main__":
24 | # Start the scheduler
25 | app.run()
--------------------------------------------------------------------------------
/docs/code/demo_basic.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 |
3 | app = RedEngine()
4 |
5 | @app.task('daily')
6 | def do_things():
7 | ...
8 |
9 | @app.task("after task 'do_things'")
10 | def do_after_things():
11 | ...
12 |
13 | if __name__ == "__main__":
14 | app.run()
--------------------------------------------------------------------------------
/docs/code/demos/advanced.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 | from redengine.args import Return, Arg, FuncArg
3 |
4 | app = RedEngine()
5 |
6 | # Custom Condition
7 | # ----------------
8 |
9 | @app.cond('is foo')
10 | def is_foo():
11 | # This is a custom condition
12 | ...
13 | return True
14 |
15 | # Parameters
16 | # ----------
17 |
18 | app.params(my_arg='Hello')
19 |
20 | @app.param('item')
21 | def get_item():
22 | # This is a custom condition
23 | ...
24 | return 'world'
25 |
26 | # Tasks
27 | # -----
28 |
29 | @app.task('daily', execution="process")
30 | def do_on_process():
31 | "This task runs once a day and runs on separate process"
32 | ...
33 | return ...
34 |
35 | @app.task("after task 'do_things'")
36 | def do_pipeline(arg1=Return('do_on_process'),
37 | arg2=Arg('item'),
38 | arg3=Arg('my_arg')):
39 | """This task runs when 'do_on_process' has succeeded.
40 | Argument 'arg1' gets the return value of 'do_on_process'
41 | Argument 'arg2' gets the return value of function 'get_item'
42 | Argument 'arg3' is simply the value of a session parameter 'my_arg'"""
43 | ...
44 |
45 | @app.task('daily & is foo', execution="thread")
46 | def do_custom():
47 | """This task runs once a day and when is_foo returns True
48 | This task runs on separate thread"""
49 | ...
50 |
51 | @app.task('(true & true) | (false & True & ~True)')
52 | def do_complex():
53 | """Notice the logical expression in the task start condition"""
54 | ...
55 |
56 | if __name__ == "__main__":
57 | app.run()
--------------------------------------------------------------------------------
/docs/code/demos/basic.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 |
3 | app = RedEngine()
4 |
5 | @app.task('daily')
6 | def do_things():
7 | ...
8 |
9 | @app.task("after task 'do_things'")
10 | def do_after_things():
11 | ...
12 |
13 | if __name__ == "__main__":
14 | app.run()
--------------------------------------------------------------------------------
/docs/code/demos/intermediate.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 | from redengine.args import Return, Arg, FuncArg
3 |
4 | app = RedEngine()
5 |
6 | @app.cond('is foo')
7 | def is_foo():
8 | "This is a custom condition"
9 | ...
10 | return True
11 |
12 |
13 | @app.task('daily & is foo', execution="process")
14 | def do_daily():
15 | "This task runs once a day and runs on separate process"
16 | ...
17 | return ...
18 |
19 | @app.task("after task 'do_daily'")
20 | def do_after(arg1=Return('do_daily')):
21 | """This task runs after 'do_daily' and it has its the
22 | return argument as an input"""
23 | ...
24 |
25 |
26 | if __name__ == "__main__":
27 | app.run()
--------------------------------------------------------------------------------
/docs/code/demos/minimal.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 |
3 | app = RedEngine()
4 |
5 | @app.task('daily')
6 | def do_things():
7 | ...
8 |
9 | if __name__ == "__main__":
10 | app.run()
--------------------------------------------------------------------------------
/docs/code/demos/monitor.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 | from redengine.args import Arg
3 | from redmail import EmailSender
4 |
5 | app = RedEngine()
6 | app.params(receivers=['me@example.com'])
7 | email = EmailSender(
8 | host="smtp.myserver.com", port=584,
9 | username="me@example.com", password=""
10 | )
11 |
12 | @app.task('hourly')
13 | def measure_performance(receivers):
14 | email.send(
15 | subject="Wake up",
16 | )
17 |
18 | @app.task('daily between 10:00 and 12:00')
19 | def eat_lunch(receivers):
20 | email.send(
21 | subject="Go to eat",
22 | )
23 |
24 | @app.task('daily between 22:00 and 04:00')
25 | def go_to_sleep(receivers):
26 | email.send(
27 | subject="Go to eat",
28 | )
29 |
30 | if __name__ == "__main__":
31 | app.run()
--------------------------------------------------------------------------------
/docs/code/execution.py:
--------------------------------------------------------------------------------
1 | @app.task("daily", execution="main")
2 | def do_main():
3 | ...
4 |
5 | @app.task("daily", execution="thread")
6 | def do_thread():
7 | ...
8 |
9 | @app.task("daily", execution="process")
10 | def do_process():
11 | ...
--------------------------------------------------------------------------------
/docs/code/parameter/parameters.py:
--------------------------------------------------------------------------------
1 | from redengine import RedEngine
2 | from redengine.args import Arg, Return, FuncArg
3 |
4 | app = RedEngine()
5 | app.params(my_arg='hello')
6 |
7 | @app.task("every 10 seconds")
8 | def do_things(arg=Arg('my_arg')):
9 | ...
10 | # Argument 'arg' has value 'hello'
11 | assert arg == 'hello'
12 | return 'stuff'
13 |
14 | @app.task("after task 'do_things'")
15 | def do_with_return(arg=Return('do_things')):
16 | ...
17 | # Argument 'arg' is the return value of the task 'do_things'
18 | assert arg == 'stuff'
19 |
20 | @app.task("after task 'do_things'")
21 | def do_with_funcarg(arg=FuncArg(lambda: 'hello world')):
22 | ...
23 | # Argument 'arg' is the return value of the task 'do_things'
24 | assert arg == 'stuff'
25 |
26 | if __name__ == "__main__":
27 | app.run()
--------------------------------------------------------------------------------
/docs/code/parameter/pipelining.py:
--------------------------------------------------------------------------------
1 | from redengine.args import Return
2 |
3 | @app.task("every 10 seconds")
4 | def do_things():
5 | ...
6 | return 'hello'
7 |
8 | @app.task("after task 'do_things'")
9 | def do_after(arg=Return('do_things')):
10 | ...
11 | assert arg == 'hello'
12 | return 'world'
13 |
14 | @app.task("after task 'do_things', 'do_stuff'")
15 | def do_after_all(arg1=Return('do_things'), arg2=Return('do_stuff')):
16 | ...
17 | assert arg1 == 'hello'
18 | assert arg2 == 'world'
19 |
--------------------------------------------------------------------------------
/docs/code/schedule/fixed_period.py:
--------------------------------------------------------------------------------
1 | @app.task('daily')
2 | def do_daily():
3 | ...
4 |
5 | @app.task('weekly')
6 | def do_weekly():
7 | ...
8 |
9 | @app.task('monthly')
10 | def do_monthly():
11 | ...
--------------------------------------------------------------------------------
/docs/code/schedule/fixed_period_with_args.py:
--------------------------------------------------------------------------------
1 | @app.task('daily after 10:00')
2 | def do_daily_after():
3 | ...
4 |
5 | @app.task('daily before 22:00')
6 | def do_daily_after():
7 | ...
8 |
9 | @app.task('daily between 10:00 and 22:00')
10 | def do_daily_between():
11 | ...
12 |
13 |
14 | @app.task('weekly on Monday')
15 | def do_on_monday():
16 | ...
17 |
18 | @app.task('weekly between Saturday and Sunday')
19 | def do_on_weekend():
20 | ...
21 |
22 |
23 | @app.task('monthy after 5th')
24 | def do_monthly_after_fifth():
25 | ...
26 |
27 | @app.task('monthy before 5th')
28 | def do_monthly_before_fifth():
29 | ...
--------------------------------------------------------------------------------
/docs/code/schedule/logic.py:
--------------------------------------------------------------------------------
1 | @app.task('true & false')
2 | def do_never():
3 | ...
4 |
5 | @app.task('true | false')
6 | def do_constantly():
7 | ...
8 |
9 | @app.task('~false')
10 | def do_constantly_2():
11 | ...
--------------------------------------------------------------------------------
/docs/code/schedule/time_of.py:
--------------------------------------------------------------------------------
1 | @app.task('every 10 seconds')
2 | def do_constantly():
3 | ...
4 |
5 | @app.task('every 1 minute')
6 | def do_minutely():
7 | ...
8 |
9 | @app.task('every 1 hour')
10 | def do_hourly():
11 | ...
12 |
13 | @app.task('every 1 day')
14 | def do_daily():
15 | ...
16 |
17 | @app.task('every 2 days 2 hours 20 seconds')
18 | def do_custom():
19 | ...
--------------------------------------------------------------------------------
/docs/code/snippets/parallelization.py:
--------------------------------------------------------------------------------
1 | @app.task("daily", execution="main")
2 | def do_unparallel():
3 | ...
4 |
5 | @app.task("daily", execution="thread")
6 | def do_on_separate_thread():
7 | ...
8 |
9 | @app.task("daily", execution="process")
10 | def do_on_separate_process():
11 | ...
--------------------------------------------------------------------------------
/docs/code/snippets/parametrize.py:
--------------------------------------------------------------------------------
1 | from redengine.args import Arg
2 |
3 | @app.param('my_param')
4 | def get_my_param():
5 | "Get a session level parameter"
6 | return 'Hello world'
7 |
8 | @app.task("daily")
9 | def do_with_param(arg=Arg('my_param')):
10 | # 'arg'
11 | assert arg == 'Hello world'
12 | ...
13 |
--------------------------------------------------------------------------------
/docs/code/snippets/pipeline.py:
--------------------------------------------------------------------------------
1 | from redengine.args import Return
2 |
3 | @app.task("daily after 07:00")
4 | def do_first():
5 | ...
6 | return 'Hello World'
7 |
8 | @app.task("after task 'do_first'")
9 | def do_second(arg=Return('do_first')):
10 | # arg contains the value of the task do_first's return
11 | ...
12 | return 'Hello Python'
13 |
--------------------------------------------------------------------------------
/docs/code/snippets/scheduling.py:
--------------------------------------------------------------------------------
1 | @app.task("every 10 seconds")
2 | def do_continuously():
3 | ...
4 |
5 | @app.task("daily after 07:00")
6 | def do_daily_after_seven():
7 | ...
8 |
9 | @app.task("hourly & time of day between 22:00 and 06:00")
10 | def do_hourly_at_night():
11 | ...
12 |
13 | @app.task("(weekly on Monday | weekly on Saturday) & time of day after 10:00")
14 | def do_twice_a_week_after_ten():
15 | ...
--------------------------------------------------------------------------------
/docs/condition_syntax/dependence.rst:
--------------------------------------------------------------------------------
1 |
2 | .. _cond-dependence:
3 |
4 | Task Dependence
5 | ---------------
6 |
7 | **Syntax**
8 |
9 | .. code-block:: none
10 |
11 | after task ''
12 | after task '' [succeeded | failed | finished | terminated]
13 | after tasks '', '' ...
14 | after tasks '', '' ... [succeeded | failed | finished]
15 | after any tasks '', '' ... [succeeded | failed | finished]
16 |
17 | **True when**
18 |
19 | True if the assigned task has not run after the given task has
20 | succeeded/failed/finished/terminated. Useful for creating
21 | task pipelines.
22 |
23 | .. note::
24 |
25 | Must be assigned to a task.
26 |
27 |
28 | **Examples**
29 |
30 | .. code-block:: python
31 |
32 | # Creating a dummy task
33 | @app.task()
34 | def a_task():
35 | ...
36 |
37 | # Examples
38 | app.task("after task 'a_task'")
39 | app.task("after task 'a_task' succeeded")
40 | app.task("after task 'a_task' failed")
41 | app.task("after task 'a_task' finished")
42 | app.task("after tasks 'a_task', 'another_task' finished")
--------------------------------------------------------------------------------
/docs/condition_syntax/execution.rst:
--------------------------------------------------------------------------------
1 |
2 | .. _cond-execution:
3 |
4 | Execution on fixed time interval
5 | --------------------------------
6 |
7 | **Syntax**
8 |
9 | .. code-block:: none
10 |
11 | [hourly | daily | weekly | monthly]
12 | [hourly | daily | weekly | monthly] between and
13 | [hourly | daily | weekly | monthly] [before | after | starting]