qgyd2021 commited on
Commit
aca9481
1 Parent(s): e35c03b

[update]add code

Browse files
examples/test/test_assistant/assistant.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import argparse
4
+ import json
5
+
6
+ from openai import OpenAI
7
+ from openai.pagination import SyncCursorPage
8
+ from openai.types.beta.threads import ThreadMessage
9
+
10
+ from project_settings import environment, project_path
11
+
12
+
13
+ def get_args():
14
+ parser = argparse.ArgumentParser()
15
+ parser.add_argument(
16
+ "--openai_api_key",
17
+ default=environment.get("openai_api_key", default=None, dtype=str),
18
+ type=str
19
+ )
20
+ args = parser.parse_args()
21
+ return args
22
+
23
+
24
+ def get_message_list(client: OpenAI, thread_id: str):
25
+ messages: SyncCursorPage[ThreadMessage] = client.beta.threads.messages.list(
26
+ thread_id=thread_id
27
+ )
28
+ result = list()
29
+ for message in messages.data:
30
+
31
+ content = list()
32
+ for msg in message.content:
33
+ content.append({
34
+ "text": {
35
+ "annotations": msg.text.annotations,
36
+ "value": msg.text.value,
37
+ },
38
+ "type": msg.type,
39
+ })
40
+
41
+ result.append({
42
+ "id": message.id,
43
+ "assistant_id": message.assistant_id,
44
+ "content": content,
45
+ "created_at": message.created_at,
46
+ "file_ids": message.file_ids,
47
+ "metadata": message.metadata,
48
+ "object": message.object,
49
+ "role": message.role,
50
+ "run_id": message.run_id,
51
+ "thread_id": message.thread_id,
52
+
53
+ })
54
+
55
+ return result
56
+
57
+
58
+ def get_assistant_list(client: OpenAI):
59
+ assistant_list = client.beta.assistants.list()
60
+
61
+ result = list()
62
+ for assistant in assistant_list.data:
63
+
64
+ tools = list()
65
+ for tool in assistant.tools:
66
+ tools.append({
67
+ "type": tool.type
68
+ })
69
+
70
+ result.append({
71
+ "id": assistant.id,
72
+ "created_at": assistant.created_at,
73
+ "description": assistant.description,
74
+ "file_ids": assistant.file_ids,
75
+ "instructions": assistant.instructions,
76
+ "metadata": assistant.metadata,
77
+ "model": assistant.model,
78
+ "name": assistant.name,
79
+
80
+ })
81
+ return result
82
+
83
+
84
+ def main():
85
+ args = get_args()
86
+
87
+ client = OpenAI()
88
+
89
+ message_list = get_message_list(client, thread_id="thread_HT89XoJP7ZoL4g2s0CWl01Oo")
90
+ message_list = json.dumps(message_list, indent=4, ensure_ascii=False)
91
+ print(message_list)
92
+
93
+ # assistant_list = get_assistant_list(client)
94
+ # assistant_list = json.dumps(assistant_list, indent=4, ensure_ascii=False)
95
+ # print(assistant_list)
96
+ return
97
+
98
+
99
+ if __name__ == '__main__':
100
+ main()
examples/test/test_assistant/test_assistant.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ https://platform.openai.com/docs/assistants/overview
5
+ """
6
+ import argparse
7
+
8
+ from openai import OpenAI
9
+
10
+ from project_settings import environment, project_path
11
+
12
+
13
+ def get_args():
14
+ parser = argparse.ArgumentParser()
15
+ parser.add_argument(
16
+ "--openai_api_key",
17
+ default=environment.get("openai_api_key", default=None, dtype=str),
18
+ type=str
19
+ )
20
+ args = parser.parse_args()
21
+ return args
22
+
23
+
24
+ client = OpenAI()
25
+
26
+
27
+ assistant = client.beta.assistants.create(
28
+ name="Math Tutor",
29
+ instructions="You are a personal math tutor. Write and run code to answer math questions.",
30
+ tools=[{"type": "code_interpreter"}],
31
+ model="gpt-4-1106-preview"
32
+ )
33
+
34
+ thread = client.beta.threads.create()
35
+
36
+ message = client.beta.threads.messages.create(
37
+ thread_id=thread.id,
38
+ role="user",
39
+ content="I need to solve the equation `3x + 11 = 14`. Can you help me?"
40
+ )
41
+ print(message)
42
+
43
+ run = client.beta.threads.runs.create(
44
+ thread_id=thread.id,
45
+ assistant_id=assistant.id,
46
+ instructions="Please address the user as Jane Doe. The user has a premium account."
47
+ )
48
+
49
+ run = client.beta.threads.runs.retrieve(
50
+ thread_id=thread.id,
51
+ run_id=run.id
52
+ )
53
+
54
+ messages = client.beta.threads.messages.list(
55
+ thread_id=thread.id
56
+ )
57
+ print(messages)
58
+
59
+ # ThreadMessage(id='msg_7DjZts4XzdQw4IQvPYg3zJYS', assistant_id=None, content=[MessageContentText(text=Text(annotations=[], value='I need to solve the equation `3x + 11 = 14`. Can you help me?'), type='text')], created_at=1699425801, file_ids=[], metadata={}, object='thread.message', role='user', run_id=None, thread_id='thread_HT89XoJP7ZoL4g2s0CWl01Oo')
60
+ # SyncCursorPage[ThreadMessage](data=[ThreadMessage(id='msg_7DjZts4XzdQw4IQvPYg3zJYS', assistant_id=None, content=[MessageContentText(text=Text(annotations=[], value='I need to solve the equation `3x + 11 = 14`. Can you help me?'), type='text')], created_at=1699425801, file_ids=[], metadata={}, object='thread.message', role='user', run_id=None, thread_id='thread_HT89XoJP7ZoL4g2s0CWl01Oo')], object='list', first_id='msg_7DjZts4XzdQw4IQvPYg3zJYS', last_id='msg_7DjZts4XzdQw4IQvPYg3zJYS', has_more=False)
61
+
62
+
63
+ if __name__ == '__main__':
64
+ pass
examples/test/test_tts/test_tts.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ https://platform.openai.com/docs/guides/text-to-speech
5
+ """
6
+ import argparse
7
+ from pathlib import Path
8
+
9
+ from openai import OpenAI
10
+
11
+ from project_settings import environment, project_path
12
+
13
+
14
+ def get_args():
15
+ parser = argparse.ArgumentParser()
16
+ parser.add_argument(
17
+ "--openai_model",
18
+ default="tts-1",
19
+ choices=["tts-1"],
20
+ type=str
21
+ )
22
+ parser.add_argument(
23
+ "--openai_voice",
24
+ default="alloy",
25
+ choices=["alloy", "nova"],
26
+ type=str
27
+ )
28
+ parser.add_argument(
29
+ "--openai_input",
30
+ default="Today is a wonderful day to build something people love!",
31
+ type=str
32
+ )
33
+ parser.add_argument(
34
+ "--speech_file_path",
35
+ default=(Path(__file__).parent / "speech_alloy.mp3").as_posix(),
36
+ type=str
37
+ )
38
+ parser.add_argument(
39
+ "--openai_api_key",
40
+ default=environment.get("openai_api_key", default=None, dtype=str),
41
+ type=str
42
+ )
43
+ args = parser.parse_args()
44
+ return args
45
+
46
+
47
+ def main():
48
+ args = get_args()
49
+
50
+ client = OpenAI()
51
+
52
+ response = client.audio.speech.create(
53
+ model=args.openai_model,
54
+ voice=args.openai_voice,
55
+ input=args.openai_input,
56
+ )
57
+
58
+ response.stream_to_file(args.speech_file_path)
59
+
60
+ return
61
+
62
+
63
+ if __name__ == '__main__':
64
+ main()
main.py ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ https://huggingface.co/spaces/fffiloni/langchain-chat-with-pdf-openai
5
+ """
6
+ import argparse
7
+ import json
8
+ import time
9
+ from typing import List, Tuple
10
+
11
+ import gradio as gr
12
+ from openai import OpenAI
13
+ from threading import Thread
14
+ import _queue
15
+ from queue import Queue
16
+
17
+ import project_settings as settings
18
+
19
+
20
+ def get_args():
21
+ parser = argparse.ArgumentParser()
22
+ parser.add_argument(
23
+ "--openai_api_key",
24
+ default=settings.environment.get("openai_api_key", default=None, dtype=str),
25
+ type=str
26
+ )
27
+ args = parser.parse_args()
28
+ return args
29
+
30
+
31
+ def greet(question: str, history: List[Tuple[str, str]]):
32
+ answer = "Hello " + question + "!"
33
+ result = history + [(question, answer)]
34
+ return result
35
+
36
+
37
+ def get_message_list(client: OpenAI, thread_id: str):
38
+ messages = client.beta.threads.messages.list(
39
+ thread_id=thread_id
40
+ )
41
+
42
+ result = list()
43
+ for message in messages.data:
44
+
45
+ content = list()
46
+ for msg in message.content:
47
+ content.append({
48
+ "text": {
49
+ "annotations": msg.text.annotations,
50
+ "value": msg.text.value,
51
+ },
52
+ "type": msg.type,
53
+
54
+ })
55
+
56
+ result.append({
57
+ "id": message.id,
58
+ "assistant_id": message.assistant_id,
59
+ "content": content,
60
+ "created_at": message.created_at,
61
+ "file_ids": message.file_ids,
62
+ "metadata": message.metadata,
63
+ "object": message.object,
64
+ "role": message.role,
65
+ "run_id": message.run_id,
66
+ "thread_id": message.thread_id,
67
+
68
+ })
69
+
70
+ result = list(sorted(result, key=lambda x: x["created_at"]))
71
+ return result
72
+
73
+
74
+ def convert_message_list_to_response(message_list: List[dict]) -> str:
75
+ response = ""
76
+ for message in message_list:
77
+ role = message["role"]
78
+ content = message["content"]
79
+
80
+ for c in content:
81
+ if c["type"] != "text":
82
+ continue
83
+ text: dict = c["text"]
84
+ msg = "{}: \n{}\n".format(role, text["value"])
85
+ response += msg
86
+ response += "-" * 80
87
+ response += "\n"
88
+
89
+ return response
90
+
91
+
92
+ def streaming_refresh(openai_api_key: str,
93
+ thread_id: str,
94
+ queue: Queue,
95
+ ):
96
+ delta_time = 0.3
97
+ last_response = None
98
+ no_updates_count = 0
99
+ max_no_updates_count = 5
100
+ while True:
101
+ time.sleep(delta_time)
102
+
103
+ this_response = refresh(openai_api_key, thread_id)
104
+
105
+ if this_response == last_response:
106
+ no_updates_count += 1
107
+ if no_updates_count >= max_no_updates_count:
108
+ break
109
+ last_response = this_response
110
+
111
+ queue.put(this_response, block=True, timeout=2)
112
+
113
+ return last_response
114
+
115
+
116
+ def refresh(openai_api_key: str,
117
+ thread_id: str,
118
+ ):
119
+ client = OpenAI(
120
+ api_key=openai_api_key,
121
+ )
122
+
123
+ message_list = get_message_list(client, thread_id=thread_id)
124
+ response = convert_message_list_to_response(message_list)
125
+ return response
126
+
127
+
128
+ def add_and_run(openai_api_key: str,
129
+ assistant_id: str,
130
+ thread_id: str,
131
+ name: str,
132
+ instructions: str,
133
+ model: str,
134
+ query: str,
135
+ ):
136
+ client = OpenAI(
137
+ api_key=openai_api_key,
138
+ )
139
+ if assistant_id is None or len(assistant_id.strip()) == 0:
140
+ assistant = client.beta.assistants.create(
141
+ name=name,
142
+ instructions=instructions,
143
+ # tools=[{"type": "code_interpreter"}],
144
+ model=model,
145
+ )
146
+ assistant_id = assistant.id
147
+
148
+ if thread_id is None or len(thread_id.strip()) == 0:
149
+ thread = client.beta.threads.create()
150
+ thread_id = thread.id
151
+
152
+ message = client.beta.threads.messages.create(
153
+ thread_id=thread_id,
154
+ role="user",
155
+ content=query
156
+ )
157
+ run = client.beta.threads.runs.create(
158
+ thread_id=thread_id,
159
+ assistant_id=assistant_id,
160
+ )
161
+ run = client.beta.threads.runs.retrieve(
162
+ thread_id=thread_id,
163
+ run_id=run.id
164
+ )
165
+
166
+ response_queue = Queue(maxsize=10)
167
+ refresh_kwargs = dict(
168
+ openai_api_key=openai_api_key,
169
+ thread_id=thread_id,
170
+ queue=response_queue,
171
+ )
172
+ thread = Thread(target=streaming_refresh, kwargs=refresh_kwargs)
173
+ thread.start()
174
+
175
+ delta_time = 0.1
176
+ last_response = None
177
+ no_updates_count = 0
178
+ max_no_updates_count = 10
179
+ while True:
180
+ time.sleep(delta_time)
181
+
182
+ try:
183
+ this_response = response_queue.get(block=True, timeout=2)
184
+ except _queue.Empty:
185
+ break
186
+
187
+ if this_response == last_response:
188
+ no_updates_count += 1
189
+ if no_updates_count >= max_no_updates_count:
190
+ break
191
+ last_response = this_response
192
+
193
+ result = [
194
+ assistant_id, thread_id,
195
+ last_response
196
+ ]
197
+ yield result
198
+
199
+
200
+ def main():
201
+ args = get_args()
202
+
203
+ description = """
204
+ chat llm
205
+ """
206
+
207
+ # ui
208
+ with gr.Blocks() as blocks:
209
+ gr.Markdown(value=description)
210
+
211
+ with gr.Row():
212
+ # settings
213
+ with gr.Column(scale=3):
214
+ with gr.Tabs():
215
+ with gr.TabItem("create assistant"):
216
+ openai_api_key = gr.Text(
217
+ value=args.openai_api_key,
218
+ label="openai_api_key",
219
+ placeholder="Fill with your `openai_api_key`"
220
+ )
221
+
222
+ name = gr.Textbox(label="name")
223
+ instructions = gr.Textbox(label="instructions")
224
+
225
+ model = gr.Dropdown(["gpt-4-1106-preview"], value="gpt-4-1106-preview", label="model")
226
+
227
+ # functions
228
+ functions = gr.TextArea(label="functions")
229
+
230
+ # upload files
231
+ retrieval_files = gr.Files(label="retrieval files")
232
+
233
+ # chat
234
+ with gr.Column(scale=5):
235
+ response = gr.Textbox(lines=5, max_lines=80, label="response")
236
+ query = gr.Textbox(lines=2, label="query")
237
+
238
+ # chat_bot = gr.Chatbot([], elem_id="context", height=400)
239
+ # text_box = gr.Textbox(show_label=False, placeholder="Enter text and press enter", container=False)
240
+
241
+ with gr.Row():
242
+ with gr.Column(scale=1):
243
+ add_and_run_button = gr.Button("Add and run")
244
+ with gr.Column(scale=1):
245
+ refresh_button = gr.Button("Refresh")
246
+
247
+ # states
248
+ with gr.Column(scale=2):
249
+ # upload files
250
+ assistant_id = gr.Textbox(value=None, label="assistant_id")
251
+ thread_id = gr.Textbox(value=None, label="thread_id")
252
+
253
+ # examples
254
+ with gr.Row():
255
+ gr.Examples(
256
+ examples=[
257
+ [
258
+ "Math Tutor",
259
+ "You are a personal math tutor. Write and run code to answer math questions.",
260
+ "gpt-4-1106-preview",
261
+ "123 * 524 等于多少?"
262
+ ]
263
+ ],
264
+ inputs=[
265
+ name, instructions, model,
266
+ query,
267
+ ],
268
+ examples_per_page=5
269
+ )
270
+
271
+ # add and run
272
+ add_and_run_button.click(
273
+ add_and_run,
274
+ inputs=[
275
+ openai_api_key,
276
+ assistant_id, thread_id,
277
+ name, instructions, model,
278
+ query,
279
+ ],
280
+ outputs=[
281
+ assistant_id, thread_id,
282
+ response,
283
+ ],
284
+ )
285
+
286
+ # refresh
287
+
288
+ refresh_button.click(
289
+ refresh,
290
+ inputs=[
291
+ openai_api_key,
292
+ thread_id,
293
+ ],
294
+ outputs=[
295
+ response
296
+ ]
297
+ )
298
+
299
+ blocks.queue().launch()
300
+
301
+ return
302
+
303
+
304
+ if __name__ == '__main__':
305
+ main()
project_settings.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import os
4
+ from pathlib import Path
5
+
6
+ from toolbox.os.environment import EnvironmentManager
7
+
8
+
9
+ project_path = os.path.abspath(os.path.dirname(__file__))
10
+ project_path = Path(project_path)
11
+
12
+
13
+ environment = EnvironmentManager(
14
+ path=os.path.join(project_path, 'dotenv'),
15
+ env=os.environ.get('environment', 'dev'),
16
+ )
17
+
18
+
19
+ if __name__ == '__main__':
20
+ pass
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ openai==1.1.1
2
+ python-dotenv==1.0.0
3
+ gradio==4.1.2
toolbox/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ if __name__ == '__main__':
6
+ pass
toolbox/json/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ if __name__ == '__main__':
6
+ pass
toolbox/json/misc.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ from typing import Callable
4
+
5
+
6
+ def traverse(js, callback: Callable, *args, **kwargs):
7
+ if isinstance(js, list):
8
+ result = list()
9
+ for l in js:
10
+ l = traverse(l, callback, *args, **kwargs)
11
+ result.append(l)
12
+ return result
13
+ elif isinstance(js, tuple):
14
+ result = list()
15
+ for l in js:
16
+ l = traverse(l, callback, *args, **kwargs)
17
+ result.append(l)
18
+ return tuple(result)
19
+ elif isinstance(js, dict):
20
+ result = dict()
21
+ for k, v in js.items():
22
+ k = traverse(k, callback, *args, **kwargs)
23
+ v = traverse(v, callback, *args, **kwargs)
24
+ result[k] = v
25
+ return result
26
+ elif isinstance(js, int):
27
+ return callback(js, *args, **kwargs)
28
+ elif isinstance(js, str):
29
+ return callback(js, *args, **kwargs)
30
+ else:
31
+ return js
32
+
33
+
34
+ def demo1():
35
+ d = {
36
+ "env": "ppe",
37
+ "mysql_connect": {
38
+ "host": "$mysql_connect_host",
39
+ "port": 3306,
40
+ "user": "callbot",
41
+ "password": "NxcloudAI2021!",
42
+ "database": "callbot_ppe",
43
+ "charset": "utf8"
44
+ },
45
+ "es_connect": {
46
+ "hosts": ["10.20.251.8"],
47
+ "http_auth": ["elastic", "ElasticAI2021!"],
48
+ "port": 9200
49
+ }
50
+ }
51
+
52
+ def callback(s):
53
+ if isinstance(s, str) and s.startswith('$'):
54
+ return s[1:]
55
+ return s
56
+
57
+ result = traverse(d, callback=callback)
58
+ print(result)
59
+ return
60
+
61
+
62
+ if __name__ == '__main__':
63
+ demo1()
toolbox/os/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ if __name__ == '__main__':
6
+ pass
toolbox/os/environment.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ import json
4
+ import os
5
+
6
+ from dotenv import load_dotenv
7
+ from dotenv.main import DotEnv
8
+
9
+ from toolbox.json.misc import traverse
10
+
11
+
12
+ class EnvironmentManager(object):
13
+ def __init__(self, path, env, override=False):
14
+ filename = os.path.join(path, '{}.env'.format(env))
15
+ self.filename = filename
16
+
17
+ load_dotenv(
18
+ dotenv_path=filename,
19
+ override=override
20
+ )
21
+
22
+ self._environ = dict()
23
+
24
+ def open_dotenv(self, filename: str = None):
25
+ filename = filename or self.filename
26
+ dotenv = DotEnv(
27
+ dotenv_path=filename,
28
+ stream=None,
29
+ verbose=False,
30
+ interpolate=False,
31
+ override=False,
32
+ encoding="utf-8",
33
+ )
34
+ result = dotenv.dict()
35
+ return result
36
+
37
+ def get(self, key, default=None, dtype=str):
38
+ result = os.environ.get(key)
39
+ if result is None:
40
+ if default is None:
41
+ result = None
42
+ else:
43
+ result = default
44
+ else:
45
+ result = dtype(result)
46
+ self._environ[key] = result
47
+ return result
48
+
49
+
50
+ _DEFAULT_DTYPE_MAP = {
51
+ 'int': int,
52
+ 'float': float,
53
+ 'str': str,
54
+ 'json.loads': json.loads
55
+ }
56
+
57
+
58
+ class JsonConfig(object):
59
+ """
60
+ 将 json 中, 形如 `$float:threshold` 的值, 处理为:
61
+ 从环境变量中查到 threshold, 再将其转换为 float 类型.
62
+ """
63
+ def __init__(self, dtype_map: dict = None, environment: EnvironmentManager = None):
64
+ self.dtype_map = dtype_map or _DEFAULT_DTYPE_MAP
65
+ self.environment = environment or os.environ
66
+
67
+ def sanitize_by_filename(self, filename: str):
68
+ with open(filename, 'r', encoding='utf-8') as f:
69
+ js = json.load(f)
70
+
71
+ return self.sanitize_by_json(js)
72
+
73
+ def sanitize_by_json(self, js):
74
+ js = traverse(
75
+ js,
76
+ callback=self.sanitize,
77
+ environment=self.environment
78
+ )
79
+ return js
80
+
81
+ def sanitize(self, string, environment):
82
+ """支持 $ 符开始的, 环境变量配置"""
83
+ if isinstance(string, str) and string.startswith('$'):
84
+ dtype, key = string[1:].split(':')
85
+ dtype = self.dtype_map[dtype]
86
+
87
+ value = environment.get(key)
88
+ if value is None:
89
+ raise AssertionError('environment not exist. key: {}'.format(key))
90
+
91
+ value = dtype(value)
92
+ result = value
93
+ else:
94
+ result = string
95
+ return result
96
+
97
+
98
+ def demo1():
99
+ import json
100
+
101
+ from project_settings import project_path
102
+
103
+ environment = EnvironmentManager(
104
+ path=os.path.join(project_path, 'server/callbot_server/dotenv'),
105
+ env='dev',
106
+ )
107
+ init_scenes = environment.get(key='init_scenes', dtype=json.loads)
108
+ print(init_scenes)
109
+ print(environment._environ)
110
+ return
111
+
112
+
113
+ if __name__ == '__main__':
114
+ demo1()
toolbox/os/other.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import inspect
3
+
4
+
5
+ def pwd():
6
+ """你在哪个文件调用此函数, 它就会返回那个文件所在的 dir 目标"""
7
+ frame = inspect.stack()[1]
8
+ module = inspect.getmodule(frame[0])
9
+ return os.path.dirname(os.path.abspath(module.__file__))