Skip to content

Commit

Permalink
Replace slacker with python slackclient (#44)
Browse files Browse the repository at this point in the history
Remove Slacker and replace with Python SlackClient

Since Slacker is now deprecated, we should be moving towards the correct
way to interact with the Slack API. This is a rather lengthy commit,
larger than I had hoped, but it removes Slacker for Python SlackClient.

I have not successfully ran the ExampleComponent, specifically it is not
writing to the channel it is in. I'll be investigating that before
submitting this branch as a PR.

Fixed example_component to be working with new python_slackclient

Completly removed Slacker from dependencies. The "hello" event one
receives from Slack does not dictate a channel, so I removed that from
the example_component. Additionally, I was getting rate limited when
testing the example_component due to responding to a user typing, so I
also removed that.

Replaced unittest with pytest and overhauled libraries used and Makefile.

Ended up adding a ton of static analyzers and other libraries to help improve the quality of the code. Improved the circleci config as well and added a badge to the README.md
  • Loading branch information
GregHilston authored Aug 21, 2020
1 parent 0f9b724 commit 33c279a
Show file tree
Hide file tree
Showing 20 changed files with 655 additions and 475 deletions.
44 changes: 11 additions & 33 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,50 +1,28 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/python:3.6.4

# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/postgres:9.4
- image: circleci/python:3.8.2-buster

working_directory: ~/repo
working_directory: ~/project

steps:
- checkout

# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "requirements.txt" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- restore_cache: # Find a cache corresponding to this specific requirements_dev.txt checksum. When this file has changed this lookup will fail which is good and intended
key: deps9-{{ .Branch }}-{{ checksum "requirements_dev.txt" }}

- run:
name: install dependencies
command: |
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
pip install -r requirements_dev.txt
- save_cache:
- save_cache: # cache Python dependencies using checksum of requirements_dev.txt as the cache-key
key: deps9-{{ .Branch }}-{{ checksum "requirements_dev.txt" }}
paths:
- ./venv
key: v1-dependencies-{{ checksum "requirements.txt" }}

# run tests!
# this example uses Django's built-in test-runner
# other common Python testing frameworks include pytest and nose
# https://pytest.org
# https://nose.readthedocs.io
- "venv"

- run:
name: run tests
name: test
command: |
. venv/bin/activate
python3 tests_simple_slack_bot.py
make magic
5 changes: 5 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[flake8]
ignore = E203, E266, E501, W503, F403, F401
max-line-length = 88
max-complexity = 18
select = B,C,E,F,W,T4,B9
7 changes: 7 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[settings]
multi_line_output = 3
include_trailing_comma = True
force_grid_wrap = 0
use_parentheses = True
ensure_newline_before_comments = True
line_length = 88
2 changes: 2 additions & 0 deletions .pydocstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pydocstyle]
ignore = D202,D212,D213,D203,D205
22 changes: 22 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[MASTER]
load-plugins=pylint.extensions.docparams

[MESSAGES CONTROL]
disable = C0330, C0326

[format]
max-line-length = 135

[SIMILARITIES]

# Minimum lines number of a similarity.
min-similarity-lines=5

# Ignore comments when computing similarities.
ignore-comments=yes

# Ignore docstrings when computing similarities.
ignore-docstrings=yes

# Ignore imports when computing similarities.
ignore-imports=no
7 changes: 7 additions & 0 deletions CONTRIB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# CONTRIB

Simple Slack Bot is a pretty open project. If there's a feature you'd like to add, simply submit a pull request.

Feel free to ask in a Github Issue to discuss anything.

Eventually we'll have better documentation and tests that can be ran.
52 changes: 41 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,23 +1,53 @@
PYTHON=python3
PID=app.pid
.DEFAULT_GOAL := help

run:
$(PYTHON) app.py
.PHONY: help
help: ## This help.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

start:
$(PYTHON) app.py > /dev/null 2>&1 & echo $$! > $(PID)
format: ## Formats the code base and tests using Black.
black --line-length 100 simple_slack_bot tests

package:
isort: ## Orders the imports of the code base and tests using isort.
isort --recursive simple_slack_bot tests

lint: ## Performs linting on the code base and tests using flake8 and pydocstyle.
flake8 simple_slack_bot tests --show-source
# does not check tests to help me keep my sanity as there's many issues that provide little value resolving
pylint simple_slack_bot --ignore=tests

type: ## Checks type hints on the code base and tests using mypy.
mypy simple_slack_bot tests --disallow-untyped-calls

security: ## Checks code base and tests for security vulnerability, bad imports and keys using bandit, safety and dodgy.
# does not check tests to help me keep my sanity as there's many issues that provide little value resolving
bandit -r simple_slack_bot
# ignoring pipenv installed in Circle Ci Docker container
safety check --full-report --ignore 38334
dodgy

magic: format isort lint type security ## Performs format, isort, lint, type and security in that order.

test: ## Runs the pytest suite.
pytest

coverage: ## Runs the pytest suite and generates code coverage.
coverage run -m pytest && coverage report -m

package: ## Packages up the project.
python3 setup.py sdist bdist_wheel

upload-test-pypi:
upload-test-pypi: ## Uploads the project to test.pypi.org.
python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*

