From 30e284c13fc3c90fb19344ebbc0f090f9e8d4e8d Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Fri, 2 Sep 2022 11:54:32 -0500 Subject: [PATCH 01/21] Slack Socket POC Some ground work to give a POC of the Slack Socket Mode. --- development/nautobot_config.py | 1 + nautobot_chatops/dispatchers/slack_socket.py | 35 ++ .../commands/slack_list_channels.py | 2 +- .../management/commands/start_slack_socket.py | 9 + nautobot_chatops/sockets/__init__.py | 0 nautobot_chatops/sockets/slack.py | 224 ++++++++ nautobot_chatops/utils.py | 2 + poetry.lock | 516 +++++++++++++++++- pyproject.toml | 7 +- tasks.py | 2 +- 10 files changed, 778 insertions(+), 20 deletions(-) create mode 100644 nautobot_chatops/dispatchers/slack_socket.py create mode 100644 nautobot_chatops/management/commands/start_slack_socket.py create mode 100644 nautobot_chatops/sockets/__init__.py create mode 100644 nautobot_chatops/sockets/slack.py diff --git a/development/nautobot_config.py b/development/nautobot_config.py index b212fa29..47f1b506 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -217,6 +217,7 @@ def is_truthy(arg): "enable_webex": True, "microsoft_app_id": os.environ.get("MICROSOFT_APP_ID"), "microsoft_app_password": os.environ.get("MICROSOFT_APP_PASSWORD"), + "slack_app_token": os.environ.get("SLACK_APP_TOKEN"), "slack_api_token": os.environ.get("SLACK_API_TOKEN"), "slack_signing_secret": os.environ.get("SLACK_SIGNING_SECRET"), "slack_slash_command_prefix": os.environ.get("SLACK_SLASH_COMMAND_PREFIX", "/"), diff --git a/nautobot_chatops/dispatchers/slack_socket.py b/nautobot_chatops/dispatchers/slack_socket.py new file mode 100644 index 00000000..7e2d5c94 --- /dev/null +++ b/nautobot_chatops/dispatchers/slack_socket.py @@ -0,0 +1,35 @@ +"""Dispatcher implementation for sending content to Slack.""" + +import logging +import os + +from django.conf import settings +from django.templatetags.static import static + +from nautobot_chatops.metrics import backend_action_sum +from .slack import SlackDispatcher + +logger = logging.getLogger("rq.worker") + +# pylint: disable=abstract-method + +# Create a metric to track time spent and requests made. +BACKEND_ACTION_LOOKUP = backend_action_sum.labels("slack_socket", "platform_lookup") +BACKEND_ACTION_MARKDOWN = backend_action_sum.labels("slack_socket", "send_markdown") +BACKEND_ACTION_BLOCKS = backend_action_sum.labels("slack_socket", "send_blocks") +BACKEND_ACTION_SNIPPET = backend_action_sum.labels("slack_socket", "send_snippet") + +class SlackSocketDispatcher(SlackDispatcher): + """Dispatch messages and cards to Slack through SocketMode.""" + + # pylint: disable=too-many-public-methods + platform_name = "Slack" + platform_slug = "slack" + + platform_color = "4A154B" # Slack Aubergine + + command_prefix = settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_slash_command_prefix"] + """Prefix prepended to all commands, such as "/" or "!" in some clients.""" + + def static_url(self, path): + return str(static(path)) \ No newline at end of file diff --git a/nautobot_chatops/management/commands/slack_list_channels.py b/nautobot_chatops/management/commands/slack_list_channels.py index 5afe715f..1ae38fa5 100644 --- a/nautobot_chatops/management/commands/slack_list_channels.py +++ b/nautobot_chatops/management/commands/slack_list_channels.py @@ -13,7 +13,7 @@ def handle(self, *args, **kwargs): """This method provides a simple manage.py command to list slack channels.""" dispatcher = SlackDispatcher() # conversation_list documentation https://api.slack.com/methods/conversations.list - conversations = dispatcher.slack_client.conversations_list(types="public_channel, private_channel") + conversations = dispatcher.slack_client.conversations_list(types="public_channel, private_channel, im") table = Texttable(max_width=0) table.set_deco(Texttable.HEADER | Texttable.HLINES | Texttable.VLINES) diff --git a/nautobot_chatops/management/commands/start_slack_socket.py b/nautobot_chatops/management/commands/start_slack_socket.py new file mode 100644 index 00000000..ca86529d --- /dev/null +++ b/nautobot_chatops/management/commands/start_slack_socket.py @@ -0,0 +1,9 @@ +import asyncio +from django.core.management.base import BaseCommand +from nautobot_chatops.sockets.slack import main + +class Command(BaseCommand): + """Starts the Slack Socket.""" + + def handle(self, *args, **kwargs): + asyncio.run(main()) diff --git a/nautobot_chatops/sockets/__init__.py b/nautobot_chatops/sockets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py new file mode 100644 index 00000000..37b8328b --- /dev/null +++ b/nautobot_chatops/sockets/slack.py @@ -0,0 +1,224 @@ +"""Websocket Client to receive inbound notifications from Slack, parse them, and enqueue worker actions.""" + +import asyncio +import json +import logging +import shlex + +from django.conf import settings +from slack_sdk.socket_mode.aiohttp import SocketModeClient +from slack_sdk.web.async_client import AsyncWebClient + +from nautobot_chatops.workers import get_commands_registry, commands_help, parse_command_string +from nautobot_chatops.dispatchers.slack_socket import SlackSocketDispatcher +from nautobot_chatops.utils import check_and_enqueue_command + + +SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") + +#logger = logging.getLogger(__name__) + +async def main(): + from slack_sdk.socket_mode.response import SocketModeResponse + from slack_sdk.socket_mode.request import SocketModeRequest + + client = SocketModeClient( + app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), + web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]), + ) + + async def process(client: SocketModeClient, req: SocketModeRequest): + client.logger.debug("SK Received a socket request.") + if req.type == "slash_commands": + client.logger.debug("Received slash command.") + # Acknowledge the request anyway + response = SocketModeResponse(envelope_id=req.envelope_id) + # Don't forget having await for method calls + await client.send_socket_mode_response(response) + await process_slash_command(client, req) + + if req.type == "interactive": + client.logger.debug("Received interactive request.") + # Acknowledge the request anyway + response = SocketModeResponse(envelope_id=req.envelope_id) + # Don't forget having await for method calls + await client.send_socket_mode_response(response) + await process_interactive(client, req) + + async def process_slash_command(client, req): + client.logger.debug("Processing slash command.") + command = req.payload.get("command") + command = command.replace(SLASH_PREFIX, "") + params = req.payload.get("text") + context = { + "org_id": req.payload.get("team_id"), + "org_name": req.payload.get("team_domain"), + "channel_id": req.payload.get("channel_id"), + "channel_name": req.payload.get("channel_name"), + "user_id": req.payload.get("user_id"), + "user_name": req.payload.get("user_name"), + "response_url": req.payload.get("response_url"), + "trigger_id": req.payload.get("trigger_id") + } + + try: + command, subcommand, params = parse_command_string(f"{command} {params}") + except ValueError as err: + client.logger.error("%s", err) + # Tried sending 400 error, but the friendly message never made it to slack. + + registry = get_commands_registry() + + if command not in registry: + SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) + + return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + + async def process_interactive(client, req): + client.logger.debug("Processing interactive.") + payload = req.payload + + context = { + "org_id": payload.get("team", {}).get("id"), + "org_name": payload.get("team", {}).get("domain"), + "channel_id": payload.get("channel", {}).get("id"), + "channel_name": payload.get("channel", {}).get("name"), + "user_id": payload.get("user", {}).get("id"), + "user_name": payload.get("user", {}).get("username"), + "response_url": payload.get("response_url"), + "trigger_id": payload.get("trigger_id"), + } + + # Check for channel_name if channel_id is present + if context["channel_name"] is None and context["channel_id"] is not None: + # Get the channel information from Slack API + channel_info = client.web_client.conversations_info(channel=context["channel_id"]) + + # Assign the Channel name out of the conversations info end point + context["channel_name"] = channel_info["channel"]["name"] + + if "actions" in payload and payload["actions"]: + # Block action triggered by a non-modal interactive component + action = payload["actions"][0] + action_id = action.get("action_id", "") + block_id = action.get("block_id", "") + if action["type"] == "static_select": + value = action.get("selected_option", {}).get("value", "") + selected_value = f"'{value}'" + elif action["type"] == "button": + value = action.get("value") + selected_value = f"'{value}'" + else: + client.logger.error(f"Unhandled action type {action['type']}") + #return HttpResponse(status=500) + + if settings.PLUGINS_CONFIG["nautobot_chatops"].get("delete_input_on_submission"): + # Delete the interactive element since it's served its purpose + SlackSocketDispatcher(context).delete_message(context["response_url"]) + if action_id == "action" and selected_value == "cancel": + # Nothing more to do + return + #return HttpResponse() + elif "view" in payload and payload["view"]: + # View submission triggered from a modal dialog + client.logger.info("Submission triggered from a modal dialog") + client.logger.info(json.dumps(payload, indent=2)) + values = payload["view"].get("state", {}).get("values", {}) + + # Handling for multiple fields. This will be used when the multi_input_dialog() method of the Slack + # Dispatcher class is utilized. + if len(values) > 1: + selected_value = "" + callback_id = payload["view"].get("callback_id") + # sometimes in the case of back-to-back dialogs there will be + # parameters included in the callback_id. Below parses those + # out and adds them to selected_value. + try: + cmds = shlex.split(callback_id) + except ValueError as err: + client.logger.error("%s", err) + #return HttpResponse(f"Error: {err} encountered when processing {callback_id}") + for i, cmd in enumerate(cmds): + if i == 2: + selected_value += f"'{cmd}'" + elif i > 2: + selected_value += f" '{cmd}'" + action_id = f"{cmds[0]} {cmds[1]}" + + sorted_params = sorted(values.keys()) + for blk_id in sorted_params: + for act_id in values[blk_id].values(): + if act_id["type"] == "static_select": + try: + value = act_id["selected_option"]["value"] + except (AttributeError, TypeError): + # Error is thrown if no option selected and field is optional + value = None + elif act_id["type"] == "plain_text_input": + value = act_id["value"] + else: + client.logger.error(f"Unhandled dialog type {act_id['type']}") + #return HttpResponse(status=500) + + # If an optional parameter is passed, it is returned as a NoneType. + # We instead want to return an empty string, otherwise 'None' is returned as a string. + if value: + selected_value += f" '{value}'" + else: + selected_value += " ''" + + # Original un-modified single-field handling below + else: + block_id = sorted(values.keys())[0] + action_id = sorted(values[block_id].keys())[0] + action = values[block_id][action_id] + if action["type"] == "plain_text_input": + value = action["value"] + selected_value = f"'{value}'" + else: + client.logger.error(f"Unhandled action type {action['type']}") + #return HttpResponse(status=500) + + # Modal view submissions don't generally contain a channel ID, but we hide one for our convenience: + if "private_metadata" in payload["view"]: + private_metadata = json.loads(payload["view"]["private_metadata"]) + if "channel_id" in private_metadata: + context["channel_id"] = private_metadata["channel_id"] + else: + client.logger.error("I didn't understand that notification.") + #return HttpResponse("I didn't understand that notification.") + + client.logger.info(f"action_id: {action_id}, selected_value: {selected_value}") + try: + command, subcommand, params = parse_command_string(f"{action_id} {selected_value}") + except ValueError as err: + client.logger.error("%s", err) + # Tried sending 400 error, but the friendly message never made it to slack. + #return HttpResponse(f"'Error: {err}' encountered on command '{action_id} {selected_value}'.") + + # Convert empty parameter strings to NoneType + for idx, param in enumerate(params): + if not param: + params[idx] = None + + client.logger.info(f"command: {command}, subcommand: {subcommand}, params: {params}") + + registry = get_commands_registry() + + if command not in registry: + SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) + #return HttpResponse() + + # What we'd like to do here is send a "Nautobot is typing..." to the channel, + # but unfortunately the API we're using doesn't support that (only the legacy/deprecated RTM API does). + # SlackDispatcher(context).send_busy_indicator() + + return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + + + client.socket_mode_request_listeners.append(process) + + await client.connect() + + await asyncio.sleep(float("inf")) + diff --git a/nautobot_chatops/utils.py b/nautobot_chatops/utils.py index c1e99e39..b55bf95e 100644 --- a/nautobot_chatops/utils.py +++ b/nautobot_chatops/utils.py @@ -4,6 +4,7 @@ import logging import sys +from asgiref.sync import sync_to_async from django.db.models import Q from django.http import HttpResponse, JsonResponse @@ -102,6 +103,7 @@ def create_command_log(dispatcher, registry, command, subcommand, params=()): ) +@sync_to_async def check_and_enqueue_command( registry, command, subcommand, params, context, dispatcher_class ): # pylint:disable=too-many-statements diff --git a/poetry.lock b/poetry.lock index d5e4ba38..b9060e74 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,49 @@ +[[package]] +name = "aiodns" +version = "1.2.0" +description = "Simple DNS resolver for asyncio" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pycares = ">=1.0.0" +typing = "*" + +[[package]] +name = "aiohttp" +version = "3.8.0" +description = "Async http client/server framework (asyncio)" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +aiosignal = ">=1.1.2" +async-timeout = ">=4.0.0a3,<5.0" +asynctest = {version = "0.13.0", markers = "python_version < \"3.8\""} +attrs = ">=17.3.0" +charset-normalizer = ">=2.0,<3.0" +frozenlist = ">=1.1.1" +idna-ssl = {version = ">=1.0", markers = "python_version < \"3.7\""} +multidict = ">=4.5,<7.0" +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["aiodns", "brotli", "cchardet"] + +[[package]] +name = "aiosignal" +version = "1.2.0" +description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +frozenlist = ">=1.1.0" + [[package]] name = "aniso8601" version = "7.0.0" @@ -16,7 +62,7 @@ python-versions = "*" [[package]] name = "asgiref" -version = "3.3.4" +version = "3.4.1" description = "ASGI specs, helper code, and adapters" category = "main" optional = false @@ -41,6 +87,25 @@ lazy-object-proxy = ">=1.4.0" typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} wrapt = ">=1.11,<1.13" +[[package]] +name = "async-timeout" +version = "4.0.1" +description = "Timeout context manager for asyncio programs" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = ">=3.6.5" + +[[package]] +name = "asynctest" +version = "0.13.0" +description = "Enhance the standard unittest package with features for testing asyncio libraries" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "attrs" version = "21.2.0" @@ -120,6 +185,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "charset-normalizer" +version = "2.0.7" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + [[package]] name = "click" version = "8.0.1" @@ -441,6 +517,14 @@ mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" +[[package]] +name = "frozenlist" +version = "1.2.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "funcy" version = "1.16" @@ -559,6 +643,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "idna-ssl" +version = "1.1.0" +description = "Patch ssl.match_hostname for Unicode(idna) domains support" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +idna = ">=2.0" + [[package]] name = "importlib-metadata" version = "3.4.0" @@ -697,6 +792,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "multidict" +version = "5.2.0" +description = "multidict implementation" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -859,6 +962,20 @@ category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +[[package]] +name = "pycares" +version = "4.1.2" +description = "Python interface for c-ares" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +cffi = ">=1.5.0" + +[package.extras] +idna = ["idna (>=2.1)"] + [[package]] name = "pycodestyle" version = "2.7.0" @@ -1282,6 +1399,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "typing" +version = "3.7.4.3" +description = "Type Hints for Python" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "typing-extensions" version = "3.10.0.0" @@ -1345,6 +1470,19 @@ python-versions = ">=3.5.*" pathspec = ">=0.5.3" pyyaml = "*" +[[package]] +name = "yarl" +version = "1.7.2" +description = "Yet another URL library" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} + [[package]] name = "zipp" version = "3.4.1" @@ -1359,10 +1497,92 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt [metadata] lock-version = "1.1" -python-versions = "^3.6" -content-hash = "3f2e613149ae7003147c0d1b340f5b32e6d4d817a9081fa860d7ea5ac0014ebf" +python-versions = "^3.6.1" +content-hash = "3a305a1737b35fabe1ee2e462ba72f66d64e97ecd483d6d53ca8e14a10463c05" [metadata.files] +aiodns = [ + {file = "aiodns-1.2.0-py2.py3-none-any.whl", hash = "sha256:970688599fcb7d65334ec490a94a51afd634ae2de8a2138d21e2ffbbddc12718"}, + {file = "aiodns-1.2.0.tar.gz", hash = "sha256:d67e14b32176bcf3ff79b5d47c466011ce4adeadfa264f7949da1377332a0449"}, +] +aiohttp = [ + {file = "aiohttp-3.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:48f218a5257b6bc16bcf26a91d97ecea0c7d29c811a90d965f3dd97c20f016d6"}, + {file = "aiohttp-3.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2fee4d656a7cc9ab47771b2a9e8fad8a9a33331c1b59c3057ecf0ac858f5bfe"}, + {file = "aiohttp-3.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:688a1eb8c1a5f7e795c7cb67e0fe600194e6723ba35f138dfae0db20c0cb8f94"}, + {file = "aiohttp-3.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ba09bb3dcb0b7ec936a485db2b64be44fe14cdce0a5eac56f50e55da3627385"}, + {file = "aiohttp-3.8.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d7715daf84f10bcebc083ad137e3eced3e1c8e7fa1f096ade9a8d02b08f0d91c"}, + {file = "aiohttp-3.8.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e3f81fbbc170418e22918a9585fd7281bbc11d027064d62aa4b507552c92671"}, + {file = "aiohttp-3.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1fa9f50aa1f114249b7963c98e20dc35c51be64096a85bc92433185f331de9cc"}, + {file = "aiohttp-3.8.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8a50150419b741ee048b53146c39c47053f060cb9d98e78be08fdbe942eaa3c4"}, + {file = "aiohttp-3.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a84c335337b676d832c1e2bc47c3a97531b46b82de9f959dafb315cbcbe0dfcd"}, + {file = "aiohttp-3.8.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:88d4917c30fcd7f6404fb1dc713fa21de59d3063dcc048f4a8a1a90e6bbbd739"}, + {file = "aiohttp-3.8.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b76669b7c058b8020b11008283c3b8e9c61bfd978807c45862956119b77ece45"}, + {file = "aiohttp-3.8.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:84fe1732648c1bc303a70faa67cbc2f7f2e810c8a5bca94f6db7818e722e4c0a"}, + {file = "aiohttp-3.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:730b7c2b7382194d9985ffdc32ab317e893bca21e0665cb1186bdfbb4089d990"}, + {file = "aiohttp-3.8.0-cp310-cp310-win32.whl", hash = "sha256:0a96473a1f61d7920a9099bc8e729dc8282539d25f79c12573ee0fdb9c8b66a8"}, + {file = "aiohttp-3.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:764c7c6aa1f78bd77bd9674fc07d1ec44654da1818d0eef9fb48aa8371a3c847"}, + {file = "aiohttp-3.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9951c2696c4357703001e1fe6edc6ae8e97553ac630492ea1bf64b429cb712a3"}, + {file = "aiohttp-3.8.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0af379221975054162959e00daf21159ff69a712fc42ed0052caddbd70d52ff4"}, + {file = "aiohttp-3.8.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9689af0f0a89e5032426c143fa3683b0451f06c83bf3b1e27902bd33acfae769"}, + {file = "aiohttp-3.8.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe4a327da0c6b6e59f2e474ae79d6ee7745ac3279fd15f200044602fa31e3d79"}, + {file = "aiohttp-3.8.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ecb314e59bedb77188017f26e6b684b1f6d0465e724c3122a726359fa62ca1ba"}, + {file = "aiohttp-3.8.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a5399a44a529083951b55521cf4ecbf6ad79fd54b9df57dbf01699ffa0549fc9"}, + {file = "aiohttp-3.8.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:09754a0d5eaab66c37591f2f8fac8f9781a5f61d51aa852a3261c4805ca6b984"}, + {file = "aiohttp-3.8.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:adf0cb251b1b842c9dee5cfcdf880ba0aae32e841b8d0e6b6feeaef002a267c5"}, + {file = "aiohttp-3.8.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:a4759e85a191de58e0ea468ab6fd9c03941986eee436e0518d7a9291fab122c8"}, + {file = "aiohttp-3.8.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:28369fe331a59d80393ec82df3d43307c7461bfaf9217999e33e2acc7984ff7c"}, + {file = "aiohttp-3.8.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2f44d1b1c740a9e2275160d77c73a11f61e8a916191c572876baa7b282bcc934"}, + {file = "aiohttp-3.8.0-cp36-cp36m-win32.whl", hash = "sha256:e27cde1e8d17b09730801ce97b6e0c444ba2a1f06348b169fd931b51d3402f0d"}, + {file = "aiohttp-3.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:15a660d06092b7c92ed17c1dbe6c1eab0a02963992d60e3e8b9d5fa7fa81f01e"}, + {file = "aiohttp-3.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:257f4fad1714d26d562572095c8c5cd271d5a333252795cb7a002dca41fdbad7"}, + {file = "aiohttp-3.8.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6074a3b2fa2d0c9bf0963f8dfc85e1e54a26114cc8594126bc52d3fa061c40e"}, + {file = "aiohttp-3.8.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a315ceb813208ef32bdd6ec3a85cbe3cb3be9bbda5fd030c234592fa9116993"}, + {file = "aiohttp-3.8.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a52b141ff3b923a9166595de6e3768a027546e75052ffba267d95b54267f4ab"}, + {file = "aiohttp-3.8.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6a038cb1e6e55b26bb5520ccffab7f539b3786f5553af2ee47eb2ec5cbd7084e"}, + {file = "aiohttp-3.8.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98b1ea2763b33559dd9ec621d67fc17b583484cb90735bfb0ec3614c17b210e4"}, + {file = "aiohttp-3.8.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9e8723c3256641e141cd18f6ce478d54a004138b9f1a36e41083b36d9ecc5fc5"}, + {file = "aiohttp-3.8.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:14a6f026eca80dfa3d52e86be89feb5cd878f6f4a6adb34457e2c689fd85229b"}, + {file = "aiohttp-3.8.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c62d4791a8212c885b97a63ef5f3974b2cd41930f0cd224ada9c6ee6654f8150"}, + {file = "aiohttp-3.8.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:90a97c2ed2830e7974cbe45f0838de0aefc1c123313f7c402e21c29ec063fbb4"}, + {file = "aiohttp-3.8.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dcc4d5dd5fba3affaf4fd08f00ef156407573de8c63338787614ccc64f96b321"}, + {file = "aiohttp-3.8.0-cp37-cp37m-win32.whl", hash = "sha256:de42f513ed7a997bc821bddab356b72e55e8396b1b7ba1bf39926d538a76a90f"}, + {file = "aiohttp-3.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:7d76e8a83396e06abe3df569b25bd3fc88bf78b7baa2c8e4cf4aaf5983af66a3"}, + {file = "aiohttp-3.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d79174d96446a02664e2bffc95e7b6fa93b9e6d8314536c5840dff130d0878b"}, + {file = "aiohttp-3.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a6551057a846bf72c7a04f73de3fcaca269c0bd85afe475ceb59d261c6a938c"}, + {file = "aiohttp-3.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:871d4fdc56288caa58b1094c20f2364215f7400411f76783ea19ad13be7c8e19"}, + {file = "aiohttp-3.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ba08a71caa42eef64357257878fb17f3fba3fba6e81a51d170e32321569e079"}, + {file = "aiohttp-3.8.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f90dabd9933b1621260b32c2f0d05d36923c7a5a909eb823e429dba0fd2f3e"}, + {file = "aiohttp-3.8.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f348ebd20554e8bc26e8ef3ed8a134110c0f4bf015b3b4da6a4ddf34e0515b19"}, + {file = "aiohttp-3.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d5f8c04574efa814a24510122810e3a3c77c0552f9f6ff65c9862f1f046be2c3"}, + {file = "aiohttp-3.8.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ecffdc748d3b40dd3618ede0170e4f5e1d3c9647cfb410d235d19e62cb54ee0"}, + {file = "aiohttp-3.8.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:577cc2c7b807b174814dac2d02e673728f2e46c7f90ceda3a70ea4bb6d90b769"}, + {file = "aiohttp-3.8.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6b79f6c31e68b6dafc0317ec453c83c86dd8db1f8f0c6f28e97186563fca87a0"}, + {file = "aiohttp-3.8.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2bdd655732e38b40f8a8344d330cfae3c727fb257585df923316aabbd489ccb8"}, + {file = "aiohttp-3.8.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:63fa57a0708573d3c059f7b5527617bd0c291e4559298473df238d502e4ab98c"}, + {file = "aiohttp-3.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d3f90ee275b1d7c942e65b5c44c8fb52d55502a0b9a679837d71be2bd8927661"}, + {file = "aiohttp-3.8.0-cp38-cp38-win32.whl", hash = "sha256:fa818609357dde5c4a94a64c097c6404ad996b1d38ca977a72834b682830a722"}, + {file = "aiohttp-3.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:097ecf52f6b9859b025c1e36401f8aa4573552e887d1b91b4b999d68d0b5a3b3"}, + {file = "aiohttp-3.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:be03a7483ad9ea60388f930160bb3728467dd0af538aa5edc60962ee700a0bdc"}, + {file = "aiohttp-3.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:78d51e35ed163783d721b6f2ce8ce3f82fccfe471e8e50a10fba13a766d31f5a"}, + {file = "aiohttp-3.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bda75d73e7400e81077b0910c9a60bf9771f715420d7e35fa7739ae95555f195"}, + {file = "aiohttp-3.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:707adc30ea6918fba725c3cb3fe782d271ba352b22d7ae54a7f9f2e8a8488c41"}, + {file = "aiohttp-3.8.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f58aa995b905ab82fe228acd38538e7dc1509e01508dcf307dad5046399130f"}, + {file = "aiohttp-3.8.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c996eb91bfbdab1e01e2c02e7ff678c51e2b28e3a04e26e41691991cc55795"}, + {file = "aiohttp-3.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d6a1a66bb8bac9bc2892c2674ea363486bfb748b86504966a390345a11b1680e"}, + {file = "aiohttp-3.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dafc01a32b4a1d7d3ef8bfd3699406bb44f7b2e0d3eb8906d574846e1019b12f"}, + {file = "aiohttp-3.8.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:949a605ef3907254b122f845baa0920407080cdb1f73aa64f8d47df4a7f4c4f9"}, + {file = "aiohttp-3.8.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0d7b056fd3972d353cb4bc305c03f9381583766b7f8c7f1c44478dba69099e33"}, + {file = "aiohttp-3.8.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f1d39a744101bf4043fa0926b3ead616607578192d0a169974fb5265ab1e9d2"}, + {file = "aiohttp-3.8.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:67ca7032dfac8d001023fadafc812d9f48bf8a8c3bb15412d9cdcf92267593f4"}, + {file = "aiohttp-3.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cb751ef712570d3bda9a73fd765ff3e1aba943ec5d52a54a0c2e89c7eef9da1e"}, + {file = "aiohttp-3.8.0-cp39-cp39-win32.whl", hash = "sha256:6d3e027fe291b77f6be9630114a0200b2c52004ef20b94dc50ca59849cd623b3"}, + {file = "aiohttp-3.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:3c5e9981e449d54308c6824f172ec8ab63eb9c5f922920970249efee83f7e919"}, + {file = "aiohttp-3.8.0.tar.gz", hash = "sha256:d3b19d8d183bcfd68b25beebab8dc3308282fe2ca3d6ea3cb4cd101b3c279f8d"}, +] +aiosignal = [ + {file = "aiosignal-1.2.0-py3-none-any.whl", hash = "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a"}, + {file = "aiosignal-1.2.0.tar.gz", hash = "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2"}, +] aniso8601 = [ {file = "aniso8601-7.0.0-py2.py3-none-any.whl", hash = "sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b"}, {file = "aniso8601-7.0.0.tar.gz", hash = "sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e"}, @@ -1372,13 +1592,21 @@ appdirs = [ {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] asgiref = [ - {file = "asgiref-3.3.4-py3-none-any.whl", hash = "sha256:92906c611ce6c967347bbfea733f13d6313901d54dcca88195eaeb52b2a8e8ee"}, - {file = "asgiref-3.3.4.tar.gz", hash = "sha256:d1216dfbdfb63826470995d31caed36225dcaf34f182e0fa257a4dd9e86f1b78"}, + {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"}, + {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, ] astroid = [ {file = "astroid-2.5.6-py3-none-any.whl", hash = "sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e"}, {file = "astroid-2.5.6.tar.gz", hash = "sha256:8a398dfce302c13f14bab13e2b14fe385d32b73f4e4853b9bdfb64598baa1975"}, ] +async-timeout = [ + {file = "async-timeout-4.0.1.tar.gz", hash = "sha256:b930cb161a39042f9222f6efb7301399c87eeab394727ec5437924a36d6eef51"}, + {file = "async_timeout-4.0.1-py3-none-any.whl", hash = "sha256:a22c0b311af23337eb05fcf05a8b51c3ea53729d46fb5460af62bee033cec690"}, +] +asynctest = [ + {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, + {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, +] attrs = [ {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, @@ -1411,36 +1639,24 @@ cffi = [ {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed"}, - {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55"}, {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"}, {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"}, {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05"}, - {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc"}, {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"}, {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"}, {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"}, {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"}, {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"}, {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f"}, - {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76"}, {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"}, {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"}, {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"}, {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"}, {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"}, {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333"}, - {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7"}, {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"}, {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"}, {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"}, @@ -1449,6 +1665,10 @@ chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] +charset-normalizer = [ + {file = "charset-normalizer-2.0.7.tar.gz", hash = "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0"}, + {file = "charset_normalizer-2.0.7-py3-none-any.whl", hash = "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b"}, +] click = [ {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, @@ -1559,6 +1779,80 @@ flake8 = [ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] +frozenlist = [ + {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:977a1438d0e0d96573fd679d291a1542097ea9f4918a8b6494b06610dfeefbf9"}, + {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8d86547a5e98d9edd47c432f7a14b0c5592624b496ae9880fb6332f34af1edc"}, + {file = "frozenlist-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:181754275d5d32487431a0a29add4f897968b7157204bc1eaaf0a0ce80c5ba7d"}, + {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5df31bb2b974f379d230a25943d9bf0d3bc666b4b0807394b131a28fca2b0e5f"}, + {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4766632cd8a68e4f10f156a12c9acd7b1609941525569dd3636d859d79279ed3"}, + {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16eef427c51cb1203a7c0ab59d1b8abccaba9a4f58c4bfca6ed278fc896dc193"}, + {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c"}, + {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28e164722ea0df0cf6d48c4d5bdf3d19e87aaa6dfb39b0ba91153f224b912020"}, + {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e63ad0beef6ece06475d29f47d1f2f29727805376e09850ebf64f90777962792"}, + {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41de4db9b9501679cf7cddc16d07ac0f10ef7eb58c525a1c8cbff43022bddca4"}, + {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a9d84ee6427b65a81fc24e6ef589cb794009f5ca4150151251c062773e7ed2"}, + {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f5f3b2942c3b8b9bfe76b408bbaba3d3bb305ee3693e8b1d631fe0a0d4f93673"}, + {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c98d3c04701773ad60d9545cd96df94d955329efc7743fdb96422c4b669c633b"}, + {file = "frozenlist-1.2.0-cp310-cp310-win32.whl", hash = "sha256:72cfbeab7a920ea9e74b19aa0afe3b4ad9c89471e3badc985d08756efa9b813b"}, + {file = "frozenlist-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:11ff401951b5ac8c0701a804f503d72c048173208490c54ebb8d7bb7c07a6d00"}, + {file = "frozenlist-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b46f997d5ed6d222a863b02cdc9c299101ee27974d9bbb2fd1b3c8441311c408"}, + {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:351686ca020d1bcd238596b1fa5c8efcbc21bffda9d0efe237aaa60348421e2a"}, + {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfbaa08cf1452acad9cb1c1d7b89394a41e712f88df522cea1a0f296b57782a0"}, + {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ae2f5e9fa10805fb1c9adbfefaaecedd9e31849434be462c3960a0139ed729"}, + {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6790b8d96bbb74b7a6f4594b6f131bd23056c25f2aa5d816bd177d95245a30e3"}, + {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:41f62468af1bd4e4b42b5508a3fe8cc46a693f0cdd0ca2f443f51f207893d837"}, + {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:ec6cf345771cdb00791d271af9a0a6fbfc2b6dd44cb753f1eeaa256e21622adb"}, + {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:14a5cef795ae3e28fb504b73e797c1800e9249f950e1c964bb6bdc8d77871161"}, + {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8b54cdd2fda15467b9b0bfa78cee2ddf6dbb4585ef23a16e14926f4b076dfae4"}, + {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f025f1d6825725b09c0038775acab9ae94264453a696cc797ce20c0769a7b367"}, + {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:84e97f59211b5b9083a2e7a45abf91cfb441369e8bb6d1f5287382c1c526def3"}, + {file = "frozenlist-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:c5328ed53fdb0a73c8a50105306a3bc013e5ca36cca714ec4f7bd31d38d8a97f"}, + {file = "frozenlist-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9ade70aea559ca98f4b1b1e5650c45678052e76a8ab2f76d90f2ac64180215a2"}, + {file = "frozenlist-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0d3ffa8772464441b52489b985d46001e2853a3b082c655ec5fad9fb6a3d618"}, + {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3457f8cf86deb6ce1ba67e120f1b0128fcba1332a180722756597253c465fc1d"}, + {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a72eecf37eface331636951249d878750db84034927c997d47f7f78a573b72b"}, + {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:acc4614e8d1feb9f46dd829a8e771b8f5c4b1051365d02efb27a3229048ade8a"}, + {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:87521e32e18a2223311afc2492ef2d99946337da0779ddcda77b82ee7319df59"}, + {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b4c7665a17c3a5430edb663e4ad4e1ad457614d1b2f2b7f87052e2ef4fa45ca"}, + {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ed58803563a8c87cf4c0771366cf0ad1aa265b6b0ae54cbbb53013480c7ad74d"}, + {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa44c4740b4e23fcfa259e9dd52315d2b1770064cde9507457e4c4a65a04c397"}, + {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2de5b931701257d50771a032bba4e448ff958076380b049fd36ed8738fdb375b"}, + {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6e105013fa84623c057a4381dc8ea0361f4d682c11f3816cc80f49a1f3bc17c6"}, + {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:705c184b77565955a99dc360f359e8249580c6b7eaa4dc0227caa861ef46b27a"}, + {file = "frozenlist-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:a37594ad6356e50073fe4f60aa4187b97d15329f2138124d252a5a19c8553ea4"}, + {file = "frozenlist-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:25b358aaa7dba5891b05968dd539f5856d69f522b6de0bf34e61f133e077c1a4"}, + {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af2a51c8a381d76eabb76f228f565ed4c3701441ecec101dd18be70ebd483cfd"}, + {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:82d22f6e6f2916e837c91c860140ef9947e31194c82aaeda843d6551cec92f19"}, + {file = "frozenlist-1.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cfe6fef507f8bac40f009c85c7eddfed88c1c0d38c75e72fe10476cef94e10f"}, + {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f602e380a5132880fa245c92030abb0fc6ff34e0c5500600366cedc6adb06a"}, + {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ad065b2ebd09f32511ff2be35c5dfafee6192978b5a1e9d279a5c6e121e3b03"}, + {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc93f5f62df3bdc1f677066327fc81f92b83644852a31c6aa9b32c2dde86ea7d"}, + {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:89fdfc84c6bf0bff2ff3170bb34ecba8a6911b260d318d377171429c4be18c73"}, + {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:47b2848e464883d0bbdcd9493c67443e5e695a84694efff0476f9059b4cb6257"}, + {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4f52d0732e56906f8ddea4bd856192984650282424049c956857fed43697ea43"}, + {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:16ef7dd5b7d17495404a2e7a49bac1bc13d6d20c16d11f4133c757dd94c4144c"}, + {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1cf63243bc5f5c19762943b0aa9e0d3fb3723d0c514d820a18a9b9a5ef864315"}, + {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:54a1e09ab7a69f843cd28fefd2bcaf23edb9e3a8d7680032c8968b8ac934587d"}, + {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:954b154a4533ef28bd3e83ffdf4eadf39deeda9e38fb8feaf066d6069885e034"}, + {file = "frozenlist-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cb3957c39668d10e2b486acc85f94153520a23263b6401e8f59422ef65b9520d"}, + {file = "frozenlist-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0a7c7cce70e41bc13d7d50f0e5dd175f14a4f1837a8549b0936ed0cbe6170bf9"}, + {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4c457220468d734e3077580a3642b7f682f5fd9507f17ddf1029452450912cdc"}, + {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e74f8b4d8677ebb4015ac01fcaf05f34e8a1f22775db1f304f497f2f88fdc697"}, + {file = "frozenlist-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fbd4844ff111449f3bbe20ba24fbb906b5b1c2384d0f3287c9f7da2354ce6d23"}, + {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0081a623c886197ff8de9e635528fd7e6a387dccef432149e25c13946cb0cd0"}, + {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b6e21e5770df2dea06cb7b6323fbc008b13c4a4e3b52cb54685276479ee7676"}, + {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:406aeb340613b4b559db78d86864485f68919b7141dec82aba24d1477fd2976f"}, + {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:878ebe074839d649a1cdb03a61077d05760624f36d196884a5cafb12290e187b"}, + {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1fef737fd1388f9b93bba8808c5f63058113c10f4e3c0763ced68431773f72f9"}, + {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a495c3d513573b0b3f935bfa887a85d9ae09f0627cf47cad17d0cc9b9ba5c38"}, + {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e7d0dd3e727c70c2680f5f09a0775525229809f1a35d8552b92ff10b2b14f2c2"}, + {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:66a518731a21a55b7d3e087b430f1956a36793acc15912e2878431c7aec54210"}, + {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94728f97ddf603d23c8c3dd5cae2644fa12d33116e69f49b1644a71bb77b89ae"}, + {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c1e8e9033d34c2c9e186e58279879d78c94dd365068a3607af33f2bc99357a53"}, + {file = "frozenlist-1.2.0-cp39-cp39-win32.whl", hash = "sha256:83334e84a290a158c0c4cc4d22e8c7cfe0bba5b76d37f1c2509dabd22acafe15"}, + {file = "frozenlist-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:735f386ec522e384f511614c01d2ef9cf799f051353876b4c6fb93ef67a6d1ee"}, + {file = "frozenlist-1.2.0.tar.gz", hash = "sha256:68201be60ac56aff972dc18085800b6ee07973c49103a8aba669dee3d71079de"}, +] funcy = [ {file = "funcy-1.16-py2.py3-none-any.whl", hash = "sha256:1d3fc5d42cf7564a6b2be04042d0df7a50c77903cf760a34786d0c9ebd659b25"}, {file = "funcy-1.16.tar.gz", hash = "sha256:2775409b7dc9106283f1224d97e6df5f2c02e7291c8caed72764f5a115dffb50"}, @@ -1594,6 +1888,9 @@ idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] +idna-ssl = [ + {file = "idna-ssl-1.1.0.tar.gz", hash = "sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"}, +] importlib-metadata = [ {file = "importlib_metadata-3.4.0-py3-none-any.whl", hash = "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771"}, {file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"}, @@ -1695,6 +1992,80 @@ mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] +multidict = [ + {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55"}, + {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e"}, + {file = "multidict-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f"}, + {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a"}, + {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86"}, + {file = "multidict-5.2.0-cp310-cp310-win32.whl", hash = "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7"}, + {file = "multidict-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f"}, + {file = "multidict-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4"}, + {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded"}, + {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d"}, + {file = "multidict-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9"}, + {file = "multidict-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0"}, + {file = "multidict-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d"}, + {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d"}, + {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b"}, + {file = "multidict-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef"}, + {file = "multidict-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a"}, + {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8"}, + {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6"}, + {file = "multidict-5.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031"}, + {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac"}, + {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22"}, + {file = "multidict-5.2.0-cp38-cp38-win32.whl", hash = "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940"}, + {file = "multidict-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0"}, + {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24"}, + {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21"}, + {file = "multidict-5.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17"}, + {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b"}, + {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5"}, + {file = "multidict-5.2.0-cp39-cp39-win32.whl", hash = "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8"}, + {file = "multidict-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac"}, + {file = "multidict-5.2.0.tar.gz", hash = "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"}, +] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, @@ -1810,6 +2181,39 @@ psycopg2-binary = [ {file = "psycopg2_binary-2.8.6-cp39-cp39-win32.whl", hash = "sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056"}, {file = "psycopg2_binary-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6"}, ] +pycares = [ + {file = "pycares-4.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71b99b9e041ae3356b859822c511f286f84c8889ec9ed1fbf6ac30fb4da13e4c"}, + {file = "pycares-4.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c000942f5fc64e6e046aa61aa53b629b576ba11607d108909727c3c8f211a157"}, + {file = "pycares-4.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b0e50ddc78252f2e2b6b5f2c73e5b2449dfb6bea7a5a0e21dfd1e2bcc9e17382"}, + {file = "pycares-4.1.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6831e963a910b0a8cbdd2750ffcdf5f2bb0edb3f53ca69ff18484de2cc3807c4"}, + {file = "pycares-4.1.2-cp310-cp310-win32.whl", hash = "sha256:ad7b28e1b6bc68edd3d678373fa3af84e39d287090434f25055d21b4716b2fc6"}, + {file = "pycares-4.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:27a6f09dbfb69bb79609724c0f90dfaa7c215876a7cd9f12d585574d1f922112"}, + {file = "pycares-4.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e5a060f5fa90ae245aa99a4a8ad13ec39c2340400de037c7e8d27b081e1a3c64"}, + {file = "pycares-4.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:056330275dea42b7199494047a745e1d9785d39fb8c4cd469dca043532240b80"}, + {file = "pycares-4.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0aa897543a786daba74ec5e19638bd38b2b432d179a0e248eac1e62de5756207"}, + {file = "pycares-4.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cbceaa9b2c416aa931627466d3240aecfc905c292c842252e3d77b8630072505"}, + {file = "pycares-4.1.2-cp36-cp36m-win32.whl", hash = "sha256:112e1385c451069112d6b5ea1f9c378544f3c6b89882ff964e9a64be3336d7e4"}, + {file = "pycares-4.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:c6680f7fdc0f1163e8f6c2a11d11b9a0b524a61000d2a71f9ccd410f154fb171"}, + {file = "pycares-4.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58a41a2baabcd95266db776c510d349d417919407f03510fc87ac7488730d913"}, + {file = "pycares-4.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a810d01c9a426ee8b0f36969c2aef5fb966712be9d7e466920beb328cd9cefa3"}, + {file = "pycares-4.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b266cec81dcea2c3efbbd3dda00af8d7eb0693ae9e47e8706518334b21f27d4a"}, + {file = "pycares-4.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8319afe4838e09df267c421ca93da408f770b945ec6217dda72f1f6a493e37e4"}, + {file = "pycares-4.1.2-cp37-cp37m-win32.whl", hash = "sha256:4d5da840aa0d9b15fa51107f09270c563a348cb77b14ae9653d0bbdbe326fcc2"}, + {file = "pycares-4.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5632f21d92cc0225ba5ff906e4e5dec415ef0b3df322c461d138190681cd5d89"}, + {file = "pycares-4.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8fd1ff17a26bb004f0f6bb902ba7dddd810059096ae0cc3b45e4f5be46315d19"}, + {file = "pycares-4.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:439799be4b7576e907139a7f9b3c8a01b90d3e38af4af9cd1fc6c1ee9a42b9e6"}, + {file = "pycares-4.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:40079ed58efa91747c50aac4edf8ecc7e570132ab57dc0a4030eb0d016a6cab8"}, + {file = "pycares-4.1.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e190471a015f8225fa38069617192e06122771cce2b169ac7a60bfdbd3d4ab2"}, + {file = "pycares-4.1.2-cp38-cp38-win32.whl", hash = "sha256:2b837315ed08c7df009b67725fe1f50489e99de9089f58ec1b243dc612f172aa"}, + {file = "pycares-4.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:c7eba3c8354b730a54d23237d0b6445a2f68570fa68d0848887da23a3f3b71f3"}, + {file = "pycares-4.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2f5f84fe9f83eab9cd68544b165b74ba6e3412d029cc9ab20098d9c332869fc5"}, + {file = "pycares-4.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569eef8597b5e02b1bc4644b9f272160304d8c9985357d7ecfcd054da97c0771"}, + {file = "pycares-4.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e1489aa25d14dbf7176110ead937c01176ed5a0ebefd3b092bbd6b202241814c"}, + {file = "pycares-4.1.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dc942692fca0e27081b7bb414bb971d34609c80df5e953f6d0c62ecc8019acd9"}, + {file = "pycares-4.1.2-cp39-cp39-win32.whl", hash = "sha256:ed71dc4290d9c3353945965604ef1f6a4de631733e9819a7ebc747220b27e641"}, + {file = "pycares-4.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:ec00f3594ee775665167b1a1630edceefb1b1283af9ac57480dba2fb6fd6c360"}, + {file = "pycares-4.1.2.tar.gz", hash = "sha256:03490be0e7b51a0c8073f877bec347eff31003f64f57d9518d419d9369452837"}, +] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, @@ -2130,6 +2534,10 @@ typed-ast = [ {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"}, {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] +typing = [ + {file = "typing-3.7.4.3-py2-none-any.whl", hash = "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"}, + {file = "typing-3.7.4.3.tar.gz", hash = "sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9"}, +] typing-extensions = [ {file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, {file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, @@ -2153,6 +2561,80 @@ wrapt = [ yamllint = [ {file = "yamllint-1.26.1.tar.gz", hash = "sha256:87d9462b3ed7e9dfa19caa177f7a77cd9888b3dc4044447d6ae0ab233bcd1324"}, ] +yarl = [ + {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"}, + {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"}, + {file = "yarl-1.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05"}, + {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523"}, + {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63"}, + {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98"}, + {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125"}, + {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e"}, + {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d"}, + {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23"}, + {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245"}, + {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739"}, + {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72"}, + {file = "yarl-1.7.2-cp310-cp310-win32.whl", hash = "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c"}, + {file = "yarl-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265"}, + {file = "yarl-1.7.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d"}, + {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656"}, + {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed"}, + {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee"}, + {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c"}, + {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92"}, + {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d"}, + {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b"}, + {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c"}, + {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa"}, + {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d"}, + {file = "yarl-1.7.2-cp36-cp36m-win32.whl", hash = "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1"}, + {file = "yarl-1.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913"}, + {file = "yarl-1.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63"}, + {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4"}, + {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba"}, + {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41"}, + {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e"}, + {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332"}, + {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52"}, + {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185"}, + {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986"}, + {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4"}, + {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b"}, + {file = "yarl-1.7.2-cp37-cp37m-win32.whl", hash = "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1"}, + {file = "yarl-1.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271"}, + {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576"}, + {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d"}, + {file = "yarl-1.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8"}, + {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d"}, + {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6"}, + {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a"}, + {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1"}, + {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0"}, + {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6"}, + {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832"}, + {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59"}, + {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8"}, + {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b"}, + {file = "yarl-1.7.2-cp38-cp38-win32.whl", hash = "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef"}, + {file = "yarl-1.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f"}, + {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0"}, + {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1"}, + {file = "yarl-1.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3"}, + {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746"}, + {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de"}, + {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda"}, + {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b"}, + {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794"}, + {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac"}, + {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec"}, + {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe"}, + {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8"}, + {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8"}, + {file = "yarl-1.7.2-cp39-cp39-win32.whl", hash = "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d"}, + {file = "yarl-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58"}, + {file = "yarl-1.7.2.tar.gz", hash = "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd"}, +] zipp = [ {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, diff --git a/pyproject.toml b/pyproject.toml index 8390a2db..6748899f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,13 +17,18 @@ include = [ "nautobot" = "nautobot_chatops.workers.nautobot:nautobot" [tool.poetry.dependencies] -python = "^3.6" +python = "^3.6.1" nautobot = "*" nautobot-capacity-metrics = "*" texttable = "^1.6.2" PyJWT = "^2.1.0" webexteamssdk = "^1.3" slack-sdk = "^3.4.2" +# For Socket Mode, websockets 9.1 doesn't support python 3.10, and websockets 10.0 doesn't support <3.7. +# websockets = "^9.1" +aiodns = "^1.0" +aiohttp = "^3.7.3" +asgiref = "^3.4.1" [tool.poetry.dev-dependencies] black = "*" diff --git a/tasks.py b/tasks.py index b9aaa77b..ff517932 100644 --- a/tasks.py +++ b/tasks.py @@ -43,7 +43,7 @@ def is_truthy(arg): "nautobot_chatops": { "nautobot_ver": "1.0.1", "project_name": "nautobot-chatops", - "python_ver": "3.6", + "python_ver": "3.7", "local": False, "compose_dir": os.path.join(os.path.dirname(__file__), "development"), "compose_files": ["docker-compose.requirements.yml", "docker-compose.base.yml", "docker-compose.dev.yml"], From 13ef3a810bc2319d37e4b32011062574058f3cc1 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Fri, 7 Oct 2022 22:01:15 -0500 Subject: [PATCH 02/21] Cleanup and provide Static Image options --- development/docker-compose.requirements.yml | 4 +-- development/nautobot_config.py | 17 ++-------- nautobot_chatops/__init__.py | 4 +++ nautobot_chatops/dispatchers/slack.py | 18 +++++++++- nautobot_chatops/dispatchers/slack_socket.py | 35 -------------------- nautobot_chatops/sockets/slack.py | 4 +-- pyproject.toml | 4 +-- 7 files changed, 29 insertions(+), 57 deletions(-) delete mode 100644 nautobot_chatops/dispatchers/slack_socket.py diff --git a/development/docker-compose.requirements.yml b/development/docker-compose.requirements.yml index 175cd297..17e52220 100644 --- a/development/docker-compose.requirements.yml +++ b/development/docker-compose.requirements.yml @@ -14,8 +14,8 @@ services: image: "redis:6-alpine" command: - "sh" - - "-c" # this is to evaluate the $REDIS_PASSWORD from the env - - "redis-server --appendonly yes --requirepass $$REDIS_PASSWORD" + - "-c" # this is to evaluate the $NAUTOBOT_REDIS_PASSWORD from the env + - "redis-server --appendonly yes --requirepass $$NAUTOBOT_REDIS_PASSWORD" env_file: - "dev.env" - "creds.env" diff --git a/development/nautobot_config.py b/development/nautobot_config.py index 47f1b506..e9b7c72d 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -6,6 +6,7 @@ from django.core.exceptions import ImproperlyConfigured from nautobot.core.settings import * # noqa: F401,F403 pylint: disable=wildcard-import,unused-wildcard-import +from nautobot.core.settings_funcs import parse_redis_connection # pylint: disable=line-too-long @@ -64,17 +65,6 @@ def is_truthy(arg): } } -# Redis variables -REDIS_HOST = os.getenv("NAUTOBOT_REDIS_HOST", "localhost") -REDIS_PORT = os.getenv("NAUTOBOT_REDIS_PORT", "6379") -REDIS_PASSWORD = os.getenv("NAUTOBOT_REDIS_PASSWORD", "") - -# Check for Redis SSL -REDIS_SCHEME = "redis" -REDIS_SSL = is_truthy(os.getenv("REDIS_SSL", "False")) -if REDIS_SSL: - REDIS_SCHEME = "rediss" - # The django-redis cache is used to establish concurrent locks using Redis. The # django-rq settings will use the same instance/database by default. # @@ -83,17 +73,16 @@ def is_truthy(arg): CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": f"{REDIS_SCHEME}://{REDIS_HOST}:{REDIS_PORT}/0", + "LOCATION": parse_redis_connection(redis_database=0), "TIMEOUT": 300, "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", - "PASSWORD": REDIS_PASSWORD, }, } } # REDIS CACHEOPS -CACHEOPS_REDIS = f"{REDIS_SCHEME}://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/1" +CACHEOPS_REDIS = parse_redis_connection(redis_database=1) # This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. # For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and diff --git a/nautobot_chatops/__init__.py b/nautobot_chatops/__init__.py index 586963b2..66988f18 100644 --- a/nautobot_chatops/__init__.py +++ b/nautobot_chatops/__init__.py @@ -36,6 +36,10 @@ class NautobotChatOpsConfig(PluginConfig): # Any prefix that's prepended to all slash-commands for this bot and should be stripped away # in order to identify the actual command name to be invoked, eg "/nautobot-" "slack_slash_command_prefix": "/", + # Since Slack Socket is meant keep Nautobot server out of public access, slack needs to know + # where to find Static images. If Django Storages is configured with an External server like S3, this can be ignored. + # If neither option is provided, then no static images (like Nautobot Logo) will be shown. + "slack_socket_static_host": None, # Microsoft-Teams-specific settings "microsoft_app_id": None, "microsoft_app_password": None, diff --git a/nautobot_chatops/dispatchers/slack.py b/nautobot_chatops/dispatchers/slack.py index dfc796ab..550482d1 100644 --- a/nautobot_chatops/dispatchers/slack.py +++ b/nautobot_chatops/dispatchers/slack.py @@ -7,6 +7,7 @@ from typing import Optional from django.conf import settings +from django.templatetags.static import static from slack_sdk import WebClient from slack_sdk.webhook.client import WebhookClient from slack_sdk.errors import SlackApiError, SlackClientError @@ -25,7 +26,7 @@ BACKEND_ACTION_SNIPPET = backend_action_sum.labels("slack", "send_snippet") SLACK_PRIVATE_MESSAGE_LIMIT = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_ephemeral_message_size_limit") - +SLACK_SOCKET_STATIC_HOST = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_socket_static_host") class SlackDispatcher(Dispatcher): """Dispatch messages and cards to Slack.""" @@ -489,3 +490,18 @@ def select_element(self, action_id, choices, default=(None, None), confirm=False def text_element(self, text): """Construct a basic plaintext element.""" return {"type": "plain_text", "text": text} + + +class SlackSocketDispatcher(SlackDispatcher): + + def static_url(self, path): + static_path = str(static(path)) + if static_path.startswith("http"): + return static_path + elif SLACK_SOCKET_STATIC_HOST: + return f"{SLACK_SOCKET_STATIC_HOST}{static_path}" + return None + + def image_element(self, url, alt_text=""): + return {"type": "image", "image_url": url, "alt_text": alt_text} if url else {} + diff --git a/nautobot_chatops/dispatchers/slack_socket.py b/nautobot_chatops/dispatchers/slack_socket.py deleted file mode 100644 index 7e2d5c94..00000000 --- a/nautobot_chatops/dispatchers/slack_socket.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Dispatcher implementation for sending content to Slack.""" - -import logging -import os - -from django.conf import settings -from django.templatetags.static import static - -from nautobot_chatops.metrics import backend_action_sum -from .slack import SlackDispatcher - -logger = logging.getLogger("rq.worker") - -# pylint: disable=abstract-method - -# Create a metric to track time spent and requests made. -BACKEND_ACTION_LOOKUP = backend_action_sum.labels("slack_socket", "platform_lookup") -BACKEND_ACTION_MARKDOWN = backend_action_sum.labels("slack_socket", "send_markdown") -BACKEND_ACTION_BLOCKS = backend_action_sum.labels("slack_socket", "send_blocks") -BACKEND_ACTION_SNIPPET = backend_action_sum.labels("slack_socket", "send_snippet") - -class SlackSocketDispatcher(SlackDispatcher): - """Dispatch messages and cards to Slack through SocketMode.""" - - # pylint: disable=too-many-public-methods - platform_name = "Slack" - platform_slug = "slack" - - platform_color = "4A154B" # Slack Aubergine - - command_prefix = settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_slash_command_prefix"] - """Prefix prepended to all commands, such as "/" or "!" in some clients.""" - - def static_url(self, path): - return str(static(path)) \ No newline at end of file diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index 37b8328b..d6331c33 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -10,7 +10,7 @@ from slack_sdk.web.async_client import AsyncWebClient from nautobot_chatops.workers import get_commands_registry, commands_help, parse_command_string -from nautobot_chatops.dispatchers.slack_socket import SlackSocketDispatcher +from nautobot_chatops.dispatchers.slack import SlackSocketDispatcher from nautobot_chatops.utils import check_and_enqueue_command @@ -211,7 +211,7 @@ async def process_interactive(client, req): # What we'd like to do here is send a "Nautobot is typing..." to the channel, # but unfortunately the API we're using doesn't support that (only the legacy/deprecated RTM API does). - # SlackDispatcher(context).send_busy_indicator() + # SlackSocketDispatcher(context).send_busy_indicator() return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) diff --git a/pyproject.toml b/pyproject.toml index eb57cf37..e6306ccb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-chatops" -version = "1.9.1" +version = "1.10.1" description = "A plugin providing chatbot capabilities for Nautobot" authors = ["Network to Code, LLC "] readme = "README.md" @@ -27,8 +27,6 @@ texttable = "^1.6.2" PyJWT = "^2.1.0" webexteamssdk = "^1.3" slack-sdk = "^3.4.2" -# For Socket Mode, websockets 9.1 doesn't support python 3.10, and websockets 10.0 doesn't support <3.7. -# websockets = "^9.1" aiodns = "^1.0" aiohttp = "^3.7.3" asgiref = "^3.4.1" From 9494ab3030921f644baf753f87de9b6baeef5317 Mon Sep 17 00:00:00 2001 From: Matt Vitale Date: Tue, 11 Oct 2022 10:23:01 -0400 Subject: [PATCH 03/21] Update docs with Slack socket mode --- docs/admin/install/slack_setup.md | 44 ++++++++++++++++---- docs/images/chatops-slack-socket-mode.png | Bin 0 -> 135403 bytes docs/images/chatops-slack-webhooks-mode.png | Bin 0 -> 135548 bytes 3 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 docs/images/chatops-slack-socket-mode.png create mode 100644 docs/images/chatops-slack-webhooks-mode.png diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index cb3694f7..e37fe5c4 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -28,24 +28,54 @@ PLUGINS_CONFIG = { } ``` +## Connecting to Slack + +The Nautobot ChatOps plugin supports two methods of communicating with Slack. + +1. Incoming Webhooks +2. Socket Mode + +The original supported method of connection was only incoming webhooks. As of version 1.10, socket mode support was added for Slack. + +### Webhooks vs. Socket Mode + +With incoming webhooks, whenever a user sends a message to the bot via the client application (phone or desktop app), (1) the connection is initiated from the client, and the message gets sent to Slacks cloud. The Slack servers then initiate a connection to the ChatOps plugin running on the Nautobot server (2). Since this is a new, incoming connection, it must be port forwarded and allowed through any firewalls in your network between the internet and your Nautobot server (3). Nautobot then replies to the existing connection to Slack, which in turn forwards the response to the client. + +![Chatops Slack Webhooks Mode](../../images/chatops-slack-client-mode.png) + +With socket mode, the Nautobot server will instead maintain a connection to the Slack cloud, initiating the connection *from* the Nautobot server itself (1). In this manner, externally facing firewalls do not need to allow inbound traffic from Slack to the Nautobot server. They only need to allow traffic outbound from the Nautobot server to Slack. Once a client sends a message to the bot (2), Slack forwards the message to Nautobot over the existing websocket connection (3). Nautobot then replies over the existing websocket connection to Slack, and Slack forwards the response to the client. + +![Chatops Slack Socket Mode](../../images/chatops-slack-socket-mode.png) + +While there are sufficient ways of securing inbound API requests from the public internet (e.g. using a secure web API gateway), using socket mode is generally easier to set up from a network and netsec perspective, especially for companies that do not currently have a web API gateway installed, or are unfamiliar with them. + ## Create Slack App using a Manifest +**Important** - In step 3, you *must* configure the manifest differently depending on if you are using Socket mode or not. + 1. Log in to [https://api.slack.com/apps](https://api.slack.com/apps) and select "Create New App". Select "From an app manifest." 2. Select your preferred Slack workspace for your app. -3. In the window titled "Enter app manifest below," copy/paste the contents of file [nautobot_slack_manifest.yml](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_slack_manifest.yml) in the root of this repo. Update the below settings, then click Next. +3. In the window titled "Enter app manifest below," select the "YAML" formatting tab and copy/paste the contents of file [nautobot_slack_manifest.yml](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_slack_manifest.yml) in the root of this repo. Update the below settings, then click Next. - On line 5, you can change the name of the Chatbot here. By default it is set to `Nautobot` - - On line 12, under setting `features/slash_commands/url`, update `` with a publicly accessible URL to your Nautobot server. Note: The trailing `/api/plugins/...` are required. - - Repeat this for line 31, under setting `settings/interactivity/request_url` + - If using Socket mode: + - On line 34, update `socket_mode_enabled` to `true` + - If not using Socket mode: + - On line 12, under setting `features/slash_commands/url`, update `` with a publicly accessible URL to your Nautobot server. Note: The trailing `/api/plugins/...` are required. + - Repeat this for line 31, under setting `settings/interactivity/request_url` + - On line 34, verify `socket_mode_enabled` is set to `false` 4. Review the summarized settings on the next window and click Create. 5. On the General --> Basic Information page, note the `Signing Secret` near the bottom, under App Credentials. This will be needed later for setting `SLACK_SIGNING_SECRET`. -6. Under Distribution --> Install App, select `Install to Workspace`. +6. On this same Basic Infomration page, select `Install to Workspace`. Select a channel to allow the app to post to (e.g. #general), and click `Allow`. - If you are not a Slack admin, this step will require approval first from an Slack admin in your company. - - Once installed, note the `Bot User OAuth Token` here. This will be needed later for setting `SLACK_API_TOKEN`. -7. Continue with below section "Post App-Creation Steps" +7. Gather the necessary API token: + - If using Socket mode: + - If not using Socket mode: + - Once installed, under Settings --> Install App, copy the `Bot User OAuth Token` here. This will be needed later for setting `SLACK_API_TOKEN`. +8. Continue with below section "Post App-Creation Steps" > **Optional:** You can configure the App Icon on the General --> Basic Information page. Under `App Icon`, select "Choose File." You can use the supplied icon [nautobot_chatops_icon.png](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_chatops_icon.png). -## Create Slack App without a Manifest (original method) +## Deprected - Create Slack App without a Manifest (original method) 1. Log in to [https://api.slack.com/apps](https://api.slack.com/apps) and select "Create New App". - Select "From scratch" diff --git a/docs/images/chatops-slack-socket-mode.png b/docs/images/chatops-slack-socket-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..2a29cf0fd99e533a2210774bdadeac8b41e93d68 GIT binary patch literal 135403 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�oLYE{s$ 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 N6y=`EmPi}F{(k{tCEEZ1 literal 0 HcmV?d00001 diff --git a/docs/images/chatops-slack-webhooks-mode.png b/docs/images/chatops-slack-webhooks-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..4fd541ae62f2461cc0bc6c1b87366928ad981174 GIT binary patch literal 135548 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

