Refactor the code of osccore-qa-testing-tools  to comply with PEP8.

Related-prod: PRODX-42195
Change-Id: Id05e7584e0d024127ce1bd5042cfe681a1b52e2d
diff --git a/testrail_bot/control/admin.py b/testrail_bot/control/admin.py
index 89a2511..2270674 100644
--- a/testrail_bot/control/admin.py
+++ b/testrail_bot/control/admin.py
@@ -1,6 +1,6 @@
 from django.contrib import admin
 
-from .models import TestRailTestRun, TestRailReport
+from .models import TestRailReport, TestRailTestRun
 
 admin.site.register(TestRailTestRun)
 admin.site.register(TestRailReport)
diff --git a/testrail_bot/control/apps.py b/testrail_bot/control/apps.py
index a5f7085..7d84cd0 100644
--- a/testrail_bot/control/apps.py
+++ b/testrail_bot/control/apps.py
@@ -2,4 +2,4 @@
 
 
 class ControlConfig(AppConfig):
-    name = 'control'
+    name = "control"
diff --git a/testrail_bot/control/celery_tasks/filters.py b/testrail_bot/control/celery_tasks/filters.py
index 4407eed..b0f0852 100644
--- a/testrail_bot/control/celery_tasks/filters.py
+++ b/testrail_bot/control/celery_tasks/filters.py
@@ -2,17 +2,18 @@
 
 
 def filter_ip(data: str) -> str:
-    ip_addr_regex = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')
+    ip_addr_regex = re.compile(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b")
     return re.sub(ip_addr_regex, "x.x.x.x", data)
 
 
 def filter_uuid(data: str) -> str:
     uuid4hex = re.compile(
-        r'[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z', re.I)
+        r"[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z", re.I
+    )
     return re.sub(uuid4hex, "xxxx", data)
 
 
 def last_traceback_filter(data: str) -> str:
     if data.rfind("Traceback") < 0:
         return data
-    return data[data.rfind("Traceback"):]
+    return data[data.rfind("Traceback") :]
diff --git a/testrail_bot/control/celery_tasks/jenkins_pipeline.py b/testrail_bot/control/celery_tasks/jenkins_pipeline.py
index e3c9904..1d93535 100644
--- a/testrail_bot/control/celery_tasks/jenkins_pipeline.py
+++ b/testrail_bot/control/celery_tasks/jenkins_pipeline.py
@@ -1,21 +1,18 @@
-from datetime import datetime, timedelta, timezone
 import json
 import os
+from datetime import datetime, timedelta, timezone
 
 from django.conf import settings
-from matplotlib import pyplot as plt
-from matplotlib import dates as mdates
-
 from jenkins import Jenkins
+from matplotlib import dates as mdates
+from matplotlib import pyplot as plt
 
 from .. import models
 
-
-__all__ = ('update_plot',)
+__all__ = ("update_plot",)
 
 
-jenkins_client = Jenkins(
-    "https://ci.mcp.mirantis.net/")
+jenkins_client = Jenkins("https://ci.mcp.mirantis.net/")
 
 VIEW_NAME = "MCP2.0 Openstack Periodic CI"
 
@@ -24,13 +21,22 @@
     def get_attr(attr):
         return getattr(original_obj, attr, 0)
 
-    return datetime(year=2000, month=1, day=1, hour=get_attr("hour"),
-                    minute=get_attr("minute"), second=get_attr("second"))
+    return datetime(
+        year=2000,
+        month=1,
+        day=1,
+        hour=get_attr("hour"),
+        minute=get_attr("minute"),
+        second=get_attr("second"),
+    )
 
 
 def build_start_time(timestamp):
-    return build_time_obj(datetime.utcfromtimestamp(
-        timestamp / 1000)).replace(tzinfo=timezone.utc).timestamp()
+    return (
+        build_time_obj(datetime.utcfromtimestamp(timestamp / 1000))
+        .replace(tzinfo=timezone.utc)
+        .timestamp()
+    )
 
 
 def process_build(job_name, build):
@@ -38,8 +44,10 @@
     if build_info["result"] != "SUCCESS":
         return None
 
-    return build_start_time(build_info["timestamp"]), \
-        build_info["duration"] / 1000
+    return (
+        build_start_time(build_info["timestamp"]),
+        build_info["duration"] / 1000,
+    )
 
 
 def calculate_average(values):
@@ -52,15 +60,18 @@
 
     start_times, durations = zip(*filter(None, builds_info))
 
-    avg_start_time = datetime.utcfromtimestamp(
-        calculate_average(start_times))
-    return {"duration": calculate_average(durations),
-            "start_time": avg_start_time}
+    avg_start_time = datetime.utcfromtimestamp(calculate_average(start_times))
+    return {
+        "duration": calculate_average(durations),
+        "start_time": avg_start_time,
+    }
 
 
 def get_aggregated_build_stats():
-    return {job_name["name"]: process_job(job_name["name"])
-            for job_name in jenkins_client.get_jobs(view_name=VIEW_NAME)}
+    return {
+        job_name["name"]: process_job(job_name["name"])
+        for job_name in jenkins_client.get_jobs(view_name=VIEW_NAME)
+    }
 
 
 def get_lines(current, standard_datetime, next_day):
@@ -70,7 +81,8 @@
     if end >= next_day:
         return [
             (standard_datetime, standard_datetime + (end - next_day)),
-            (start_time, next_day - timedelta(seconds=1))]
+            (start_time, next_day - timedelta(seconds=1)),
+        ]
 
     return [(start_time, end)]
 
@@ -78,8 +90,10 @@
 def build_data_for_jobs_time_plot(jobs):
     standard_datetime = build_time_obj()
     next_day = standard_datetime + timedelta(days=1)
-    return {job_name: get_lines(jobs[job_name], standard_datetime, next_day)
-            for job_name in jobs}
+    return {
+        job_name: get_lines(jobs[job_name], standard_datetime, next_day)
+        for job_name in jobs
+    }
 
 
 def draw_plot(plot_data):
@@ -100,7 +114,8 @@
     # Set date limits
     start_time = build_time_obj()
     ax.set_xlim(
-        start_time, start_time + timedelta(days=1) + timedelta(seconds=1))
+        start_time, start_time + timedelta(days=1) + timedelta(seconds=1)
+    )
 
     # Set y axes limits
     jobs_num = len(plot_data) + 1
@@ -136,7 +151,8 @@
 
         try:
             log_record = models.ActionLog.objects.get(
-                name="update_jenkins_plot")
+                name="update_jenkins_plot"
+            )
         except models.ActionLog.DoesNotExist:
             log_record = models.ActionLog(name="update_jenkins_plot")
         log_record.date = datetime.now()
diff --git a/testrail_bot/control/celery_tasks/schedules_pipeline.py b/testrail_bot/control/celery_tasks/schedules_pipeline.py
index b121a14..1ad090a 100644
--- a/testrail_bot/control/celery_tasks/schedules_pipeline.py
+++ b/testrail_bot/control/celery_tasks/schedules_pipeline.py
@@ -1,9 +1,9 @@
-from datetime import datetime, timedelta, timezone
 import os
+from datetime import datetime
 
 from .. import models
-from .test_rail_api import get_planid_by_name
 from . import tasks
+from .test_rail_api import get_planid_by_name
 
 
 def task_to_check_today_testplan():
@@ -17,8 +17,8 @@
     today = datetime.today().strftime("%Y-%m-%d")
     plan_name = f"[MCP2.0]OSCORE-{today}"
     plan_id = get_planid_by_name(
-        name=plan_name,
-        project_name="Mirantis Cloud Platform")
+        name=plan_name, project_name="Mirantis Cloud Platform"
+    )
     if not plan_id:
         print(f"Can't found {plan_name} TestPlan")
         return
@@ -36,15 +36,17 @@
         pass
 
     report_obj, _ = models.TestRailReport.objects.get_or_create(
-        report_name=report_name,
-        path=path)
+        report_name=report_name, path=path
+    )
     report_obj.finished = False
     report_obj.save()
 
-    return tasks.process_run(bot_run_id=testrun_obj.id,
-                             report_id=report_obj.id,
-                             path=path,
-                             is_testplan=True)
+    return tasks.process_run(
+        bot_run_id=testrun_obj.id,
+        report_id=report_obj.id,
+        path=path,
+        is_testplan=True,
+    )
 
 
 def task_to_check_testplan(testplan_id: int):
@@ -68,12 +70,14 @@
         pass
 
     report_obj, _ = models.TestRailReport.objects.get_or_create(
-        report_name=report_name,
-        path=path)
+        report_name=report_name, path=path
+    )
     report_obj.finished = False
     report_obj.save()
 
-    return tasks.process_run(bot_run_id=testrun_obj.id,
-                             report_id=report_obj.id,
-                             path=path,
-                             is_testplan=True)
+    return tasks.process_run(
+        bot_run_id=testrun_obj.id,
+        report_id=report_obj.id,
+        path=path,
+        is_testplan=True,
+    )
diff --git a/testrail_bot/control/celery_tasks/tasks.py b/testrail_bot/control/celery_tasks/tasks.py
index dcc9cc1..cd18f6d 100644
--- a/testrail_bot/control/celery_tasks/tasks.py
+++ b/testrail_bot/control/celery_tasks/tasks.py
@@ -1,22 +1,26 @@
 from __future__ import absolute_import, unicode_literals
 
 import traceback
+
 from celery import shared_task
 
-from . import jenkins_pipeline, testrail_pipeline, schedules_pipeline
+from . import jenkins_pipeline, schedules_pipeline, testrail_pipeline
 
 
 @shared_task
 def process_run(bot_run_id, report_id, path, is_testplan):
     try:
-        testrail_pipeline.process_test_run(bot_run_id, report_id, path,
-                                           is_testplan)
+        testrail_pipeline.process_test_run(
+            bot_run_id, report_id, path, is_testplan
+        )
     except BaseException as e:
-        with open(path, 'a') as f:
+        with open(path, "a") as f:
             print(f"Caught next exception: {e}")
             traceback.print_exc()
-            f.write("<b style='color:red;background-color:pink'>Task "
-                    "completed unsuccessfully</b>\n")
+            f.write(
+                "<b style='color:red;background-color:pink'>Task "
+                "completed unsuccessfully</b>\n"
+            )
             f.flush()
 
 
@@ -33,6 +37,7 @@
         print(f"Caught next exception: {e}")
         traceback.print_exc()
         from .. import models
+
         r = models.SuitePassRate.objects.get(pk=report_id)
         r.status = "Unexpected fail"
         r.finished = True
