Welcome to githubissuesbot’s documentation!

Contents:

Introduction

GitHub Issues Bot for MI-PYT in FIT CTU in Prague. The program has two modes: console and web app. In console mode it labels issues (checks new one with the specified frequency) in the given repository by the issues itself and their comments, and in web mode the program labels new opened issue as soon as possible (by webhook notification and so one by one).

Link to testpypi.

Link to Read The Docs.

Requirements

Manual

Installation

Install package by typing the command:

python -m pip install --extra-index-url https://testpypi.python.org/pypi githubissuesbot

Running app

Then you may run the app by typing

python -m githubissuesbot or just githubissuesbot.

Type --help for command line manual.

Creating config files

Read how to generate configuration files by typing

python -m githubissuesbot genconf --help

or githubissuesbot genconf --help.

The app requires the following configuration files: auth.cfg (with GitHub personal access token), label.cfg (with available labels and the appropriate rules as regular expressions), secret.cfg (with webhook secret token) and web.cfg (web app uses it for reading info about other configuration files).

If you want to deploy this app on some host (tested on pythonanywhere), don’t forget to manually fix web_config_file value in web_app.py on line 39.

Type --help for command line manual.

Running tests

You may run tests by typing python setup.py test.

You must have file ./tests/fixtures/auth.cfg.truetoken.test, if you want to rewrite betamax cassettes.

Documentation

Go to package directory and type

pip install -r docs/requirements.txt

Then type the following command in order to generate documentation in HTML

cd docs && make html

And verify code and documentation consistency by typing

cd docs && make doctest

You can reindex package modules by typing from the package directory

python -m sphinx.apidoc -f -o docs githubissuesbot

githubissuesbot

githubissuesbot package

Submodules

githubissuesbot.command_line module

githubissuesbot.command_line.create_web_config(new_dir, filename)[source]

The function searches for the specified filename in config directory of this module and, if that file exists, copies it to the new_dir directory.

Parameters:
  • new_dir (str) – Config file filename will be created in this directory.
  • filename (str) – Config file to copy.
githubissuesbot.command_line.main()[source]

Handles command line arguments.

githubissuesbot.github_bot module

class githubissuesbot.github_bot.GitHubBot(auth_file, label_file, url, default_label, session=None, auth_token=None)[source]

Bases: object

The class realizes GitHub bot functionality such as labeling all issues at once or processing them by one.

url

str

Url of issues in the specified repo (ex.: https://api.github.com/repos/<username>/<repo>/issues)).

default_label

str

If no rule may be applied to issue, an issue will be labeled by this string

If you have token in auth.cfg.sample file and labeling rules in label.cfg file, you may call this class the following way

from githubissuesbot import github_bot

bot = github_bot.GitHubBot(auth_cfg_file,
             label_cfg_file,
             "https://api.github.com/repos/my-username/my-repo/issues",
             "default")

And access its url and default label by invoking

>>> bot.url
'https://api.github.com/repos/my-username/my-repo/issues'
>>> bot.default_label
'default'

You can also send GitHub personal access token as parameter and in this case doesn’t matter what you have in auth_cfg_file

from githubissuesbot import github_bot

bot = github_bot.GitHubBot(auth_cfg_file,
             label_cfg_file,
             "https://api.github.com/repos/my-username/my-repo/issues",
             "default",
             auth_token='mypersonalaccesstoken')
print(bot._token)
mypersonalaccesstoken
label_all_issues(label_comments)[source]

Call this function to label all unlabeled issues at once.

Parameters:label_comments (bool) – Set it to True, if the program must use comments (in addition to issues themselves) for labeling.
Returns:Dictionary with numbers of issues as keys and lists of assigned labels together with POST HTTP status code as values (ex.: results[15][0] gives labels of the 15-th issue, and results[15][1] gives POST status code of the same issue (if labeling on GitHub was successful or not)).
Return type:dict
label_issue(issue_info)[source]

Call this function to label only the given unlabeled issue.

Parameters:issue_info (json) – Issue information in JSON format. Example issue JSON: https://developer.github.com/v3/activity/events/types/#issuesevent
Returns:List of assigned labels together with POST HTTP status code (if labeling on GitHub was successful or not). Example: results[0] gives labels of the issue, and results[1] gives POST status code of the same issue).
Return type:list

