



  

Photon 0.4 documentation

 [Photon](index.html#document-index) 

 stable

 

* [The core](index.html#document-core)

* [Tools](index.html#document-tools)

* [Utility](index.html#document-util)

[Photon](index.html#document-index)

* [Docs](index.html#document-index) »

* Photon 0.4 documentation

* [Edit on GitHub](https://github.com/spookey/photon/blob/936de5e8f1c62c46e8100cfb5bae2594907c13a6/docs/index.rst)

---

Photon[¶](#photon "Permalink to this headline")

===============================================

[![Photon logo, not a moustache](_images/photon_logo.png)](_images/photon_logo.png)

Welcome to the Photon Documentation.

  

  

Photon Intro[¶](#photon-intro "Permalink to this headline")

-----------------------------------------------------------

It could be best described as a **shell backend as python module**

Contributions are highly welcome [[1]](#contributions), also feel free to use the [issue tracker](http://github.com/spookey/photon/issues) if you encounter any problems.

| Repository: | [github.com/spookey/photon](http://github.com/spookey/photon/) |

| Documentation: | [photon.readthedocs.org](http://photon.readthedocs.org/en/latest/) |

| Package: | [pypi.python.org/pypi/photon\_core](https://pypi.python.org/pypi/photon_core/) |

### Examples[¶](#examples "Permalink to this headline")

The **/examples** directory contains some basic receipts on how to use Photon in your scripts.

Photon helps at [Freifunk MWU](http://freifunk-mwu.de/) to solve some tasks:

> 

> * See our [collection of backend-scripts](https://github.com/freifunk-mwu/backend-scripts) for some scripts using photon, running in production.

> * To automatically compile gluon firmware for routers, we wrote the [gluon builder](https://github.com/freifunk-mwu/gluon-builder-ffmwu).

> 

> 

> 

Installation[¶](#installation "Permalink to this headline")

-----------------------------------------------------------

Photon is available as package on pypi, it is called `photon\_core` [[2]](#photon-core).

You can install/update the package via pip3 [[3]](#pip3):

```

pip3 install photon_core

```

```

pip3 install -U photon_core

```

Bleeding-Edge

Development is still at an very early stage, expect anything to change completely in near future.

As long we still have a leading zero in the version (see *info* file) use *pip3* with the `--pre` switch:

```

pip3 install -U photon_core --pre

```

Versions

Tags in the git repository will be released as a new pypi package version.

Versions of a pypi package has always it’s git tag.

And vice versa.

Not every version increase will be tagged/released. I will only do so if I feel the urge to do so.

| [[1]](#id1) | Teach me how to write good code, help me to improve. |

| [[2]](#id2) | because photon itself was already taken :/ |

| [[3]](#id3) | Photon is written in python3 ~ be careful with easy\_install |

Structure[¶](#structure "Permalink to this headline")

-----------------------------------------------------

Photon aimes to be modular and can be divided into

[The core](index.html#core), it’s [Utility](index.html#util) and some [Tools](index.html#tools),

provided through [Photon](index.html#photon) itself.

If you just want to use Photon in your Scripts as a normal User you

may especially be interested in the parts [Photon](index.html#photon) and [Tools](index.html#tools).

### The core[¶](#the-core "Permalink to this headline")

All three modules depend on the [Utility](index.html#util):

See also

[Files](index.html#util-files),

[Locations](index.html#util-locations),

[Structures](index.html#util-structures),

[System](index.html#util-system)

[Settings](#settings) and [Meta](#meta) could be used independently or both together.

Bundling [Settings](#settings) and [Meta](#meta) together plus adding the

[Tools](index.html#tools), [Photon](#photon) provides a interface to use in your scripts.

See also

[Git Tool](index.html#tools-git),

[Mail Tool](index.html#tools-mail),

[Ping Tool](index.html#tools-ping),

[Signal Tool](index.html#tools-signal)

#### Settings[¶](#settings "Permalink to this headline")

*class* `settings.``Settings`(*defaults*, *config='config.yaml'*, *verbose=True*)[[source]](_modules/settings.html#Settings)[¶](#settings.Settings "Permalink to this definition")

Settings is a class which provides access to

compiled settings loaded from YAML-files.

The YAML-files will be read with specific loaders which enables

certain logic within the configuration.

It is possible to:

> 

> * Insert references to existing fields via anchors and `!str\_join` or `!loc\_join`

> * Insert keywords like **hostname** or **timestamp** using `!str\_join`

> * Combine path-segments using `!loc\_join`

> * Insert keywords like **home\_dir** or **conf\_dir** using `!loc\_join`

> 

> 

> 

It is also possible to import or merge further content.

| Parameters: | * **defaults** – The initial configuration to load. Will be located using [`util.locations.search\_location()`](index.html#util.locations.search_location "util.locations.search_location")

	+ The common way is to use a short-filename to locate it next to the script using Photon.

	+ Can also be a full path.

	+ Can also passed directly as a dict

	+ Bring your own defaults! Tears down (using [`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify") with

	state set to `True`) whole application if not found or none passed.

* **config** – Where to store the loaded output from the defaults. Will be located using [`util.locations.search\_location()`](index.html#util.locations.search_location "util.locations.search_location")

	+ File must already exist, will be created in ‘conf\_dir’ from [`util.locations.get\_locations()`](index.html#util.locations.get_locations "util.locations.get_locations") otherwise

	

		- Therefore use a short name (or full path) if one should be created

Note

The last loaded file wins

	+ The config is intended to provide a editable file for the end-user

	+ If a value differs from the original values in defaults, the value in config wins

	

		- Other values which not exist in config will be set from defaults

		- If a value in config contains a loader call which expresses the same as the value in defaults it will be skipped.

	+ Be careful using **timestamp** s in a config. The timestamp of the first launch will always be used.

	+ Simply delete all lines within the config to completely reset it to the defaults

	+ Can be skipped by explicitly setting it to `None`

* **verbose** – Sets the verbose flag for the underlying [Utility](index.html#util) functions

 |

See also

[`util.structures.yaml\_str\_join()`](index.html#util.structures.yaml_str_join "util.structures.yaml_str_join")

and [`util.structures.yaml\_loc\_join()`](index.html#util.structures.yaml_loc_join "util.structures.yaml_loc_join") as well as the [Example Settings File](#settings-file-example)

`get`[¶](#settings.Settings.get "Permalink to this definition")

| Returns: | Current settings |

`load`(*skey*, *sdesc*, *sdict=None*, *loaders=None*, *merge=False*, *writeback=False*)[[source]](_modules/settings.html#Settings.load)[¶](#settings.Settings.load "Permalink to this definition")

Loads a dictionary into current settings

| Parameters: | * **skey** – Type of data to load. Is be used to reference the data in the files sections within settings

* **sdesc** – Either filename of yaml-file to load or further description of imported data when sdict is used

* **sdict** ([*dict*](http://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.5)")) – Directly pass data as dictionary instead of loading it from a yaml-file. Make sure to set skey and sdesc accordingly

* **loaders** ([*list*](http://docs.python.org/3/library/stdtypes.html#list "(in Python v3.5)")) – Append custom loaders to the YAML-loader.

* **merge** – Merge received data into current settings or place it under skey within meta

* **writeback** – Write back loaded (and merged/imported) result back to the original file. This is used to generate the summary files

 |

| Returns: | The loaded (or directly passed) content |

See also

[`util.structures.yaml\_str\_join()`](index.html#util.structures.yaml_str_join "util.structures.yaml_str_join")

and [`util.structures.yaml\_loc\_join()`](index.html#util.structures.yaml_loc_join "util.structures.yaml_loc_join")

##### Example Settings File[¶](#example-settings-file "Permalink to this headline")

defaults.sample.yaml

|  |  |

| --- | --- |

| 

```

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

```

 | 

```

# The syntax of the settings files is YAML:

01\_syntax:

    dictionary: 'value is a string'

    dictionary\_with\_list: ['value', 'is', 'a', 'list']

    dictionary\_with\_list2:

    - this

    - is

    - another

    - list

# ----

# YAML supports backreferences by anchors.

# First yo have define a dictionary value as anchor:

02\_anchor:

    prefix: &MY\_PRFX 'Photon is a software that '

# Then use them together with !str\_join:

    poll:

        yay: !str\_join [\*MY\_PRFX, 'realy helps me']

        nay: !str\_join [\*MY\_PRFX, 'sucks']

# This turns into:

# yay: Photon is a software that really helps me

# nay: Photon is a software that sucks

# (The anchor ('&'-sign) must appear before the Reference ('\*'-sign) in the YAML-file.

# (Note the whitespace.)

# ----

# !str\_join can listen to the keywords - 'hostname' & 'timestamp':

03\_keywords:

    message:

    - !str\_join ['my machine "', 'hostname', '" is the best']

    - !str\_join ['yours, herbert. date: ', 'timestamp']

# This turns into:

# message:

# - my machine "blechschachtel" is the best

# - 'yours, herbert. date: YYYY.MM.DD-HH.MM.SS'

# (with current date expanded)

# ----

# Use !loc\_join to combine files and paths:

04\_locations:

    simple\_file: !loc\_join ['/', 'usr', 'local', 'bin', 'myscript.sh']

    same\_simple\_file: !loc\_join ['/usr/local/bin', 'myscript.sh']

# This turns into:

# simple\_file: /usr/local/bin/myscript.sh

# same\_simple\_file: /usr/local/bin/myscript.sh

# But be careful with leading '/'-signs:

    not\_the\_simple\_file: !loc\_join ['/usr/local', '/bin', 'myscript.sh']

# This turns into not what we wanted:

# not\_the\_simple\_file: /bin/myscript.sh

# It can also listen to keywords:

    in\_the\_home\_dir: !loc\_join ['home\_dir', 'my\_directory']

# in\_the\_home\_dir: /home/herbert/my\_directory

# ----

# Combine them alltogether:

05\_combined:

    name: &MY\_ASS my\_awesome\_server\_software

    main: &OH\_MY !loc\_join ['home\_dir', \*MY\_ASS, 'main']

    main\_run: !loc\_join [\*OH\_MY, 'run.py']

    backup\_dir: !loc\_join ['data\_dir', \*MY\_ASS, !str\_join ['backup-', 'timestamp']]

    git-remote: !str\_join

    - 'https://github.com/user404/'

    - \*MY\_ASS

    - .git

# This turns into:

# name: my\_awesome\_server\_software

# main: /home/herbert/my\_awesome\_server\_software/main

# main\_run: /home/herbert/my\_awesome\_server\_software/main/run.py

# backup\_dir: /home/herbert/.local/share/photon/my\_awesome\_server\_software/backup-YYYY.MM.DD-HH.MM.SS

# git-remote: https://github.com/user404/my\_awesome\_server\_software.git

```

 |

See also

The [wikipedia page on YAML](http://en.wikipedia.org/wiki/YAML)

for some syntax reference.

See also

* !loc\_join: [`util.structures.yaml\_loc\_join()`](index.html#util.structures.yaml_loc_join "util.structures.yaml_loc_join")

(get locations by keyword and join paths)

* !str\_join: [`util.structures.yaml\_str\_join()`](index.html#util.structures.yaml_str_join "util.structures.yaml_str_join")

(get variables by keyword and join strings)

See also

[Example Settings File](#settings-file-example),

[Mail Tool Example](index.html#tools-mail-example),

[Ping Tool Example](index.html#tools-ping-example)

#### Meta[¶](#meta "Permalink to this headline")

*class* `meta.``Meta`(*meta='meta.json'*, *verbose=True*)[[source]](_modules/meta.html#Meta)[¶](#meta.Meta "Permalink to this definition")

Meta is a class which bounds to an actual json-file on disk.

It provides a logger storing the entries in that json-file.

It is also possible to import contents.

By staging out to a different directory meta-files are left behind

for further debugging or to see what was going on.

| Parameters: | * **meta** – Initial, clean meta file to use. See [`stage()`](#meta.Meta.stage "meta.Meta.stage") for more

* **verbose** – Sets the verbose flag for the underlying [Utility](index.html#util) functions

 |

`load`(*mkey*, *mdesc*, *mdict=None*, *merge=False*)[[source]](_modules/meta.html#Meta.load)[¶](#meta.Meta.load "Permalink to this definition")

Loads a dictionary into current meta

| Parameters: | * **mkey** – Type of data to load.

Is be used to reference the data from the ‘header’ within meta

* **mdesc** – Either filename of json-file to load or further description

of imported data when mdict is used

* **mdict** ([*dict*](http://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.5)")) – Directly pass data as dictionary instead of

loading it from a json-file.

Make sure to set mkey and mdesc accordingly

* **merge** – Merge received data into current meta or place it

under ‘import’ within meta

 |

| Returns: | The loaded (or directly passed) content |

`log`[¶](#meta.Meta.log "Permalink to this definition")

| Parameters: | **elem** – Add a new log entry to the meta.* Can be anything.

* The log is a dictionary with keys generated from the output of [`util.system.get\_timestamp()`](index.html#util.system.get_timestamp "util.system.get_timestamp") and elem as value

 |

| Returns: | Current meta |

`stage`(*name*, *clean=False*)[[source]](_modules/meta.html#Meta.stage)[¶](#meta.Meta.stage "Permalink to this definition")

Switch stage

| Parameters: | * **name** – Filename of new meta file. Will be located using [`util.locations.search\_location()`](index.html#util.locations.search_location "util.locations.search_location")

	+ File must not already exist, will be created in ‘data\_dir’ from [`util.locations.get\_locations()`](index.html#util.locations.get_locations "util.locations.get_locations")

	+ Can also be a full path to place it anywhere desired

* **clean** – What to do with preexisting meta files?

	+ `False`: Merge current meta with preexisting one

	+ `True`: Replace preexisting meta with current one

 |

#### Photon[¶](#photon "Permalink to this headline")

*class* `photon.``Photon`(*defaults*, *config='config.yaml'*, *meta='meta.json'*, *verbose=True*)[[source]](_modules/photon.html#Photon)[¶](#photon.Photon "Permalink to this definition")

Photon uses [The core](#core) and some functions from [Utility](index.html#util) in its

[`m()`](#photon.Photon.m "photon.Photon.m")-method.

The [`m()`](#photon.Photon.m "photon.Photon.m")-method itself is used in each tool to interact with

photon to:

> 

> * Launch shell commands, and receive the results

> * Add messages to the meta-file

> * Show the messages if necessary

> * Tear down application completely in case of any serious problems

> 

> 

> 

Further, Photon provides direct handlers for

[`settings.Settings`](#settings.Settings "settings.Settings") and [`meta.Meta`](#meta.Meta "meta.Meta")

and a handler for each tool from [Tools](index.html#tools) by it’s methods.

| Parameters: | * **defaults** – Pass defaults down to [`settings.Settings`](#settings.Settings "settings.Settings")

* **config** – Pass config down to [`settings.Settings`](#settings.Settings "settings.Settings")

* **meta** – Pass meta down to [`meta.Meta`](#meta.Meta "meta.Meta")

* **verbose** – Sets the global verbose flag. Passes it down to the underlying

[Utility](index.html#util) functions and [The core](#core)

 |

| Variables: | * [**settings**](index.html#module-settings "settings") – The settings handler initialized with defaults and config

* [**meta**](index.html#module-meta "meta") – The meta handler initialized with meta

 |

At startup the loaded settings are imported into meta

`git_handler`(*\*args*, *\*\*kwargs*)[[source]](_modules/photon.html#Photon.git_handler)[¶](#photon.Photon.git_handler "Permalink to this definition")

| Returns: | A new git handler |

See also

[Git Tool](index.html#tools-git)

`m`(*msg*, *state=False*, *more=None*, *cmdd=None*, *critical=True*, *verbose=None*)[[source]](_modules/photon.html#Photon.m)[¶](#photon.Photon.m "Permalink to this definition")

Mysterious mega method managing multiple meshed modules magically

Note

If this function is used, the code contains facepalms: `m(`

* It is possible to just show a message, or to run a command with message.

* But it is not possible to run a command without a message, use the verbose-flag to hide your debug message.

| Parameters: | * **msg** – Add a message. Shown depending on verbose (see below)

* **state** – Pass state down to [`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify")

* **more** – Pass more down to [`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify")

* **cmdd** ([*dict*](http://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.5)")) – If given, [`util.system.shell\_run()`](index.html#util.system.shell_run "util.system.shell_run") is launched with

it’s values

* **critical** – If set to `True`: Tears down (using [`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify") with

state set to `True`) whole application on failure of cmdd contents.

	+ Similar to [`util.system.shell\_run()`](index.html#util.system.shell_run "util.system.shell_run") critical-flag

* **verbose** – Overrules parent’s class verbose-flag.

	+ If left to `None`, the verbose value Photon was started with is used

	+ Messages are shown/hidden if explicitly set to `True`/`False`

 |

| Returns: | A dictionary specified the following:

* ‘more’:

more if it is not a dictionary otherwise it gets merged in if more is specified

* The output of [`util.system.shell\_run()`](index.html#util.system.shell_run "util.system.shell_run") gets merged in if cmdd is specified

* ‘failed’: `True` if command failed

[`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify") is used with this dictionary

to pipe it’s output into [`meta.Meta.log()`](#meta.Meta.log "meta.Meta.log") before returning.

 |

`mail_handler`(*punchline=None*, *add\_meta=False*, *add\_settings=True*, *\*args*, *\*\*kwargs*)[[source]](_modules/photon.html#Photon.mail_handler)[¶](#photon.Photon.mail_handler "Permalink to this definition")

| Parameters: | * **punchline** – Adds a punchline before further text

* **add\_meta** – Appends current meta to the mail

* **add\_settings** – Appends current settings to the mail

 |

| Returns: | A new mail handler |

See also

[Mail Tool](index.html#tools-mail)

`ping_handler`(*\*args*, *\*\*kwargs*)[[source]](_modules/photon.html#Photon.ping_handler)[¶](#photon.Photon.ping_handler "Permalink to this definition")

| Returns: | A new ping handler |

See also

[Ping Tool](index.html#tools-ping)

`s2m`[¶](#photon.Photon.s2m "Permalink to this definition")

Imports settings to meta

`signal_handler`(*\*args*, *\*\*kwargs*)[[source]](_modules/photon.html#Photon.signal_handler)[¶](#photon.Photon.signal_handler "Permalink to this definition")

| Returns: | A new signal handler |

See also

[Signal Tool](index.html#tools-signal)

`template_handler`(*\*args*, *\*\*kwargs*)[[source]](_modules/photon.html#Photon.template_handler)[¶](#photon.Photon.template_handler "Permalink to this definition")

| Returns: | A new template handler |

See also

[Template Tool](index.html#tools-template)

`photon.``check_m`(*pm*)[[source]](_modules/photon.html#check_m)[¶](#photon.check_m "Permalink to this definition")

Shared helper function for all [Tools](index.html#tools) to check if the passed

m-function is indeed [`photon.Photon.m()`](#photon.Photon.m "photon.Photon.m")

| Params pm: | Suspected m-function |

| Returns: | Now to be proven correct m-function,

tears down whole application otherwise. |

### Tools[¶](#tools "Permalink to this headline")

This are the tools for the user using Photon.

You should not directly use them,

instead they will get provided to you by [Photon](index.html#photon).

See also

[Settings](index.html#settings),

[Meta](index.html#meta),

[Photon](index.html#photon)

Some functionality here is bought from the [Utility](index.html#util):

See also

[Files](index.html#util-files),

[Locations](index.html#util-locations),

[Structures](index.html#util-structures),

[System](index.html#util-system)

#### Git Tool[¶](#module-tools.git "Permalink to this headline")

*class* `tools.git.``Git`(*m*, *local*, *remote\_url=None*, *mbranch=None*)[[source]](_modules/tools/git.html#Git)[¶](#tools.git.Git "Permalink to this definition")

The git tool helps to deal with git repositories.

| Parameters: | * **local** – The local folder of the repository

	+ If `None` given (default), it will be ignored if there is already a git repo at local

	+ If no git repo is found at local, a new one gets cloned from remote\_url

* **remote\_url** – The remote URL of the repository

	+ Tears down (using [`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify") with

	state set to `True`) whole application if remote\_url is set to `None` but a new clone is necessary

* **mbranch** – The repository’s main branch.

Is set to master when left to `None`

 |

`_checkout`(*treeish*)[[source]](_modules/tools/git.html#Git._checkout)[¶](#tools.git.Git._checkout "Permalink to this definition")

Helper function to checkout something

| Parameters: | **treeish** – String for ‘tag‘, ‘branch‘, or remote tracking ‘-B banch‘ |

`_get_branch`(*remotes=False*)[[source]](_modules/tools/git.html#Git._get_branch)[¶](#tools.git.Git._get_branch "Permalink to this definition")

Helper function to determine current branch

| Parameters: | **remotes** – List the remote-tracking branches |

`_get_remote`(*cached=True*)[[source]](_modules/tools/git.html#Git._get_remote)[¶](#tools.git.Git._get_remote "Permalink to this definition")

Helper function to determine remote

| Parameters: | **cached** – Use cached values or query remotes |

`_log`(*num=None*, *format=None*)[[source]](_modules/tools/git.html#Git._log)[¶](#tools.git.Git._log "Permalink to this definition")

Helper function to receive git log

| Parameters: | * **num** – Number of entries

* **format** – Use formatted output with specified format string

 |

`_pull`()[[source]](_modules/tools/git.html#Git._pull)[¶](#tools.git.Git._pull "Permalink to this definition")

Helper function to pull from remote

`branch`[¶](#tools.git.Git.branch "Permalink to this definition")

| Parameters: | **branch** – Checks out specified branch (tracking if it exists on remote).

If set to `None`, ‘master’ will be checked out |

| Returns: | The current branch

(This could also be ‘master (Detatched-Head)’ - Be warned) |

`cleanup`[¶](#tools.git.Git.cleanup "Permalink to this definition")

Commits all local changes (if any) into a working branch,

merges it with ‘master’.

Checks out your old branch afterwards.

Tears down (using [`util.system.shell\_notify()`](index.html#util.system.shell_notify "util.system.shell_notify") with

state set to `True`) whole application if conflicts are discovered

`commit`[¶](#tools.git.Git.commit "Permalink to this definition")

| Parameters: | **tag** – Checks out specified commit.

If set to `None` the latest commit will be checked out |

| Returns: | A list of all commits, descending |

`local`[¶](#tools.git.Git.local "Permalink to this definition")

| Returns: | The local folder of the repository |

`log`[¶](#tools.git.Git.log "Permalink to this definition")

| Returns: | The last 10 commit entries as dictionary |

* ‘commit’: The commit-ID

* ‘message’: First line of the commit message

`publish`[¶](#tools.git.Git.publish "Permalink to this definition")

Runs [`cleanup()`](#tools.git.Git.cleanup "tools.git.Git.cleanup") first,

then pushes the changes to the [`remote`](#tools.git.Git.remote "tools.git.Git.remote").

`remote`[¶](#tools.git.Git.remote "Permalink to this definition")

| Returns: | Current remote |

`remote_url`[¶](#tools.git.Git.remote_url "Permalink to this definition")

| Returns: | The remote URL of the repository |

`short_commit`[¶](#tools.git.Git.short_commit "Permalink to this definition")

| Returns: | A list of all commits, descending |

See also

[`commit`](#tools.git.Git.commit "tools.git.Git.commit")

`status`[¶](#tools.git.Git.status "Permalink to this definition")

| Returns: | Current repository status as dictionary: |

* ‘clean’: `True` if there are no changes `False` otherwise

* ‘untracked’: A list of untracked files (if any and not ‘clean’)

* ‘modified’: A list of modified files (if any and not ‘clean’)

* ‘deleted’: A list of deleted files (if any and not ‘clean’)

* ‘conflicting’: A list of conflicting files (if any and not ‘clean’)

`tag`[¶](#tools.git.Git.tag "Permalink to this definition")

| Parameters: | **tag** – Checks out specified tag. If set to `None` the latest

tag will be checked out |

| Returns: | A list of all tags, sorted as version numbers, ascending |

#### Mail Tool[¶](#module-tools.mail "Permalink to this headline")

*class* `tools.mail.``Mail`(*m*, *to*, *sender*, *subject=None*, *cc=None*, *bcc=None*)[[source]](_modules/tools/mail.html#Mail)[¶](#tools.mail.Mail "Permalink to this definition")

The Mail tool helps to send out mails.

| Parameters: | * **to** – Where to send the mail (['user@example.com](mailto:'user%40example.com)‘)

* **sender** – Yourself (['me@example.com](mailto:'me%40example.com)‘)

	+ set a reverse DNS entry for `example.com` so your mail does not get caught up in spamfilters.

* **subject** – The subject line

* **cc** – One or a list of CCs

* **bcc** – One or a list of BCCs

 |

`send`[¶](#tools.mail.Mail.send "Permalink to this definition")

| Returns: | A dictionary with the following:* ‘sender’: The sender

* ‘recipients’: All recipients, compiled from to, cc and bcc

* ‘result’: The [`smtplib.SMTP.sendmail()`](http://docs.python.org/3/library/smtplib.html#smtplib.SMTP.sendmail "(in Python v3.5)")-result

* ‘exception’: The exception message (if any)

 |

Note

You need to have a postfix/sendmail running

and listening on localhost.

`text`[¶](#tools.mail.Mail.text "Permalink to this definition")

| Parameters: | **text** – Add some more text |

| Returns: | All text & headers as raw mail source |

##### Mail Tool Example[¶](#mail-tool-example "Permalink to this headline")

mail.sample.yaml

|  |  |

| --- | --- |

| 

```

1

2

3

4

5

```

 | 

```

mail:

    recipient: you@example.com

    sender: me@example.com

    subject: 'Fire!'

    punchline: 'Dear Sir or Madam, I am writing to inform you about a fire in the building ...'

```

 |

mail.sample.py

|  |  |

| --- | --- |

| 

```

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

```

 | 

```

from photon import Photon

photon = Photon('mail.sample.yaml')

settings = photon.settings.get['mail']

mail = photon.mail\_handler(

    to=settings['recipient'],

    sender=settings['sender'],

    subject=settings['subject'],

    punchline=settings['punchline'],

    add\_meta=True

)

###

# Shows the message source so far

print(mail.text)

###

# Add some more text (do this as often as you like):

mail.text = '''

Dear Sir or Madam,

bla bla

No, that's too formal..

'''

###

# Guess what happens here:

mail.send

```

 |

See also

[Example Settings File](index.html#settings-file-example),

[Mail Tool Example](#tools-mail-example),

[Ping Tool Example](#tools-ping-example)

#### Ping Tool[¶](#module-tools.ping "Permalink to this headline")

*class* `tools.ping.``Ping`(*m*, *six=False*, *net\_if=None*, *num=5*, *max\_pool\_size=None*)[[source]](_modules/tools/ping.html#Ping)[¶](#tools.ping.Ping "Permalink to this definition")

The Ping tool helps to send pings, returning detailed results each probe,

and calculates a summary of all probes.

| Parameters: | * **six** – Either use `ping` or `ping6`

* **net\_if** – Specify network interface to send pings from

* **num** – How many pings to send each probe

* **max\_pool\_size** – Hosts passed to [`probe()`](#tools.ping.Ping.probe "tools.ping.Ping.probe") in form of a list,

will be processed in parallel.

Specify the maximum size of the thread pool workers here.

If skipped, the number of current CPUs is used

 |

`probe`[¶](#tools.ping.Ping.probe "Permalink to this definition")

| Parameters: | **hosts** – One or a list of hosts (URLs, IP-addresses) to send pings to* If you need to check multiple hosts, it is best to pass them together as a list.

* This will probe all hosts in parallel, with `max\_pool\_size` workers.

 |

| Returns: | A dictionary with all hosts probed as keys specified as following: |

* ‘up’: `True` or `False` depending if ping was successful

* ‘loss’: The packet loss as list (if ‘up’)

* ‘ms’: A list of times each packet sent (if ‘up’)

* ‘rtt’: A dictionary with the fields *avg*, *min*, *max* & *stddev* (if ‘up’)

`status`[¶](#tools.ping.Ping.status "Permalink to this definition")

| Returns: | A dictionary with the following: |

* ‘num’: Total number of hosts already probed

* ‘up’: Number of hosts up

* ‘down’: Number of hosts down

* ‘ratio’: Ratio between ‘up’/’down’ as float

Ratio:

* `100%` up == 1.0

* `10%` up == 0.1

* `0%` up == 0.0

##### Ping Tool Example[¶](#ping-tool-example "Permalink to this headline")

ping.sample.yaml

|  |  |

| --- | --- |

| 

```

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

```

 | 

```

hosts:

    addresses:

    - '127.0.0.1'

    - '127.0.0.2'

    - '127.0.0.3'

    urls:

    - exampla.com

    - example.com

    - exampli.com

    - examplo.com

    - examplu.com

```

 |

ping.sample.py

|  |  |

| --- | --- |

| 

```

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

```

 | 

```

from pprint import pprint

from photon import Photon

photon = Photon('ping.sample.yaml')

hosts = photon.settings.get['hosts']

ping = photon.ping\_handler()

###

# Let's start off with localhost to demonstrate the handling of the probe-function:

pprint(hosts)

a = hosts['addresses'][0]

ping.probe = a

if ping.probe[a]['up']:

    print('%s is reachable - %s ms rtt in average' %(a, ping.probe[a]['rtt']['avg']))

else:

    print('%s could not be reached!' %(a))

pprint(ping.probe)

print('-' \* 8)

###

# You can also pass a complete list to probe. This will be faster, because the list is processed in parallel.

# The status per host will be overwritten with new information if it encounters the same host again:

ping.probe = hosts['addresses']

pprint(ping.probe)

print('These are the statistics so far:')

pprint(ping.status)

print('-' \* 8)

###

# Another round of pings to demonstrate the handling of the status-function:

ping.probe = hosts['urls']

if ping.status['ratio'] <= 0.75:

    print('more than three quarters of all addresses are not reachable!!1!')

print('The statistics have changed now:')

pprint(ping.status)

```

 |

See also

[Example Settings File](index.html#settings-file-example),

[Mail Tool Example](#tools-mail-example),

[Ping Tool Example](#tools-ping-example)

#### Signal Tool[¶](#module-tools.signal "Permalink to this headline")

*class* `tools.signal.``Signal`(*m*, *pid*, *sudo=True*, *cmdd\_if\_no\_pid=None*)[[source]](_modules/tools/signal.html#Signal)[¶](#tools.signal.Signal "Permalink to this definition")

The Signal tool can send signals to processes via `kill`,

returning the results.

| Parameters: | * **pid** – Either the full path to the pidfile (e.g. `/var/run/proc.pid`)

or the pid as number

* **sudo** – Prepend sudo before command.

(Make sure to be root yourself if set to `False` or expect errors.

Further for unattended operation add the user to `sudoers` file.)

 |

`_Signal__signal`(*sig*, *verbose=None*)[¶](#tools.signal.Signal._Signal__signal "Permalink to this definition")

Helper class preventing code duplication..

| Parameters: | * **sig** – Signal to use (e.g. “HUP”, “ALRM”)

* **verbose** – Overwrite [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s verbose

 |

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid with specified pid |

`alrm`[¶](#tools.signal.Signal.alrm "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGALRM |

`hup`[¶](#tools.signal.Signal.hup "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGHUP |

`int`[¶](#tools.signal.Signal.int "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGINT with visible shell warning |

`kill`[¶](#tools.signal.Signal.kill "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGKILL with visible shell warning |

`quit`[¶](#tools.signal.Signal.quit "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGQUIT with visible shell warning |

`stop`[¶](#tools.signal.Signal.stop "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGSTOP with visible shell warning |

`usr1`[¶](#tools.signal.Signal.usr1 "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGUSR1 |

`usr2`[¶](#tools.signal.Signal.usr2 "Permalink to this definition")

| Returns: | [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m")‘s result of killing pid using SIGUSR2 |

#### Template Tool[¶](#module-tools.template "Permalink to this headline")

*class* `tools.template.``Template`(*m*, *template*, *fields=None*)[[source]](_modules/tools/template.html#Template)[¶](#tools.template.Template "Permalink to this definition")

The Template tool helps to process on strings.

| Parameters: | * **template** – The initial template to start with.

	+ If it’s value is recognized by [`util.locations.search\_location()`](index.html#util.locations.search_location "util.locations.search_location") (a.k.a is a filename) the file contents will be loaded as template.

Note

If the file is not found, you will be doing string processing

on the filename instead of the contents!

* **fields** – Initially set up fields.

Can be done later, using [`sub()`](#tools.template.Template.sub "tools.template.Template.sub")

 |

The templating-language itself are normal [Template strings](http://docs.python.org/3/library/string.html#template-strings "(in Python v3.5)"),

see there for syntax.

`raw`[¶](#tools.template.Template.raw "Permalink to this definition")

| Returns: | The raw template |

`sub`[¶](#tools.template.Template.sub "Permalink to this definition")

| Parameters: | **fields** – Set fields to substitute |

| Returns: | Substituted Template with given fields.

If no fields were set up beforehand, [`raw()`](#tools.template.Template.raw "tools.template.Template.raw") is used. |

`write`(*filename*, *append=True*, *backup=True*)[[source]](_modules/tools/template.html#Template.write)[¶](#tools.template.Template.write "Permalink to this definition")

| Parameters: | * **filename** – File to write into

* **append** – Either append to existing content (if not already included)

or completely replace filename

* **backup** – Create a backup of filename before writing.

Only applies when append is set

 |

### Utility[¶](#utility "Permalink to this headline")

This is the toolbox used by [The core](index.html#core):

See also

[Settings](index.html#settings),

[Meta](index.html#meta),

[Photon](index.html#photon)

As well as used by the [Tools](index.html#tools):

See also

[Git Tool](index.html#tools-git),

[Mail Tool](index.html#tools-mail),

[Ping Tool](index.html#tools-ping),

[Signal Tool](index.html#tools-signal)

Note

If you have no explicit reason, do **not** use the functions here directly.

* Always try to work trough [`photon.Photon`](index.html#photon.Photon "photon.Photon") and it’s handlers.

* If you discover you are repeatedly calling backend functions

consider adding a tool for that job!

#### Files[¶](#module-util.files "Permalink to this headline")

`util.files.``read_file`(*filename*)[[source]](_modules/util/files.html#read_file)[¶](#util.files.read_file "Permalink to this definition")

Reads files

| Parameters: | **filename** – The full path of the file to read |

| Returns: | The content of the file as string (if filename exists) |

Note

If filename‘s content is empty, `None` will also returned.

To check if a file really exists

use [`util.locations.search\_location()`](#util.locations.search_location "util.locations.search_location")

`util.files.``read_json`(*filename*)[[source]](_modules/util/files.html#read_json)[¶](#util.files.read_json "Permalink to this definition")

Reads json files

| Parameters: | **filename** – The full path to the json file |

| Returns: | Loaded json content as represented data structure |

`util.files.``read_yaml`(*filename*, *add\_constructor=None*)[[source]](_modules/util/files.html#read_yaml)[¶](#util.files.read_yaml "Permalink to this definition")

Reads YAML files

| Parameters: | * **filename** – The full path to the YAML file

* **add\_constructor** – A list of yaml constructors (loaders)

 |

| Returns: | Loaded YAML content as represented data structure |

See also

[`util.structures.yaml\_str\_join()`](#util.structures.yaml_str_join "util.structures.yaml_str_join"),

[`util.structures.yaml\_loc\_join()`](#util.structures.yaml_loc_join "util.structures.yaml_loc_join")

`util.files.``write_file`(*filename*, *content*)[[source]](_modules/util/files.html#write_file)[¶](#util.files.write_file "Permalink to this definition")

Writes files

| Parameters: | * **filename** – The full path of the file to write

(enclosing folder must already exist)

* **content** – The content to write

 |

| Returns: | The size of the data written |

`util.files.``write_json`(*filename*, *content*)[[source]](_modules/util/files.html#write_json)[¶](#util.files.write_json "Permalink to this definition")

Writes json files

| Parameters: | * **filename** – The full path to the json file

* **content** – The content to dump

 |

| Returns: | The size written |

`util.files.``write_yaml`(*filename*, *content*)[[source]](_modules/util/files.html#write_yaml)[¶](#util.files.write_yaml "Permalink to this definition")

Writes YAML files

| Parameters: | * **filename** – The full path to the YAML file

* **content** – The content to dump

 |

| Returns: | The size written |

#### Locations[¶](#module-util.locations "Permalink to this headline")

`util.locations.``backup_location`(*src*, *loc=None*)[[source]](_modules/util/locations.html#backup_location)[¶](#util.locations.backup_location "Permalink to this definition")

Writes Backups of locations

| Parameters: | * **src** – The source file/folder to backup

* **loc** – The target folder to backup into

The backup will be called src + [`util.system.get\_timestamp()`](#util.system.get_timestamp "util.system.get_timestamp").

\* If loc left to none, the backup gets written in the same folder like src resides in

	+ Otherwise the specified path will be used.

 |

`util.locations.``change_location`(*src*, *tgt*, *move=False*, *verbose=True*)[[source]](_modules/util/locations.html#change_location)[¶](#util.locations.change_location "Permalink to this definition")

Copies/moves/deletes locations

| Parameters: | * **src** – Source location where to copy from

* **tgt** – Target location where to copy to

	+ To backup src, set tgt explicitly to `True`. tgt will be set to src + ‘\_backup\_’ + [`util.system.get\_timestamp()`](#util.system.get_timestamp "util.system.get_timestamp") then

* **move** – Deletes original location after copy (a.k.a. move)

	+ To delete src , set tgt explicitly to `False` and move to `True` (be careful!!1!)

* **verbose** – Show warnings

 |

`util.locations.``get_locations`()[[source]](_modules/util/locations.html#get_locations)[¶](#util.locations.get_locations "Permalink to this definition")

Compiles default locations

| Returns: | A dictionary with folders as values: |

* ‘home\_dir’: Your home-directory (`~`)

* ‘call\_dir’: Where you called the first Python script from. (`argv[0]`)

* ‘conf\_dir’: The `XDG\_CONFIG\_HOME`-directory + `photon` (`~/.config/photon`)

* ‘data\_dir’: The `XDG\_DATA\_HOME`-directory + `photon` (`~/.local/share/photon`)

Note

* Both [`search\_location()`](#util.locations.search_location "util.locations.search_location") and [`make\_locations()`](#util.locations.make_locations "util.locations.make_locations") have the argument locations.

* If locations is set to `None` (by default),

it will be filled with the output of [`get\_locations()`](#util.locations.get_locations "util.locations.get_locations").

`util.locations.``make_locations`(*locations=None*, *verbose=True*)[[source]](_modules/util/locations.html#make_locations)[¶](#util.locations.make_locations "Permalink to this definition")

Creates folders

| Parameters: | * **locations** – A list of folders to create (can be a dictionary, see note below)

* **verbose** – Warn if any folders were created

 |

Note

* If locations is not a list, but a dictionary,

all values in the dictionary will be used

(as specified in [`util.structures.to\_list()`](#util.structures.to_list "util.structures.to_list"))

* If locations is set to `None` (by default),

it will be filled with the output of [`get\_locations()`](#util.locations.get_locations "util.locations.get_locations").

`util.locations.``search_location`(*loc*, *locations=None*, *critical=False*, *create\_in=None*, *verbose=True*)[[source]](_modules/util/locations.html#search_location)[¶](#util.locations.search_location "Permalink to this definition")

Locates files with a twist:

> 

> * Check the existence of a file using the full path in loc

> * Search for the filename loc in locations

> * Create it’s enclosing folders if the file does not exist. use create\_in

> 

> 

> 

| Parameters: | * **loc** – Filename to search

* **locations** – A list of possible locations to search within

(can be a dictionary, see note below)

* **critical** – Tears down (using [`util.system.shell\_notify()`](#util.system.shell_notify "util.system.shell_notify") with

state set to `True`) whole application if file was not found

* **create\_in** – If loc was not found, the folder create\_in is created.

If locations is a dictionary, create\_in can also specify

a key of locations. The value will be used then.

* **verbose** – Pass verbose flag to [`make\_locations()`](#util.locations.make_locations "util.locations.make_locations")

 |

| Returns: | The full path of loc in matched location |

Note

* If locations is not a list, but a dictionary,

all values in the dictionary will be used

(as specified in [`util.structures.to\_list()`](#util.structures.to_list "util.structures.to_list"))

* If locations is set to `None` (by default),

it will be filled with the output of [`get\_locations()`](#util.locations.get_locations "util.locations.get_locations").

#### Structures[¶](#module-util.structures "Permalink to this headline")

`util.structures.``dict_merge`(*o*, *v*)[[source]](_modules/util/structures.html#dict_merge)[¶](#util.structures.dict_merge "Permalink to this definition")

Recursively climbs through dictionaries and merges them together.

| Parameters: | * **o** – The first dictionary

* **v** – The second dictionary

 |

| Returns: | A dictionary (who would have guessed?) |

Note

Make sure o & v are indeed dictionaries,

bad things will happen otherwise!

`util.structures.``to_list`(*i*, *use\_keys=False*)[[source]](_modules/util/structures.html#to_list)[¶](#util.structures.to_list "Permalink to this definition")

Converts items to a list.

| Parameters: | * **i** – Item to convert

	+ If i is `None`, the result is an empty list

	+ If i is ‘string’, the result won’t be `['s', 't', 'r',...]` rather more like `['string']`

	+ If i is a nested dictionary, the result will be a flattened list.

* **use\_keys** – If i is a dictionary, use the keys instead of values

 |

| Returns: | All items in i as list |

`util.structures.``yaml_loc_join`(*l*, *n*)[[source]](_modules/util/structures.html#yaml_loc_join)[¶](#util.structures.yaml_loc_join "Permalink to this definition")

YAML loader to join paths

The keywords come directly from [`util.locations.get\_locations()`](#util.locations.get_locations "util.locations.get_locations").

See there!

| Returns: | A path seperator (`/`) joined string with keywords extended. Used in [`settings.Settings.load()`](index.html#settings.Settings.load "settings.Settings.load") |

See also

The YAML files mentioned in [Example Settings File](index.html#settings-file-example),

[Mail Tool Example](index.html#tools-mail-example),

[Ping Tool Example](index.html#tools-ping-example)

`util.structures.``yaml_str_join`(*l*, *n*)[[source]](_modules/util/structures.html#yaml_str_join)[¶](#util.structures.yaml_str_join "Permalink to this definition")

YAML loader to join strings

The keywords are as following:

* hostname: Your hostname (from [`util.system.get\_hostname()`](#util.system.get_hostname "util.system.get_hostname"))

* timestamp: Current timestamp (from [`util.system.get\_timestamp()`](#util.system.get_timestamp "util.system.get_timestamp"))

| Returns: | A non character joined string with keywords extended. Used in [`settings.Settings.load()`](index.html#settings.Settings.load "settings.Settings.load") |

Note

Be careful with timestamps when using a config in [Settings](index.html#settings).

See also

The YAML files mentioned in [Example Settings File](index.html#settings-file-example),

[Mail Tool Example](index.html#tools-mail-example),

[Ping Tool Example](index.html#tools-ping-example)

#### System[¶](#module-util.system "Permalink to this headline")

`util.system.``get_hostname`()[[source]](_modules/util/system.html#get_hostname)[¶](#util.system.get_hostname "Permalink to this definition")

Determines the current hostname by probing `uname -n`.

Falls back to `hostname` in case of problems.

Tears down (using [`util.system.shell\_notify()`](#util.system.shell_notify "util.system.shell_notify") with

state set to `True`) whole application if both failed (usually they don’t but consider

this if you are debugging weird problems..)

| Returns: | The hostname as string. Domain parts will be split off |

`util.system.``get_timestamp`(*time=True*, *precice=False*)[[source]](_modules/util/system.html#get_timestamp)[¶](#util.system.get_timestamp "Permalink to this definition")

What time is it?

| Parameters: | * **time** – Append `-%H.%M.%S` to the final string.

* **precice** – Append `-%f` to the final string.

Is only recognized when time is set to `True`

 |

| Returns: | A timestamp string of now in the format `%Y.%m.%d-%H.%M.%S-%f` |

See also

[strftime.org](http://strftime.org/) is awesome!

`util.system.``shell_notify`(*msg*, *state=False*, *more=None*, *exitcode=None*, *verbose=True*)[[source]](_modules/util/system.html#shell_notify)[¶](#util.system.shell_notify "Permalink to this definition")

A pretty long wrapper for a [`print()`](http://docs.python.org/3/library/functions.html#print "(in Python v3.5)") function.

But this [`print()`](http://docs.python.org/3/library/functions.html#print "(in Python v3.5)") is the only one in Photon.

Note

This method is just a helper method within photon.

If you need this functionality use [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m") instead

| Parameters: | * **msg** – The message to show

* **state** – The message will be prefixed with [state]

	+ If `False` (default): Prefixed with ~

	+ If `None`: Prefixed with [WARNING]

	+ If `True`: Prefixed with [FATAL] and the exitcode will be set (see below)

* **more** – Something to add to the message (see below)

	+ Anything you have. Just for further information.

	+ Will be displayed after the message, pretty printed using [`pprint.pformat()`](http://docs.python.org/3/library/pprint.html#pprint.pformat "(in Python v3.5)")

* **exitcode** – Tears down (using [`util.system.shell\_notify()`](#util.system.shell_notify "util.system.shell_notify") with

state set to `True`) whole application with given code

* **verbose** – Show message or not (see below)

	+ If set to `False`, you can use [`shell\_notify()`](#util.system.shell_notify "util.system.shell_notify") for the dictionary it returns.

	+ Will be overruled if exitcode is set.

 |

| Returns: | A dictionary containing untouched msg, more and verbose |

`util.system.``shell_run`(*cmd*, *cin=None*, *cwd=None*, *timeout=10*, *critical=True*, *verbose=True*)[[source]](_modules/util/system.html#shell_run)[¶](#util.system.shell_run "Permalink to this definition")

Runs a shell command within a controlled environment.

Note

This method is just a helper method within photon.

If you need this functionality use [`photon.Photon.m()`](index.html#photon.Photon.m "photon.Photon.m") instead

| Parameters: | * **cmd** – The command to run

	+ A string one would type into a console like **git push -u origin master**.

	+ Will be split using [`shlex.split()`](http://docs.python.org/3/library/shlex.html#shlex.split "(in Python v3.5)").

	+ It is possible to use a list here, but then no splitting is done.

* **cin** – Add something to stdin of cmd

* **cwd** – Run cmd insde specified current working directory

* **timeout** – Catch infinite loops (e.g. `ping`).

Exit after timeout seconds

* **critical** – If set to `True`: Tears down (using [`util.system.shell\_notify()`](#util.system.shell_notify "util.system.shell_notify") with

state set to `True`) whole application on failure of cmd

* **verbose** – Show messages and warnings

 |

| Returns: | A dictionary containing the results from

running cmd with the following:

* ‘command’: cmd

* ‘stdin’: cin (If data was set in cin)

* ‘cwd’: cwd (If cwd was set)

* ‘exception’: exception message (If an exception was thrown)

* ‘timeout’: timeout (If a timeout exception was thrown)

* ‘stdout’: List from stdout (If any)

* ‘stderr’: List from stderr (If any)

* ‘returncode’: The returncode (If not any exception)

* ‘out’: The most urgent message as joined string. (‘exception’ > ‘stderr’ > ‘stdout’)

 |

I am lost:

* [Index](genindex.html)

* [Module Index](py-modindex.html)

* [Search Page](search.html)

Info[¶](#module-info "Permalink to this headline")

--------------------------------------------------

The *info* file

The *info* file is not vital to Photon, it just helps to share common

values between documentation and the package builder (*setup* file).

`info.``author`()[[source]](_modules/info.html#author)[¶](#info.author "Permalink to this definition")

| Returns: | The main author (last entry of [`contributors()`](#info.contributors "info.contributors")) |

`info.``contributors`()[[source]](_modules/info.html#contributors)[¶](#info.contributors "Permalink to this definition")

| Returns: | A list of all contributors |

`info.``contributors_str`()[[source]](_modules/info.html#contributors_str)[¶](#info.contributors_str "Permalink to this definition")

| Returns: | The [`contributors()`](#info.contributors "info.contributors") as comma joined string |

`info.``email`()[[source]](_modules/info.html#email)[¶](#info.email "Permalink to this definition")

| Returns: | Main [`author()`](#info.author "info.author")‘s mail |

`info.``pkg_name`()[[source]](_modules/info.html#pkg_name)[¶](#info.pkg_name "Permalink to this definition")

| Returns: | The package name (on pypi) |

`info.``release`()[[source]](_modules/info.html#release)[¶](#info.release "Permalink to this definition")

| Returns: | Current release string |

| Current: | 0.4 |

`info.``url`()[[source]](_modules/info.html#url)[¶](#info.url "Permalink to this definition")

| Returns: | The repo url (on github) |

`info.``version`()[[source]](_modules/info.html#version)[¶](#info.version "Permalink to this definition")

| Returns: | Current version string |

| Current: | 0.4 (Release: 0.4) |

