console.py 3.49 KB
Newer Older
ymir's avatar
CLI  
ymir committed
1
2
3
#!/usr/bin/env python3
# coding=utf-8
# import
ymir's avatar
CLI    
ymir committed
4
from dummypythongraphqlserver.graphQL import schema, SubscriptionObserver
ymir's avatar
CLI    
ymir committed
5
from json import dumps, loads
ymir's avatar
CLI    
ymir committed
6
from sys import exit
ymir's avatar
CLI    
ymir committed
7
from time import sleep
ymir's avatar
CLI    
ymir committed
8
from threading import Thread
ymir's avatar
CLI    
ymir committed
9
from multiprocessing import Queue
ymir's avatar
CLI    
ymir committed
10
# format result
ymir's avatar
CLI    
ymir committed
11
def formatResponse(response):
ymir's avatar
CLI    
ymir committed
12
    formattedResponse = "\n<<< data\n" + dumps(response.data, indent=4)
ymir's avatar
CLI    
ymir committed
13
14
15
16
    if response.errors and len(response.errors) > 0:
        for index, error in enumerate(response.errors):
            if hasattr(error, "message"):
                error = error.message
ymir's avatar
CLI    
ymir committed
17
                formattedResponse += "\n<<< error #" + str(index) + "\n" + str(error)
ymir's avatar
CLI    
ymir committed
18
19
20
21
22
23
24
25
26
27
28
29
30
    return formattedResponse
# (thread safe) file writer
# INFO : for complete safety, this class should be a singleton
class FileWriter(Thread):
    queue = Queue()
    fileName = "out.txt"
    # inheritance
    def run(self):
        while True :
            response = FileWriter.queue.get()
            file = open(FileWriter.fileName, 'a')
            file.write(formatResponse(response))
            file.close()
ymir's avatar
CLI    
ymir committed
31
    pass
ymir's avatar
CLI    
ymir committed
32
# subscription
ymir's avatar
CLI    
ymir committed
33
34
35
36
37
38
class SubscriptionThread(Thread):
    # inner observer
    class InnerObserver(SubscriptionObserver):
        # inheritance
        def on_next(self, value):
            response = super().on_next(value)
ymir's avatar
CLI    
ymir committed
39
            FileWriter.queue.put(response)
ymir's avatar
CLI    
ymir committed
40
41
    # inheritance
    def run(self):
ymir's avatar
CLI    
ymir committed
42
        observer = SubscriptionThread.InnerObserver(self.request, self.parameters)
ymir's avatar
CLI    
ymir committed
43
44
45
46
47
48
49
50
51
        observable = schema.execute(self.request, variables=self.parameters, allow_subscriptions=True)
        # INFO : timestamp decorator function increment a loop conter name 'value'
        observable.interval(observer.period * 1000).timestamp().filter( lambda o: o.value < observer.occurencesNumber).subscribe(observer=observer)
        sleep(observer.period * (observer.occurencesNumber + 1))
    # constructor
    def __init__(self, request, parameters):
        super().__init__()
        self.request = request
        self.parameters = parameters
ymir's avatar
CLI    
ymir committed
52
53
# multiligne input
# WARN : this method do not allow you to edit previous line, only the current one
ymir's avatar
CLI    
ymir committed
54
def multilineText():
ymir's avatar
CLI    
ymir committed
55
56
57
58
59
60
61
62
63
    lines = []
    while True:
        line = input()
        if line:
            lines.append(line)
        else:
            break
    text = '\n'.join(lines)
    return text
ymir's avatar
CLI  
ymir committed
64
# run console
ymir's avatar
CLI    
ymir committed
65
66
67
68
69
70
def main():
    fileWriter = FileWriter()
    fileWriter.start()
    while True:
        try:
            # stop console message
ymir's avatar
ymir committed
71
            print("* press CTRL-C or CTRL-D to stop this console")
ymir's avatar
CLI    
ymir committed
72
73
            # ask for request
            print(">>> request")
ymir's avatar
CLI    
ymir committed
74
            request = multilineText()
ymir's avatar
CLI    
ymir committed
75
76
            firstWord = request.split(maxsplit=1)[0]
            print(">>> parameters")
ymir's avatar
CLI    
ymir committed
77
            parameters = multilineText()
ymir's avatar
CLI    
ymir committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
            if len(parameters.strip()) > 0:
                parameters = loads(parameters)
            # asynchronous subscription
            if firstWord.upper() == "SUBSCRIPTION":
                SubscriptionThread(request, parameters).start()
            # synchronous query/mutation
            else:
                response = schema.execute(request, variables=parameters)
                print(formatResponse(response))
        except Exception as e:
            # keyboard interruption
            if str(e) == "EOF when reading a line":
                fileWriter._tstate_lock = None
                fileWriter._stop()
                exit()
            # print any other issue & continue looping
            else:
                print(e)
        pass
ymir's avatar
CLI    
ymir committed
97
    pass
ymir's avatar
CLI    
ymir committed
98
if __name__ == "__main__":
ymir's avatar
CLI    
ymir committed
99
100
    main()
pass