githubissuesbot.web_app module

githubissuesbot.web_app.convert_markdown(text)[source]

Custom Flask template filter. Converts markdown text to safe html.

Parameters:text (str) – Markdown formatted text as Unicode or ASCII string.
githubissuesbot.web_app.hook()[source]

The function handles labeling GitHub issues by receiving GitHub webhook POST requests. See https://developer.github.com/webhooks/

First, webhook signature (in header “X-Hub-Signature”) is verified for security reasons as we don’t want to handle undesirable requests. Then github_bot.GitHubBot() class is used for issue labeling.

githubissuesbot.web_app.index()[source]

This function generates HTML formatted main page from README.md.

githubissuesbot.web_app.run_local_web(web_config)[source]

Runs local Flask server.

Parameters:web_config (str) – File with main web configuration. If None, the default file web.cfg will be used.
githubissuesbot.web_app.verify_signature(secret: str, signature: str, resp_body) → None[source]

Verify HMAC-SHA1 signature of the given response body. The signature is expected to be in format sha1=<hex-digest>.

Parameters:
Raises:
  • Exception – Error: signature is malformed.
  • Exception – Error: expected type sha1.
  • Exception – Error: digests do not match.

Verification of bad signature

bad_signature = 'sha1=18fdf73c44d3a4c72b55b382c494f35a25b3a6e5'
web_app.verify_signature(fake_secret, bad_signature, body)
Traceback (most recent call last):
    ...
Exception: Error: digests do not match

The following signature is broken: there is no ‘=’ between hash type and signature itself

bad_signature2 = 'sha118fdf73c44d3a4c72b55b382c494f35a25b3a6e5'
web_app.verify_signature(fake_secret, bad_signature2, body)
Traceback (most recent call last):
    ...
Exception: Error: signature is malformed

The last signature is hashed by unsupported hash type (sha2)

bad_signature3 = 'sha2=18fdf73c44d3a4c72b55b382c494f35a25b3a6e5'
web_app.verify_signature(fake_secret, bad_signature3, body)
Traceback (most recent call last):
    ...
Exception: Error: expected type sha1, but got sha2

Module contents

class githubissuesbot.GitHubBot(auth_file, label_file, url, default_label, session=None, auth_token=None)[source]

Bases: object

The class realizes GitHub bot functionality such as labeling all issues at once or processing them by one.

url

str

Url of issues in the specified repo (ex.: https://api.github.com/repos/<username>/<repo>/issues)).

default_label

str

If no rule may be applied to issue, an issue will be labeled by this string

If you have token in auth.cfg.sample file and labeling rules in label.cfg file, you may call this class the following way

from githubissuesbot import github_bot

bot = github_bot.GitHubBot(auth_cfg_file,
             label_cfg_file,
             "https://api.github.com/repos/my-username/my-repo/issues",
             "default")

And access its url and default label by invoking

>>> bot.url
'https://api.github.com/repos/my-username/my-repo/issues'
>>> bot.default_label
'default'

You can also send GitHub personal access token as parameter and in this case doesn’t matter what you have in auth_cfg_file

from githubissuesbot import github_bot

bot = github_bot.GitHubBot(auth_cfg_file,
             label_cfg_file,
             "https://api.github.com/repos/my-username/my-repo/issues",
             "default",
             auth_token='mypersonalaccesstoken')
print(bot._token)
mypersonalaccesstoken
label_all_issues(label_comments)[source]

Call this function to label all unlabeled issues at once.

Parameters:label_comments (bool) – Set it to True, if the program must use comments (in addition to issues themselves) for labeling.
Returns:Dictionary with numbers of issues as keys and lists of assigned labels together with POST HTTP status code as values (ex.: results[15][0] gives labels of the 15-th issue, and results[15][1] gives POST status code of the same issue (if labeling on GitHub was successful or not)).
Return type:dict
label_issue(issue_info)[source]

Call this function to label only the given unlabeled issue.

Parameters:issue_info (json) – Issue information in JSON format. Example issue JSON: https://developer.github.com/v3/activity/events/types/#issuesevent
Returns:List of assigned labels together with POST HTTP status code (if labeling on GitHub was successful or not). Example: results[0] gives labels of the issue, and results[1] gives POST status code of the same issue).
Return type:list

Indices and tables