@@ -61,4 +66,3 @@
     :return:
     """
     schedules_pipeline.task_to_check_testplan(testplan_id)
-
diff --git a/testrail_bot/control/celery_tasks/test_rail_api.py b/testrail_bot/control/celery_tasks/test_rail_api.py
index 142f403..47c4e6a 100644
--- a/testrail_bot/control/celery_tasks/test_rail_api.py
+++ b/testrail_bot/control/celery_tasks/test_rail_api.py
@@ -1,61 +1,71 @@
-from testrail_api import TestRailAPI, StatusCodeError
-from requests.exceptions import ReadTimeout
+from typing import Iterator, List, Optional
+
 from django.conf import settings
 from django.utils.html import escape
-from typing import Optional, List, Iterator
-
+from requests.exceptions import ReadTimeout
 from retry import retry
-from .enums import StatusEnum, TimeEnum
+from testrail_api import StatusCodeError, TestRailAPI
+
 from ..utils import cached
+from .enums import StatusEnum, TimeEnum
 
 api = TestRailAPI(
     "https://mirantis.testrail.com/",
     settings.TESTRAIL_EMAIL,
-    settings.TESTRAIL_PASSWORD)
+    settings.TESTRAIL_PASSWORD,
+)
 
 
 @cached()
 def get_project_id(project_name: str) -> Optional[int]:
-    project = list(filter(
-        lambda x: x["name"] == project_name,
-        api.projects.get_projects()['projects']))
+    project = list(
+        filter(
+            lambda x: x["name"] == project_name,
+            api.projects.get_projects()["projects"],
+        )
+    )
     if project:
         return project[0]["id"]
     else:
         return None
 
 
-@cached(timeout=1*TimeEnum.DAYS)
+@cached(timeout=1 * TimeEnum.DAYS)
 def get_suite_by_id(suite_id: int) -> dict:
     return api.suites.get_suite(suite_id)
 
 
 @cached()
 def get_suite_name_by_id(suite_id: int) -> str:
-    return api.suites.get_suite(suite_id)['name']
+    return api.suites.get_suite(suite_id)["name"]
 
 
 @cached()
 def get_suite_test_type(suite_id: int) -> str:
     suite_name = get_suite_name_by_id(suite_id)
-    return suite_name.split(']')[1]
+    return suite_name.split("]")[1]
 
 
-@cached(timeout=1*TimeEnum.HOURS)
+@cached(timeout=1 * TimeEnum.HOURS)
 def get_plans(project_id: int, **kwargs) -> List[dict]:
-    plans = api.plans.get_plans(project_id=project_id, **kwargs)['plans']
+    plans = api.plans.get_plans(project_id=project_id, **kwargs)["plans"]
     return plans
 
 
-@cached(timeout=2*TimeEnum.HOURS,
-        condition_for_endless_cache=lambda x: x is not None)
-def get_planid_by_name(name: str, project_name: str, **kwargs) \
-        -> Optional[int]:
+@cached(
+    timeout=2 * TimeEnum.HOURS,
+    condition_for_endless_cache=lambda x: x is not None,
+)
+def get_planid_by_name(
+    name: str, project_name: str, **kwargs
+) -> Optional[int]:
     limit_step = 100
     for offset in range(0, 500, limit_step):
-        plans = get_plans(project_id=get_project_id(project_name),
-                          limit=limit_step,
-                          offset=offset)
+        plans = get_plans(
+            project_id=get_project_id(project_name),
+            limit=limit_step,
+            offset=offset,
+        )
         if not plans:
             return
         for plan in plans:
@@ -65,7 +75,7 @@
     return
 
 
-@cached(timeout=1*TimeEnum.HOURS)
+@cached(timeout=1 * TimeEnum.HOURS)
 def get_entries(plan_id: int) -> List[dict]:
     return api.plans.get_plan(plan_id)["entries"]
 
@@ -83,25 +93,28 @@
     return api.plans.get_plan(plan_id)
 
 
-def get_result_history_for_case(case_id: int,
-                                status_id: int = None,
-                                project_name: str = "Mirantis Cloud Platform",
-                                plan_name: str = None,
-                                created_after: str = None,
-                                created_before: str = None,
-                                created_by: int = None,
-                                testrun_pattern: str = None,
-                                **kwargs) -> \
-        Iterator[List[dict]]:
+def get_result_history_for_case(
+    case_id: int,
+    status_id: int = None,
+    project_name: str = "Mirantis Cloud Platform",
+    plan_name: str = None,
+    created_after: str = None,
+    created_before: str = None,
+    created_by: int = None,
+    testrun_pattern: str = None,
+    **kwargs,
+) -> Iterator[List[dict]]:
     limit_step = 100
     suite_id = api.cases.get_case(case_id=case_id)["suite_id"]
     for offset in range(0, 2000, limit_step):
-        plans = get_plans(project_id=get_project_id(project_name),
-                          limit=limit_step,
-                          offset=offset,
-                          created_after=created_after,
-                          created_before=created_before,
-                          created_by=created_by)
+        plans = get_plans(
+            project_id=get_project_id(project_name),
+            limit=limit_step,
+            offset=offset,
+            created_after=created_after,
+            created_before=created_before,
+            created_by=created_by,
+        )
         if not plans:
             return
         for plan in plans:
@@ -117,50 +130,48 @@
                     if type(status_id) is list:
                         status_id = ",".join(map(lambda x: str(x), status_id))
 
-                    results = get_result_for_case(run_id=run["id"],
-                                                  case_id=case_id,
-                                                  status_id=status_id)
+                    results = get_result_for_case(
+                        run_id=run["id"], case_id=case_id, status_id=status_id
+                    )
                     if results:
                         yield results
 
 
 def get_run_id(entries: List[dict], run_name: str) -> Optional[int]:
-    entries = list(filter(
-        lambda x: x["name"] == run_name,
-        entries))
+    entries = list(filter(lambda x: x["name"] == run_name, entries))
     if not entries:
         return None
     return entries[0]["runs"][0]["id"]
 
 
-@cached(timeout=2*TimeEnum.HOURS,
-        condition_for_endless_cache=lambda x: x is None)
+@cached(
+    timeout=2 * TimeEnum.HOURS, condition_for_endless_cache=lambda x: x is None
+)
 @retry(ReadTimeout, delay=1, jitter=2, tries=3)
-def get_result_for_case(run_id: int,
-                        case_id: int,
-                        **kwargs) -> Optional[List[dict]]:
+def get_result_for_case(
+    run_id: int, case_id: int, **kwargs
+) -> Optional[List[dict]]:
     try:
-        results = api.results.get_results_for_case(run_id, case_id, **kwargs
-                                                   )['results']
+        results = api.results.get_results_for_case(run_id, case_id, **kwargs)[
+            "results"
+        ]
     except StatusCodeError:
         return None
     return results
 
 
 def get_failed_tests(last_run_id: int, by_plans=False) -> List[dict]:
-    failed_statuses = [StatusEnum.failed,
-                       StatusEnum.blocked]
+    failed_statuses = [StatusEnum.failed, StatusEnum.blocked]
     status_id = ",".join(map(str, failed_statuses))
     if by_plans:
         failed_tests = []
         for entry in get_entries(last_run_id):
             for run in entry["runs"]:
                 failed_tests += api.tests.get_tests(
-                    run_id=run["id"],
-                    status_id=status_id)['tests']
+                    run_id=run["id"], status_id=status_id
+                )["tests"]
         return failed_tests
-    return api.tests.get_tests(
-        last_run_id, status_id=status_id)['tests']
+    return api.tests.get_tests(last_run_id, status_id=status_id)["tests"]
 
 
 def add_result(test_id: int, update_dict: dict) -> None:
@@ -178,5 +189,7 @@
 
 
 def html_link(type: str, id: int, title: str) -> str:
-    return f"<a href='https://mirantis.testrail.com/index.php?/{type}s/view/" \
-           f"{id}'>{escape(title)}</a>"
+    return (
+        f"<a href='https://mirantis.testrail.com/index.php?/{type}s/view/"
+        f"{id}'>{escape(title)}</a>"
+    )
diff --git a/testrail_bot/control/celery_tasks/testrail_pipeline.py b/testrail_bot/control/celery_tasks/testrail_pipeline.py
index d0eae11..472046d 100644
--- a/testrail_bot/control/celery_tasks/testrail_pipeline.py
+++ b/testrail_bot/control/celery_tasks/testrail_pipeline.py
@@ -1,16 +1,15 @@
 import datetime
 import difflib
 import json
-from typing import TextIO, List, Tuple, Optional, Iterator, Dict
-
 from datetime import datetime as dt
 from datetime import timedelta
 from itertools import islice
-from . import filters
-from .enums import StatusEnum
-from . import test_rail_api
+from typing import Dict, Iterator, List, Optional, TextIO, Tuple
+
 from .. import models
 from ..jira_manager import JiraIssue
+from . import filters, test_rail_api
+from .enums import StatusEnum
 
 __all__ = ("process_test_run",)
 
@@ -25,12 +24,13 @@
     report.save()
 
 
-def apply_filters(data: str,
-                  filter_last_traceback: bool,
-                  ip_filter: bool,
-                  uuid_filter: bool,
-                  filter_func: str
-                  ) -> str:
+def apply_filters(
+    data: str,
+    filter_last_traceback: bool,
+    ip_filter: bool,
+    uuid_filter: bool,
+    filter_func: str,
+) -> str:
     """
     Applies various text modifiers (filtering, masking, etc.) to the input
     text.
@@ -65,9 +65,9 @@
     return data
 
 
-def get_runs_by_pattern(runs_in_plan: List[dict],
-                        test_pattern: str,
-                        suite_id: int) -> List[int]:
+def get_runs_by_pattern(
+    runs_in_plan: List[dict], test_pattern: str, suite_id: int
+) -> List[int]:
     """
     Returns a list of run IDs that are related to a specific Test Suite
     and have names containing a pattern (test_pattern)
@@ -82,64 +82,68 @@
     """
     run = []
     for t_run in runs_in_plan:
-        if test_pattern in t_run['name'] and t_run['suite_id'] == suite_id:
-            run.append(t_run['runs'][0]['id'])
+        if test_pattern in t_run["name"] and t_run["suite_id"] == suite_id:
+            run.append(t_run["runs"][0]["id"])
     return run
 
 
 def find_fail_with_same_comment(
-        case_id: int,
-        last_comment: str,
-        plan_name: str,
-        testrun_pattern: str,
-        created_by_id: int,
-        created_after: int,
-        created_before: int,
-        text_filters: dict,
+    case_id: int,
+    last_comment: str,
+    plan_name: str,
+    testrun_pattern: str,
+    created_by_id: int,
+    created_after: int,
+    created_before: int,
+    text_filters: dict,
 ) -> Iterator[Tuple[Optional[dict], float, int]]:
     """
-        Searches for similar failures within a test plan based on specific
-        criteria.
+    Searches for similar failures within a test plan based on specific
+    criteria.
 
-        :param case_id: The ID of the test case for which the failure is
-         being searched
-        :param last_comment: The last comment associated with the failed test
-        :param plan_name: The name of the test plan to search within
-        :param testrun_pattern: A pattern for filtering test runs
-        :param created_by_id: The ID of the user who created the test plan
-        :param created_after: The date (created_after) after which the test
-        plan was created
-        :param created_before: The date (created_before) before which the test
-        plan was created
-        :param run_name: The name of the test run
-        :param text_filters: A dictionary of text filters to apply when
-        comparing comments
+    :param case_id: The ID of the test case for which the failure is
+     being searched
+    :param last_comment: The last comment associated with the failed test
+    :param plan_name: The name of the test plan to search within
+    :param testrun_pattern: A pattern for filtering test runs
+    :param created_by_id: The ID of the user who created the test plan
+    :param created_after: The date (created_after) after which the test
+    plan was created
+    :param created_before: The date (created_before) before which the test
+    plan was created
+    :param run_name: The name of the test run
+    :param text_filters: A dictionary of text filters to apply when
+    comparing comments
 
-        :return: An iterator that yields tuples containing information
-        about matching test results, including test result data, similarity
-        ratio, and the associated run ID.
-        """
+    :return: An iterator that yields tuples containing information
+    about matching test results, including test result data, similarity
+    ratio, and the associated run ID.
+    """
     end_lookup_date = dt.strptime(
-        f"{created_before} 23:59:59", "%Y-%m-%d %H:%M:%S")
+        f"{created_before} 23:59:59", "%Y-%m-%d %H:%M:%S"
+    )
     start_lookup_date = dt.strptime(
-        f"{created_after} 00:00:00", "%Y-%m-%d %H:%M:%S")
+        f"{created_after} 00:00:00", "%Y-%m-%d %H:%M:%S"
+    )
     filters = {
         "created_by": created_by_id,
         "created_before": int(dt.timestamp(end_lookup_date)),
         "created_after": int(dt.timestamp(start_lookup_date)),
         "plan_name": plan_name,
-        "status_id": [StatusEnum.test_failed,
-                      StatusEnum.failed,
-                      StatusEnum.blocked,
-                      StatusEnum.product_failed,
-                      StatusEnum.wont_fix,
-                      StatusEnum.retest],
-        "testrun_pattern": testrun_pattern
+        "status_id": [
+            StatusEnum.test_failed,
+            StatusEnum.failed,
+            StatusEnum.blocked,
+            StatusEnum.product_failed,
+            StatusEnum.wont_fix,
+            StatusEnum.retest,
+        ],
+        "testrun_pattern": testrun_pattern,
     }
 
-    for n, results in enumerate(test_rail_api.get_result_history_for_case(
-            case_id,
-            **filters)):
+    for n, results in enumerate(
+        test_rail_api.get_result_history_for_case(case_id, **filters)
+    ):
         if n >= 500 or not results:
             yield None, None, None
             return
@@ -147,17 +151,21 @@
         comment = apply_filters(results[-1]["comment"], **text_filters)
         ratio = difflib.SequenceMatcher(
             lambda symbol: symbol in [" ", ",", "\n"],
-            last_comment, comment, autojunk=False).ratio()
+            last_comment,
+            comment,
+            autojunk=False,
+        ).ratio()
 
         if ratio > 0.7:
             run_id = test_rail_api.api.tests.get_test(results[0]["test_id"])[
-                "run_id"]
+                "run_id"
+            ]
             yield results[0], ratio, run_id
 
 
-def get_project_id(f: TextIO,
-                   test_run: models.TestRailTestRun,
-                   report: models.TestRailReport) -> Optional[int]:
+def get_project_id(
+    f: TextIO, test_run: models.TestRailTestRun, report: models.TestRailReport
+) -> Optional[int]:
     """
     Returns the TestRail Project ID associated with a specific test run
 