cSIDJE+CrnrUP`laA&>HBfRLY|U!1 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 z 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 literal 0 HcmV?d00001 From 6105b145d465404f65ad5523d78921477f425c9a Mon Sep 17 00:00:00 2001 From: Matt Vitale Date: Tue, 11 Oct 2022 10:23:07 -0400 Subject: [PATCH 04/21] Update manifest --- setup_files/nautobot_slack_manifest.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup_files/nautobot_slack_manifest.yml b/setup_files/nautobot_slack_manifest.yml index 6b6df7d2..2156ad0d 100644 --- a/setup_files/nautobot_slack_manifest.yml +++ b/setup_files/nautobot_slack_manifest.yml @@ -29,4 +29,6 @@ settings: interactivity: is_enabled: true request_url: https:///api/plugins/chatops/slack/interaction/ + org_deploy_enabled: false + token_rotation_enabled: false socket_mode_enabled: false From 6677c29811e77dd7d176695fb51847ddbad8c463 Mon Sep 17 00:00:00 2001 From: Matt Vitale Date: Tue, 11 Oct 2022 12:02:26 -0400 Subject: [PATCH 05/21] Update docs with socket mode token --- docs/admin/install/slack_setup.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index e37fe5c4..85673908 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -69,6 +69,10 @@ While there are sufficient ways of securing inbound API requests from the public - If you are not a Slack admin, this step will require approval first from an Slack admin in your company. 7. Gather the necessary API token: - If using Socket mode: + - Under Settings --> Basic Informmation, scroll down to section "App-Level Tokens" and click `Generate Token and Scopes` to generate an API token. + - **Token Name**: This can be anything you want. + - **Scopes**: Click `Add Scope` and select the option `connections:write`. + - Click `Generate`. Copy this API token. This will be needed later for setting `SLACK_API_TOKEN`. - If not using Socket mode: - Once installed, under Settings --> Install App, copy the `Bot User OAuth Token` here. This will be needed later for setting `SLACK_API_TOKEN`. 8. Continue with below section "Post App-Creation Steps" From af7f1041f8727fa4c5d194919e1c235795b9c3d3 Mon Sep 17 00:00:00 2001 From: Matt Vitale Date: Tue, 11 Oct 2022 14:00:38 -0400 Subject: [PATCH 06/21] Update docs with additional socket mode info --- docs/admin/install/slack_setup.md | 182 ++++++++++++++++++------------ 1 file changed, 111 insertions(+), 71 deletions(-) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index 85673908..dd9db729 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -67,20 +67,121 @@ While there are sufficient ways of securing inbound API requests from the public 5. On the General --> Basic Information page, note the `Signing Secret` near the bottom, under App Credentials. This will be needed later for setting `SLACK_SIGNING_SECRET`. 6. On this same Basic Infomration page, select `Install to Workspace`. Select a channel to allow the app to post to (e.g. #general), and click `Allow`. - If you are not a Slack admin, this step will require approval first from an Slack admin in your company. -7. Gather the necessary API token: - - If using Socket mode: - - Under Settings --> Basic Informmation, scroll down to section "App-Level Tokens" and click `Generate Token and Scopes` to generate an API token. - - **Token Name**: This can be anything you want. - - **Scopes**: Click `Add Scope` and select the option `connections:write`. - - Click `Generate`. Copy this API token. This will be needed later for setting `SLACK_API_TOKEN`. - - If not using Socket mode: - - Once installed, under Settings --> Install App, copy the `Bot User OAuth Token` here. This will be needed later for setting `SLACK_API_TOKEN`. -8. Continue with below section "Post App-Creation Steps" +7. If using Socket mode: + - Under Settings --> Basic Informmation, scroll down to section "App-Level Tokens" and click `Generate Token and Scopes` to generate an API token. + - **Token Name**: This can be anything you want. + - **Scopes**: Click `Add Scope` and select the option `connections:write`. + - Click `Generate`. Copy this API token. This will be needed later for setting `SLACK_APP_TOKEN`. +8. Under Settings --> Install App, copy the `Bot User OAuth Token` here. This will be needed later for setting `SLACK_API_TOKEN`. +9. Continue with below section "Post App-Creation Steps" > **Optional:** You can configure the App Icon on the General --> Basic Information page. Under `App Icon`, select "Choose File." You can use the supplied icon [nautobot_chatops_icon.png](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_chatops_icon.png). +## Post App-Creation Steps + +### Configuration Examples + +Before continuing to the general install guide (linked below), you will need the token(s) and secret you previously generated. + +In your `nautobot_config.py` file, the following `PLUGINS` and `PLUGINS_CONFIG` variables will need to look simlar to this: + +```python +PLUGINS = ["nautobot_chatops"] + +PLUGINS_CONFIG = { + "nautobot_chatops": { + "enable_slack": True, + "slack_api_token": "", + "slack_app_token": "", + "slack_signing_secret": "", + "slack_slash_command_prefix": "/", + } +} +``` + +The `slack_app_token` is *only* used if you are using Socket mode when setting up your chatbot. Otherwise it can be safely ignored. + +You can also set these values as environment variables, and use the example listed below. Note the environment variables are all uppercase. + +```python +PLUGINS = ["nautobot_chatops"] + +PLUGINS_CONFIG = { + "nautobot_chatops": { + "enable_slack": True, + "slack_api_token": os.environ.get("SLACK_API_TOKEN"), + "slack_app_token": os.environ.get("SLACK_APP_TOKEN"), + "slack_signing_secret": os.environ.get("SLACK_SIGNING_SECRET"), + "slack_slash_command_prefix": os.environ.get("SLACK_SLASH_COMMAND_PREFIX", "/"), + } +} +``` + +### Invite Chatbot to Channels + +> **Note**: In the Slack app, you will need to invite the chatbot to each channel that it will belong to with `@`. +> For example, when an app named `Nautobot ChatOps` is installed to the workspace: +> +> 1. A message is displayed in the channel, saying that the integration`Nautobot ChatOps` has been added +> 2. You `@Nautobot ChatOps` in the channel +> 3. You are prompted to add `@Nautobot ChatOps` to the channel + +![slack integration invite](../../images/add_nautobot.png) + +Once these steps are completed, you can proceed to the [Install Guide](index.md#Install-Guide) section. + +## Configuring Multiple Chatbots in a Workspace + +Chatbots from multiple Nautobot implementations can exist in a single Slack workspace and even channel. + +They will be differentiated in the workspace using the `slack_slash_command_prefix` value in `PLUGINS_CONFIG`. + +Here is an example `nautobot_config.py` for the first Nautobot chatbot implementation in the workspace. This chatbot will be called in the workspace using `/nautobot`. + +```python +# Enable installed plugins. Add the name of each plugin to the list. +PLUGINS = ["nautobot_chatops"] + +PLUGINS_CONFIG = { + "nautobot_chatops": { + "enable_slack": True, + "slack_api_token": "", + "slack_signing_secret": "", + } +} +``` + +Here is an example `nautobot_config.py` for a second Nautobot chatbot implementation in the workspace. +This configuration explicitly configures the `slack_slash_command_prefix` key/value. +This chatbot will be called in the workspace using `/network2-nautobot`. + +```python +# Enable installed plugins. Add the name of each plugin to the list. +PLUGINS = ["nautobot_chatops"] + +PLUGINS_CONFIG = { + "nautobot_chatops": { + "enable_slack": True, + "slack_api_token": "", + "slack_signing_secret": "", + "slack_slash_command_prefix": "/network2-" + } +} +``` + +> NOTE: by default, your slash command must end with `nautobot`. If no `slack_slash_command_prefix` is specified, +> the slash command will be `/nautobot`. If a `slack_slash_command_prefix` is specified, the slash command will be `nautobot`. + +> NOTE: Custom chatbot development allows for chatbot slash commands such as `/grafana` and `/meraki`. + +## General Chat Setup Instructions + +See [admin_install](index.md) instructions here for general plugin setup instructions. + ## Deprected - Create Slack App without a Manifest (original method) +While this method is still possible, we recommend using the App Manifest method (described above) to install your Slack App. + 1. Log in to [https://api.slack.com/apps](https://api.slack.com/apps) and select "Create New App". - Select "From scratch" - Enter "Nautobot ChatOps" as the "App Name" @@ -133,65 +234,4 @@ While there are sufficient ways of securing inbound API requests from the public 6. Returning to the "Basic Information" page for your app, under "Display Information", you can specify the name, description, icon, and accent/background color for the app. You can use the `nautobot_logo.png` from this directory if desired. -7. Continue with below section "Post App-Creation Steps" - -## Post App-Creation Steps - -Proceed to the [Install Guide](index.md#Install-Guide) section. - -> **Note**: In the Slack app, you will need to invite the chatbot to each channel that it will belong to with `@`. -> For example, when an app named `Nautobot ChatOps` is installed to the workspace: -> -> 1. A message is displayed in the channel, saying that the integration`Nautobot ChatOps` has been added -> 2. You `@Nautobot ChatOps` in the channel -> 3. You are prompted to add `@Nautobot ChatOps` to the channel - -![slack integration invite](../../images/add_nautobot.png) - -## Configuring Multiple Chatbots in a Workspace - -Chatbots from multiple Nautobot implementations can exist in a single Slack workspace and even channel. - -They will be differentiated in the workspace using the `slack_slash_command_prefix` value in `PLUGINS_CONFIG`. - -Here is an example `nautobot_config.py` for the first Nautobot chatbot implementation in the workspace. This chatbot will be called in the workspace using `/nautobot`. - -```python -# Enable installed plugins. Add the name of each plugin to the list. -PLUGINS = ["nautobot_chatops"] - -PLUGINS_CONFIG = { - 'nautobot_chatops': { - 'enable_slack': True, - 'slack_api_token': '', - 'slack_signing_secret': '', - } -} -``` - -Here is an example `nautobot_config.py` for a second Nautobot chatbot implementation in the workspace. -This configuration explicitly configures the `slack_slash_command_prefix` key/value. -This chatbot will be called in the workspace using `/network2-nautobot`. - -```python -# Enable installed plugins. Add the name of each plugin to the list. -PLUGINS = ["nautobot_chatops"] - -PLUGINS_CONFIG = { - 'nautobot_chatops': { - 'enable_slack': True, - 'slack_api_token': '', - 'slack_signing_secret': '', - 'slack_slash_command_prefix': '/network2-' - } -} -``` - -> NOTE: by default, your slash command must end with `nautobot`. If no `slack_slash_command_prefix` is specified, -> the slash command will be `/nautobot`. If a `slack_slash_command_prefix` is specified, the slash command will be `nautobot`. - -> NOTE: Custom chatbot development allows for chatbot slash commands such as `/grafana` and `/meraki`. - -## General Chat Setup Instructions - -See [admin_install](index.md) instructions here for general plugin setup instructions. +7. Continue with below section "Post App-Creation Steps" \ No newline at end of file From cce034918ac56948ae274d488354787ce2a07fb5 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Tue, 11 Oct 2022 14:38:30 -0500 Subject: [PATCH 07/21] Cleanup for testing. --- development/docker-compose.socket.yml | 17 +++++++++++ nautobot_chatops/__init__.py | 3 +- nautobot_chatops/dispatchers/slack.py | 9 ++++-- .../management/commands/start_slack_socket.py | 4 +++ nautobot_chatops/sockets/slack.py | 28 ++++++------------- poetry.lock | 4 +-- pyproject.toml | 2 +- tasks.py | 3 +- 8 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 development/docker-compose.socket.yml diff --git a/development/docker-compose.socket.yml b/development/docker-compose.socket.yml new file mode 100644 index 00000000..1311584e --- /dev/null +++ b/development/docker-compose.socket.yml @@ -0,0 +1,17 @@ +--- +version: "3.4" +services: + socket: + image: "nautobot-chatops-plugin/nautobot:${NAUTOBOT_VER}-py${PYTHON_VER}" + env_file: + - "dev.env" + - "creds.env" + tty: true + entrypoint: "nautobot-server start_slack_socket" + depends_on: + - "nautobot" + healthcheck: + disable: true + volumes: + - "./nautobot_config.py:/opt/nautobot/nautobot_config.py" + - "../:/source" diff --git a/nautobot_chatops/__init__.py b/nautobot_chatops/__init__.py index 66988f18..cc521d76 100644 --- a/nautobot_chatops/__init__.py +++ b/nautobot_chatops/__init__.py @@ -37,7 +37,8 @@ class NautobotChatOpsConfig(PluginConfig): # in order to identify the actual command name to be invoked, eg "/nautobot-" "slack_slash_command_prefix": "/", # Since Slack Socket is meant keep Nautobot server out of public access, slack needs to know - # where to find Static images. If Django Storages is configured with an External server like S3, this can be ignored. + # where to find Static images. If Django Storages is configured with an External server like S3, + # this can be ignored. # If neither option is provided, then no static images (like Nautobot Logo) will be shown. "slack_socket_static_host": None, # Microsoft-Teams-specific settings diff --git a/nautobot_chatops/dispatchers/slack.py b/nautobot_chatops/dispatchers/slack.py index 550482d1..9d9fecf8 100644 --- a/nautobot_chatops/dispatchers/slack.py +++ b/nautobot_chatops/dispatchers/slack.py @@ -28,6 +28,7 @@ SLACK_PRIVATE_MESSAGE_LIMIT = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_ephemeral_message_size_limit") SLACK_SOCKET_STATIC_HOST = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_socket_static_host") + class SlackDispatcher(Dispatcher): """Dispatch messages and cards to Slack.""" @@ -493,15 +494,19 @@ def text_element(self, text): class SlackSocketDispatcher(SlackDispatcher): + """Overrides to support Slack Socket Mode.""" def static_url(self, path): + """Return a url to access the static file.""" static_path = str(static(path)) if static_path.startswith("http"): + # Static is being provided by Django Storages return static_path - elif SLACK_SOCKET_STATIC_HOST: + if SLACK_SOCKET_STATIC_HOST: + # Use the settings provided Static Host. return f"{SLACK_SOCKET_STATIC_HOST}{static_path}" return None def image_element(self, url, alt_text=""): + """Construct an image element that can be embedded in a block if URL is provided.""" return {"type": "image", "image_url": url, "alt_text": alt_text} if url else {} - diff --git a/nautobot_chatops/management/commands/start_slack_socket.py b/nautobot_chatops/management/commands/start_slack_socket.py index ca86529d..0c8fb3f2 100644 --- a/nautobot_chatops/management/commands/start_slack_socket.py +++ b/nautobot_chatops/management/commands/start_slack_socket.py @@ -1,9 +1,13 @@ +"""Command to start a slack socket.""" + import asyncio from django.core.management.base import BaseCommand from nautobot_chatops.sockets.slack import main + class Command(BaseCommand): """Starts the Slack Socket.""" def handle(self, *args, **kwargs): + """Start the Slack Socket Main loop.""" asyncio.run(main()) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index d6331c33..a4c97619 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -2,11 +2,12 @@ import asyncio import json -import logging import shlex from django.conf import settings from slack_sdk.socket_mode.aiohttp import SocketModeClient +from slack_sdk.socket_mode.response import SocketModeResponse +from slack_sdk.socket_mode.request import SocketModeRequest from slack_sdk.web.async_client import AsyncWebClient from nautobot_chatops.workers import get_commands_registry, commands_help, parse_command_string @@ -16,12 +17,9 @@ SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") -#logger = logging.getLogger(__name__) - -async def main(): - from slack_sdk.socket_mode.response import SocketModeResponse - from slack_sdk.socket_mode.request import SocketModeRequest +async def main(): # pylint: disable=too-many-statements + """Slack Socket Main Loop.""" client = SocketModeClient( app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]), @@ -58,15 +56,14 @@ async def process_slash_command(client, req): "user_id": req.payload.get("user_id"), "user_name": req.payload.get("user_name"), "response_url": req.payload.get("response_url"), - "trigger_id": req.payload.get("trigger_id") + "trigger_id": req.payload.get("trigger_id"), } try: command, subcommand, params = parse_command_string(f"{command} {params}") except ValueError as err: client.logger.error("%s", err) - # Tried sending 400 error, but the friendly message never made it to slack. - + registry = get_commands_registry() if command not in registry: @@ -74,6 +71,7 @@ async def process_slash_command(client, req): return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements,too-many-nested-blocks async def process_interactive(client, req): client.logger.debug("Processing interactive.") payload = req.payload @@ -110,7 +108,6 @@ async def process_interactive(client, req): selected_value = f"'{value}'" else: client.logger.error(f"Unhandled action type {action['type']}") - #return HttpResponse(status=500) if settings.PLUGINS_CONFIG["nautobot_chatops"].get("delete_input_on_submission"): # Delete the interactive element since it's served its purpose @@ -118,7 +115,7 @@ async def process_interactive(client, req): if action_id == "action" and selected_value == "cancel": # Nothing more to do return - #return HttpResponse() + elif "view" in payload and payload["view"]: # View submission triggered from a modal dialog client.logger.info("Submission triggered from a modal dialog") @@ -137,7 +134,6 @@ async def process_interactive(client, req): cmds = shlex.split(callback_id) except ValueError as err: client.logger.error("%s", err) - #return HttpResponse(f"Error: {err} encountered when processing {callback_id}") for i, cmd in enumerate(cmds): if i == 2: selected_value += f"'{cmd}'" @@ -158,7 +154,6 @@ async def process_interactive(client, req): value = act_id["value"] else: client.logger.error(f"Unhandled dialog type {act_id['type']}") - #return HttpResponse(status=500) # If an optional parameter is passed, it is returned as a NoneType. # We instead want to return an empty string, otherwise 'None' is returned as a string. @@ -177,7 +172,6 @@ async def process_interactive(client, req): selected_value = f"'{value}'" else: client.logger.error(f"Unhandled action type {action['type']}") - #return HttpResponse(status=500) # Modal view submissions don't generally contain a channel ID, but we hide one for our convenience: if "private_metadata" in payload["view"]: @@ -186,15 +180,12 @@ async def process_interactive(client, req): context["channel_id"] = private_metadata["channel_id"] else: client.logger.error("I didn't understand that notification.") - #return HttpResponse("I didn't understand that notification.") client.logger.info(f"action_id: {action_id}, selected_value: {selected_value}") try: command, subcommand, params = parse_command_string(f"{action_id} {selected_value}") except ValueError as err: client.logger.error("%s", err) - # Tried sending 400 error, but the friendly message never made it to slack. - #return HttpResponse(f"'Error: {err}' encountered on command '{action_id} {selected_value}'.") # Convert empty parameter strings to NoneType for idx, param in enumerate(params): @@ -207,7 +198,6 @@ async def process_interactive(client, req): if command not in registry: SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) - #return HttpResponse() # What we'd like to do here is send a "Nautobot is typing..." to the channel, # but unfortunately the API we're using doesn't support that (only the legacy/deprecated RTM API does). @@ -215,10 +205,8 @@ async def process_interactive(client, req): return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) - client.socket_mode_request_listeners.append(process) await client.connect() await asyncio.sleep(float("inf")) - diff --git a/poetry.lock b/poetry.lock index 6c404fdd..35de8d3b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -74,7 +74,7 @@ python-versions = ">=3.7" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] +tests = ["pytest", "mypy (>=0.800)"] [[package]] name = "astroid" @@ -1827,7 +1827,7 @@ python-versions = ">=3.6.0" [package.extras] optional = ["aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "SQLAlchemy (>=1,<2)", "websockets (>=10,<11)", "websocket-client (>=1,<2)"] -testing = ["pytest (>=6.2.5,<7)", "pytest-asyncio (<1)", "Flask-Sockets (>=0.2,<1)", "Flask (>=1,<2)", "Werkzeug (<2)", "itsdangerous (==1.1.0)", "Jinja2 (==3.0.3)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=5,<6)", "black (==22.8.0)", "click (==8.0.4)", "psutil (>=5,<6)", "databases (>=0.5)", "boto3 (<=2)", "moto (>=3,<4)"] +testing = ["pytest (>=6.2.5,<7)", "Flask-Sockets (>=0.2,<1)", "Flask (>=1,<2)", "Werkzeug (<2)", "itsdangerous (==1.1.0)", "Jinja2 (==3.0.3)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=5,<6)", "black (==22.8.0)", "click (==8.0.4)", "psutil (>=5,<6)", "databases (>=0.5)", "boto3 (<=2)", "moto (>=3,<4)"] [[package]] name = "smmap" diff --git a/pyproject.toml b/pyproject.toml index e6306ccb..d8f2fa38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,7 +97,7 @@ max-public-methods=22 [tool.pylint.similarities] ignore-imports= true -min-similarity-lines=12 +min-similarity-lines=0 [tool.pylint.format] max-line-length=120 diff --git a/tasks.py b/tasks.py index dfac99c4..e09177a3 100644 --- a/tasks.py +++ b/tasks.py @@ -35,8 +35,6 @@ def is_truthy(arg): # Use pyinvoke configuration for default values, see http://docs.pyinvoke.org/en/stable/concepts/configuration.html # Variables may be overwritten in invoke.yml or by the environment variables INVOKE_NAUTOBOT_CHATOPS_xxx -# To test with celery support first run `poetry lock` to update your lock file, then -# change nautobot_ver to match the lock file and add docker-compose.celery.yml to the compose_files namespace = Collection("nautobot_chatops") namespace.configure( { @@ -51,6 +49,7 @@ def is_truthy(arg): "docker-compose.celery.yml", "docker-compose.base.yml", "docker-compose.dev.yml", + # "docker-compose.socket.yml", ], } } From bbcff857bb4f41784e3e6460cd74095dfcaef2c0 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 13 Oct 2022 00:10:10 -0500 Subject: [PATCH 08/21] Correct failing tests. --- creds.env.example | 10 -------- docs/admin/install/slack_setup.md | 2 +- nautobot_chatops/tests/test_utils.py | 38 ++++++++++++++-------------- 3 files changed, 20 insertions(+), 30 deletions(-) delete mode 100644 creds.env.example diff --git a/creds.env.example b/creds.env.example deleted file mode 100644 index 183d849f..00000000 --- a/creds.env.example +++ /dev/null @@ -1,10 +0,0 @@ -# nautobot_chatops -SLACK_API_TOKEN=xoxb-... -SLACK_SIGNING_SECRET=... -# SLACK_SLASH_COMMAND_PREFIX=/ -MICROSOFT_APP_ID=... -MICROSOFT_APP_PASSWORD=... -WEBEX_ACCESS_TOKEN=... -WEBEX_SIGNING_SECRET=... -MATTERMOST_API_TOKEN=... -MATTERMOST_URL=... diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index dd9db729..63efe9d1 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -41,7 +41,7 @@ The original supported method of connection was only incoming webhooks. As of ve With incoming webhooks, whenever a user sends a message to the bot via the client application (phone or desktop app), (1) the connection is initiated from the client, and the message gets sent to Slacks cloud. The Slack servers then initiate a connection to the ChatOps plugin running on the Nautobot server (2). Since this is a new, incoming connection, it must be port forwarded and allowed through any firewalls in your network between the internet and your Nautobot server (3). Nautobot then replies to the existing connection to Slack, which in turn forwards the response to the client. -![Chatops Slack Webhooks Mode](../../images/chatops-slack-client-mode.png) +![Chatops Slack Webhooks Mode](../../images/chatops-slack-webhooks-mode.png) With socket mode, the Nautobot server will instead maintain a connection to the Slack cloud, initiating the connection *from* the Nautobot server itself (1). In this manner, externally facing firewalls do not need to allow inbound traffic from Slack to the Nautobot server. They only need to allow traffic outbound from the Nautobot server to Slack. Once a client sends a message to the bot (2), Slack forwards the message to Nautobot over the existing websocket connection (3). Nautobot then replies over the existing websocket connection to Slack, and Slack forwards the response to the client. diff --git a/nautobot_chatops/tests/test_utils.py b/nautobot_chatops/tests/test_utils.py index f9c10cd8..442a8ba5 100644 --- a/nautobot_chatops/tests/test_utils.py +++ b/nautobot_chatops/tests/test_utils.py @@ -48,10 +48,10 @@ class TestCheckAndEnqueue(TestCase): "z": {"function": nada, "subcommands": {}}, } - def test_default_deny(self, mock_enqueue_task): + async def test_default_deny(self, mock_enqueue_task): """With no AccessGrants in the database, all requests are denied by default.""" mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, "x", "y", @@ -75,7 +75,7 @@ def test_default_deny(self, mock_enqueue_task): value="11", ) mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, "x", "y", @@ -99,7 +99,7 @@ def test_default_deny(self, mock_enqueue_task): value="111", ) mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, "x", "y", @@ -123,7 +123,7 @@ def test_default_deny(self, mock_enqueue_task): value="1111", ) mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, "x", "y", @@ -226,13 +226,13 @@ def setup_db(self): value="*", ) - def test_permitted_globally(self, mock_enqueue_task): + async def test_permitted_globally(self, mock_enqueue_task): """A global access grant applies to all commands and subcommands.""" self.setup_db() # user1/channel1/org1 are globally permitted for cmd, subcmd in [("x", "a"), ("x", "b"), ("y", "a"), ("z", "a")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -243,14 +243,14 @@ def test_permitted_globally(self, mock_enqueue_task): self.assertIsNone(MockDispatcher.error) mock_enqueue_task.assert_called_once() - def test_permitted_command(self, mock_enqueue_task): + async def test_permitted_command(self, mock_enqueue_task): """A per-command access grant applies to all subcommands under the command, and no others.""" self.setup_db() # user2/channel2/org2 are explicitly permitted to subcommands of command "x" # all users/channels/orgs are permitted to subcommands of command "y" for cmd, subcmd in [("x", "a"), ("x", "b"), ("y", "a")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -262,7 +262,7 @@ def test_permitted_command(self, mock_enqueue_task): mock_enqueue_task.assert_called_once() for cmd, subcmd in [("z", "a")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -277,7 +277,7 @@ def test_permitted_command(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - def test_permitted_subcommand(self, mock_enqueue_task): + async def test_permitted_subcommand(self, mock_enqueue_task): """A per-subcommand access grant applies that subcommands under that command, and no others.""" self.setup_db() # user3/channel3/org3 are only permitted to subcommand "a" of command "x" @@ -285,7 +285,7 @@ def test_permitted_subcommand(self, mock_enqueue_task): # 3rd and 4th use cases are for verifying that the help commands will execute for cmd, subcmd in [("x", "a"), ("y", "a"), ("x", ""), ("y", "")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -298,7 +298,7 @@ def test_permitted_subcommand(self, mock_enqueue_task): for cmd, subcmd in [("x", "b"), ("z", "a"), ("z", "")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -313,12 +313,12 @@ def test_permitted_subcommand(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - def test_not_permitted_user(self, mock_enqueue_task): + async def test_not_permitted_user(self, mock_enqueue_task): """Per-user access grants are checked.""" self.setup_db() for cmd, subcmd in [("x", "a"), ("x", "b"), ("z", "a")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -333,12 +333,12 @@ def test_not_permitted_user(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - def test_not_permitted_channel(self, mock_enqueue_task): + async def test_not_permitted_channel(self, mock_enqueue_task): """Per-channel access grants are checked.""" self.setup_db() for cmd, subcmd in [("x", "a"), ("x", "b"), ("z", "a")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -353,12 +353,12 @@ def test_not_permitted_channel(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - def test_not_permitted_organization(self, mock_enqueue_task): + async def test_not_permitted_organization(self, mock_enqueue_task): """Per-organization access grants are checked.""" self.setup_db() for cmd, subcmd in [("x", "a"), ("x", "b"), ("z", "a")]: mock_enqueue_task.reset_mock() - check_and_enqueue_command( + await check_and_enqueue_command( self.mock_registry, cmd, subcmd, From 207ae610f7cc22e30a92b777697bc87bba860921 Mon Sep 17 00:00:00 2001 From: Matt Vitale Date: Thu, 13 Oct 2022 12:37:14 -0400 Subject: [PATCH 09/21] Fix non-socket mode --- nautobot_chatops/sockets/slack.py | 6 +++--- nautobot_chatops/utils.py | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index a4c97619..07a53993 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -12,7 +12,7 @@ from nautobot_chatops.workers import get_commands_registry, commands_help, parse_command_string from nautobot_chatops.dispatchers.slack import SlackSocketDispatcher -from nautobot_chatops.utils import check_and_enqueue_command +from nautobot_chatops.utils import socket_check_and_enqueue_command SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") @@ -69,7 +69,7 @@ async def process_slash_command(client, req): if command not in registry: SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) - return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements,too-many-nested-blocks async def process_interactive(client, req): @@ -203,7 +203,7 @@ async def process_interactive(client, req): # but unfortunately the API we're using doesn't support that (only the legacy/deprecated RTM API does). # SlackSocketDispatcher(context).send_busy_indicator() - return await check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) client.socket_mode_request_listeners.append(process) diff --git a/nautobot_chatops/utils.py b/nautobot_chatops/utils.py index eea12e26..50fdcf5b 100644 --- a/nautobot_chatops/utils.py +++ b/nautobot_chatops/utils.py @@ -108,6 +108,13 @@ def create_command_log(dispatcher, registry, command, subcommand, params=()): @sync_to_async +def socket_check_and_enqueue_command( + registry, command, subcommand, params, context, dispatcher_class +): # pylint:disable=too-many-statements + """Calls check_and_enqueue_command() when in Socket mode.""" + return check_and_enqueue_command(registry, command, subcommand, params, context, dispatcher_class) + + def check_and_enqueue_command( registry, command, subcommand, params, context, dispatcher_class ): # pylint:disable=too-many-statements From d9c4a4a153e688bd5dc9004659fc42eb8d399a28 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 13 Oct 2022 12:03:41 -0500 Subject: [PATCH 10/21] Fix tests after changes. --- nautobot_chatops/sockets/slack.py | 8 ++++-- nautobot_chatops/tests/test_utils.py | 38 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index 07a53993..85d16e86 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -69,7 +69,9 @@ async def process_slash_command(client, req): if command not in registry: SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) - return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + return await socket_check_and_enqueue_command( + registry, command, subcommand, params, context, SlackSocketDispatcher + ) # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements,too-many-nested-blocks async def process_interactive(client, req): @@ -203,7 +205,9 @@ async def process_interactive(client, req): # but unfortunately the API we're using doesn't support that (only the legacy/deprecated RTM API does). # SlackSocketDispatcher(context).send_busy_indicator() - return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackSocketDispatcher) + return await socket_check_and_enqueue_command( + registry, command, subcommand, params, context, SlackSocketDispatcher + ) client.socket_mode_request_listeners.append(process) diff --git a/nautobot_chatops/tests/test_utils.py b/nautobot_chatops/tests/test_utils.py index 442a8ba5..f9c10cd8 100644 --- a/nautobot_chatops/tests/test_utils.py +++ b/nautobot_chatops/tests/test_utils.py @@ -48,10 +48,10 @@ class TestCheckAndEnqueue(TestCase): "z": {"function": nada, "subcommands": {}}, } - async def test_default_deny(self, mock_enqueue_task): + def test_default_deny(self, mock_enqueue_task): """With no AccessGrants in the database, all requests are denied by default.""" mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, "x", "y", @@ -75,7 +75,7 @@ async def test_default_deny(self, mock_enqueue_task): value="11", ) mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, "x", "y", @@ -99,7 +99,7 @@ async def test_default_deny(self, mock_enqueue_task): value="111", ) mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, "x", "y", @@ -123,7 +123,7 @@ async def test_default_deny(self, mock_enqueue_task): value="1111", ) mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, "x", "y", @@ -226,13 +226,13 @@ def setup_db(self): value="*", ) - async def test_permitted_globally(self, mock_enqueue_task): + def test_permitted_globally(self, mock_enqueue_task): """A global access grant applies to all commands and subcommands.""" self.setup_db() # user1/channel1/org1 are globally permitted for cmd, subcmd in [("x", "a"), ("x", "b"), ("y", "a"), ("z", "a")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -243,14 +243,14 @@ async def test_permitted_globally(self, mock_enqueue_task): self.assertIsNone(MockDispatcher.error) mock_enqueue_task.assert_called_once() - async def test_permitted_command(self, mock_enqueue_task): + def test_permitted_command(self, mock_enqueue_task): """A per-command access grant applies to all subcommands under the command, and no others.""" self.setup_db() # user2/channel2/org2 are explicitly permitted to subcommands of command "x" # all users/channels/orgs are permitted to subcommands of command "y" for cmd, subcmd in [("x", "a"), ("x", "b"), ("y", "a")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -262,7 +262,7 @@ async def test_permitted_command(self, mock_enqueue_task): mock_enqueue_task.assert_called_once() for cmd, subcmd in [("z", "a")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -277,7 +277,7 @@ async def test_permitted_command(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - async def test_permitted_subcommand(self, mock_enqueue_task): + def test_permitted_subcommand(self, mock_enqueue_task): """A per-subcommand access grant applies that subcommands under that command, and no others.""" self.setup_db() # user3/channel3/org3 are only permitted to subcommand "a" of command "x" @@ -285,7 +285,7 @@ async def test_permitted_subcommand(self, mock_enqueue_task): # 3rd and 4th use cases are for verifying that the help commands will execute for cmd, subcmd in [("x", "a"), ("y", "a"), ("x", ""), ("y", "")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -298,7 +298,7 @@ async def test_permitted_subcommand(self, mock_enqueue_task): for cmd, subcmd in [("x", "b"), ("z", "a"), ("z", "")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -313,12 +313,12 @@ async def test_permitted_subcommand(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - async def test_not_permitted_user(self, mock_enqueue_task): + def test_not_permitted_user(self, mock_enqueue_task): """Per-user access grants are checked.""" self.setup_db() for cmd, subcmd in [("x", "a"), ("x", "b"), ("z", "a")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -333,12 +333,12 @@ async def test_not_permitted_user(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - async def test_not_permitted_channel(self, mock_enqueue_task): + def test_not_permitted_channel(self, mock_enqueue_task): """Per-channel access grants are checked.""" self.setup_db() for cmd, subcmd in [("x", "a"), ("x", "b"), ("z", "a")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, @@ -353,12 +353,12 @@ async def test_not_permitted_channel(self, mock_enqueue_task): ) mock_enqueue_task.assert_not_called() - async def test_not_permitted_organization(self, mock_enqueue_task): + def test_not_permitted_organization(self, mock_enqueue_task): """Per-organization access grants are checked.""" self.setup_db() for cmd, subcmd in [("x", "a"), ("x", "b"), ("z", "a")]: mock_enqueue_task.reset_mock() - await check_and_enqueue_command( + check_and_enqueue_command( self.mock_registry, cmd, subcmd, From 64febe303d4c138863aad1b869e484fe43654db3 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Fri, 14 Oct 2022 11:14:20 -0500 Subject: [PATCH 11/21] Add Slack Socket Startup documentation --- docs/admin/install/slack_setup.md | 43 ++++++++++++++++++++++++++++++- pyproject.toml | 2 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index 63efe9d1..414f2806 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -178,6 +178,47 @@ PLUGINS_CONFIG = { See [admin_install](index.md) instructions here for general plugin setup instructions. +## Startup Slack Sockets (Socket Mode) + +Socket Mode requires it's own Worker in order poll Slack for new slash commands and interactions. Slack Socket Mode supports up to 10 active connections. To start a new connection there is a new Management Command provided. + +### start_slack_socket Management Command + +`nautobot-server start_slack_socket` + +Start a worker to connect to Slack. + +### Slack Socket Systemd Service + +To establish the `systemd` unit file for the Slack Socket worker, copy and paste the following into `/etc/systemd/system/chatops-slack-socket.service`: + +```ini +[Unit] +Description=Nautobot Chatops Slack Socket Worker +Documentation=https://docs.nautobot.com/projects/chatops/en/latest/ +After=nautobot.service +Wants=network-online.target + +[Service] +Type=exec +Environment="NAUTOBOT_ROOT=/opt/nautobot" + +User=nautobot +Group=nautobot +WorkingDirectory=/opt/nautobot + +ExecStart=/opt/nautobot/bin/nautobot-server start_slack_socket + +Restart=always +RestartSec=30 +PrivateTmp=true + +[Install] +WantedBy=multi-user.target +``` + +This can be done multiple times to create more workers. Up to 10 workers can be created. + ## Deprected - Create Slack App without a Manifest (original method) While this method is still possible, we recommend using the App Manifest method (described above) to install your Slack App. @@ -234,4 +275,4 @@ While this method is still possible, we recommend using the App Manifest method 6. Returning to the "Basic Information" page for your app, under "Display Information", you can specify the name, description, icon, and accent/background color for the app. You can use the `nautobot_logo.png` from this directory if desired. -7. Continue with below section "Post App-Creation Steps" \ No newline at end of file +7. Continue with below section "Post App-Creation Steps" diff --git a/pyproject.toml b/pyproject.toml index d8f2fa38..39477caf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-chatops" -version = "1.10.1" +version = "1.10.0" description = "A plugin providing chatbot capabilities for Nautobot" authors = ["Network to Code, LLC "] readme = "README.md" From 9438fa27c922d96b058c7d33d46c8e58710766ad Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Fri, 21 Oct 2022 14:30:08 -0500 Subject: [PATCH 12/21] Finalize documentation. --- docs/admin/compatibility_matrix.md | 1 + docs/admin/install/slack_setup.md | 9 +++++++++ docs/admin/release_notes/version_1.10.md | 11 +++++++++++ mkdocs.yml | 1 + 4 files changed, 22 insertions(+) create mode 100644 docs/admin/release_notes/version_1.10.md diff --git a/docs/admin/compatibility_matrix.md b/docs/admin/compatibility_matrix.md index 85fca707..b58a5d76 100644 --- a/docs/admin/compatibility_matrix.md +++ b/docs/admin/compatibility_matrix.md @@ -18,3 +18,4 @@ While that last supported version will not be strictly enforced via the `max_ver | 1.7.X | 1.0.0 | 1.2.99 [Official] | | 1.8.X | 1.1.0 | 1.4.99 [Official] | | 1.9.X | 1.2.0 | 1.5.99 [Official] | +| 1.10.X | 1.3.0 | 1.5.99 [Official] | diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index 414f2806..84975e8b 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -6,8 +6,10 @@ These are the four distinct configuration values you will need to configure in ` | ---------------------------- | ---------- | ------- | | `enable_slack` | **Yes** | False | | `slack_api_token` | **Yes** | -- | +| `slack_app_token`************| Socket Mode| -- | | `slack_signing_secret` | **Yes** | -- | | `slack_slash_command_prefix` | No | `"/"` | +| `slack_socket_static_host` | No | -- | These values will be used in the `nautobot_config.py` file, once we get to the section where we cover server configuration. For now, take a mental note that in this section where we are configuring the Slack application, we will need to explicitly note the @@ -28,6 +30,13 @@ PLUGINS_CONFIG = { } ``` +!!! info + When running Slack in Socket Mode, Nautobot ChatOps Plugin can specify where the static files are hosted. + This is helpful for giving Slack access to only the server hosting Nautobot Static Files. If Django Storage + is configured, Nautobot ChatOps Plugin will use the static host from Django Storage. This is optional as + ChatOps only uses static files for sending logos with messages. To configure the static files host, use + `slack_socket_static_host` ex. `slack_socket_static_host: 'https://example.com/static/'`. + ## Connecting to Slack The Nautobot ChatOps plugin supports two methods of communicating with Slack. diff --git a/docs/admin/release_notes/version_1.10.md b/docs/admin/release_notes/version_1.10.md new file mode 100644 index 00000000..0c642468 --- /dev/null +++ b/docs/admin/release_notes/version_1.10.md @@ -0,0 +1,11 @@ + +# v1.10 Release Notes + +## [v1.10.0](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v1.10.0) + +### What's Changed + +* Drop official support for Nautobot <1.3.0 +* Add support for Slack Socket Mode. + +[**Full Changelog**](https://github.com/nautobot/nautobot-plugin-chatops/compare/v1.9.1...v1.10.0) diff --git a/mkdocs.yml b/mkdocs.yml index c77575c5..aea4f1cb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -110,6 +110,7 @@ nav: - Compatibility Matrix: "admin/compatibility_matrix.md" - Release Notes: - "admin/release_notes/index.md" + - v1.10: "admin/release_notes/version_1.10.md" - v1.9: "admin/release_notes/version_1.9.md" - v1.8: "admin/release_notes/version_1.8.md" - v1.7: "admin/release_notes/version_1.7.md" From a0032e6ecf5f38a4b3fd95b8e77bf138e5a69bec Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 09:35:51 -0500 Subject: [PATCH 13/21] Rename service and document enabling the service --- docs/admin/install/slack_setup.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index 84975e8b..86a97c44 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -199,7 +199,7 @@ Start a worker to connect to Slack. ### Slack Socket Systemd Service -To establish the `systemd` unit file for the Slack Socket worker, copy and paste the following into `/etc/systemd/system/chatops-slack-socket.service`: +To establish the `systemd` unit file for the Slack Socket worker, copy and paste the following into `/etc/systemd/system/nautobot-chatops-slack-socket.service`: ```ini [Unit] @@ -228,6 +228,20 @@ WantedBy=multi-user.target This can be done multiple times to create more workers. Up to 10 workers can be created. +### Configure systemd + +Because we just added new service files, you'll need to reload the systemd daemon: + +```no-highlight +sudo systemctl daemon-reload +``` + +Then, start the `nautobot-chatops-slack-socket` services and enable it to initiate at boot time: + +```no-highlight +sudo systemctl enable --now nautobot-chatops-slack-socket +``` + ## Deprected - Create Slack App without a Manifest (original method) While this method is still possible, we recommend using the App Manifest method (described above) to install your Slack App. From ce6c7f434acc2977aef0d2e3577c0154bf10a005 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 11:07:02 -0500 Subject: [PATCH 14/21] Update docs/admin/install/slack_setup.md Co-authored-by: Glenn Matthews --- docs/admin/install/slack_setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index 86a97c44..1f5792d1 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -48,7 +48,7 @@ The original supported method of connection was only incoming webhooks. As of ve ### Webhooks vs. Socket Mode -With incoming webhooks, whenever a user sends a message to the bot via the client application (phone or desktop app), (1) the connection is initiated from the client, and the message gets sent to Slacks cloud. The Slack servers then initiate a connection to the ChatOps plugin running on the Nautobot server (2). Since this is a new, incoming connection, it must be port forwarded and allowed through any firewalls in your network between the internet and your Nautobot server (3). Nautobot then replies to the existing connection to Slack, which in turn forwards the response to the client. +With incoming webhooks, whenever a user sends a message to the bot via the client application (phone or desktop app), (1) the connection is initiated from the client, and the message gets sent to Slack's cloud. The Slack servers then initiate a connection to the ChatOps plugin running on the Nautobot server (2). Since this is a new, incoming connection, it must be port forwarded and allowed through any firewalls in your network between the internet and your Nautobot server (3). Nautobot then replies to the existing connection to Slack, which in turn forwards the response to the client. ![Chatops Slack Webhooks Mode](../../images/chatops-slack-webhooks-mode.png) From 648d0590525ffadd0c0a99b56ca553b80a32a583 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 11:12:56 -0500 Subject: [PATCH 15/21] Apply suggestions from code review Co-authored-by: Glenn Matthews --- docs/admin/install/slack_setup.md | 8 ++++---- nautobot_chatops/utils.py | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index 1f5792d1..e3137255 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -64,7 +64,7 @@ While there are sufficient ways of securing inbound API requests from the public 1. Log in to [https://api.slack.com/apps](https://api.slack.com/apps) and select "Create New App". Select "From an app manifest." 2. Select your preferred Slack workspace for your app. -3. In the window titled "Enter app manifest below," select the "YAML" formatting tab and copy/paste the contents of file [nautobot_slack_manifest.yml](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_slack_manifest.yml) in the root of this repo. Update the below settings, then click Next. +3. In the window titled "Enter app manifest below," select the "YAML" formatting tab and copy/paste the contents of file [nautobot_slack_manifest.yml](https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/setup_files/nautobot_slack_manifest.yml) from this repo. Update the below settings, then click Next. - On line 5, you can change the name of the Chatbot here. By default it is set to `Nautobot` - If using Socket mode: - On line 34, update `socket_mode_enabled` to `true` @@ -74,10 +74,10 @@ While there are sufficient ways of securing inbound API requests from the public - On line 34, verify `socket_mode_enabled` is set to `false` 4. Review the summarized settings on the next window and click Create. 5. On the General --> Basic Information page, note the `Signing Secret` near the bottom, under App Credentials. This will be needed later for setting `SLACK_SIGNING_SECRET`. -6. On this same Basic Infomration page, select `Install to Workspace`. Select a channel to allow the app to post to (e.g. #general), and click `Allow`. +6. On this same Basic Information page, select `Install to Workspace`. Select a channel to allow the app to post to (e.g. #general), and click `Allow`. - If you are not a Slack admin, this step will require approval first from an Slack admin in your company. 7. If using Socket mode: - - Under Settings --> Basic Informmation, scroll down to section "App-Level Tokens" and click `Generate Token and Scopes` to generate an API token. + - Under Settings --> Basic Information, scroll down to section "App-Level Tokens" and click `Generate Token and Scopes` to generate an API token. - **Token Name**: This can be anything you want. - **Scopes**: Click `Add Scope` and select the option `connections:write`. - Click `Generate`. Copy this API token. This will be needed later for setting `SLACK_APP_TOKEN`. @@ -131,7 +131,7 @@ PLUGINS_CONFIG = { > **Note**: In the Slack app, you will need to invite the chatbot to each channel that it will belong to with `@`. > For example, when an app named `Nautobot ChatOps` is installed to the workspace: > -> 1. A message is displayed in the channel, saying that the integration`Nautobot ChatOps` has been added +> 1. A message is displayed in the channel, saying that the integration `Nautobot ChatOps` has been added > 2. You `@Nautobot ChatOps` in the channel > 3. You are prompted to add `@Nautobot ChatOps` to the channel diff --git a/nautobot_chatops/utils.py b/nautobot_chatops/utils.py index 50fdcf5b..f89621a7 100644 --- a/nautobot_chatops/utils.py +++ b/nautobot_chatops/utils.py @@ -108,11 +108,9 @@ def create_command_log(dispatcher, registry, command, subcommand, params=()): @sync_to_async -def socket_check_and_enqueue_command( - registry, command, subcommand, params, context, dispatcher_class -): # pylint:disable=too-many-statements +def socket_check_and_enqueue_command(*args, **kwargs): """Calls check_and_enqueue_command() when in Socket mode.""" - return check_and_enqueue_command(registry, command, subcommand, params, context, dispatcher_class) + return check_and_enqueue_command(*args, **kwargs) def check_and_enqueue_command( From c982415b56fb5d54a3bb4729576f8735ed9ab0a3 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 16:23:17 -0500 Subject: [PATCH 16/21] Update nautobot_config.py Align nautobot_config with dev standards. --- development/nautobot_config.py | 285 ++++++++++----------------------- 1 file changed, 82 insertions(+), 203 deletions(-) diff --git a/development/nautobot_config.py b/development/nautobot_config.py index e9b7c72d..27709c1a 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -2,69 +2,98 @@ import os import sys -from distutils.util import strtobool - -from django.core.exceptions import ImproperlyConfigured from nautobot.core.settings import * # noqa: F401,F403 pylint: disable=wildcard-import,unused-wildcard-import from nautobot.core.settings_funcs import parse_redis_connection -# pylint: disable=line-too-long - - -def is_truthy(arg): - """Convert "truthy" strings into Booleans. - - Examples: - >>> is_truthy('yes') - True - Args: - arg (str): Truthy string (True values are y, yes, t, true, on and 1; false values are n, no, - f, false, off and 0. Raises ValueError if val is anything else. - """ - if isinstance(arg, bool): - return arg - return bool(strtobool(arg)) - -# Enforce required configuration parameters -for key in [ - "NAUTOBOT_ALLOWED_HOSTS", - "NAUTOBOT_DB_USER", - "NAUTOBOT_DB_PASSWORD", - "NAUTOBOT_REDIS_HOST", - "NAUTOBOT_REDIS_PASSWORD", - "NAUTOBOT_SECRET_KEY", -]: - if not os.environ.get(key): - raise ImproperlyConfigured(f"Required environment variable {key} is missing.") - -# For reference see https://nautobot.readthedocs.io/en/latest/configuration/required-settings/ -# Based on config from nautobot-server init - -######################### -# # -# Required settings # -# # -######################### - -# This is a list of valid fully-qualified domain names (FQDNs) for the Nautobot server. Nautobot will not permit write -# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. -# -# Example: ALLOWED_HOSTS = ['nautobot.example.com', 'nautobot.internal.local'] ALLOWED_HOSTS = os.getenv("NAUTOBOT_ALLOWED_HOSTS", "").split(" ") +SECRET_KEY = os.getenv("NAUTOBOT_SECRET_KEY", "") +nautobot_db_engine = os.getenv("NAUTOBOT_DB_ENGINE", "django.db.backends.postgresql") +default_db_settings = { + "django.db.backends.postgresql": { + "NAUTOBOT_DB_PORT": "5432", + }, + "django.db.backends.mysql": { + "NAUTOBOT_DB_PORT": "3306", + }, +} DATABASES = { "default": { "NAME": os.getenv("NAUTOBOT_DB_NAME", "nautobot"), # Database name "USER": os.getenv("NAUTOBOT_DB_USER", ""), # Database username - "PASSWORD": os.getenv("NAUTOBOT_DB_PASSWORD", ""), # Datbase password + "PASSWORD": os.getenv("NAUTOBOT_DB_PASSWORD", ""), # Database password "HOST": os.getenv("NAUTOBOT_DB_HOST", "localhost"), # Database server - "PORT": os.getenv("NAUTOBOT_DB_PORT", ""), # Database port (leave blank for default) - "CONN_MAX_AGE": int(os.environ.get("NAUTOBOT_DB_TIMEOUT", 300)), # Database timeout - "ENGINE": os.getenv("NAUTOBOT_DB_ENGINE", "django.db.backends.postgresql"), # Database driver + "PORT": os.getenv( + "NAUTOBOT_DB_PORT", default_db_settings[nautobot_db_engine]["NAUTOBOT_DB_PORT"] + ), # Database port, default to postgres + "CONN_MAX_AGE": int(os.getenv("NAUTOBOT_DB_TIMEOUT", 300)), # Database timeout + "ENGINE": nautobot_db_engine, } } +# +# Debug +# + +DEBUG = True + +# Django Debug Toolbar +DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING} + +if DEBUG and "debug_toolbar" not in INSTALLED_APPS: # noqa: F405 + INSTALLED_APPS.append("debug_toolbar") # noqa: F405 +if DEBUG and "debug_toolbar.middleware.DebugToolbarMiddleware" not in MIDDLEWARE: # noqa: F405 + MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware") # noqa: F405 + +# +# Logging +# + +LOG_LEVEL = "DEBUG" if DEBUG else "INFO" + +TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" + +# Verbose logging during normal development operation, but quiet logging during unit test execution +if not TESTING: + LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "normal": { + "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)s :\n %(message)s", + "datefmt": "%H:%M:%S", + }, + "verbose": { + "format": "%(asctime)s.%(msecs)03d %(levelname)-7s %(name)-20s %(filename)-15s %(funcName)30s() :\n %(message)s", + "datefmt": "%H:%M:%S", + }, + }, + "handlers": { + "normal_console": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "normal", + }, + "verbose_console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "verbose", + }, + }, + "loggers": { + "django": {"handlers": ["normal_console"], "level": "INFO"}, + "nautobot": { + "handlers": ["verbose_console" if DEBUG else "normal_console"], + "level": LOG_LEVEL, + }, + }, + } + +# +# Redis +# + # The django-redis cache is used to establish concurrent locks using Redis. The # django-rq settings will use the same instance/database by default. # @@ -81,118 +110,11 @@ def is_truthy(arg): } } -# REDIS CACHEOPS -CACHEOPS_REDIS = parse_redis_connection(redis_database=1) - -# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. -# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and -# symbols. Nautobot will not run without this defined. For more information, see -# https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-SECRET_KEY -SECRET_KEY = os.environ["NAUTOBOT_SECRET_KEY"] - - -######################### -# # -# Optional settings # -# # -######################### +# RQ_QUEUES is not set here because it just uses the default that gets imported +# up top via `from nautobot.core.settings import *`. -# Specify one or more name and email address tuples representing Nautobot administrators. These people will be notified of -# application errors (assuming correct email settings are provided). -ADMINS = [ - # ['John Doe', 'jdoe@example.com'], -] - -# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same -# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP. -BANNER_TOP = os.environ.get("BANNER_TOP", "") -BANNER_BOTTOM = os.environ.get("BANNER_BOTTOM", "") - -# Text to include on the login page above the login form. HTML is allowed. -BANNER_LOGIN = os.environ.get("BANNER_LOGIN", "") - -# Base URL path if accessing Nautobot within a directory. For example, if installed at https://example.com/nautobot/, set: -# BASE_PATH = 'nautobot/' -BASE_PATH = os.environ.get("BASE_PATH", "") - -# Cache timeout in seconds. Set to 0 to dissable caching. Defaults to 900 (15 minutes) -CACHEOPS_DEFAULTS = {"timeout": 900} - -# The file path where jobs will be stored. A trailing slash is not needed. Note that the default value of -# this setting is inside the invoking user's home directory. -# JOBS_ROOT = os.path.expanduser('~/.nautobot/jobs') - -# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal -# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging -# on a production system. -DEBUG = is_truthy(os.environ.get("DEBUG", False)) - -# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space -# within the global table (all prefixes and IP addresses not assigned to a VRF), set -# ENFORCE_GLOBAL_UNIQUE to True. -ENFORCE_GLOBAL_UNIQUE = is_truthy(os.environ.get("ENFORCE_GLOBAL_UNIQUE", False)) - -# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and -# by anonymous users. List models in the form `.`. Add '*' to this list to exempt all models. -EXEMPT_VIEW_PERMISSIONS = [ - # 'dcim.site', - # 'dcim.region', - # 'ipam.prefix', -] - -# A list of strings designating all applications that are enabled in this Django installation. Each string should be a dotted Python path to an application configuration class (preferred), or a package containing an application. -# http://nautobot.readthedocs.io/configuration/optional-settings/#extra-applications -EXTRA_INSTALLED_APPS = [] - -# HTTP proxies Nautobot should use when sending outbound HTTP requests (e.g. for webhooks). -# HTTP_PROXIES = { -# 'http': 'http://10.10.1.10:3128', -# 'https': 'http://10.10.1.10:1080', -# } - -# IP addresses recognized as internal to the system. The debugging toolbar will be available only to clients accessing -# Nautobot from an internal IP. -INTERNAL_IPS = ("127.0.0.1", "::1") - -# The file path where jobs will be stored. A trailing slash is not needed. Note that the default value of -# this setting is derived from the installed location. -JOBS_ROOT = os.environ.get("JOBS_ROOT", os.path.expanduser("~/.nautobot/jobs")) - -LOG_LEVEL = os.environ.get("LOG_LEVEL", "DEBUG" if DEBUG else "INFO") - -# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs: -# https://docs.djangoproject.com/en/stable/topics/logging/ -LOGGING = { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "verbose": { - "format": "{asctime} {levelname} {message} - {name} - {module} - {pathname}:{lineno}", - "datefmt": "%H:%M:%S", - "style": "{", - }, - }, - "handlers": {"console": {"level": "DEBUG", "class": "rq.utils.ColorizingStreamHandler", "formatter": "verbose"}}, - "root": {"handlers": ["console"], "level": LOG_LEVEL}, -} - -# Setting this to True will display a "maintenance mode" banner at the top of every page. -MAINTENANCE_MODE = is_truthy(os.environ.get("MAINTENANCE_MODE", False)) - -# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g. -# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request -# all objects by specifying "?limit=0". -MAX_PAGE_SIZE = int(os.environ.get("MAX_PAGE_SIZE", 1000)) - -# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that -# the default value of this setting is within the invoking user's home directory -MEDIA_ROOT = os.environ.get("MEDIA_ROOT", os.path.expanduser("~/.nautobot/media")) - -# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics' -METRICS_ENABLED = True - -# Determine how many objects to display per page within a list. (Default: 50) -PAGINATE_COUNT = int(os.environ.get("PAGINATE_COUNT", 50)) +# Redis Cacheops +CACHEOPS_REDIS = parse_redis_connection(redis_database=1) # Enable installed plugins. Add the name of each plugin to the list. PLUGINS = ["nautobot_chatops", "nautobot_capacity_metrics"] @@ -217,46 +139,3 @@ def is_truthy(arg): "mattermost_url": os.environ.get("MATTERMOST_URL"), }, } - - -# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to -# prefer IPv4 instead. -PREFER_IPV4 = is_truthy(os.environ.get("PREFER_IPV4", False)) - -# Remote authentication support -REMOTE_AUTH_ENABLED = False -REMOTE_AUTH_BACKEND = "nautobot.core.authentication.RemoteUserBackend" -REMOTE_AUTH_HEADER = "HTTP_REMOTE_USER" -REMOTE_AUTH_AUTO_CREATE_USER = True -REMOTE_AUTH_DEFAULT_GROUPS = [] -REMOTE_AUTH_DEFAULT_PERMISSIONS = {} - -# This determines how often the GitHub API is called to check the latest release of Nautobot. Must be at least 1 hour. -RELEASE_CHECK_TIMEOUT = 24 * 3600 - -# Maximum execution time for background tasks, in seconds. -RQ_DEFAULT_TIMEOUT = 300 - -# Configure SSO, for more information see docs/configuration/authentication/sso.md -SOCIAL_AUTH_ENABLED = False - -# By default uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the -# class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example: -# STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage' -# STORAGE_CONFIG = { -# 'AWS_ACCESS_KEY_ID': 'Key ID', -# 'AWS_SECRET_ACCESS_KEY': 'Secret', -# 'AWS_STORAGE_BUCKET_NAME': 'nautobot', -# 'AWS_S3_REGION_NAME': 'eu-west-1', -# } - -# Time zone (default: UTC) -TIME_ZONE = os.environ.get("TIME_ZONE", "UTC") - -# Django Debug Toolbar -TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" -DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda _request: DEBUG and not TESTING} -# -# Celery settings are not defined here because they can be overloaded with -# environment variables. By default they use `CACHES["default"]["LOCATION"]`. -# From 6d161f76b3c86d04bf1e97642bdb3075ede067dc Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 16:24:11 -0500 Subject: [PATCH 17/21] Make recommended changes from review --- docs/admin/install/slack_setup.md | 18 ++++++------- docs/requirements.txt | 1 + mkdocs.yml | 1 + nautobot_chatops/__init__.py | 2 +- nautobot_chatops/dispatchers/slack.py | 37 +++++++++++--------------- nautobot_chatops/sockets/slack.py | 38 ++++++++++++++------------- poetry.lock | 19 ++++++++++---- pyproject.toml | 2 ++ 8 files changed, 64 insertions(+), 54 deletions(-) diff --git a/docs/admin/install/slack_setup.md b/docs/admin/install/slack_setup.md index e3137255..d825df43 100644 --- a/docs/admin/install/slack_setup.md +++ b/docs/admin/install/slack_setup.md @@ -1,12 +1,12 @@ # Slack Setup -These are the four distinct configuration values you will need to configure in `nautobot_config.py`. +These are the distinct configuration values you will need to configure in `nautobot_config.py`. | Configuration Setting | Mandatory? | Default | | ---------------------------- | ---------- | ------- | | `enable_slack` | **Yes** | False | | `slack_api_token` | **Yes** | -- | -| `slack_app_token`************| Socket Mode| -- | +| `slack_app_token` | Socket Mode| -- | | `slack_signing_secret` | **Yes** | -- | | `slack_slash_command_prefix` | No | `"/"` | | `slack_socket_static_host` | No | -- | @@ -31,11 +31,10 @@ PLUGINS_CONFIG = { ``` !!! info - When running Slack in Socket Mode, Nautobot ChatOps Plugin can specify where the static files are hosted. - This is helpful for giving Slack access to only the server hosting Nautobot Static Files. If Django Storage - is configured, Nautobot ChatOps Plugin will use the static host from Django Storage. This is optional as - ChatOps only uses static files for sending logos with messages. To configure the static files host, use - `slack_socket_static_host` ex. `slack_socket_static_host: 'https://example.com/static/'`. + Optional: Logos rely on Slack being able to access the Static URL provided by Nautobot. If you are running + Slack in Socket Mode, Nautobot ChatOps Plugin will need you to specify where the static files are hosted. + This is helpful for giving Slack access to only the server hosting Nautobot Static Files. To configure the + static files host, use `slack_socket_static_host` ex. `slack_socket_static_host: 'https://example.com/static/'`. ## Connecting to Slack @@ -44,7 +43,8 @@ The Nautobot ChatOps plugin supports two methods of communicating with Slack. 1. Incoming Webhooks 2. Socket Mode -The original supported method of connection was only incoming webhooks. As of version 1.10, socket mode support was added for Slack. ++++ 1.10 + Added socket mode support. ### Webhooks vs. Socket Mode @@ -226,7 +226,7 @@ PrivateTmp=true WantedBy=multi-user.target ``` -This can be done multiple times to create more workers. Up to 10 workers can be created. +This can be done multiple times to create more workers. Up to 10 total workers can be created across all instances. Additional workers are useful to increase the amount of messages that can be processed from Slack. Additional workers are also useful for allowing ChatOps functionality during Server maintenance. ### Configure systemd diff --git a/docs/requirements.txt b/docs/requirements.txt index 1b42aa9f..50291782 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,6 @@ mkdocs==1.3.1 mkdocs-material==8.4.2 +mkdocs-version-annotations==1.0.0 mkdocstrings==0.19 mkdocstrings-python==0.7.1 Jinja2==3.0.3 diff --git a/mkdocs.yml b/mkdocs.yml index aea4f1cb..98a0aa52 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -81,6 +81,7 @@ markdown_extensions: plugins: - "search" + - "mkdocs-version-annotations" - mkdocstrings: default_handler: "python" handlers: diff --git a/nautobot_chatops/__init__.py b/nautobot_chatops/__init__.py index cc521d76..4df8467d 100644 --- a/nautobot_chatops/__init__.py +++ b/nautobot_chatops/__init__.py @@ -58,7 +58,7 @@ class NautobotChatOpsConfig(PluginConfig): } max_version = "1.999" - min_version = "1.2.0" + min_version = "1.3.0" caching_config = {} def ready(self): diff --git a/nautobot_chatops/dispatchers/slack.py b/nautobot_chatops/dispatchers/slack.py index 9d9fecf8..1491e889 100644 --- a/nautobot_chatops/dispatchers/slack.py +++ b/nautobot_chatops/dispatchers/slack.py @@ -241,6 +241,20 @@ def send_snippet(self, text, title=None, ephemeral=None): except SlackClientError as slack_error: self.send_exception(slack_error) + def static_url(self, path): + """Return a url to access the static file.""" + static_path = str(static(path)) + if static_path.startswith("http"): + # Static is being provided by Django Storages + return static_path + try: + return f"{self.context['request_scheme']}://{self.context['request_host']}{static_path}" + except KeyError: + if SLACK_SOCKET_STATIC_HOST: + # Use the settings provided Static Host. + return f"{SLACK_SOCKET_STATIC_HOST}{static_path}" + return None + def send_image(self, image_path): """Send an image as a file upload.""" if self.context.get("channel_name") == "directmessage": @@ -448,8 +462,8 @@ def markdown_block(self, text): return {"type": "section", "text": self.markdown_element(text)} def image_element(self, url, alt_text=""): - """Construct an image element that can be embedded in a block.""" - return {"type": "image", "image_url": url, "alt_text": alt_text} + """Construct an image element that can be embedded in a block if URL is provided.""" + return {"type": "image", "image_url": url, "alt_text": alt_text} if url else {} def markdown_element(self, text): """Construct a basic Markdown-formatted text element.""" @@ -491,22 +505,3 @@ def select_element(self, action_id, choices, default=(None, None), confirm=False def text_element(self, text): """Construct a basic plaintext element.""" return {"type": "plain_text", "text": text} - - -class SlackSocketDispatcher(SlackDispatcher): - """Overrides to support Slack Socket Mode.""" - - def static_url(self, path): - """Return a url to access the static file.""" - static_path = str(static(path)) - if static_path.startswith("http"): - # Static is being provided by Django Storages - return static_path - if SLACK_SOCKET_STATIC_HOST: - # Use the settings provided Static Host. - return f"{SLACK_SOCKET_STATIC_HOST}{static_path}" - return None - - def image_element(self, url, alt_text=""): - """Construct an image element that can be embedded in a block if URL is provided.""" - return {"type": "image", "image_url": url, "alt_text": alt_text} if url else {} diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index 85d16e86..c06735ab 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -11,22 +11,22 @@ from slack_sdk.web.async_client import AsyncWebClient from nautobot_chatops.workers import get_commands_registry, commands_help, parse_command_string -from nautobot_chatops.dispatchers.slack import SlackSocketDispatcher +from nautobot_chatops.dispatchers.slack import SlackDispatcher from nautobot_chatops.utils import socket_check_and_enqueue_command -SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") async def main(): # pylint: disable=too-many-statements """Slack Socket Main Loop.""" + SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") client = SocketModeClient( app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]), ) async def process(client: SocketModeClient, req: SocketModeRequest): - client.logger.debug("SK Received a socket request.") + client.logger.debug("Worker received a socket request.") if req.type == "slash_commands": client.logger.debug("Received slash command.") # Acknowledge the request anyway @@ -63,15 +63,14 @@ async def process_slash_command(client, req): command, subcommand, params = parse_command_string(f"{command} {params}") except ValueError as err: client.logger.error("%s", err) + return registry = get_commands_registry() if command not in registry: - SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) + SlackDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) - return await socket_check_and_enqueue_command( - registry, command, subcommand, params, context, SlackSocketDispatcher - ) + return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackDispatcher) # pylint: disable=too-many-locals,too-many-return-statements,too-many-branches,too-many-statements,too-many-nested-blocks async def process_interactive(client, req): @@ -113,7 +112,7 @@ async def process_interactive(client, req): if settings.PLUGINS_CONFIG["nautobot_chatops"].get("delete_input_on_submission"): # Delete the interactive element since it's served its purpose - SlackSocketDispatcher(context).delete_message(context["response_url"]) + SlackDispatcher(context).delete_message(context["response_url"]) if action_id == "action" and selected_value == "cancel": # Nothing more to do return @@ -136,12 +135,13 @@ async def process_interactive(client, req): cmds = shlex.split(callback_id) except ValueError as err: client.logger.error("%s", err) + return for i, cmd in enumerate(cmds): if i == 2: - selected_value += f"'{cmd}'" + selected_value += shlex.quote(f"'{cmd}'") elif i > 2: - selected_value += f" '{cmd}'" - action_id = f"{cmds[0]} {cmds[1]}" + selected_value += shlex.quote(f" '{cmd}'") + action_id = shlex.quote(f"{cmds[0]} {cmds[1]}") sorted_params = sorted(values.keys()) for blk_id in sorted_params: @@ -160,9 +160,9 @@ async def process_interactive(client, req): # If an optional parameter is passed, it is returned as a NoneType. # We instead want to return an empty string, otherwise 'None' is returned as a string. if value: - selected_value += f" '{value}'" + selected_value += shlex.quote(f" '{value}'") else: - selected_value += " ''" + selected_value += shlex.quote(" ''") # Original un-modified single-field handling below else: @@ -174,6 +174,7 @@ async def process_interactive(client, req): selected_value = f"'{value}'" else: client.logger.error(f"Unhandled action type {action['type']}") + return # Modal view submissions don't generally contain a channel ID, but we hide one for our convenience: if "private_metadata" in payload["view"]: @@ -182,12 +183,14 @@ async def process_interactive(client, req): context["channel_id"] = private_metadata["channel_id"] else: client.logger.error("I didn't understand that notification.") + return client.logger.info(f"action_id: {action_id}, selected_value: {selected_value}") try: command, subcommand, params = parse_command_string(f"{action_id} {selected_value}") except ValueError as err: client.logger.error("%s", err) + return # Convert empty parameter strings to NoneType for idx, param in enumerate(params): @@ -199,15 +202,14 @@ async def process_interactive(client, req): registry = get_commands_registry() if command not in registry: - SlackSocketDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) + SlackDispatcher(context).send_markdown(commands_help(prefix=SLASH_PREFIX)) + return # What we'd like to do here is send a "Nautobot is typing..." to the channel, # but unfortunately the API we're using doesn't support that (only the legacy/deprecated RTM API does). - # SlackSocketDispatcher(context).send_busy_indicator() + # SlackDispatcher(context).send_busy_indicator() - return await socket_check_and_enqueue_command( - registry, command, subcommand, params, context, SlackSocketDispatcher - ) + return await socket_check_and_enqueue_command(registry, command, subcommand, params, context, SlackDispatcher) client.socket_mode_request_listeners.append(process) diff --git a/poetry.lock b/poetry.lock index 35de8d3b..177de4a4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -74,7 +74,7 @@ python-versions = ">=3.7" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -tests = ["pytest", "mypy (>=0.800)"] +tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] [[package]] name = "astroid" @@ -1192,6 +1192,14 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "mkdocs-version-annotations" +version = "1.0.0" +description = "MkDocs plugin to add custom admonitions for documenting version differences" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" + [[package]] name = "mkdocstrings" version = "0.19.0" @@ -1294,12 +1302,12 @@ social-auth-app-django = ">=5.0.0,<5.1.0" svgwrite = ">=1.4.2,<1.5.0" [package.extras] -all = ["django-auth-ldap (>=4.1.0,<4.2.0)", "django-storages (>=1.12.3,<1.13.0)", "mysqlclient (>=2.1.0,<2.2.0)", "napalm (>=3.4.1,<3.5.0)", "social-auth-core[openidconnect,saml] (>=4.3.0,<4.4.0)"] +all = ["django-auth-ldap (>=4.1.0,<4.2.0)", "django-storages (>=1.12.3,<1.13.0)", "mysqlclient (>=2.1.0,<2.2.0)", "napalm (>=3.4.1,<3.5.0)", "social-auth-core[saml,openidconnect] (>=4.3.0,<4.4.0)"] ldap = ["django-auth-ldap (>=4.1.0,<4.2.0)"] remote_storage = ["django-storages (>=1.12.3,<1.13.0)"] mysql = ["mysqlclient (>=2.1.0,<2.2.0)"] napalm = ["napalm (>=3.4.1,<3.5.0)"] -sso = ["social-auth-core[openidconnect,saml] (>=4.3.0,<4.4.0)"] +sso = ["social-auth-core[saml,openidconnect] (>=4.3.0,<4.4.0)"] [[package]] name = "nautobot-capacity-metrics" @@ -1827,7 +1835,7 @@ python-versions = ">=3.6.0" [package.extras] optional = ["aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "SQLAlchemy (>=1,<2)", "websockets (>=10,<11)", "websocket-client (>=1,<2)"] -testing = ["pytest (>=6.2.5,<7)", "Flask-Sockets (>=0.2,<1)", "Flask (>=1,<2)", "Werkzeug (<2)", "itsdangerous (==1.1.0)", "Jinja2 (==3.0.3)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=5,<6)", "black (==22.8.0)", "click (==8.0.4)", "psutil (>=5,<6)", "databases (>=0.5)", "boto3 (<=2)", "moto (>=3,<4)"] +testing = ["pytest (>=6.2.5,<7)", "pytest-asyncio (<1)", "Flask-Sockets (>=0.2,<1)", "Flask (>=1,<2)", "Werkzeug (<2)", "itsdangerous (==1.1.0)", "Jinja2 (==3.0.3)", "pytest-cov (>=2,<3)", "codecov (>=2,<3)", "flake8 (>=5,<6)", "black (==22.8.0)", "click (==8.0.4)", "psutil (>=5,<6)", "databases (>=0.5)", "boto3 (<=2)", "moto (>=3,<4)"] [[package]] name = "smmap" @@ -2079,7 +2087,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "2fb2ad0139d6ed2c3fb5cf912c5c0dc0d3dad8ac692600f6571a87d605d0550a" +content-hash = "1b0a4d4fd092081988e49b74b9ebb118723540e18216e21243b891ac3d4c1bfe" [metadata.files] aiodns = [ @@ -2421,6 +2429,7 @@ mkdocs = [] mkdocs-autorefs = [] mkdocs-material = [] mkdocs-material-extensions = [] +mkdocs-version-annotations = [] mkdocstrings = [] mkdocstrings-python = [] multidict = [] diff --git a/pyproject.toml b/pyproject.toml index 39477caf..94612c3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,8 @@ mkdocs-material = "8.4.2" # Automatic documentation from sources, for MkDocs mkdocstrings = "0.19" mkdocstrings-python = "0.7.1" +# Render custom markdown for version added/changed/remove notes +mkdocs-version-annotations = "~1.0.0" [tool.black] From 7b5e7be400e824c3588a1408defed54aa89dfd0a Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 16:27:36 -0500 Subject: [PATCH 18/21] Black --- nautobot_chatops/sockets/slack.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index c06735ab..c88638fa 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -15,8 +15,6 @@ from nautobot_chatops.utils import socket_check_and_enqueue_command - - async def main(): # pylint: disable=too-many-statements """Slack Socket Main Loop.""" SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") From ab032c71a514ab1ff8649ff83e680a565f8873fc Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 21:00:25 -0500 Subject: [PATCH 19/21] Ignore invalid name on SLASH_PREFIX --- nautobot_chatops/sockets/slack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index c88638fa..f2f916f0 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -17,7 +17,7 @@ async def main(): # pylint: disable=too-many-statements """Slack Socket Main Loop.""" - SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") + SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") # pylint:disable=invalid-name client = SocketModeClient( app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]), From 6ca56fca212f2b0537733b9e950f4249e3e35633 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 21:01:14 -0500 Subject: [PATCH 20/21] Black again --- nautobot_chatops/sockets/slack.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index f2f916f0..3a7b6305 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -17,7 +17,9 @@ async def main(): # pylint: disable=too-many-statements """Slack Socket Main Loop.""" - SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_slash_command_prefix") # pylint:disable=invalid-name + SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get( + "slack_slash_command_prefix" + ) # pylint:disable=invalid-name client = SocketModeClient( app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]), From bb7816cebe50145e8202536ae98cdf1f664ab623 Mon Sep 17 00:00:00 2001 From: Stephen Kiely Date: Thu, 27 Oct 2022 21:40:36 -0500 Subject: [PATCH 21/21] Move pylint disable to proper line. --- nautobot_chatops/sockets/slack.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nautobot_chatops/sockets/slack.py b/nautobot_chatops/sockets/slack.py index 3a7b6305..b18702bd 100644 --- a/nautobot_chatops/sockets/slack.py +++ b/nautobot_chatops/sockets/slack.py @@ -17,9 +17,9 @@ async def main(): # pylint: disable=too-many-statements """Slack Socket Main Loop.""" - SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get( + SLASH_PREFIX = settings.PLUGINS_CONFIG["nautobot_chatops"].get( # pylint:disable=invalid-name "slack_slash_command_prefix" - ) # pylint:disable=invalid-name + ) client = SocketModeClient( app_token=settings.PLUGINS_CONFIG["nautobot_chatops"].get("slack_app_token"), web_client=AsyncWebClient(token=settings.PLUGINS_CONFIG["nautobot_chatops"]["slack_api_token"]),

-ZzV)2c%iDM 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