Skip to content

Commit

Permalink
Merge pull request #101 from da-h/event_exists
Browse files Browse the repository at this point in the history
event: added method event.exists(event_name)
  • Loading branch information
da-h authored Nov 19, 2021
0 parents commit bd968b2
Show file tree
Hide file tree
Showing 18 changed files with 1,015 additions and 0 deletions.
103 changes: 103 additions & 0 deletions 01-Getting-Started/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{theme=documentation}

\include{"../include.md"}

> A long time ago in a galaxy full of plugin-engines ...
# Geting Started with Miniflask {section-contentlist=False}
## Miniflask is a **small** research-oriented **plugin**-engine for **python**.



Quick Start
===========

For a quick look into miniflask, just install it using
```shell
pip install miniflask
```


Short Example
=============


**Module Definition**
Let's start a new project first by creating a new directory:
```shell
> ls
main.py
modules/
module1/__init__.py
module2/__init__.py
module1/__init__.py
```

Let's define a simple module, `modules/module1/__init__.py`:
```python
def main(state, event):
print("main event called by module1")

def register(mf):
mf.register_event('main', main, unique=False)
```

Let's define another module, `modules/module2/__init__.py`:
```python
def main(state, event):
print("main event called by module2")
print("it uses a variable var:", state["var"])

def register(mf):
mf.register_defaults({
"var": 42
})
mf.register_event('main', main, unique=False)
```



Our main.py looks like this:
```python
import miniflask

# initialize miniflask
mf = miniflask.init(module_dirs="./modules")
mf.parse_args()

# check if all requested modules are loaded
if not mf.halt_parse:

# call event "main" if exists
if hasattr(mf.event, 'main'):
mf.event.main()
else:
print("There is nothing to do.")
```


**Usage**:
Now, we can use our program in the following ways:
```sh
> python main.py
There is nothing to do.
```

```sh
> python main.py module1
main event called by module1
```

```sh
> python main.py module2,module1
main event called by module2
it uses a variable var: 42
main event called by module1
```

```sh
> python main.py module2,module1 --module2.var 9001
main event called by module2
it uses a variable var: 9001
main event called by module1
```
38 changes: 38 additions & 0 deletions 02-Launching-MiniFlask/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{theme=documentation}

# Launching MiniFlask
Things to do in the launch file.

\include{"../include.md"}


## Launch file

The first step in creating a new MiniFlask project is to create the launch file. The launch file initializes MiniFlask and tells it where modules are located.
**Typically, you will never need to touch this file ever again!**

The following function calls have to be included:
**Example file:** do.py
```python
import miniflask

# tells MiniFlask where the modules are located
# simply feed it a list of module folders
mf = miniflask.init(["module_collection_1","module_collection_2"])

# Parses arguments from the command line and runs the modules that have been specified
# as entrypoints. The run command first launches the `init` event if it exists and then
# the `main` events of all modules. If multiple modules with a main method are loaded,
# the main methods are executed in the order modules are specified using the CLI.
mf.run()
```

## Executing the launch file
In order to start our MiniFlask project, simply execute the `do.py` file and list all modules to load separated by a comma. To overwrite the default arguments, simply pass the new parameters precising the modules after the modules.

```python
> python main.py module2,module1 --module2.var 9001
main event called by module2
it uses a variable var: 9001
main event called by module1
```
82 changes: 82 additions & 0 deletions 03-Modules/01-Module-Declaration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{theme=documentation}

\include{"../include.md"}

# Register Modules {section-contentlist=False}
Telling MiniFlask what exists.

### Initialize Miniflask
\include{"../08-API/02-miniflask-Instance/01-miniflask.init.md"}

\main


**Example Launch File**
```python
import miniflask

# tell miniflask where to look for modules
mf = miniflask.init(module_dirs="./modules")

# parse CLI-args & run the main event
mf.run()
```

Project structure may be very project specific. Miniflask allows various way to organize your projects.
Other possibilities are to define modules directly or to specify multiple distinct folders that contain miniflask modules.

\examples

