andreped commited on
Commit
91aba60
·
1 Parent(s): a632443

Implemented stdout redirect method - logger widget in progress

Browse files
Files changed (2) hide show
  1. app.py +9 -2
  2. chatbot/redirect.py +133 -0
app.py CHANGED
@@ -2,8 +2,9 @@ import os
2
 
3
  import streamlit as st
4
 
5
- from chatbot.utils import download_test_data
6
- from chatbot.utils import load_data
 
7
 
8
  # add OpenAI API key to environemntal variables
9
  os.environ["OPENAI_API_KEY"] = st.secrets["OPENAI_API_KEY"]
@@ -15,6 +16,12 @@ if "messages" not in st.session_state.keys(): # Initialize the chat message his
15
  st.session_state.messages = [{"role": "assistant", "content": "Ask me a question about André's research!"}]
16
 
17
  def main():
 
 
 
 
 
 
18
  # setup dataset
19
  download_test_data()
20
  index = load_data()
 
2
 
3
  import streamlit as st
4
 
5
+ from chatbot import redirect as rd
6
+ from chatbot.data import download_test_data
7
+ from chatbot.data import load_data
8
 
9
  # add OpenAI API key to environemntal variables
10
  os.environ["OPENAI_API_KEY"] = st.secrets["OPENAI_API_KEY"]
 
16
  st.session_state.messages = [{"role": "assistant", "content": "Ask me a question about André's research!"}]
17
 
18
  def main():
19
+ # setup logger sidebar
20
+ #st.sidebar.text("Standard output log:")
21
+ #_sidebar_out = st.sidebar.empty()
22
+ #with rd.stdout(to=_sidebar_out, format='text'):
23
+ # print("test")
24
+
25
  # setup dataset
26
  download_test_data()
27
  index = load_data()
chatbot/redirect.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import io
3
+ import contextlib
4
+ import sys
5
+ import re
6
+
7
+
8
+ class _Redirect:
9
+ """
10
+ Based on: https://gist.github.com/schaumb/037f139035d93cff3ad9f4f7e5f739ce
11
+ Also see: https://github.com/streamlit/streamlit/issues/268#issuecomment-810478208
12
+ """
13
+ class IOStuff(io.StringIO):
14
+ def __init__(self, trigger, max_buffer, buffer_separator, regex, dup=None):
15
+ super().__init__()
16
+ self._trigger = trigger
17
+ self._max_buffer = max_buffer
18
+ self._buffer_separator = buffer_separator
19
+ self._regex = regex and re.compile(regex)
20
+ self._dup = dup
21
+
22
+ def write(self, __s: str) -> int:
23
+ if self._max_buffer:
24
+ concatenated_len = super().tell() + len(__s)
25
+ if concatenated_len > self._max_buffer:
26
+ rest = self.get_filtered_output()[concatenated_len - self._max_buffer:]
27
+ if self._buffer_separator is not None:
28
+ rest = rest.split(self._buffer_separator, 1)[-1]
29
+ super().seek(0)
30
+ super().write(rest)
31
+ super().truncate(super().tell() + len(__s))
32
+ res = super().write(__s)
33
+ if self._dup is not None:
34
+ self._dup.write(__s)
35
+ self._trigger(self.get_filtered_output())
36
+ return res
37
+
38
+ def get_filtered_output(self):
39
+ if self._regex is None or self._buffer_separator is None:
40
+ return self.getvalue()
41
+
42
+ return self._buffer_separator.join(filter(self._regex.search, self.getvalue().split(self._buffer_separator)))
43
+
44
+ def print_at_end(self):
45
+ self._trigger(self.get_filtered_output())
46
+
47
+ def __init__(self, stdout=None, stderr=False, format=None, to=None, max_buffer=None, buffer_separator='\n',
48
+ regex=None, duplicate_out=False):
49
+ self.io_args = {'trigger': self._write, 'max_buffer': max_buffer, 'buffer_separator': buffer_separator,
50
+ 'regex': regex}
51
+ self.redirections = []
52
+ self.st = None
53
+ self.stderr = stderr is True
54
+ self.stdout = stdout is True or (stdout is None and not self.stderr)
55
+ self.format = format or 'code'
56
+ self.to = to
57
+ self.fun = None
58
+ self.duplicate_out = duplicate_out or None
59
+ self.active_nested = None
60
+
61
+ if not self.stdout and not self.stderr:
62
+ raise ValueError("one of stdout or stderr must be True")
63
+
64
+ if self.format not in ['text', 'markdown', 'latex', 'code', 'write']:
65
+ raise ValueError(
66
+ f"format need oneof the following: {', '.join(['text', 'markdown', 'latex', 'code', 'write'])}")
67
+
68
+ if self.to and (not hasattr(self.to, 'text') or not hasattr(self.to, 'empty')):
69
+ raise ValueError(f"'to' is not a streamlit container object")
70
+
71
+ def __enter__(self):
72
+ if self.st is not None:
73
+ if self.to is None:
74
+ if self.active_nested is None:
75
+ self.active_nested = self(format=self.format, max_buffer=self.io_args['max_buffer'],
76
+ buffer_separator=self.io_args['buffer_separator'],
77
+ regex=self.io_args['regex'], duplicate_out=self.duplicate_out)
78
+ return self.active_nested.__enter__()
79
+ else:
80
+ raise Exception("Already entered")
81
+ to = self.to or st
82
+
83
+ to.text(f"Redirected output from "
84
+ f"{'stdout and stderr' if self.stdout and self.stderr else 'stdout' if self.stdout else 'stderr'}"
85
+ f"{' [' + self.io_args['regex'] + ']' if self.io_args['regex'] else ''}"
86
+ f":")
87
+ self.st = to.empty()
88
+ self.fun = getattr(self.st, self.format)
89
+
90
+ io_obj = None
91
+
92
+ def redirect(to_duplicate):
93
+ nonlocal io_obj
94
+ io_obj = _Redirect.IOStuff(dup=self.duplicate_out and to_duplicate, **self.io_args)
95
+ redirection = contextlib.redirect_stdout(io_obj)
96
+ self.redirections.append((redirection, io_obj))
97
+ redirection.__enter__()
98
+
99
+ if self.stderr:
100
+ redirect(sys.stderr)
101
+ if self.stdout:
102
+ redirect(sys.stdout)
103
+
104
+ return io_obj
105
+
106
+ def __call__(self, to=None, format=None, max_buffer=None, buffer_separator='\n', regex=None, duplicate_out=False):
107
+ return _Redirect(self.stdout, self.stderr, format=format, to=to, max_buffer=max_buffer,
108
+ buffer_separator=buffer_separator, regex=regex, duplicate_out=duplicate_out)
109
+
110
+ def __exit__(self, *exc):
111
+ if self.active_nested is not None:
112
+ nested = self.active_nested
113
+ if nested.active_nested is None:
114
+ self.active_nested = None
115
+ return nested.__exit__(*exc)
116
+
117
+ res = None
118
+ for redirection, io_obj in reversed(self.redirections):
119
+ res = redirection.__exit__(*exc)
120
+ io_obj.print_at_end()
121
+
122
+ self.redirections = []
123
+ self.st = None
124
+ self.fun = None
125
+ return res
126
+
127
+ def _write(self, data):
128
+ self.fun(data)
129
+
130
+
131
+ stdout = _Redirect(max_buffer=1, buffer_separator="\n")
132
+ stderr = _Redirect(stderr=True)
133
+ stdouterr = _Redirect(stdout=True, stderr=True)