code: def main():
      print("ClearML experiment monitor Slack service\n")
  
      # Slack Monitor arguments
      parser = argparse.ArgumentParser(
          description="ClearML monitor experiments and post Slack Alerts"
      )
      parser.add_argument(
          "--channel",
          type=str,
          help="Set the channel to post the Slack alerts",
      )
      parser.add_argument(
          "--slack_api",
          type=str,
          default=os.environ.get("SLACK_API_TOKEN", None),
          help="Slack API key for sending messages",
      )
      parser.add_argument(
          "--message_prefix",
          type=str,
          help='Add message prefix (For example, to alert all channel members use: "Hey <!here>,")',
      )
      parser.add_argument(
          "--project",
          type=str,
          default="",
          help="The name (or partial name) of the project to monitor, use empty for all projects",
      )
      parser.add_argument(
          "--min_num_iterations",
          type=int,
          default=0,
          help="Minimum number of iterations of failed/completed experiment to alert. "
          "This will help eliminate unnecessary debug sessions that crashed right after starting "
          "(default:0 alert on all)",
      )
      parser.add_argument(
          "--include_manual_experiments",
          action="store_true",
          default=False,
          help="Include experiments running manually (i.e. not by clearml-agent)",
      )
      parser.add_argument(
          "--include_completed_experiments",
          action="store_true",
          default=False,
          help="Include completed experiments (i.e. not just failed experiments)",
      )
      parser.add_argument(
          "--include_archived",
          action="store_true",
          default=False,
          help="Include archived experiments",
      )
      parser.add_argument(
          "--refresh_rate",
          type=float,
          default=10.0,
          help="Set refresh rate of the monitoring service, default every 10.0 sec",
      )
      parser.add_argument(
          "--service_queue",
          type=str,
          default="services",
          help="Queue name to use when running as a service (default: 'services'",
      )
      parser.add_argument(
          "-v",
          "--verbose",
          action="store_true",
          default=False,
          help="Increase standard output verbosity for SlackMonitor",
      )
      users_group = parser.add_mutually_exclusive_group()
      users_group.add_argument(
          "--include_users",
          type=str,
          nargs="+",
          help="Only report tasks from these users",
      )
      users_group.add_argument(
          "--exclude_users",
          type=str,
          nargs="+",
          help="Only report tasks not from these users",
      )
      parser.add_argument(
          "--local",
          action="store_true",
          default=False,
          help="Run service locally instead of as a service "
          "(Default: Automatically launch itself on the services queue)",
      )
  
      args = parser.parse_args()
  
      if not args.slack_api:
          print(
              "Slack API key was not provided, please run with --slack_api <KEY>"
          )
          exit(1)
  
      if not args.channel:
          print(
              "Slack channel was not provided, please run with --channel <channel_name>"
          )
          exit(1)
  
      filters = list()
      # create the user filter if needed
      if args.include_users or args.exclude_users:
          filters.append(
              UserFilter(
                  include=args.include_users, exclude=args.exclude_users
              )
          )
  
      # create the slack monitoring object
      slack_monitor = SlackMonitor(
          slack_api_token=args.slack_api,
          channel=args.channel,
          message_prefix=args.message_prefix,
          filters=filters,
      )
  
      # configure the monitoring filters
      slack_monitor.min_num_iterations = args.min_num_iterations
      slack_monitor.include_manual_experiments = (
          args.include_manual_experiments
      )
      slack_monitor.include_archived = args.include_archived
      slack_monitor.verbose = args.verbose
      if args.project:
          slack_monitor.set_projects(project_names_re=[args.project])
      if args.include_completed_experiments:
          slack_monitor.status_alerts += ["completed"]
  
      # start the monitoring Task
      # Connecting ClearML with the current process,
      # from here on everything is logged automatically
      task = Task.init(
          project_name="DevOps",
          task_name="Slack Alerts",
          task_type=Task.TaskTypes.monitor,
      )
      if not args.local:
          task.execute_remotely(queue_name=args.service_queue)
          # we will not get here if we are running locally
  
      print(
          '\nStarting monitoring service\nProject: "{}"\nRefresh rate: {}s\n'.format(
              args.project or "all", args.refresh_rate
          )
      )
  
      # Let everyone know we are up and running
      start_message = "{}ClearML Slack monitoring service started\nMonitoring project '{}'".format(
          (args.message_prefix + " ") if args.message_prefix else "",
          args.project or "all",
      )
      slack_monitor.post_message(start_message)
  
      # Start the monitor service, this function will never end
      slack_monitor.monitor(pool_period=args.refresh_rate)
  
file_path: clearml/examples/services/monitoring/slack_alerts.py
imports: import argparse
  import os
  from pathlib import Path
  from time import sleep
  from typing import Optional, Callable, List, Union
  from slack_sdk import WebClient
  from slack_sdk.errors import SlackApiError
  from clearml import Task
  from clearml.automation.monitor import Monitor
label_desc: Use image node_id 1 for calling a global function with example usage: main() without return types