diff --git a/README.md b/README.md
new file mode 100644
index 0000000..49be645
--- /dev/null
+++ b/README.md
@@ -0,0 +1,50 @@
+# WECHAT NOTIFY
+
+Many scripts today may take a long time to run, such as deep learning tasks. We wonder to check the results immediately after its accomplishment but keeping an eye on the process is not desirable.
+
+This project is aimed to notify you through WeChat when certain command is completed.
+
+## requirements
+
+This package rely on `requests`.
+
+```bash
+pip3 install requests
+```
+
+### SERVER CHAN
+
+This project rely on [SERVER CHAN](http://sc.ftqq.com/3.version) to push notifications to WeChat. Please follow the instructions on the website and **set your SCKEY to environment variable** as `SERVER_CHAN_TOKEN`.
+
+Your command's output and error will be write to file `stdout` and `stderr` regardless of whether notification will be push or not.
+
+## usage
+
+```bash
+notify [bash command]
+```
+
+Note that special chars of bash, such as `>`, need to be escaped so that the script can capture the corrent bash command. For example:
+
+```bash
+notify python train.py \> trail.log
+```
+
+## example
+
+WECHAT_NOTIFY will push three kinds of notifications.
+
+* [Success]: inform you [what command, start time, how long the command takes, last three lines of output(if exists)]
+
+* [Failed]: inform you [what command, start time, how long the command takes, last three lines of stderr(if exists)]
+
+
+* [Keyboard Interrupt]: inform you [what command, start time, 'Keyboard Interrupt']
+
+
+
+## TODO
+
+- [ ] unit test
+- [ ] Email support
+- [ ] test on WeChat Work
diff --git a/imgs/failed.png b/imgs/failed.png
new file mode 100644
index 0000000..54a3923
Binary files /dev/null and b/imgs/failed.png differ
diff --git a/imgs/kayboard.png b/imgs/kayboard.png
new file mode 100644
index 0000000..7cb5e58
Binary files /dev/null and b/imgs/kayboard.png differ
diff --git a/imgs/success.png b/imgs/success.png
new file mode 100644
index 0000000..82a4cea
Binary files /dev/null and b/imgs/success.png differ
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..a0d3147
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,16 @@
+from setuptools import setup
+
+setup(name="wechat-notify",
+ description="notify you on Wechat when certain task is completed",
+ version="1.0",
+ author="Tab_version",
+ author_email="tabvision@bupt.edu.cn",
+ packages=['wechat_notify'],
+ install_requires=[
+ 'requests',
+ ],
+ entry_points = {
+ 'console_scripts': ['notify=wechat_notify.notify:main'],
+ },
+ include_package_data=True,
+)
diff --git a/wechat_notify/__init__.py b/wechat_notify/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/wechat_notify/notify.py b/wechat_notify/notify.py
new file mode 100644
index 0000000..55f1d7c
--- /dev/null
+++ b/wechat_notify/notify.py
@@ -0,0 +1,70 @@
+import sys
+import os
+import subprocess
+import requests
+import time
+
+def build_parser():
+ if len(sys.argv) == 1:
+ raise ValueError('please input command')
+ return sys.argv[1:]
+
+
+def send_request(output, err, process, token, command, start, duration, is_win):
+ if output is not None:
+ output = output.decode('utf-8').split('\r\n') if is_win else output.decode('utf-8').split('\n')
+ with open('stdout', 'w') as f:
+ f.write('\n'.join(output))
+ if err is not None:
+ err = err.decode('utf-8').split('\r\n') if is_win else err.decode('utf-8').split('\n')
+ with open('stderr', 'w') as f:
+ f.write('\n'.join(err))
+ temp = None
+ # import ipdb; ipdb.set_trace()
+ if process.poll() == 0:
+ if output is not None:
+ output = [''] * 3 + output
+ temp = 'the following are last three lines of stdout:\n' + '\n'.join(output[-3:])
+ post_str = r'https://sc.ftqq.com/' + token + '.send?' + f'text=[Scuucess] command: ' + ' '.join(command) + f'&desp=start at {time.ctime(int(start))}\ttake time: {duration}\t' + (temp if temp is not None else '')
+ requests.post(post_str)
+ else:
+ if err is not None:
+ err = [''] * 3 + err
+ temp = 'the following are last three lines of stderr:\n' + '\n'.join(err[-3:])
+ # import ipdb; ipdb.set_trace()
+ post_str = r'https://sc.ftqq.com/' + token + '.send?' + f'text=[Failed] command: ' + ' '.join(command) + f'&desp=start at {time.ctime(int(start))}\ttake time: {duration}\terror code: {process.poll()}'+ (temp if temp is not None else '')
+ print(post_str)
+ requests.post(post_str)
+
+
+
+def init():
+ try:
+ token = os.environ['SERVER_CHAN_TOKEN']
+ except KeyError:
+ print('environment variable `SERVER_CHAN_TOKEN` unfound')
+ exit(1)
+ return token
+
+def main():
+ token = init()
+ start = time.time()
+ try:
+ command = build_parser()
+ process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ output, err = process.communicate()
+
+ except KeyboardInterrupt:
+ print('keyboard')
+ process.kill()
+ requests.post(r'https://sc.ftqq.com/' + token + '.send?' + f'text=[Failed] command: ' + ' '.join(command) + f'&desp=start at {time.ctime(int(start))}\nbecause of Keyboard Interrupt')
+ exit(0)
+
+ duration = time.time() - start
+ is_win = (sys.platform == 'win32')
+ send_request(output=output, err=err, duration=duration, is_win=is_win,start=start, token=token, command=command, process=process)
+
+
+
+if __name__ == "__main__":
+ main()