@@ -171,17 +179,20 @@
     """
     project_id = test_rail_api.get_project_id(test_run.project_name)
     if not project_id:
-        f.write("Incorrect Project {}. Stopping processing\n".format(
-            test_run.project_name))
+        f.write(
+            "Incorrect Project {}. Stopping processing\n".format(
+                test_run.project_name
+            )
+        )
         f.flush()
         finish_report(report)
         return None
     return project_id
 
 
-def get_plans(test_run: models.TestRailTestRun,
-              run_date: dt,
-              project_id: int) -> List[dict]:
+def get_plans(
+    test_run: models.TestRailTestRun, run_date: dt, project_id: int
+) -> List[dict]:
     """
     Get plans which will be processed
 
@@ -209,20 +220,20 @@
     :return: A string containing the filtered last comment for the specified
     test case in the given test run
     """
-    last_result = test_rail_api.get_result_for_case(
-        run_id, case_id)
+    last_result = test_rail_api.get_result_for_case(run_id, case_id)
 
-    return apply_filters(
-        last_result[0]["comment"], **text_filters)
+    return apply_filters(last_result[0]["comment"], **text_filters)
 
 
-def process_old_test(f: TextIO,
-                     case_id: int,
-                     last_comment: str,
-                     run_id: int,
-                     test: dict,
-                     testrail_filters: dict,
-                     text_filters: dict) -> bool:
+def process_old_test(
+    f: TextIO,
+    case_id: int,
+    last_comment: str,
+    run_id: int,
+    test: dict,
+    testrail_filters: dict,
+    text_filters: dict,
+) -> bool:
     """
     Writes to report file similarity info about the TestCase under the test
 
@@ -230,109 +241,130 @@
     """
     found_unknown_fail = 0
     for sim_result, ratio, old_run_id in find_fail_with_same_comment(
-            case_id,
-            last_comment,
-            text_filters=text_filters,
-            **testrail_filters):
+        case_id, last_comment, text_filters=text_filters, **testrail_filters
+    ):
         if str(run_id) == str(old_run_id):
             continue
         per = round(100.0 * ratio, 2)
-        run_link = test_rail_api.html_link('run', old_run_id, old_run_id)
+        run_link = test_rail_api.html_link("run", old_run_id, old_run_id)
         if type(sim_result) is not dict:
-            f.write(f"Similarity not found due to similarity: {per}, "
-                    f"in run {run_link}\n")
+            f.write(
+                f"Similarity not found due to similarity: {per}, "
+                f"in run {run_link}\n"
+            )
             f.flush()
             return False
 
-        prod_link = "None" \
-            if str(sim_result["defects"]) == "None" \
+        prod_link = (
+            "None"
+            if str(sim_result["defects"]) == "None"
             else JiraIssue(sim_result["defects"]).html()
-        test_link = test_rail_api.html_link('test',
-                                            sim_result["test_id"],
-                                            str(sim_result["test_id"]))
-        status_id = int(sim_result['status_id'])
-        if status_id in [StatusEnum.retest, StatusEnum.failed,
-                         StatusEnum.blocked]:
-            f.write(f"Found a similar result on the test "
-                    f"{test_link} with similarity {per}% and "
-                    f"{StatusEnum(status_id).name} status and {prod_link} "
-                    f"defect. <i>Continuing...</i>\n")
+        )
+        test_link = test_rail_api.html_link(
+            "test", sim_result["test_id"], str(sim_result["test_id"])
+        )
+        status_id = int(sim_result["status_id"])
+        if status_id in [
+            StatusEnum.retest,
+            StatusEnum.failed,
+            StatusEnum.blocked,
+        ]:
+            f.write(
+                f"Found a similar result on the test "
+                f"{test_link} with similarity {per}% and "
+                f"{StatusEnum(status_id).name} status and {prod_link} "
+                f"defect. <i>Continuing...</i>\n"
+            )
             f.flush()
             found_unknown_fail += 1
             if found_unknown_fail >= 10:
-                f.write(f"<b style='color:red;'>"
-                        f"Detected 10+ consecutive unknown failures\n </b>")
+                f.write(
+                    "<b style='color:red;'>"
+                    "Detected 10+ consecutive unknown failures\n </b>"
+                )
                 f.flush()
                 return False
             continue
         elif ratio > 0.9:
-            comment = f"Marked by TestRailBot because of similarity " \
-                      f"with test {sim_result['test_id']} {per}%"
+            comment = (
+                f"Marked by TestRailBot because of similarity "
+                f"with test {sim_result['test_id']} {per}%"
+            )
             # Copy the original comment if it was not created by this bot
-            if str(sim_result["status_id"]) == StatusEnum.wont_fix \
-                    and sim_result["comment"] \
-                    and "Marked by TestRailBot" not in sim_result["comment"]:
+            if (
+                str(sim_result["status_id"]) == StatusEnum.wont_fix
+                and sim_result["comment"]
+                and "Marked by TestRailBot" not in sim_result["comment"]
+            ):
                 comment = sim_result["comment"]
 
             update_dict = {
                 "status_id": sim_result["status_id"],
                 "comment": comment,
-                "defects": sim_result["defects"]
+                "defects": sim_result["defects"],
             }
-            f.write(f"Found a similar result on the test "
-                    f"{test_link} with similarity {per}% and "
-                    f"{StatusEnum(status_id).name} status and {prod_link} "
-                    f"defect\n"
-                    f"<i style='color:ForestGreen;'>Pushing to TestRail "
-                    f"{update_dict}"
-                    f"</i>\n\n")
+            f.write(
+                f"Found a similar result on the test "
+                f"{test_link} with similarity {per}% and "
+                f"{StatusEnum(status_id).name} status and {prod_link} "
+                f"defect\n"
+                f"<i style='color:ForestGreen;'>Pushing to TestRail "
+                f"{update_dict}"
+                f"</i>\n\n"
+            )
             f.flush()
             test_rail_api.add_result(test["id"], update_dict)
             return True
         elif ratio > 0.7:
-            f.write(f"<b style='color:red;'> "
-                    f"Found a similar result on the test "
-                    f"{test_link} with similarity {per}% and "
-                    f"{StatusEnum(status_id).name} status and {prod_link} "
-                    f"defect,\n but NOT marked by "
-                    f"TestRailBot because of similarity only, "
-                    f"you can update manually \n </b>")
+            f.write(
+                f"<b style='color:red;'> "
+                f"Found a similar result on the test "
+                f"{test_link} with similarity {per}% and "
+                f"{StatusEnum(status_id).name} status and {prod_link} "
+                f"defect,\n but NOT marked by "
+                f"TestRailBot because of similarity only, "
+                f"you can update manually \n </b>"
+            )
             f.flush()
             return True
 
 
-def process_test(f: TextIO,
-                 test: dict,
-                 testrail_filters: dict,
-                 text_filters: dict) -> None:
+def process_test(
+    f: TextIO, test: dict, testrail_filters: dict, text_filters: dict
+) -> None:
     """
     Starts processing for the TestCase for each TestPlan
     """
     case_id = test["case_id"]
     run_id = test["run_id"]
     run_name = test_rail_api.get_run_name(run_id)
-    test_link = test_rail_api.html_link('test', test['id'], test["title"])
-    run_link = test_rail_api.html_link('run', run_id, run_name)
+    test_link = test_rail_api.html_link("test", test["id"], test["title"])
+    run_link = test_rail_api.html_link("run", run_id, run_name)
 
-    f.write(f"<br><b>Proceeding test {test_link} <br>"
-            f"in {run_link} run</b>\n")
+    f.write(
+        f"<br><b>Proceeding test {test_link} <br>" f"in {run_link} run</b>\n"
+    )
     f.flush()
 
     last_comment = get_last_comment(case_id, run_id, text_filters)
 
     found = process_old_test(
-        f, case_id, last_comment, run_id, test, testrail_filters, text_filters)
+        f, case_id, last_comment, run_id, test, testrail_filters, text_filters
+    )
     if found:
         return
     else:
-        f.write(f"<b style='color:red;'>Automatic test processing failed. "
-                "Please process test manually "
-                f"{test_link}</b>\n\n")
+        f.write(
+            f"<b style='color:red;'>Automatic test processing failed. "
+            "Please process test manually "
+            f"{test_link}</b>\n\n"
+        )
         f.flush()
 
 
-def process_test_run(bot_run_id: int, report_id: int, path: str,
-                     is_testplan: bool) -> None:
+def process_test_run(
+    bot_run_id: int, report_id: int, path: str, is_testplan: bool
+) -> None:
     """
     This function processes a created bot test run. It retrieves a list
     of test plans to process, gathers the failed tests from the test run,
@@ -354,7 +386,9 @@
         else:
             test_run = test_rail_api.get_run_by_id(bot_test_run.run_id)
             run_type = "run"
-        link = test_rail_api.html_link(run_type, test_run['id'], test_run['name'])
+        link = test_rail_api.html_link(
+            run_type, test_run["id"], test_run["name"]
+        )
         f.write(f"Start processing {run_type} {link}\n")
         f.flush()
 
@@ -363,15 +397,21 @@
             return
 
         # failed_tests: all failed tests in test run/plan