### What is a Module?
> A miniflask module is a self-contained functional unit with a persistent variable store. In principle, it's a singleton class.
**Module Declaration**
- **A MiniFlask module is a folder that contains at least these two files**:
- `__init__.py` containing a method called `register(mf)`.
The method `register(mf)` is called whenever a module is loaded.
It's purpose is to tell miniflask in which way the module is to be used.
- `.module` *(empty file)*


### Unique & Short Module Identifiers
When working with miniflask modules we will want to reference modules uniquely.
The unique module identifier is just the path to the folder (starting with the base directory defined during initialization), where the module seperator is a dot (`.`).


**Example**
For instance, we could organize the folder `./modules` like this:
```shell
> ls
main.py
modules/
module1/__init__.py
... /.module
module2/__init__.py
... /.module
... /.noshortid
subfolder1/module3/__init__.py
... / ... /.module
subfolder1/module4/__init__.py
... / ... /.module
... and so on ...
```

Further, we initialized miniflask using the line
```py
mf = miniflask.init({
"mods": "./modules",
})
```
by specifying the name `mods` for our main repository contained in the folder `./modules/`.


Every module in this repository can now be referenced in two ways: \block[
| **Type** | unique module identifier | (short) module identifier |
| ---------- | -------------------- | --------------------- |
| **Description** | unique identification by specifying the whole module path | any subset of the unique identifier if only one module matches that description |
| **Availability** | Always | Not available if \block[
- two modules would share the same short identifier
- module-folder contains the file `.noshortid`
] |
| **Example** | `module1`,\n (has no shorter id)\n `subfolder1.module3` or also `mods.module3`,\n `subfolder1.module4` or also `mods.module4`| `mods.module1`\n`mods.module2`\n`mods.subfolder1.module3`\n`mods.subfolder1.module4` |
]
108 changes: 108 additions & 0 deletions 03-Modules/02-Register-Settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
{theme=documentation}

\include{"../include.md"}

\include{"../08-API/02-miniflask-Instance/08-register_defaults.md"}

# Register Module Settings:
\shortdescr

\main


## Example
A typical used case are variables that can be overridden freely using CLI.
Example file: `modules/module1/__init__.py`
\examples

## Overriding these using the CLI
Whenever we load `module1`, e.g. by using
```shell
python main.py module1
```
we also load these variables into the argument parser of miniflask.
For the example above, we list all arguments that can be used for `module1`:
```shell
> python main.py module1 -h
usage: main.py modulelist [optional arguments]

optional arguments:
-h, --help show this help message and exit
--module1.variableA int
--module1.variableB string
--module1.variableC
--no-module1.variableC
--module1.variableD [int]
```

Thus, to turn `variableC` off, we can just add `--no-module1.variableC` to the above command.

## Overriding Booleans
For a boolean typed variable, the following arguments are possible:

| **Set to True** | **Set to False** |
| ---------------- | ---------------- |
| \block[
```
--module.var
--module.var true
--module.var TrUe (well, boolean values are case insensitive)
--module.var yes
--module.var y
--module.var t
--module.var 1
```
] | \block[
```
--no-module.var
--module.var false
--module.var FalSE (well, boolean values are case-insensitive)
--module.var no
--module.var n
--module.var f
--module.var 0
```
] |

**Overriding Lists of basic types**:
List arguments are just as easy as
```
--module.var 1 2 3 4 5
```



## Required Arguments
Set any basic data type (`str`, `bool`, `int`, `float`) or list of any basic data type as default value to register an argument that has to be specified by the CLI.
```python
def register(mf):
mf.register_defaults({
"variableA": int,
"variableB": str,
"variableC": bool,
"variableD": [float] # only lists of same type are supported
})
```




## Nested Arguments
Given nested modules, it is possible to group variables in the CLI using the folllowing syntax:
```python
--module1.submodule [ --var1 42 --var2 43 ]
```
or
```python
--module1 [ --submodule [ --var1 42 --var2 43 ] ]
```

These calls would translate to the following:
```
--module1.submodule.var1 42
--module1.submodule.var2 43
```




Loading

0 comments on commit bd968b2

Please sign in to comment.