upload-pypi:
upload-pypi: ## Uploads the project to pypi.org
python3 -m twine upload dist/*

example:
example: ## Runs the example component.
python3 example_component.py

kill:
kill $$(cat $(PID))
circle-ci-validate: ## Validates the circleci config.
circleci config validate

circle-ci-local-execute: ## Execute circleci config locally.
circleci local execute
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Simple Slack Bot

[![<ORG_NAME>](https://circleci.com/gh/GregHilston/Simple-Slack-Bot.svg?style=svg)](https://app.circleci.com/pipelines/github/GregHilston/Simple-Slack-Bot)

Simple Slack Bot makes writing your next Slack bot incredibly easy. By factoring out common functionality all Slack Bots require, you can focus on writing your business logic.


Expand Down Expand Up @@ -218,7 +220,7 @@ _If you have written a Simple Slack Bot, please contact me to have yours added!_

| Name | Author | Description |
|:---------------------------------------------------------------:|:----------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| [Ping Pong Bot](https://github.com/GregHilston/Ping-Pong-Bot) | [Greg Hilston](https://github.com/GregHilston) | Ping Pong Bot was created to act as an example of how easy it is to create a bot using the open source Simple-Slack-Bot library. Ping-Pong-Bot will look at every message sent to the channels that it is in, waiting for the case insensitive message "Ping". Once received Ping-Pong-Bot will write back to the very same channel "Pong". |
| [Ping Pong Bot](https://github.com/GregHilston/Ping-Pong-Bot) | [Greg Hilston](https://github.com/GregHilston) | Ping Pong Bot was created to act as an example of how easy it is to create a bot using the open source Simple-Slack-Bot framework. Ping-Pong-Bot will look at every message sent to the channels that it is in, waiting for the case insensitive message "Ping". Once received Ping-Pong-Bot will write back to the very same channel "Pong". |
| [The Office Bot](https://github.com/GregHilston/The-Office-Bot) | [Greg Hilston](https://github.com/GregHilston) | The Office Bot will look at every message sent to the channels that,it is in, waiting for a mention of the name of a character in the show, The Office, specifically the US version. Once received, The-Office-Bot will write back a random line that this character had throughout the show, including lines from deleted scenes. |
| [Stan Bot](https://github.com/jahirfiquitiva/StanBot) | [Jahir Fiquitiva](https://github.com/jahirfiquitiva) | Stan Bot is a bot to help one with the SCRUM stand-up process. |
| [Dice Bot](https://github.com/GregHilston/dice_bot) | [Greg Hilston](https://github.com/GregHilston) | Dice Bot is used to perform simple dice rolls |
Expand Down
File renamed without changes.
11 changes: 0 additions & 11 deletions example_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,6 @@
simple_slack_bot = SimpleSlackBot(debug=True)


@simple_slack_bot.register("hello")
def hello_callback(request):
request.write("Hello!")


@simple_slack_bot.register("user_typing")
def user_typing_callback(request):
user_id = simple_slack_bot.helper_user_id_to_user_name(request._slack_event.event['user'])
request.write(f"I see you typing {user_id}")


@simple_slack_bot.register("message")
def pong_callback(request):
if request.message and request.message.lower() == "ping":
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ chardet==3.0.4
idna==2.10
requests==2.24.0
six==1.15.0
slackclient==2.8.0
slacker==0.14.0
slackclient==2.8.0
slacksocket==1.0.1
urllib3==1.25.10
websocket-client==0.56.0
37 changes: 13 additions & 24 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
bleach==3.1.5
certifi==2020.6.20
cffi==1.14.2
chardet==3.0.4
colorama==0.4.3
cryptography==3.0
docutils==0.16
idna==2.10
jeepney==0.4.3
keyring==21.3.0
packaging==20.4
pkginfo==1.5.0.1
pycparser==2.20
Pygments==2.6.1
pyparsing==2.4.7
readme-renderer==26.0
requests==2.24.0
requests-toolbelt==0.9.1
rfc3986==1.4.0
SecretStorage==3.1.2
six==1.15.0
tqdm==4.48.2
-r requirements.txt

bandit==1.6.2
black==19.10b0
coverage==5.2.1
dodgy==0.2.1
flake8==3.8.3
isort==4.2.5
mypy==0.782
pip-chill==1.0.0
pylint==2.5.3
pytest==6.0.1
safety==1.9.0
twine==3.2.0
urllib3==1.25.10
webencodings==0.5.1
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from setuptools import setup
from os import path

from setuptools import setup

# read the contents of your README file
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, "README.md"), encoding="utf-8") as f:
Expand All @@ -9,7 +10,7 @@
setup(
name="simple_slack_bot",
packages=["simple_slack_bot"], # this must be the same as the name above
version="1.3.3",
version="2.0.0",
description="Simple Slack Bot makes writing your next Slack bot incredibly easy",
long_description=long_description,
long_description_content_type="text/markdown",
Expand All @@ -23,6 +24,7 @@
"slacker==0.14.0",
"slacksocket>=0.7,!=0.8,<=0.9",
"pyyaml",
"websocket-client==0.48", # required to define as our dependency has a dependency which broke backwards compatibility
"wheel",
"websocket-client==0.48", # required to define as our dependency has a dependency which broke backwards compatibility
],
)
7 changes: 6 additions & 1 deletion simple_slack_bot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
"""Please refer to the documentation provided in the README.md.
which can be found at the PyPI URL: https://pypi.org/project/simple-slack-bot/
"""


import logging
from logging import NullHandler

logging.getLogger(__name__).addHandler(NullHandler())

Loading

0 comments on commit 33c279a

Please sign in to comment.