async_process.py (2434B)
1 #
2 # Copyright (c) 2018 Joris Vink <joris@coders.se>
3 #
4 # Permission to use, copy, modify, and distribute this software for any
5 # purpose with or without fee is hereby granted, provided that the above
6 # copyright notice and this permission notice appear in all copies.
7 #
8 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 #
16
17 #
18 # Asynchronous process example.
19 #
20 # Wait for the result of an external process asynchronously.
21 # The handler will execute "/bin/ls" on the current directory and
22 # read the result.
23 #
24
25 import kore
26 import json
27
28 @kore.route("/proc", methods=["get"])
29 async def async_proc(req):
30 #
31 # You may specify a timeout when creating the kore.proc object.
32 # If the timeout is reached before the process exits kore will
33 # raise a TimeoutError exception.
34 #
35 # Ex: set timeout to 100ms:
36 # proc = kore.proc("/bin/ls -lR", 100)
37
38 proc = kore.proc("/bin/ls -lR")
39
40 try:
41 stdout = ""
42
43 # Read until EOF (None is returned)
44 while True:
45 try:
46 # Read from the process, with an optional 1 second timeout.
47 # The recv() call will throw a TimeoutError exception if
48 # the timeout has elapsed before any data was read.
49 chunk = await proc.recv(1024, 1000)
50 if chunk is None:
51 break
52 except TimeoutError as e:
53 print("recv() timed out: %s" % e)
54 continue
55 stdout += chunk.decode()
56
57 # Reap the process.
58 retcode = await proc.reap()
59
60 # Respond with the return code + the result as JSON.
61 payload = {
62 "retcode": retcode,
63 "stdout": stdout
64 }
65
66 data = json.dumps(payload, indent=4)
67 req.response(200, data.encode())
68 except Exception as e:
69 # If an exception occurs we must kill the process first.
70 proc.kill()
71 errmsg = "Exception: %s" % e
72 req.response(500, errmsg.encode())