{"id":13412290,"url":"https://github.com/huggingface/knockknock","last_synced_at":"2025-10-07T08:28:12.802Z","repository":{"id":37334505,"uuid":"176736173","full_name":"huggingface/knockknock","owner":"huggingface","description":"🚪✊Knock Knock: Get notified when your training ends with only two additional lines of code","archived":false,"fork":false,"pushed_at":"2023-06-23T10:52:46.000Z","size":75,"stargazers_count":2818,"open_issues_count":37,"forks_count":233,"subscribers_count":62,"default_branch":"master","last_synced_at":"2025-09-28T09:08:24.508Z","etag":null,"topics":["computer-vision","cv","deep-learning","machine-learning","natural-language-processing","neural-networks","nlp","nlproc","python","python36","train"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/huggingface.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-20T13:08:55.000Z","updated_at":"2025-09-15T21:58:14.000Z","dependencies_parsed_at":"2024-06-18T13:39:30.992Z","dependency_job_id":"a30d95a9-d9b7-4a68-903f-2a3d362b3030","html_url":"https://github.com/huggingface/knockknock","commit_stats":{"total_commits":71,"total_committers":19,"mean_commits":3.736842105263158,"dds":0.3943661971830986,"last_synced_commit":"1160ab756d8caa81a3b326c07364e342cf9439b8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/huggingface/knockknock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huggingface%2Fknockknock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huggingface%2Fknockknock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huggingface%2Fknockknock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huggingface%2Fknockknock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/huggingface","download_url":"https://codeload.github.com/huggingface/knockknock/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huggingface%2Fknockknock/sbom","scorecard":{"id":472287,"data":{"date":"2025-08-11","repo":{"name":"github.com/huggingface/knockknock","commit":"1160ab756d8caa81a3b326c07364e342cf9439b8"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.7,"checks":[{"name":"Code-Review","score":5,"reason":"Found 10/18 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T14:15:37.786Z","repository_id":37334505,"created_at":"2025-08-19T14:15:37.786Z","updated_at":"2025-08-19T14:15:37.786Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278742611,"owners_count":26037857,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computer-vision","cv","deep-learning","machine-learning","natural-language-processing","neural-networks","nlp","nlproc","python","python36","train"],"created_at":"2024-07-30T20:01:23.039Z","updated_at":"2025-10-07T08:28:12.754Z","avatar_url":"https://github.com/huggingface.png","language":"Python","funding_links":[],"categories":["Toolbox","Python","Uncategorized","🤗 Official Libraries","工作流程和实验跟踪"],"sub_categories":["Code Tools","Uncategorized"],"readme":"# Knock Knock\n\n[![made-with-python](https://img.shields.io/badge/Made%20with-Python-red.svg)](#python) [![Downloads](https://pepy.tech/badge/knockknock)](https://pepy.tech/project/knockknock) [![Downloads](https://pepy.tech/badge/knockknock/month)](https://pepy.tech/project/knockknock/month) [![GitHub stars](https://img.shields.io/github/stars/huggingface/knockknock.svg?style=social\u0026label=Star\u0026maxAge=1000)](https://github.com/huggingface/knockknock/stargazers/)\n\nA small library to get a notification when your training is complete or when it crashes during the process with two additional lines of code.\n\nWhen training deep learning models, it is common to use early stopping. Apart from a rough estimate, it is difficult to predict when the training will finish. Thus, it can be interesting to set up automatic notifications for your training. It is also interesting to be notified when your training crashes in the middle of the process for unexpected reasons.\n\n## Installation\n\nInstall with `pip` or equivalent.\n\n```bash\npip install knockknock\n```\n\nThis code has only been tested with Python \u003e= 3.6.\n\n## Usage\n\nThe library is designed to be used in a seamless way, with minimal code modification: you only need to add a decorator on top your main function call. The return value (if there is one) is also reported in the notification.\n\nThere are currently *twelve* ways to setup notifications:\n\n|               Platform                |                                   External Contributors                                   |\n| :-----------------------------------: | :---------------------------------------------------------------------------------------: |\n|            [email](#email)            |                                             -                                             |\n|            [Slack](#slack)            |                                             -                                             |\n|         [Telegram](#telegram)         |                                             -                                             |\n|  [Microsoft Teams](#microsoft-teams)  |                           [@noklam](https://github.com/noklam)                            |\n| [Text Message](\u003c#text-message-(sms)\u003e) |                 [@abhishekkrthakur](https://github.com/abhishekkrthakur)                  |\n|          [Discord](#discord)          |                         [@watkinsm](https://github.com/watkinsm)                          |\n|   [Desktop](#desktop-notification)    | [@atakanyenel](https://github.com/atakanyenel) [@eyalmazuz](https://github.com/eyalmazuz) |\n|           [Matrix](#matrix)           |                           [@jcklie](https://github.com/jcklie)                            |\n|     [Amazon Chime](#amazon-chime)     |                     [@prabhakar267](https://github.com/prabhakar267)                      |\n|         [DingTalk](#dingtalk)         |                         [@wuutiing](https://github.com/wuutiing)                          |\n|       [RocketChat](#rocketchat)       |                            [@radao](https://github.com/radao)                             |\n|      [WeChat Work](#wechat-work)      |                             [@jcyk](https://github.com/jcyk)                              |\n\n\n### Email\n\nThe service relies on [Yagmail](https://github.com/kootenpv/yagmail) a GMAIL/SMTP client. You'll need a gmail email address to use it (you can setup one [here](https://accounts.google.com), it's free). I recommend creating a new one (rather than your usual one) since you'll have to modify the account's security settings to allow the Python library to access it by [Turning on less secure apps](https://devanswers.co/allow-less-secure-apps-access-gmail-account/).\n\n#### Python\n\n```python\nfrom knockknock import email_sender\n\n@email_sender(recipient_emails=[\"\u003cyour_email@address.com\u003e\", \"\u003cyour_second_email@address.com\u003e\"], sender_email=\"\u003cgrandma's_email@gmail.com\u003e\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock email \\\n    --recipient-emails \u003cyour_email@address.com\u003e,\u003cyour_second_email@address.com\u003e \\\n    --sender-email \u003cgrandma's_email@gmail.com\u003e \\\n    sleep 10\n```\n\nIf `sender_email` is not specified, then the first email in `recipient_emails` will be used as the sender's email.\n\nNote that launching this will asks you for the sender's email password. It will be safely stored in the system keyring service through the [`keyring` Python library](https://pypi.org/project/keyring/).\n\n\n### Slack\n\nSimilarly, you can also use Slack to get notifications. You'll have to get your Slack room [webhook URL](https://api.slack.com/incoming-webhooks#create_a_webhook) and optionally your [user id](https://api.slack.com/methods/users.identity) (if you want to tag yourself or someone else).\n\n#### Python\n\n```python\nfrom knockknock import slack_sender\n\nwebhook_url = \"\u003cwebhook_url_to_your_slack_room\u003e\"\n@slack_sender(webhook_url=webhook_url, channel=\"\u003cyour_favorite_slack_channel\u003e\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\nYou can also specify an optional argument to tag specific people: `user_mentions=[\u003cyour_slack_id\u003e, \u003cgrandma's_slack_id\u003e]`.\n\n#### Command-line\n\n```bash\nknockknock slack \\\n    --webhook-url \u003cwebhook_url_to_your_slack_room\u003e \\\n    --channel \u003cyour_favorite_slack_channel\u003e \\\n    sleep 10\n```\n\nYou can also specify an optional argument to tag specific people: `--user-mentions \u003cyour_slack_id\u003e,\u003cgrandma's_slack_id\u003e`.\n\n\n### Telegram\n\nYou can also use Telegram Messenger to get notifications. You'll first have to create your own notification bot by following the three steps provided by Telegram [here](https://core.telegram.org/bots#6-botfather) and save your API access `TOKEN`.\n\nTelegram bots are shy and can't send the first message so you'll have to do the first step. By sending the first message, you'll be able to get the `chat_id` required (identification of your messaging room) by visiting `https://api.telegram.org/bot\u003cYourBOTToken\u003e/getUpdates` and get the `int` under the key `message['chat']['id']`.\n\n#### Python\n\n```python\nfrom knockknock import telegram_sender\n\nCHAT_ID: int = \u003cyour_messaging_room_id\u003e\n@telegram_sender(token=\"\u003cyour_api_token\u003e\", chat_id=CHAT_ID)\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock telegram \\\n    --token \u003cyour_api_token\u003e \\\n    --chat-id \u003cyour_messaging_room_id\u003e \\\n    sleep 10\n```\n\n\n### Microsoft Teams\n\nThanks to [@noklam](https://github.com/noklam), you can also use Microsoft Teams to get notifications. You'll have to get your Team Channel [webhook URL](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors/connectors-using).\n\n#### Python\n\n```python\nfrom knockknock import teams_sender\n\n@teams_sender(token=\"\u003cwebhook_url_to_your_teams_channel\u003e\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock teams \\\n    --webhook-url \u003cwebhook_url_to_your_teams_channel\u003e \\\n    sleep 10\n```\n\nYou can also specify an optional argument to tag specific people: `user_mentions=[\u003cyour_teams_id\u003e, \u003cgrandma's_teams_id\u003e]`.\n\n\n### Text Message (SMS)\n\nThanks to [@abhishekkrthakur](https://github.com/abhishekkrthakur), you can use Twilio to send text message notifications. You'll have to setup a [Twilio](www.twilio.com) account [here](https://www.twilio.com/try-twilio), which is paid service with competitive prices: for instance in the US, getting a new number and sending one text message through this service respectively cost $1.00 and $0.0075. You'll need to get (a) a phone number, (b) your [account SID](https://www.twilio.com/docs/glossary/what-is-a-sid) and (c) your [authentification token](https://www.twilio.com/docs/iam/access-tokens). Some detail [here](https://www.twilio.com/docs/iam/api/account).\n\n#### Python\n\n```python\nfrom knockknock import sms_sender\n\nACCOUNT_SID: str = \"\u003cyour_account_sid\u003e\"\nAUTH_TOKEN: str = \"\u003cyour_auth_token\u003e\"\n@sms_sender(account_sid=ACCOUNT_SID, auth_token=AUTH_TOKEN, recipient_number=\"\u003crecipient's_number\u003e\", sender_number=\"\u003csender's_number\u003e\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock sms \\\n    --account-sid \u003cyour_account_sid\u003e \\\n    --auth-token \u003cyour_account_auth_token\u003e \\\n    --recipient-number \u003crecipient_number\u003e \\\n    --sender-number \u003csender_number\u003e\n    sleep 10\n```\n\n\n### Discord\n\nThanks to [@watkinsm](https://github.com/watkinsm), you can also use Discord to get notifications. You'll just have to get your Discord channel's [webhook URL](https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks).\n\n#### Python\n\n```python\nfrom knockknock import discord_sender\n\nwebhook_url = \"\u003cwebhook_url_to_your_discord_channel\u003e\"\n@discord_sender(webhook_url=webhook_url)\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock discord \\\n    --webhook-url \u003cwebhook_url_to_your_discord_channel\u003e \\\n    sleep 10\n```\n\n\n### Desktop Notification\n\nYou can also get notified from a desktop notification. It is currently only available for MacOS and Linux and Windows 10.\nFor Linux it uses the nofity-send command which uses libnotify, In order to use libnotify, you have to install a notification server. Cinnamon, Deepin, Enlightenment, GNOME, GNOME Flashback and KDE Plasma use their own implementations to display notifications. In other desktop environments, the notification server needs to be launched using your WM's/DE's \"autostart\" option.\n\n#### Python\n\n```python\nfrom knockknock import desktop_sender\n\n@desktop_sender(title=\"Knockknock Desktop Notifier\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {\"loss\": 0.9}\n```\n\n#### Command Line\n\n```bash\nknockknock desktop \\\n    --title 'Knockknock Desktop Notifier' \\\n    sleep 2\n```\n\n### Matrix\n\nThanks to [@jcklie](https://github.com/jcklie), you can send notifications via [Matrix](https://matrix.org/). The homeserver is the\nserver on which your user that will send messages is registered. Do not forget the schema for the URL (`http` or `https`).\nYou'll have to get the access token for a bot or your own user. The easiest way to obtain it is to look into Riot looking\nin the riot settings, `Help \u0026 About`, down the bottom is: `Access Token:\u003cclick to reveal\u003e`. You also need to specify a\nroom alias to which messages are sent. To obtain the alias in Riot, create a room you want to use, then open the room\nsettings under `Room Addresses` and add an alias.\n\n#### Python\n\n```python\nfrom knockknock import matrix_sender\n\nHOMESERVER = \"\u003curl_to_your_home_server\u003e\" # e.g. https://matrix.org\nTOKEN = \"\u003cyour_auth_token\u003e\"              # e.g. WiTyGizlr8ntvBXdFfZLctyY\nROOM = \"\u003croom_alias\"                     # e.g. #knockknock:matrix.org\n\n@matrix_sender(homeserver=HOMESERVER, token=TOKEN, room=ROOM)\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock matrix \\\n    --homeserver \u003chomeserver\u003e \\\n    --token \u003ctoken\u003e \\\n    --room \u003croom\u003e \\\n    sleep 10\n```\n\n\n### Amazon Chime\n\nThanks to [@prabhakar267](https://github.com/prabhakar267), you can also use Amazon Chime to get notifications. You'll have to get your Chime room [webhook URL](https://docs.aws.amazon.com/chime/latest/dg/webhooks.html).\n\n#### Python\n\n```python\nfrom knockknock import chime_sender\n\n@chime_sender(webhook_url=\"\u003cwebhook_url_to_your_chime_room\u003e\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock chime \\\n    --webhook-url \u003cwebhook_url_to_your_chime_room\u003e \\\n    sleep 10\n```\n\nYou can also specify an optional argument to tag specific people: `user_mentions=[\u003cyour_alias\u003e, \u003cgrandma's_alias\u003e]`.\n\n\n### DingTalk\n\nDingTalk is now supported thanks to [@wuutiing](https://github.com/wuutiing). Given DingTalk chatroom robot's webhook url and secret/keywords(at least one of them are set when creating a chatroom robot), your notifications will be sent to reach any one in that chatroom.\n\n#### Python\n\n```python\nfrom knockknock import dingtalk_sender\n\nwebhook_url = \"\u003cwebhook_url_to_your_dingtalk_chatroom_robot\u003e\"\n@dingtalk_sender(webhook_url=webhook_url, secret=\"\u003cyour_robot_secret_if_set\u003e\", keywords=[\"\u003clist_of_keywords_if_set\u003e\"])\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock dingtalk \\\n    --webhook-url \u003cwebhook_url_to_your_dingtalk_chatroom_robot\u003e \\\n    --secret \u003cyour_robot_secret_if_set\u003e \\\n    sleep 10\n```\n\nYou can also specify an optional argument to at specific people: `user_mentions=[\"\u003clist_of_phonenumbers_who_you_want_to_tag\u003e\"]`.\n\n\n### RocketChat\n\nYou can use [RocketChat](https://rocket.chat/) to get notifications. You'll need the following before you can post notifications:\n\n- a RocketChat server e.g. rocketchat.yourcompany.com\n- a RocketChat user id (you'll be able to view your user id when you create a personal access token in the next step)\n- a RocketChat personal access token ([create one as per this guide](https://rocket.chat/docs/developer-guides/rest-api/personal-access-tokens/))\n- a RocketChat channel\n\n#### Python\n\n```python\nfrom knockknock import rocketchat_sender\n\n@rocketchat_sender(\n    rocketchat_server_url=\"\u003curl_to_your_rocketchat_server\u003e\",\n    rocketchat_user_id=\"\u003cyour_rocketchat_user_id\u003e\",\n    rocketchat_auth_token=\"\u003cyour_rocketchat_auth_token\u003e\",\n    channel=\"\u003cchannel_name\u003e\")\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\nYou can also specify two optional arguments:\n\n- to tag specific users: `user_mentions=[\u003cyour_user_name\u003e, \u003cgrandma's_user_name\u003e]`\n- to use an alias for the notification: `alias=\"My Alias\"`\n\n#### Command-line\n\n```bash\nknockknock rocketchat \\\n    --rocketchat-server-url \u003curl_to_your_rocketchat_server\u003e \\\n    --rocketchat-user-id \u003cyour_rocketchat_user_id\u003e \\\n    --rocketchat-auth-token \u003cyour_rocketchat_auth_token\u003e \\\n    --channel \u003cchannel_name\u003e \\\n    sleep 10\n```\n\n\n### WeChat Work\n\nWeChat Work is now supported thanks to [@jcyk](https://github.com/jcyk). Given WeChat Work chatroom robot's webhook url, your notifications will be sent to reach anyone in that chatroom.\n\n#### Python\n\n```python\nfrom knockknock import wechat_sender\n\nwebhook_url = \"\u003cwebhook_url_to_your_wechat_work_chatroom_robot\u003e\"\n@wechat_sender(webhook_url=webhook_url)\ndef train_your_nicest_model(your_nicest_parameters):\n    import time\n    time.sleep(10000)\n    return {'loss': 0.9} # Optional return value\n```\n\n#### Command-line\n\n```bash\nknockknock wechat \\\n    --webhook-url \u003cwebhook_url_to_your_wechat_work_chatroom_robot\u003e \\\n    sleep 10\n```\n\nYou can also specify an optional argument to tag specific people: `user-mentions=[\"\u003clist_of_userids_you_want_to_tag\u003e\"]` and/or `user-mentions-mobile=[\"\u003clist_of_phonenumbers_you_want_to_tag\u003e\"]`.\n\n\n## Note on distributed training\n\nWhen using distributed training, a GPU is bound to its process using the local rank variable. Since knockknock works at the process level, if you are using 8 GPUs, you would get 8 notifications at the beginning and 8 notifications at the end... To circumvent that, except for errors, only the master process is allowed to send notifications so that you receive only one notification at the beginning and one notification at the end.\n\n**Note:** _In PyTorch, the launch of `torch.distributed.launch` sets up a RANK environment variable for each process (see [here](https://github.com/pytorch/pytorch/blob/master/torch/distributed/launch.py#L211)). This is used to detect the master process, and for now, the only simple way I came up with. Unfortunately, this is not intended to be general for all platforms but I would happily discuss smarter/better ways to handle distributed training in an issue/PR._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuggingface%2Fknockknock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhuggingface%2Fknockknock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuggingface%2Fknockknock/lists"}