Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More pre-commit hooks #760

Merged
merged 5 commits into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
line_length = 120
multi_line_output = 3
include_trailing_comma = True
known_third_party = Crypto,PyQt5,alembic,appdirs,bitshares,bitsharesapi,bitsharesbase,ccxt,click,docker,events,grapheneapi,graphenecommon,pytest,pywaves,requests,ruamel,setuptools,sqlalchemy,uptick,websocket
50 changes: 45 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,55 @@ repos:
- id: check-yaml
- id: end-of-file-fixer
- id: no-commit-to-branch
- id: flake8
- id: debug-statements
- id: check-merge-conflict

- repo: https://github.com/ambv/black
rev: 19.10b0
hooks:
- id: black
language_version: python3

- repo: https://github.com/myint/docformatter
rev: v1.3.1
hooks:
- id: docformatter
args: [-i, --wrap-summaries=120, --wrap-descriptions=120, --pre-summary-newline]

- repo: https://github.com/humitos/mirrors-autoflake
rev: v1.1
hooks:
- id: autoflake
args: ['--in-place', '--remove-all-unused-imports', '--remove-unused-variable']

- repo: https://gitlab.com/pycqa/flake8
rev: 3.7.9
hooks:
- id: flake8
additional_dependencies: [
'pep8-naming',
'flake8-comprehensions',
'flake8-bugbear',
'flake8-mutable',
'flake8-pytest-style',
'flake8-variables-names',
'flake8-class-attributes-order',
'dlint',
]

- repo: https://github.com/asottile/seed-isort-config
rev: v2.1.0
hooks:
- id: seed-isort-config

- repo: https://github.com/timothycrosley/isort
rev: 4.3.21
hooks:
- id: isort

- repo: https://github.com/ambv/black
rev: 19.10b0
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.770
hooks:
- id: black
language_version: python3
- id: mypy
args: [--ignore-missing-imports, --disallow-incomplete-defs]
exclude: 'tests'
29 changes: 13 additions & 16 deletions dexbot/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
import click # noqa: E402
import graphenecommon.exceptions
from bitshares.market import Market
from uptick.decorators import online

from dexbot.cli_conf import SYSTEMD_SERVICE_NAME, get_whiptail, setup_systemd
from dexbot.config import DEFAULT_CONFIG_FILE, Config
from dexbot.helper import initialize_data_folders, initialize_orders_log
from dexbot.storage import Storage
from dexbot.ui import chain, configfile, reset_nodes, unlock, verbose
from uptick.decorators import online

from . import errors, helper
from .cli_conf import configure_dexbot, dexbot_service_running
Expand Down Expand Up @@ -64,9 +65,7 @@ def main(ctx, **kwargs):
@click.pass_context
@reset_nodes
def resetnodes(ctx):
"""
Reset nodes to the default list, use -s option to sort
"""
"""Reset nodes to the default list, use -s option to sort."""
log.info("Resetting node list in config.yml to default list")
log.info("To sort nodes by timeout, use: `dexbot-cli -s 2 resetnodes`")

Expand All @@ -78,8 +77,7 @@ def resetnodes(ctx):
@unlock
@verbose
def run(ctx):
""" Continuously run the worker
"""
"""Continuously run the worker."""
if ctx.obj['pidfile']:
with open(ctx.obj['pidfile'], 'w') as fd:
fd.write(str(os.getpid()))
Expand Down Expand Up @@ -120,8 +118,7 @@ def run(ctx):
@chain
@unlock
def runservice():
""" Continuously run the worker as a service
"""
"""Continuously run the worker as a service."""
if dexbot_service_running():
click.echo("Stopping dexbot daemon")
os.system('systemctl --user stop dexbot')
Expand All @@ -139,8 +136,7 @@ def runservice():
@chain
@unlock
def configure(ctx):
""" Interactively configure dexbot
"""
"""Interactively configure dexbot."""
# Make sure the dexbot service isn't running while we do the config edits
if dexbot_service_running():
click.echo("Stopping dexbot daemon")
Expand Down Expand Up @@ -190,8 +186,7 @@ def cancel(ctx, market, account):

@click.argument('worker_name')
def drop_state(worker_name):
""" Drop state of the worker (sqlite data)
"""
"""Drop state of the worker (sqlite data)"""
click.echo('Dropping state for {}'.format(worker_name))
Storage.clear_worker_data(worker_name)
time.sleep(1)
Expand All @@ -202,10 +197,12 @@ def worker_job(worker, job):


if __name__ == '__main__':
""" Add freeze_support for when a program which uses multiprocessing (node_manager) has been
frozen to produce a Windows executable. If the freeze_support() line is omitted
then trying to run the frozen executable will raise RuntimeError. Calling
freeze_support() has no effect when invoked on any operating system other than Windows.
"""
Add freeze_support for when a program which uses multiprocessing (node_manager) has been frozen to produce a Windows
executable.