-        failed_tests = test_rail_api.get_failed_tests(bot_test_run.run_id,
-                                                      by_plans=is_testplan)
+        failed_tests = test_rail_api.get_failed_tests(
+            bot_test_run.run_id, by_plans=is_testplan
+        )
         for test in failed_tests:
-            if bot_test_run.caching_tests_enabled and \
-                    test["id"] in bot_test_run.checked_tests:
+            if (
+                bot_test_run.caching_tests_enabled
+                and test["id"] in bot_test_run.checked_tests
+            ):
                 continue
-            process_test(f, test,
-                         bot_test_run.testrail_filters,
-                         bot_test_run.text_filters)
+            process_test(
+                f,
+                test,
+                bot_test_run.testrail_filters,
+                bot_test_run.text_filters,
+            )
             bot_test_run.checked_tests.append(test["id"])
             bot_test_run.save()
         f.write("Test processing finished")
@@ -379,13 +419,15 @@
         finish_report(report)
 
 
-def get_cases(project_id: int, suite_id: int,
-              limit: int = 250,
-              max_limit: int = 1000,
-              filter: str = None,
-              created_after: int = None,
-              created_before: int = None,
-              ) -> Iterator[Dict]:
+def get_cases(
+    project_id: int,
+    suite_id: int,
+    limit: int = 250,
+    max_limit: int = 1000,
+    filter: str = None,
+    created_after: int = None,
+    created_before: int = None,
+) -> Iterator[Dict]:
     for offset in range(0, max_limit, limit):
         cases = test_rail_api.api.cases.get_cases(
             project_id=project_id,
@@ -394,7 +436,8 @@
             offset=offset,
             created_after=created_after,
             created_before=created_before,
-            filter=filter).get("cases")
+            filter=filter,
+        ).get("cases")
 
         if not cases:
             return
