Skip to content

Commit

Permalink
Asyncio-based machinery (#1)
Browse files Browse the repository at this point in the history
* Asyncio-based machinery
* Updated dispatcher for newest RTM client
* Refactored message object and dispatcher
* CircleCI configuration
  • Loading branch information
pirogoeth authored Nov 8, 2019
1 parent f99bec1 commit 23c3567
Show file tree
Hide file tree
Showing 46 changed files with 2,022 additions and 1,395 deletions.
81 changes: 81 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
version: 2.1

workflows:
version: 2
workflow:
jobs:
- lint-flake8
- test-python37
- test-python38

commands:
tox:
description: "Execute tox env"
parameters:
env:
type: "string"
default: "py37"
steps:
- restore_cache:
keys:
- venv-{{ .Environment.CIRCLE_STAGE }}-{{ .Environment.cacheVer }}-{{ checksum "requirements.txt" }}-{{ checksum "setup.py" }}
- run:
name: "setup up test environment"
command: |
mkdir ./test-reports
mkdir ./test-reports/coverage
test ! -d venv && pip install virtualenv && virtualenv venv
source venv/bin/activate
pip install -U setuptools tox codecov
- save_cache:
key: venv-{{ .Environment.CIRCLE_STAGE }}-{{ .Environment.cacheVer }}-{{ checksum "requirements.txt" }}-{{ checksum "setup.py" }}
paths:
- venv
- run:
name: "tox: << parameters.env >>"
command: |
source venv/bin/activate
tox -e << parameters.env >>
- store_artifacts:
path: test-reports
- store_test_results:
path: test-reports

executors:
python:
parameters:
version:
type: "string"
default: "3.8"
docker:
- image: circleci/python:<< parameters.version >>
environment:
PYTHON_VERSION: "<< parameters.version >>"

jobs:
test-python37:
executor:
name: "python"
version: "3.7"
steps:
- checkout
- tox:
env: py37

test-python38:
executor:
name: "python"
version: "3.8"
steps:
- checkout
- tox:
env: py38

lint-flake8:
executor:
name: "python"
version: "3.8"
steps:
- checkout
- tox:
env: flake8
48 changes: 48 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
default_language_version:
python: python3.7

fail_fast: true

repos:
- repo: https://github.com/ambv/black
rev: 19.3b0
hooks:
- id: black

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.3
hooks:
- id: check-added-large-files
- id: check-ast
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: check-yaml
args:
- --unsafe
- id: debug-statements
- id: end-of-file-fixer
- id: fix-encoding-pragma
- id: flake8
args:
- --exclude=docs/*,tests/*
- --max-line-length=131
- --ignore=E203
- id: forbid-new-submodules
- id: mixed-line-ending
args:
- --fix=lf
- id: no-commit-to-branch
args:
- -b master
- id: trailing-whitespace

- repo: https://github.com/Lucas-C/pre-commit-hooks
rev: v1.1.6
hooks:
- id: remove-tabs

- repo: https://github.com/Lucas-C/pre-commit-hooks-safety
rev: v1.1.0
hooks:
- id: python-safety-dependencies-check
23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

17 changes: 12 additions & 5 deletions machine/__about__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
# -*- coding: utf-8 -*-
__all__ = [
'__title__', '__description__', '__uri__', '__version__', '__author__',
'__email__', '__license__', '__copyright__'
"__title__",
"__description__",
"__uri__",
"__version__",
"__author__",
"__email__",
"__license__",
"__copyright__",
]

__title__ = "slack-machine"
__title__ = "aio-slack-machine"
__description__ = "A sexy, simple, yet powerful and extendable Slack bot"
__uri__ = "https://github.com/DandyDev/slack-machine"

__version_info__ = (0, 18, 0)
__version__ = '.'.join(map(str, __version_info__))
__version_info__ = (0, 19, 0)
__version__ = ".".join(map(str, __version_info__))

__author__ = "Daan Debie"
__email__ = "[email protected]"
Expand Down
53 changes: 46 additions & 7 deletions machine/bin/run.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,56 @@
# -*- coding: utf-8 -*-

import asyncio
import signal
import sys
import os
from functools import partial

from loguru import logger

from machine import Machine
from machine.utils.text import announce


def main():
# When running this function as console entry point, the current working dir is not in the
# Python path, so we have to add it
sys.path.insert(0, os.getcwd())
bot = Machine()
try:
bot.run()
except KeyboardInterrupt:
announce("Thanks for playing!")
sys.exit(0)

loop = asyncio.new_event_loop()

# Handle INT and TERM by gracefully halting the event loop
for s in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(s, partial(prepare_to_stop, loop))

bot = Machine(loop=loop)
loop.run_until_complete(bot.run())

# Once `prepare_to_stop` returns, `loop` is guaranteed
# to be stopped.
prepare_to_stop(loop)

loop.close()
sys.exit(0)


def prepare_to_stop(loop: asyncio.AbstractEventLoop):
# Calling `cancel` on each task in the active loop causes
# a `CancelledError` to be thrown into each wrapped coroutine during
# the next iteration, which _should_ halt execution of the coroutine
# if the coroutine does not explicitly suppress the `CancelledError`.
for task in asyncio.Task.all_tasks(loop=loop):
task.cancel()

# Using `ensure_future` on the `stop` coroutine here ensures that
# the `stop` coroutine is the last thing to run after each cancelled
# task has its `CancelledError` emitted.
asyncio.ensure_future(stop(), loop=loop)
loop.run_forever()


# @asyncio.coroutine
async def stop():
loop = asyncio.get_event_loop()
logger.info("Thanks for playing!")

loop.stop()
Loading

0 comments on commit 23c3567

Please sign in to comment.