If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError. Calling
freeze_support() has no effect when invoked on any operating system other than Windows.
"""
freeze_support()
main()
78 changes: 42 additions & 36 deletions dexbot/cli_conf.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""
A module to provide an interactive text-based tool for dexbot configuration
The result is dexbot can be run without having to hand-edit config files.
If systemd is detected it will offer to install a user service unit (under ~/.local/share/systemd)
This requires a per-user systemd process to be running
A module to provide an interactive text-based tool for dexbot configuration The result is dexbot can be run without
having to hand-edit config files. If systemd is detected it will offer to install a user service unit (under
~/.local/share/systemd) This requires a per-user systemd process to be running.

Requires the 'whiptail' tool for text-based configuration (so UNIX only)
if not available, falls back to a line-based configurator ("NoWhiptail")
Expand All @@ -21,8 +20,9 @@
import subprocess
import sys

import dexbot.helper
from bitshares.account import Account

import dexbot.helper
from dexbot.config_validator import ConfigValidator
from dexbot.node_manager import get_sorted_nodelist
from dexbot.strategies.base import StrategyBase
Expand All @@ -43,7 +43,7 @@
while tag in tags_so_far:
tag = tag + str(i)
i += 1
tags_so_far.add(tag)
tags_so_far.append(tag)
STRATEGIES.append({'tag': tag, 'class': module, 'name': desc})

SYSTEMD_SERVICE_NAME = os.path.expanduser("~/.local/share/systemd/user/dexbot.service")
Expand All @@ -66,17 +66,17 @@


def select_choice(current, choices):
""" For the radiolist, get us a list with the current value selected
"""
"""For the radiolist, get us a list with the current value selected."""
return [(tag, text, (current == tag and "ON") or "OFF") for tag, text in choices]


def process_config_element(element, whiptail, worker_config):
""" Process an item of configuration metadata, display a widget as appropriate
"""
Process an item of configuration metadata, display a widget as appropriate.

:param base_config.ConfigElement element: config element
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param collections.OrderedDict worker_config: the config dictionary for this worker
:param base_config.ConfigElement element: config element
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param collections.OrderedDict worker_config: the config dictionary for this worker
"""
if element.description:
title = '{} - {}'.format(element.title, element.description)
Expand Down Expand Up @@ -125,8 +125,7 @@ def process_config_element(element, whiptail, worker_config):


def dexbot_service_running():
""" Return True if dexbot service is running
"""
"""Return True if dexbot service is running."""
cmd = 'systemctl --user status dexbot'
output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in output.stdout.readlines():
Expand All @@ -136,10 +135,11 @@ def dexbot_service_running():


def setup_systemd(whiptail, config):
""" Setup systemd unit to auto-start dexbot
"""
Setup systemd unit to auto-start dexbot.

:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param dexbot.config.Config config: dexbot config
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param dexbot.config.Config config: dexbot config
"""
if not os.path.exists("/etc/systemd"):
return # No working systemd
Expand Down Expand Up @@ -175,11 +175,12 @@ def setup_systemd(whiptail, config):


def get_strategy_tag(strategy_class):
""" Obtain tag for a strategy
"""
Obtain tag for a strategy.

:param str strategy_class: strategy class name, example: dexbot.strategies.foo_bar
:param str strategy_class: strategy class name, example: dexbot.strategies.foo_bar

It may seems that tags may be common across strategies, but it is not. Every strategy must use unique tag.
It may seems that tags may be common across strategies, but it is not. Every strategy must use unique tag.
"""
for strategy in STRATEGIES:
if strategy_class == strategy['class']:
Expand All @@ -188,11 +189,12 @@ def get_strategy_tag(strategy_class):


def configure_worker(whiptail, worker_config, validator):
""" Single worker configurator
"""
Single worker configurator.

:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param collections.OrderedDict worker_config: tohe config dictionary for this worker
:param dexbot.config_validator.ConfigValidator validator: dexbot config validator
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param collections.OrderedDict worker_config: tohe config dictionary for this worker
:param dexbot.config_validator.ConfigValidator validator: dexbot config validator
"""
# By default always editing
editing = True
Expand Down Expand Up @@ -263,9 +265,10 @@ def configure_worker(whiptail, worker_config, validator):


def configure_dexbot(config, ctx):
""" Main `cli configure` entrypoint
"""
Main `cli configure` entrypoint.

:param dexbot.config.Config config: dexbot config
:param dexbot.config.Config config: dexbot config
"""
whiptail = get_whiptail('DEXBot configure')
workers = config.get('workers', {})
Expand Down Expand Up @@ -391,11 +394,12 @@ def configure_dexbot(config, ctx):


def add_account(validator, whiptail):
""" "Add account" dialog
"""
"Add account" dialog.

:param dexbot.config_validator.ConfigValidator validator: dexbot config validator
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:return str: user-supplied account name
:param dexbot.config_validator.ConfigValidator validator: dexbot config validator
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:return str: user-supplied account name
"""

account = whiptail.prompt("Your Account Name")
Expand All @@ -420,22 +424,24 @@ def add_account(validator, whiptail):


def del_account(whiptail, bitshares_instance):
""" Delete account from the wallet
"""
Delete account from the wallet.

:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param bitshares.BitShares bitshares_instance: an instance of BitShares class
:param whiptail.Whiptail whiptail: instance of Whiptail or NoWhiptail
:param bitshares.BitShares bitshares_instance: an instance of BitShares class
"""
account = whiptail.prompt("Account Name")
wallet = bitshares_instance.wallet
wallet.removeAccount(account)


def list_accounts(bitshares_instance):
""" Get all accounts installed in local wallet in format suitable for Whiptail.menu()
"""
Get all accounts installed in local wallet in format suitable for Whiptail.menu()

Returning format is compatible both with Whiptail and NoWhiptail.
Returning format is compatible both with Whiptail and NoWhiptail.

:return: list of tuples (int, 'account_name - key_type')
:return: list of tuples (int, 'account_name - key_type')
"""
accounts = []
pubkeys = bitshares_instance.wallet.getPublicKeys(current=True)
Expand Down
Loading