@@ -423,10 +466,12 @@
     }
     """
 
-    diff_obj: models.DiffOfSuitesPassRates = \
+    diff_obj: models.DiffOfSuitesPassRates = (
         models.DiffOfSuitesPassRates.objects.get(pk=diff_id)
+    )
     report: models.SuitePassRate = models.SuitePassRate.objects.get(
-        pk=report_id)
+        pk=report_id
+    )
     suite_id = report.suite_id
 
     project_id = test_rail_api.get_project_id("Mirantis Cloud Platform")
@@ -442,32 +487,40 @@
     }
 
     passrate_by_cases = dict()
-    params = dict(project_id=project_id,
-                  suite_id=suite_id,
-                  filter=diff_obj.test_keyword,
-                  limit=200)
+    params = dict(
+        project_id=project_id,
+        suite_id=suite_id,
+        filter=diff_obj.test_keyword,
+        limit=200,
+    )
     for _n, case in enumerate(get_cases(**params), start=1):
-        case_title = case['title']
+        case_title = case["title"]
         case_id = case["id"]
         report.status = f"Current case: {_n}"
         report.save()
         # Limit generator to the list with  the length defined in the
         # DiffOfSuitesPassRates
-        last_case_results = list(islice(
-            test_rail_api.get_result_history_for_case(case_id, **_filters),
-            diff_obj.limit))
+        last_case_results = list(
+            islice(
+                test_rail_api.get_result_history_for_case(case_id, **_filters),
+                diff_obj.limit,
+            )
+        )
 
         passrate_by_cases[case_title] = dict()
-        passrate_by_cases[case_title]['case_id'] = case_id
+        passrate_by_cases[case_title]["case_id"] = case_id
         if last_case_results:
-            passed_tests = [x for x in last_case_results
-                            if x[-1]["status_id"] == StatusEnum.passed]
-            passrate_by_cases[case_title]['rate'] = \
+            passed_tests = [
+                x
+                for x in last_case_results
+                if x[-1]["status_id"] == StatusEnum.passed
+            ]
+            passrate_by_cases[case_title]["rate"] = (
                 len(passed_tests) * 100 / diff_obj.limit
+            )
         else:
-            passrate_by_cases[case_title]['rate'] = "No result found"
-        report.passrate_by_tests = json.dumps(passrate_by_cases,
-                                              indent=4)
+            passrate_by_cases[case_title]["rate"] = "No result found"
+        report.passrate_by_tests = json.dumps(passrate_by_cases, indent=4)
         report.status = f"Current case: {_n}"
         report.save()
     report.finished = True
diff --git a/testrail_bot/control/forms.py b/testrail_bot/control/forms.py
index 363035b..8d1ef8c 100644
--- a/testrail_bot/control/forms.py
+++ b/testrail_bot/control/forms.py
@@ -1,18 +1,24 @@
 from datetime import date
+
 from django import forms
-from .models import TestRailTestRun, \
-    DiffOfSuitesPassRates, \
-    SuitePassRate, \
-    CronPeriodicTask
+
+from .models import (
+    CronPeriodicTask,
+    DiffOfSuitesPassRates,
+    SuitePassRate,
+    TestRailTestRun,
+)
 
 
 class TestRunForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
-        self.fields["created_after"].widget = forms.SelectDateWidget(years=[
-            date.today().year + i for i in range(-3, 5)])
-        self.fields["created_before"].widget = forms.SelectDateWidget(years=[
-            date.today().year + i for i in range(-3, 5)])
+        self.fields["created_after"].widget = forms.SelectDateWidget(
+            years=[date.today().year + i for i in range(-3, 5)]
+        )
+        self.fields["created_before"].widget = forms.SelectDateWidget(
+            years=[date.today().year + i for i in range(-3, 5)]
+        )
 
     class Meta:
         model = TestRailTestRun
@@ -28,11 +34,10 @@
             "ip_filter": "Mask all IP with x.x.x.x",
             "uuid_filter": "Mask all UUID with xxxx",
             "filter_last_traceback": "Use only traceback to "
-                                     "compare comments",
+            "compare comments",
             "created_after": "Search in period from",
             "created_before": "till",
-            "caching_tests_enabled": "Don't check already checked results"
-
+            "caching_tests_enabled": "Don't check already checked results",
         }
         help_texts = {
             "filter_func": "Leave blank if not used",
@@ -48,7 +53,7 @@
         labels = {
             "test_keyword": "Pattern to search by tests",
             "limit": "Count of tests to define the passrate. Don't recommend "
-                     "to use a number greater that 10"
+            "to use a number greater that 10",
         }
 
 
@@ -56,12 +61,17 @@
     class Meta:
         model = SuitePassRate
         fields = ["suite_id"]
-        labels = {
-            "suite_id": "Suite ID"
-        }
+        labels = {"suite_id": "Suite ID"}
 
 
 class PeriodicTaskForm(forms.ModelForm):
     class Meta:
         model = CronPeriodicTask
-        fields = ["id", "enabled", "name", "cron", "task_name", "testplan_id_arg"]
+        fields = [
+            "id",
+            "enabled",
+            "name",
+            "cron",
+            "task_name",
+            "testplan_id_arg",
+        ]
diff --git a/testrail_bot/control/jira_manager.py b/testrail_bot/control/jira_manager.py
index ee81efa..6068a84 100644
--- a/testrail_bot/control/jira_manager.py
+++ b/testrail_bot/control/jira_manager.py
@@ -1,15 +1,19 @@
 from django.conf import settings
 from jira import JIRA, Issue
 
-jira = JIRA(server=settings.JIRA_SERVER,
-            basic_auth=(settings.JIRA_USER, settings.JIRA_PASSWORD))
+jira = JIRA(
+    server=settings.JIRA_SERVER,
+    basic_auth=(settings.JIRA_USER, settings.JIRA_PASSWORD),
+)
 
 
 class JiraIssue:
     def __init__(self, key: str):
         self.key = key
         self._issue = None
-        self._style_prod_area = "background-color:aliceblue;border-color:CornflowerBlue;"
+        self._style_prod_area = (
+            "background-color:aliceblue;border-color:CornflowerBlue;"
+        )
         self._style_prod_text = "color:blue"
 
     @property
@@ -23,12 +27,16 @@
         return f"{settings.JIRA_SERVER}/browse/{self.issue.key}"
 
     def html(self) -> str:
-        if self.issue.fields.status.name in ['Completed', 'Released']:
+        if self.issue.fields.status.name in ["Completed", "Released"]:
             self._style_prod_area = "background-color:red;border-color:black;"
             self._style_prod_text = "color:white"
-        return f"<div style='display:inline-block;border:1px solid;{self._style_prod_area}" \
-               f"border-radius:5px;padding:2px;'>" \
-               f"<a style={self._style_prod_text} href='{self.get_link()}'>" \
-               f"{self.key}: {self.issue.fields.summary[:50]}</a>" \
-               f"<b style={self._style_prod_text}> {self.issue.fields.status.name}</b>" \
-               f"</div>"
+        return (
+            f"<div style='display:inline-block;border:1px solid;"
+            f"{self._style_prod_area}"
+            f"border-radius:5px;padding:2px;'>"
+            f"<a style={self._style_prod_text} href='{self.get_link()}'>"
+            f"{self.key}: {self.issue.fields.summary[:50]}</a>"
+            f"<b style={self._style_prod_text}> "
+            f"{self.issue.fields.status.name}</b>"
+            f"</div>"
+        )
diff --git a/testrail_bot/control/migrations/0001_initial.py b/testrail_bot/control/migrations/0001_initial.py
index b8d4697..a450f5d 100644
--- a/testrail_bot/control/migrations/0001_initial.py
+++ b/testrail_bot/control/migrations/0001_initial.py
@@ -1,6 +1,7 @@
 # Generated by Django 4.2.6 on 2023-11-04 10:46
 
 import datetime
+
 import django.core.files.storage
 from django.db import migrations, models
 
@@ -9,69 +10,83 @@
 
     initial = True
 
-    dependencies = [
-    ]
+    dependencies = []
 
     operations = [
         migrations.CreateModel(
-            name='ActionLog',
+            name="ActionLog",
             fields=[
-                ('id', models.AutoField(
-                    auto_created=True,
-                    primary_key=True,
-                    serialize=False,
-                    verbose_name='ID')),
-                ('name', models.CharField(max_length=500)),
-                ('date', models.DateTimeField(null=True)),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("name", models.CharField(max_length=500)),
+                ("date", models.DateTimeField(null=True)),
             ],
         ),
         migrations.CreateModel(
-            name='TestRailReport',
+            name="TestRailReport",
             fields=[
-                ('id', models.AutoField(
-                    auto_created=True,
-                    primary_key=True,
-                    serialize=False,
-                    verbose_name='ID')),
-                ('path', models.FileField(
-                    blank=True,
-                    max_length=500,
-                    null=True,
-                    storage=django.core.files.storage.FileSystemStorage(),
-                    upload_to='')),
-                ('report_name', models.CharField(max_length=300)),
-                ('finished', models.BooleanField(default=False)),
-                ('created_at', models.DateTimeField(auto_now_add=True)),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "path",
+                    models.FileField(
+                        blank=True,
+                        max_length=500,
+                        null=True,
+                        storage=django.core.files.storage.FileSystemStorage(),
+                        upload_to="",
+                    ),
+                ),
+                ("report_name", models.CharField(max_length=300)),
+                ("finished", models.BooleanField(default=False)),
+                ("created_at", models.DateTimeField(auto_now_add=True)),
             ],
         ),
         migrations.CreateModel(
-            name='TestRailTestRun',
+            name="TestRailTestRun",
             fields=[
-                ('id', models.AutoField(
-                    auto_created=True,
-                    primary_key=True,
-                    serialize=False,
-                    verbose_name='ID')),
-                ('project_name', models.CharField(
-                    default='Mirantis Cloud Platform',
-                    max_length=300)),
-                ('plan_name', models.CharField(
-                    default='[MCP2.0]OSCORE',
-                    max_length=300)),
-                ('run_name', models.CharField(
-                    blank=True,
-                    max_length=300)),
-                ('test_pattern', models.CharField(
-                    blank=True,
-                    max_length=300)),
-                ('run_id', models.CharField(max_length=300)),
-                ('created_by_id', models.IntegerField(default='109')),
-                ('filter_func', models.TextField(blank=True, null=True)),
-                ('ip_filter', models.BooleanField(default=True)),
-                ('uuid_filter', models.BooleanField(default=True)),
-                ('filter_last_traceback', models.BooleanField(default=False)),
-                ('timestamp', models.DateField(
-                    default=datetime.date.today())),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "project_name",
+                    models.CharField(
+                        default="Mirantis Cloud Platform", max_length=300
+                    ),
+                ),
+                (
+                    "plan_name",
+                    models.CharField(default="[MCP2.0]OSCORE", max_length=300),
+                ),
+                ("run_name", models.CharField(blank=True, max_length=300)),
+                ("test_pattern", models.CharField(blank=True, max_length=300)),
+                ("run_id", models.CharField(max_length=300)),
+                ("created_by_id", models.IntegerField(default="109")),
+                ("filter_func", models.TextField(blank=True, null=True)),
+                ("ip_filter", models.BooleanField(default=True)),
+                ("uuid_filter", models.BooleanField(default=True)),
+                ("filter_last_traceback", models.BooleanField(default=False)),
+                ("timestamp", models.DateField(default=datetime.date.today())),
             ],
         ),
     ]
diff --git a/testrail_bot/control/migrations/0002_testrailtestrun_checked_tests.py b/testrail_bot/control/migrations/0002_testrailtestrun_checked_tests.py
index 4e62602..3ad73d2 100644
--- a/testrail_bot/control/migrations/0002_testrailtestrun_checked_tests.py
+++ b/testrail_bot/control/migrations/0002_testrailtestrun_checked_tests.py
@@ -7,13 +7,13 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0001_initial'),
+        ("control", "0001_initial"),
     ]
 
     operations = [
         migrations.AddField(
-            model_name='testrailtestrun',
-            name='checked_tests',
+            model_name="testrailtestrun",
+            name="checked_tests",
             field=control.models.IntegerListField(default=[], editable=False),
         ),
     ]
diff --git a/testrail_bot/control/migrations/0003_suitepassrate_diffofsuitespassrates.py b/testrail_bot/control/migrations/0003_suitepassrate_diffofsuitespassrates.py
index 6215a62..13be3e1 100644
--- a/testrail_bot/control/migrations/0003_suitepassrate_diffofsuitespassrates.py
+++ b/testrail_bot/control/migrations/0003_suitepassrate_diffofsuitespassrates.py
@@ -1,36 +1,97 @@
 # Generated by Django 4.2.7 on 2023-11-20 17:46
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0002_testrailtestrun_checked_tests'),
+        ("control", "0002_testrailtestrun_checked_tests"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='SuitePassRate',
+            name="SuitePassRate",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('suite_id', models.CharField(choices=[('10651', '[MCP2.0_ROCKY]Tempest'), ('10635', '[MCP2.0_STEIN]Tempest'), ('10653', '[MCP2.0_TRAIN]Tempest'), ('10710', '[MCP2.0_USSURI]Tempest'), ('10888', '[MCP2.0_VICTORIA]Tempest'), ('11167', '[MCP2.0_WALLABY]Tempest'), ('11188', '[MCP2.0_XENA]Tempest'), ('11170', '[MCP2.0_YOGA]Tempest'), ('11192', '[MCP2.0_ANTELOPE]Tempest'), ('11193', '[MCP2.0_ANTELOPE]Stepler'), ('10886', '[MCP2.0_USSURI]Stepler'), ('10887', '[MCP2.0_VICTORIA]Stepler'), ('11171', '[MCP2.0_YOGA]Stepler')], max_length=20)),
-                ('suite_name', models.CharField(blank=True, max_length=100)),
-                ('passrate_by_tests', models.JSONField(blank=True, default='{}')),
-                ('status', models.TextField(blank=True, max_length=300)),
-                ('finished', models.BooleanField(blank=True, default=False)),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "suite_id",
+                    models.CharField(
+                        choices=[
+                            ("10651", "[MCP2.0_ROCKY]Tempest"),
+                            ("10635", "[MCP2.0_STEIN]Tempest"),
+                            ("10653", "[MCP2.0_TRAIN]Tempest"),
+                            ("10710", "[MCP2.0_USSURI]Tempest"),
+                            ("10888", "[MCP2.0_VICTORIA]Tempest"),
+                            ("11167", "[MCP2.0_WALLABY]Tempest"),
+                            ("11188", "[MCP2.0_XENA]Tempest"),
+                            ("11170", "[MCP2.0_YOGA]Tempest"),
+                            ("11192", "[MCP2.0_ANTELOPE]Tempest"),
+                            ("11193", "[MCP2.0_ANTELOPE]Stepler"),
+                            ("10886", "[MCP2.0_USSURI]Stepler"),
+                            ("10887", "[MCP2.0_VICTORIA]Stepler"),
+                            ("11171", "[MCP2.0_YOGA]Stepler"),
+                        ],
+                        max_length=20,
+                    ),
+                ),
+                ("suite_name", models.CharField(blank=True, max_length=100)),
+                (
+                    "passrate_by_tests",
+                    models.JSONField(blank=True, default="{}"),
+                ),
+                ("status", models.TextField(blank=True, max_length=300)),
+                ("finished", models.BooleanField(blank=True, default=False)),
             ],
         ),
         migrations.CreateModel(
-            name='DiffOfSuitesPassRates',
+            name="DiffOfSuitesPassRates",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('started_at', models.DateTimeField(auto_created=True, auto_now=True)),
-                ('limit', models.IntegerField(blank=True, default=10)),
-                ('test_keyword', models.CharField(blank=True, default='', max_length=300)),
-                ('report1', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='report1', to='control.suitepassrate')),
-                ('report2', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='report2', to='control.suitepassrate')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "started_at",
+                    models.DateTimeField(auto_created=True, auto_now=True),
+                ),
+                ("limit", models.IntegerField(blank=True, default=10)),
+                (
+                    "test_keyword",
+                    models.CharField(blank=True, default="", max_length=300),
+                ),
+                (
+                    "report1",
+                    models.ForeignKey(
+                        blank=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="report1",
+                        to="control.suitepassrate",
+                    ),
+                ),
+                (
+                    "report2",
+                    models.ForeignKey(
+                        blank=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="report2",
+                        to="control.suitepassrate",
+                    ),
+                ),
             ],
         ),
     ]
diff --git a/testrail_bot/control/migrations/0004_rename_timestamp_testrailtestrun_created_before.py b/testrail_bot/control/migrations/0004_rename_timestamp_testrailtestrun_created_before.py
index aee1b1f..f4a345a 100644
--- a/testrail_bot/control/migrations/0004_rename_timestamp_testrailtestrun_created_before.py
+++ b/testrail_bot/control/migrations/0004_rename_timestamp_testrailtestrun_created_before.py
@@ -1,24 +1,25 @@
 # Generated by Django 4.2.7 on 2023-11-28 14:07
 
 import datetime
+
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0003_suitepassrate_diffofsuitespassrates'),
+        ("control", "0003_suitepassrate_diffofsuitespassrates"),
     ]
 
     operations = [
         migrations.RenameField(
-            model_name='testrailtestrun',
-            old_name='timestamp',
-            new_name='created_before',
+            model_name="testrailtestrun",
+            old_name="timestamp",
+            new_name="created_before",
         ),
         migrations.AddField(
-            model_name='testrailtestrun',
-            name='created_after',
+            model_name="testrailtestrun",
+            name="created_after",
             field=models.DateField(default=datetime.date(2023, 8, 30)),
         ),
     ]
diff --git a/testrail_bot/control/migrations/0005_alter_suitepassrate_suite_id_and_more.py b/testrail_bot/control/migrations/0005_alter_suitepassrate_suite_id_and_more.py
index 27d098c..6478349 100644
--- a/testrail_bot/control/migrations/0005_alter_suitepassrate_suite_id_and_more.py
+++ b/testrail_bot/control/migrations/0005_alter_suitepassrate_suite_id_and_more.py
@@ -1,19 +1,45 @@
 # Generated by Django 4.2.7 on 2023-11-30 13:03
 
-import datetime
 from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0004_rename_timestamp_testrailtestrun_created_before'),
+        ("control", "0004_rename_timestamp_testrailtestrun_created_before"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='suitepassrate',
-            name='suite_id',
-            field=models.CharField(choices=[('Tempest', (('10651', '[MCP2.0_ROCKY]Tempest'), ('10635', '[MCP2.0_STEIN]Tempest'), ('10653', '[MCP2.0_TRAIN]Tempest'), ('10710', '[MCP2.0_USSURI]Tempest'), ('10888', '[MCP2.0_VICTORIA]Tempest'), ('11167', '[MCP2.0_WALLABY]Tempest'), ('11188', '[MCP2.0_XENA]Tempest'), ('11170', '[MCP2.0_YOGA]Tempest'), ('11192', '[MCP2.0_ANTELOPE]Tempest'))), ('Stepler', (('10886', '[MCP2.0_USSURI]Stepler'), ('10887', '[MCP2.0_VICTORIA]Stepler'), ('11171', '[MCP2.0_YOGA]Stepler'), ('11193', '[MCP2.0_ANTELOPE]Stepler')))], max_length=20),
+            model_name="suitepassrate",
+            name="suite_id",
+            field=models.CharField(
+                choices=[
+                    (
+                        "Tempest",
+                        (
+                            ("10651", "[MCP2.0_ROCKY]Tempest"),
+                            ("10635", "[MCP2.0_STEIN]Tempest"),
+                            ("10653", "[MCP2.0_TRAIN]Tempest"),
+                            ("10710", "[MCP2.0_USSURI]Tempest"),
+                            ("10888", "[MCP2.0_VICTORIA]Tempest"),
+                            ("11167", "[MCP2.0_WALLABY]Tempest"),
+                            ("11188", "[MCP2.0_XENA]Tempest"),
+                            ("11170", "[MCP2.0_YOGA]Tempest"),
+                            ("11192", "[MCP2.0_ANTELOPE]Tempest"),
+                        ),
+                    ),
+                    (
+                        "Stepler",
+                        (
+                            ("10886", "[MCP2.0_USSURI]Stepler"),
+                            ("10887", "[MCP2.0_VICTORIA]Stepler"),
+                            ("11171", "[MCP2.0_YOGA]Stepler"),
+                            ("11193", "[MCP2.0_ANTELOPE]Stepler"),
+                        ),
+                    ),
+                ],
+                max_length=20,
+            ),
         )
     ]
diff --git a/testrail_bot/control/migrations/0006_alter_testrailtestrun_created_after_and_more.py b/testrail_bot/control/migrations/0006_alter_testrailtestrun_created_after_and_more.py
index 4fcbc75..7e5ec61 100644
--- a/testrail_bot/control/migrations/0006_alter_testrailtestrun_created_after_and_more.py
+++ b/testrail_bot/control/migrations/0006_alter_testrailtestrun_created_after_and_more.py
@@ -1,29 +1,29 @@
 # Generated by Django 4.2.7 on 2024-01-10 10:16
 
-from django.db import migrations, models
 import django.utils.timezone
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0005_alter_suitepassrate_suite_id_and_more'),
+        ("control", "0005_alter_suitepassrate_suite_id_and_more"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='testrailtestrun',
-            name='created_after',
+            model_name="testrailtestrun",
+            name="created_after",
             field=models.DateField(default=django.utils.timezone.now),
         ),
         migrations.AlterField(
-            model_name='testrailtestrun',
-            name='created_before',
+            model_name="testrailtestrun",
+            name="created_before",
             field=models.DateField(default=django.utils.timezone.now),
         ),
         migrations.AlterField(
-            model_name='testrailtestrun',
-            name='filter_last_traceback',
+            model_name="testrailtestrun",
+            name="filter_last_traceback",
             field=models.BooleanField(default=True),
         ),
     ]
diff --git a/testrail_bot/control/migrations/0007_testrailtestrun_caching_tests_enabled.py b/testrail_bot/control/migrations/0007_testrailtestrun_caching_tests_enabled.py
index a33fc75..a902a2b 100644
--- a/testrail_bot/control/migrations/0007_testrailtestrun_caching_tests_enabled.py
+++ b/testrail_bot/control/migrations/0007_testrailtestrun_caching_tests_enabled.py
@@ -6,13 +6,13 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0006_alter_testrailtestrun_created_after_and_more'),
+        ("control", "0006_alter_testrailtestrun_created_after_and_more"),
     ]
 
     operations = [
         migrations.AddField(
-            model_name='testrailtestrun',
-            name='caching_tests_enabled',
+            model_name="testrailtestrun",
+            name="caching_tests_enabled",
             field=models.BooleanField(default=False),
         ),
     ]
diff --git a/testrail_bot/control/migrations/0008_rename_test_pattern_testrailtestrun_testrun_pattern.py b/testrail_bot/control/migrations/0008_rename_test_pattern_testrailtestrun_testrun_pattern.py
index ec350ca..73a2873 100644
--- a/testrail_bot/control/migrations/0008_rename_test_pattern_testrailtestrun_testrun_pattern.py
+++ b/testrail_bot/control/migrations/0008_rename_test_pattern_testrailtestrun_testrun_pattern.py
@@ -6,13 +6,13 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0007_testrailtestrun_caching_tests_enabled'),
+        ("control", "0007_testrailtestrun_caching_tests_enabled"),
     ]
 
     operations = [
         migrations.RenameField(
-            model_name='testrailtestrun',
-            old_name='test_pattern',
-            new_name='testrun_pattern',
+            model_name="testrailtestrun",
+            old_name="test_pattern",
+            new_name="testrun_pattern",
         ),
     ]
diff --git a/testrail_bot/control/migrations/0009_cronperiodictask_alter_testrailtestrun_created_after.py b/testrail_bot/control/migrations/0009_cronperiodictask_alter_testrailtestrun_created_after.py
index 443115b..fabe448 100644
--- a/testrail_bot/control/migrations/0009_cronperiodictask_alter_testrailtestrun_created_after.py
+++ b/testrail_bot/control/migrations/0009_cronperiodictask_alter_testrailtestrun_created_after.py
@@ -1,32 +1,47 @@
 # Generated by Django 4.2.7 on 2024-02-20 14:18
 
 import control.models
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('django_celery_beat', '0018_improve_crontab_helptext'),
-        ('control', '0008_rename_test_pattern_testrailtestrun_testrun_pattern'),
+        ("django_celery_beat", "0018_improve_crontab_helptext"),
+        (
+            "control",
+            "0008_rename_test_pattern_testrailtestrun_testrun_pattern",
+        ),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='CronPeriodicTask',
+            name="CronPeriodicTask",
             fields=[
-                ('periodictask_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='django_celery_beat.periodictask')),
-                ('cron', models.CharField(default='', max_length=300)),
+                (
+                    "periodictask_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="django_celery_beat.periodictask",
+                    ),
+                ),
+                ("cron", models.CharField(default="", max_length=300)),
             ],
             options={
-                'ordering': ['id'],
+                "ordering": ["id"],
             },
-            bases=('django_celery_beat.periodictask',),
+            bases=("django_celery_beat.periodictask",),
         ),
         migrations.AlterField(
-            model_name='testrailtestrun',
-            name='created_after',
-            field=models.DateField(default=control.models.default_created_after),
+            model_name="testrailtestrun",
+            name="created_after",
+            field=models.DateField(
+                default=control.models.default_created_after
+            ),
         ),
     ]
diff --git a/testrail_bot/control/migrations/0010_alter_testrailtestrun_options.py b/testrail_bot/control/migrations/0010_alter_testrailtestrun_options.py
index ca00143..1d9afd9 100644
--- a/testrail_bot/control/migrations/0010_alter_testrailtestrun_options.py
+++ b/testrail_bot/control/migrations/0010_alter_testrailtestrun_options.py
@@ -6,12 +6,15 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0009_cronperiodictask_alter_testrailtestrun_created_after'),
+        (
+            "control",
+            "0009_cronperiodictask_alter_testrailtestrun_created_after",
+        ),
     ]
 
     operations = [
         migrations.AlterModelOptions(
-            name='testrailtestrun',
-            options={'ordering': ['-run_id']},
+            name="testrailtestrun",
+            options={"ordering": ["-run_id"]},
         ),
     ]
diff --git a/testrail_bot/control/migrations/0011_cronperiodictask_task_name_and_more.py b/testrail_bot/control/migrations/0011_cronperiodictask_task_name_and_more.py
index 2901309..ce5926d 100644
--- a/testrail_bot/control/migrations/0011_cronperiodictask_task_name_and_more.py
+++ b/testrail_bot/control/migrations/0011_cronperiodictask_task_name_and_more.py
@@ -6,18 +6,31 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0010_alter_testrailtestrun_options'),
+        ("control", "0010_alter_testrailtestrun_options"),
     ]
 
     operations = [
         migrations.AddField(
-            model_name='cronperiodictask',
-            name='task_name',
-            field=models.CharField(choices=[('control.celery_tasks.tasks.check_today_testplan', 'Check today testplan'), ('control.celery_tasks.tasks.check_specific_testplan', 'Check specific testplan')], default='control.celery_tasks.tasks.check_today_testplan', max_length=300),
+            model_name="cronperiodictask",
+            name="task_name",
+            field=models.CharField(
+                choices=[
+                    (
+                        "control.celery_tasks.tasks.check_today_testplan",
+                        "Check today testplan",
+                    ),
+                    (
+                        "control.celery_tasks.tasks.check_specific_testplan",
+                        "Check specific testplan",
+                    ),
+                ],
+                default="control.celery_tasks.tasks.check_today_testplan",
+                max_length=300,
+            ),
         ),
         migrations.AddField(
-            model_name='cronperiodictask',
-            name='testplan_id_arg',
+            model_name="cronperiodictask",
+            name="testplan_id_arg",
             field=models.CharField(blank=True, max_length=30, null=True),
         ),
     ]
diff --git a/testrail_bot/control/migrations/0012_alter_suitepassrate_suite_id.py b/testrail_bot/control/migrations/0012_alter_suitepassrate_suite_id.py
index 62e0193..4650a53 100644
--- a/testrail_bot/control/migrations/0012_alter_suitepassrate_suite_id.py
+++ b/testrail_bot/control/migrations/0012_alter_suitepassrate_suite_id.py
@@ -6,13 +6,43 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('control', '0011_cronperiodictask_task_name_and_more'),
+        ("control", "0011_cronperiodictask_task_name_and_more"),
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='suitepassrate',
-            name='suite_id',
-            field=models.CharField(choices=[('Tempest', (('10650', '[MCP2.0_QUEENS]Tempest'), ('10651', '[MCP2.0_ROCKY]Tempest'), ('10635', '[MCP2.0_STEIN]Tempest'), ('10653', '[MCP2.0_TRAIN]Tempest'), ('10710', '[MCP2.0_USSURI]Tempest'), ('10888', '[MCP2.0_VICTORIA]Tempest'), ('11167', '[MCP2.0_WALLABY]Tempest'), ('11188', '[MCP2.0_XENA]Tempest'), ('11170', '[MCP2.0_YOGA]Tempest'), ('11192', '[MCP2.0_ANTELOPE]Tempest'), ('11195', '[MCP2.0_CARACAL]Tempest'))), ('Stepler', (('10886', '[MCP2.0_USSURI]Stepler'), ('10887', '[MCP2.0_VICTORIA]Stepler'), ('11171', '[MCP2.0_YOGA]Stepler'), ('11193', '[MCP2.0_ANTELOPE]Stepler'), ('11196', '[MCP2.0_CARACAL]Stepler')))], max_length=20),
+            model_name="suitepassrate",
+            name="suite_id",
+            field=models.CharField(
+                choices=[
+                    (
+                        "Tempest",
+                        (
+                            ("10650", "[MCP2.0_QUEENS]Tempest"),
+                            ("10651", "[MCP2.0_ROCKY]Tempest"),
+                            ("10635", "[MCP2.0_STEIN]Tempest"),
+                            ("10653", "[MCP2.0_TRAIN]Tempest"),
+                            ("10710", "[MCP2.0_USSURI]Tempest"),
+                            ("10888", "[MCP2.0_VICTORIA]Tempest"),
+                            ("11167", "[MCP2.0_WALLABY]Tempest"),
+                            ("11188", "[MCP2.0_XENA]Tempest"),
+                            ("11170", "[MCP2.0_YOGA]Tempest"),
+                            ("11192", "[MCP2.0_ANTELOPE]Tempest"),
+                            ("11195", "[MCP2.0_CARACAL]Tempest"),
+                        ),
+                    ),
+                    (
+                        "Stepler",
+                        (
+                            ("10886", "[MCP2.0_USSURI]Stepler"),
+                            ("10887", "[MCP2.0_VICTORIA]Stepler"),
+                            ("11171", "[MCP2.0_YOGA]Stepler"),
+                            ("11193", "[MCP2.0_ANTELOPE]Stepler"),
+                            ("11196", "[MCP2.0_CARACAL]Stepler"),
+                        ),
+                    ),
+                ],
+                max_length=20,
+            ),
         ),
     ]
diff --git a/testrail_bot/control/models.py b/testrail_bot/control/models.py
index a8a0910..b438dec 100644
--- a/testrail_bot/control/models.py
+++ b/testrail_bot/control/models.py
@@ -6,28 +6,28 @@
 
 class IntegerListField(models.Field):
     def __init__(self, *args, **kwargs):
-        kwargs['editable'] = False
+        kwargs["editable"] = False
         super(IntegerListField, self).__init__(*args, **kwargs)
 
     def db_type(self, connection):
-        return 'text'
+        return "text"
 
     def from_db_value(self, value, expression, connection):
         if not value:
             return []
-        return [int(x) for x in value.split(',')]
+        return [int(x) for x in value.split(",")]
 
     def to_python(self, value):
         if isinstance(value, list):
             return value
         if not value:
             return []
-        return [int(x) for x in value.split(',')]
+        return [int(x) for x in value.split(",")]
 
     def get_prep_value(self, value):
         if not value:
-            return ''
-        return ','.join(str(int(x)) for x in value)
+            return ""
+        return ",".join(str(int(x)) for x in value)
 
 
 def default_created_after():
@@ -35,15 +35,16 @@
 
 
 class TestRailTestRun(models.Model):
-    project_name = models.CharField(max_length=300,
-                                    default="Mirantis Cloud Platform")
+    project_name = models.CharField(
+        max_length=300, default="Mirantis Cloud Platform"
+    )
     plan_name = models.CharField(max_length=300, default="[MCP2.0]OSCORE")
     run_name = models.CharField(max_length=300, blank=True)
     testrun_pattern = models.CharField(max_length=300, blank=True)
     run_id = models.CharField(max_length=300)
     checked_tests = IntegerListField(default=list())
     caching_tests_enabled = models.BooleanField(default=False)
-    created_by_id = models.IntegerField(default='109')
+    created_by_id = models.IntegerField(default="109")
     filter_func = models.TextField(null=True, blank=True)
     ip_filter = models.BooleanField(default=True)
     uuid_filter = models.BooleanField(default=True)
@@ -91,26 +92,32 @@
 
 class SuitePassRate(models.Model):
     SUITE_CHOICES = [
-        ("Tempest", (
-            ("10650", "[MCP2.0_QUEENS]Tempest"),
-            ("10651", "[MCP2.0_ROCKY]Tempest"),
-            ("10635", "[MCP2.0_STEIN]Tempest"),
-            ("10653", "[MCP2.0_TRAIN]Tempest"),
-            ("10710", "[MCP2.0_USSURI]Tempest"),
-            ("10888", "[MCP2.0_VICTORIA]Tempest"),
-            ("11167", "[MCP2.0_WALLABY]Tempest"),
-            ("11188", "[MCP2.0_XENA]Tempest"),
-            ("11170", "[MCP2.0_YOGA]Tempest"),
-            ("11192", "[MCP2.0_ANTELOPE]Tempest"),
-            ("11195", "[MCP2.0_CARACAL]Tempest"))
-         ),
-        ("Stepler", (
-            ("10886", "[MCP2.0_USSURI]Stepler"),
-            ("10887", "[MCP2.0_VICTORIA]Stepler"),
-            ("11171", "[MCP2.0_YOGA]Stepler"),
-            ("11193", "[MCP2.0_ANTELOPE]Stepler"),
-            ("11196", "[MCP2.0_CARACAL]Stepler"))
-         ),
+        (
+            "Tempest",
+            (
+                ("10650", "[MCP2.0_QUEENS]Tempest"),
+                ("10651", "[MCP2.0_ROCKY]Tempest"),
+                ("10635", "[MCP2.0_STEIN]Tempest"),
+                ("10653", "[MCP2.0_TRAIN]Tempest"),
+                ("10710", "[MCP2.0_USSURI]Tempest"),
+                ("10888", "[MCP2.0_VICTORIA]Tempest"),
+                ("11167", "[MCP2.0_WALLABY]Tempest"),
+                ("11188", "[MCP2.0_XENA]Tempest"),
+                ("11170", "[MCP2.0_YOGA]Tempest"),
+                ("11192", "[MCP2.0_ANTELOPE]Tempest"),
+                ("11195", "[MCP2.0_CARACAL]Tempest"),
+            ),
+        ),
+        (
+            "Stepler",
+            (
+                ("10886", "[MCP2.0_USSURI]Stepler"),
+                ("10887", "[MCP2.0_VICTORIA]Stepler"),
+                ("11171", "[MCP2.0_YOGA]Stepler"),
+                ("11193", "[MCP2.0_ANTELOPE]Stepler"),
+                ("11196", "[MCP2.0_CARACAL]Stepler"),
+            ),
+        ),
     ]
     suite_id = models.CharField(max_length=20, choices=SUITE_CHOICES)
     suite_name = models.CharField(max_length=100, blank=True)
@@ -122,38 +129,42 @@
 class DiffOfSuitesPassRates(models.Model):
     limit = models.IntegerField(default=10, blank=True)
     test_keyword = models.CharField(default="", max_length=300, blank=True)
-    report1 = models.ForeignKey(to=SuitePassRate,
-                                related_name="report1",
-                                on_delete=models.CASCADE,
-                                blank=True)
-    report2 = models.ForeignKey(to=SuitePassRate,
-                                related_name="report2",
-                                on_delete=models.CASCADE,
-                                blank=True)
-    started_at = models.DateTimeField(auto_created=True,
-                                      auto_now=True)
+    report1 = models.ForeignKey(
+        to=SuitePassRate,
+        related_name="report1",
+        on_delete=models.CASCADE,
+        blank=True,
+    )
+    report2 = models.ForeignKey(
+        to=SuitePassRate,
+        related_name="report2",
+        on_delete=models.CASCADE,
+        blank=True,
+    )
+    started_at = models.DateTimeField(auto_created=True, auto_now=True)
 
 
 TASKS = [
-        ("control.celery_tasks.tasks.check_today_testplan",
-         "Check today testplan",
-         []
-         ),
-        ("control.celery_tasks.tasks.check_specific_testplan",
-         "Check specific testplan",
-         ["testplan_id_arg"]
-         ),
-    ]
+    (
+        "control.celery_tasks.tasks.check_today_testplan",
+        "Check today testplan",
+        [],
+    ),
+    (
+        "control.celery_tasks.tasks.check_specific_testplan",
+        "Check specific testplan",
+        ["testplan_id_arg"],
+    ),
+]
 
-TASK_CHOICES = list(map(lambda x:  x[:-1], TASKS))
+TASK_CHOICES = list(map(lambda x: x[:-1], TASKS))
 
 
 class CronPeriodicTask(PeriodicTask):
-    cron = models.CharField(default="",
-                            max_length=300,
-                            blank=False)
-    task_name = models.CharField(max_length=300, choices=TASK_CHOICES,
-                                 default=TASK_CHOICES[0][0])
+    cron = models.CharField(default="", max_length=300, blank=False)
+    task_name = models.CharField(
+        max_length=300, choices=TASK_CHOICES, default=TASK_CHOICES[0][0]
+    )
     testplan_id_arg = models.CharField(max_length=30, blank=True, null=True)
 
     class Meta:
diff --git a/testrail_bot/control/tests.py b/testrail_bot/control/tests.py
index 7ce503c..a39b155 100644
--- a/testrail_bot/control/tests.py
+++ b/testrail_bot/control/tests.py
@@ -1,3 +1 @@
-from django.test import TestCase
-
 # Create your tests here.
diff --git a/testrail_bot/control/urls.py b/testrail_bot/control/urls.py
index d385891..d0249f7 100644
--- a/testrail_bot/control/urls.py
+++ b/testrail_bot/control/urls.py
@@ -2,7 +2,6 @@
 
 from . import views
 
-
 urlpatterns = [
     path("", views.redirect_to_index, name="redirect"),
     path("runs/", views.create_run, name="create_run"),
@@ -10,28 +9,41 @@
     path("runs/<int:run_id>/submit/", views.submit_run, name="submit_run"),
     path("runs/<int:run_id>/delete/", views.delete_run, name="delete_run"),
     path("reports/", views.list_reports, name="list_reports"),
-    path("reports/<int:report_id>/", views.single_report, name="single_report"),
-    path("reports/<int:report_id>/delete", views.delete_report,
-         name="delete_report"),
-    path('index/', views.index, name='index'),
+    path(
+        "reports/<int:report_id>/", views.single_report, name="single_report"
+    ),
+    path(
+        "reports/<int:report_id>/delete",
+        views.delete_report,
+        name="delete_report",
+    ),
+    path("index/", views.index, name="index"),
     path("help/", views.show_help, name="help"),
-    path("update_jenkins_plot",
-         views.update_jenkins_plot,
-         name="update_jenkins"),
+    path(
+        "update_jenkins_plot", views.update_jenkins_plot, name="update_jenkins"
+    ),
     path("jenkins_plot", views.jenkins_plot, name="jenkins_plot"),
     path("schedulers/", views.schedulers, name="schedulers"),
-
     path("scheduler/new/", views.scheduler, name="create_scheduler"),
     path("scheduler/<int:pk>/", views.scheduler, name="scheduler"),
-    path("scheduler/<int:pk>/save", views.save_scheduler, name="save_scheduler"),
-    path("scheduler/<int:pk>/delete/", views.delete_scheduler,
-         name="delete_scheduler"),
-
+    path(
+        "scheduler/<int:pk>/save", views.save_scheduler, name="save_scheduler"
+    ),
+    path(
+        "scheduler/<int:pk>/delete/",
+        views.delete_scheduler,
+        name="delete_scheduler",
+    ),
     path("compare_suites/new/", views.compare_suites, name="compare_suites"),
-    path("compare_suites/",
-         views.list_of_comparing_reports,
-         name="list_of_comparing_reports"),
+    path(
+        "compare_suites/",
+        views.list_of_comparing_reports,
+        name="list_of_comparing_reports",
+    ),
     path("compare_suites/submit/", views.submit_suites, name="submit_suites"),
-    path("compare_suites/<int:report_id>/", views.report_comparing_suites,
-         name="report_comparing_suites"),
+    path(
+        "compare_suites/<int:report_id>/",
+        views.report_comparing_suites,
+        name="report_comparing_suites",
+    ),
 ]
diff --git a/testrail_bot/control/utils.py b/testrail_bot/control/utils.py
index 2038aba..6c41f58 100644
--- a/testrail_bot/control/utils.py
+++ b/testrail_bot/control/utils.py
@@ -1,6 +1,7 @@
-from parse import parse
-from typing import Dict, List, Callable, Any
+from typing import Any, Callable, Dict, List
+
 from django.core.cache import cache
+from parse import parse
 
 
 def parse_title(test_name):
@@ -22,7 +23,7 @@
         return f"{r['test_title']}[{r['id']}]"
     except TypeError:
         # return file_name.test_class.test_name in other complicated cases
-        return '.'.join(test_name.split(".")[:3])
+        return ".".join(test_name.split(".")[:3])
 
 
 def short_names_for_dict(_dict):
@@ -36,16 +37,17 @@
     return __dict
 
 
-def get_dict_diff(dict1: dict,
-                  dict2: dict,
-                  compare_by_key=None) -> Dict[str, List]:
+def get_dict_diff(
+    dict1: dict, dict2: dict, compare_by_key=None
+) -> Dict[str, List]:
     all_keys = sorted(set(list(dict1.keys()) + list(dict2.keys())))
 
     result = dict()
     for k in all_keys:
         if compare_by_key:
             if dict1.get(k, {}).get(compare_by_key) == dict2.get(k, {}).get(
-                    compare_by_key):
+                compare_by_key
+            ):
                 continue
         else:
             if dict1.get(k) == dict2.get(k):
@@ -61,9 +63,10 @@
     return r
 
 
-def cached(timeout: int = None,
-           condition_for_endless_cache: Callable = lambda x: False
-           ) -> Callable:
+def cached(
+    timeout: int = None,
+    condition_for_endless_cache: Callable = lambda x: False,
+) -> Callable:
     """
     :param timeout: (in seconds) usage accordingly
     https://docs.djangoproject.com/en/4.2/topics/cache/#basic-usage
@@ -74,17 +77,18 @@
 
     :return: decorator
     """
+
     def decorator(func: Callable) -> Callable:
         def wrapper(*args, **kwargs) -> Any:
-            cache_key = f'{func.__name__}_{args}_{kwargs}'
-            cache_key = replace_all(cache_key, "{}()\'\" .,:", "_")
+            cache_key = f"{func.__name__}_{args}_{kwargs}"
+            cache_key = replace_all(cache_key, "{}()'\" .,:", "_")
             cached_value = cache.get(cache_key)
             if cached_value is None:
                 print(f"{func.__name__} MISS")
                 result = func(*args, **kwargs)
-                _timeout = None \
-                    if condition_for_endless_cache(result) \
-                    else timeout
+                _timeout = (
+                    None if condition_for_endless_cache(result) else timeout
+                )
 
                 cache.set(cache_key, result, timeout=_timeout)
                 return result
@@ -99,7 +103,9 @@
             # # ENDFIXME
 
             return cached_value
+
         return wrapper
+
     return decorator
 
 
diff --git a/testrail_bot/control/views.py b/testrail_bot/control/views.py
index e6655ad..8a362ef 100644
--- a/testrail_bot/control/views.py
+++ b/testrail_bot/control/views.py
@@ -1,16 +1,18 @@
 import datetime
 import json
 import os
-from .celery_tasks import test_rail_api
 
-from django.shortcuts import render, redirect, HttpResponse
+from django.shortcuts import HttpResponse, redirect, render
 from django_celery_beat.models import CrontabSchedule, PeriodicTasks
 
-from . import models
-from . import forms
-from .celery_tasks.tasks import process_run, update_plot_data, \
-    get_test_passability_in_suite
-from .utils import short_names_for_dict, get_dict_diff
+from . import forms, models
+from .celery_tasks import test_rail_api
+from .celery_tasks.tasks import (
+    get_test_passability_in_suite,
+    process_run,
+    update_plot_data,
+)
+from .utils import get_dict_diff, short_names_for_dict
 
 
 def index(request):
@@ -32,9 +34,11 @@
     else:
         form = forms.TestRunForm(instance=run)
 
-    return render(request, "control/update_run.html",
-                  {"form": form, "run_id": run_id, "checked_tests":
-                      run.checked_tests})
+    return render(
+        request,
+        "control/update_run.html",
+        {"form": form, "run_id": run_id, "checked_tests": run.checked_tests},
+    )
 
 
 def create_run(request):
@@ -46,8 +50,9 @@
     else:
         form = forms.TestRunForm()
 
-    form.fields["created_after"].initial = datetime.date.today() + \
-                                           datetime.timedelta(days=-3 * 30)
+    form.fields["created_after"].initial = (
+        datetime.date.today() + datetime.timedelta(days=-3 * 30)
+    )
     form.fields["created_before"].initial = datetime.date.today()
     return render(request, "control/update_run.html", {"form": form})
 
@@ -60,20 +65,26 @@
 def single_report(request, report_id):
     report = models.TestRailReport.objects.get(pk=report_id)
     data = report.path.read().decode("utf-8")
-    if request.method == "POST" \
-            and request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
+    if (
+        request.method == "POST"
+        and request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest"
+    ):
         return HttpResponse(
             json.dumps({"data": data, "finished": report.finished}),
-            content_type="application/json")
+            content_type="application/json",
+        )
 
-    return render(request, "control/report.html",
-                  {"report_id": report.id,
-                   "report": data,
-                   "finished": report.finished})
+    return render(
+        request,
+        "control/report.html",
+        {"report_id": report.id, "report": data, "finished": report.finished},
+    )
 
 
 def delete_report(request, report_id):
-    report:models.TestRailReport = models.TestRailReport.objects.get(pk=report_id)
+    report: models.TestRailReport = models.TestRailReport.objects.get(
+        pk=report_id
+    )
     try:
         os.remove(report.path.path)
     except FileNotFoundError:
@@ -94,8 +105,9 @@
             _name = f"Plan {testrail_run['name']}"
         else:
             parent_plan_id = testrail_run["plan_id"]
-            parent_plan_name = \
-                test_rail_api.get_plan_by_id(parent_plan_id)["name"]
+            parent_plan_name = test_rail_api.get_plan_by_id(parent_plan_id)[
+                "name"
+            ]
             _name = f"Run {testrail_run['name']} from {parent_plan_name}"
         run.run_name = _name
         run.save()
@@ -103,14 +115,13 @@
     report_name = "{}-run_id-{}-date-{}".format(
         run.run_name,
         run.run_id,
-        datetime.datetime.isoformat(datetime.datetime.now()))
+        datetime.datetime.isoformat(datetime.datetime.now()),
+    )
     path = os.path.join(models.fs.location, report_name)
     with open(path, "w"):
         pass
 
-    report = models.TestRailReport(
-        report_name=report_name,
-        path=path)
+    report = models.TestRailReport(report_name=report_name, path=path)
     report.save()
     process_run.delay(run_id, report.id, path, is_testplan)
     return redirect("single_report", report.id)
@@ -133,7 +144,8 @@
     except models.ActionLog.DoesNotExist:
         pass
     update = models.ActionLog(
-        name="update_plot_started", date=datetime.datetime.now())
+        name="update_plot_started", date=datetime.datetime.now()
+    )
     update.save()
     update_plot_data.delay()
     return HttpResponse("Started Update", status=200)
@@ -142,7 +154,8 @@
 def jenkins_plot(request):
     try:
         update_date = models.ActionLog.objects.get(
-            name="update_jenkins_plot").date
+            name="update_jenkins_plot"
+        ).date
     except models.ActionLog.DoesNotExist:
         update_date = None
     try:
@@ -157,13 +170,18 @@
         try:
             with open(job_names_path, "r") as f:
                 job_names = json.load(f)
-        except:
+        except Exception:
             pass
 
     return render(
-        request, "control/jenkins_plot.html",
-        {"update_date": update_date, "update_started": update_started,
-         "job_names": enumerate(job_names, 1)})
+        request,
+        "control/jenkins_plot.html",
+        {
+            "update_date": update_date,
+            "update_started": update_started,
+            "job_names": enumerate(job_names, 1),
+        },
+    )
 
 
 def submit_suites(request):
@@ -180,7 +198,7 @@
         report1=report1,
         report2=report2,
         limit=form.cleaned_data["limit"],
-        test_keyword=form.cleaned_data["test_keyword"]
+        test_keyword=form.cleaned_data["test_keyword"],
     )
     diff_model.save()
     get_test_passability_in_suite.delay(diff_model.id, report1.id)
@@ -194,60 +212,72 @@
         return submit_suites(request)
 
     diff_form = forms.DiffPassRatesForm()
-    report1_form = forms.SuitePassRateForm(prefix='first')
-    report2_form = forms.SuitePassRateForm(prefix='second')
+    report1_form = forms.SuitePassRateForm(prefix="first")
+    report2_form = forms.SuitePassRateForm(prefix="second")
 
     return render(
-        request, "control/compare_suites.html",
+        request,
+        "control/compare_suites.html",
         {
-         "diff_form": diff_form,
-         "report1_form": report1_form,
-         "report2_form": report2_form,
-         "finished": None
-        })
+            "diff_form": diff_form,
+            "report1_form": report1_form,
+            "report2_form": report2_form,
+            "finished": None,
+        },
+    )
 
 
 def list_of_comparing_reports(request):
     list_of_reports = models.DiffOfSuitesPassRates.objects.all()
     return render(
-        request, "control/list_comparing_suites.html",
-        {
-            "reports": list_of_reports
-        })
+        request,
+        "control/list_comparing_suites.html",
+        {"reports": list_of_reports},
+    )
 
 
 def report_comparing_suites(request, report_id):
     report = models.DiffOfSuitesPassRates.objects.get(pk=report_id)
-    passrate1 = short_names_for_dict(json.loads(
-        report.report1.passrate_by_tests))
-    passrate2 = short_names_for_dict(json.loads(
-        report.report2.passrate_by_tests))
+    passrate1 = short_names_for_dict(
+        json.loads(report.report1.passrate_by_tests)
+    )
+    passrate2 = short_names_for_dict(
+        json.loads(report.report2.passrate_by_tests)
+    )
 
-    diff_table = get_dict_diff(dict1=passrate1,
-                               dict2=passrate2,
-                               compare_by_key="rate")
+    diff_table = get_dict_diff(
+        dict1=passrate1, dict2=passrate2, compare_by_key="rate"
+    )
     diff_form = forms.DiffPassRatesForm(instance=report)
-    report1_form = forms.SuitePassRateForm(instance=report.report1,
-                                           prefix="first")
-    report2_form = forms.SuitePassRateForm(instance=report.report2,
-                                           prefix="second")
+    report1_form = forms.SuitePassRateForm(
+        instance=report.report1, prefix="first"
+    )
+    report2_form = forms.SuitePassRateForm(
+        instance=report.report2, prefix="second"
+    )
 
     return render(
-        request, "control/compare_suites.html",
-        {"diff_form": diff_form,
-         "report1_form": report1_form,
-         "report2_form": report2_form,
-         "report1": report.report1,
-         "report2": report.report2,
-         "is_finished": report.report1.finished and report.report2.finished,
-         "diff_table": diff_table})
+        request,
+        "control/compare_suites.html",
+        {
+            "diff_form": diff_form,
+            "report1_form": report1_form,
+            "report2_form": report2_form,
+            "report1": report.report1,
+            "report2": report.report2,
+            "is_finished": report.report1.finished and report.report2.finished,
+            "diff_table": diff_table,
+        },
+    )
 
 
 def schedulers(request):
 
     return render(
-        request, "control/schedulers.html",
-        {"schedulers": models.CronPeriodicTask.objects.all()})
+        request,
+        "control/schedulers.html",
+        {"schedulers": models.CronPeriodicTask.objects.all()},
+    )
 
 
 def scheduler(request, pk=None):
@@ -261,33 +291,31 @@
         form = forms.PeriodicTaskForm()
 
     return render(
-        request, "control/scheduler.html",
-        {
-            "form": form,
-            "pk": pk,
-            "TASKS": models.TASKS
-        }
+        request,
+        "control/scheduler.html",
+        {"form": form, "pk": pk, "TASKS": models.TASKS},
     )
 
 
 def save_scheduler(request, pk=None):
     print(f"{request.POST=}")
-    minute, hour, day_of_month, month_of_year, day_of_week = \
-        request.POST.get("cron", "* * * * *").split(" ")
+    minute, hour, day_of_month, month_of_year, day_of_week = request.POST.get(
+        "cron", "* * * * *"
+    ).split(" ")
     if pk is None:
         sch = CrontabSchedule.objects.create(
             minute=minute,
             hour=hour,
             day_of_month=day_of_month,
             month_of_year=month_of_year,
-            day_of_week=day_of_week
+            day_of_week=day_of_week,
         )
         task = models.CronPeriodicTask.objects.create(
             crontab=sch,
             cron=request.POST.get("cron"),
             name=request.POST.get("name"),
             task_name=request.POST.get("task_name"),
-            enabled=request.POST.get("enabled") == 'on',
+            enabled=request.POST.get("enabled") == "on",
             testplan_id_arg=request.POST.get("testplan_id_arg"),
         )
     else:
@@ -303,7 +331,7 @@
         hour=hour,
         day_of_month=day_of_month,
         month_of_year=month_of_year,
-        day_of_week=day_of_week
+        day_of_week=day_of_week,
     )
     if not form.is_valid():
         print(f"{form.errors=}")
@@ -311,12 +339,9 @@
     form.save()
     PeriodicTasks.update_changed()
     return render(
-        request, "control/scheduler.html",
-        {
-            "form": form,
-            "pk": task.id,
-            "TASKS": models.TASKS
-        }
+        request,
+        "control/scheduler.html",
+        {"form": form, "pk": task.id, "TASKS": models.TASKS},
     )