Spaces:
Sleeping
Sleeping
fix prompt add refactor & add gradio interface
Browse files- .env_template +1 -0
- .gitignore +6 -1
- .vscode/settings.json +7 -0
- interface.py +173 -0
- llm/__init__.py +0 -0
- llm/__pycache__/basemodel.cpython-311.pyc +0 -0
- llm/__pycache__/llm.cpython-311.pyc +0 -0
- llm/__pycache__/prompt.cpython-311.pyc +0 -0
- llm/basemodel.py +2 -2
- llm/llm.py +71 -25
- llm/models.py +41 -0
- llm/prompt.py +83 -80
- main.py +42 -23
- poetry.lock +815 -1
- pyproject.toml +2 -0
.env_template
CHANGED
@@ -1,2 +1,3 @@
|
|
1 |
TYPHOON_CHAT_API = *
|
|
|
2 |
OPENTHAIGPT_CHAT_API = *
|
|
|
1 |
TYPHOON_CHAT_API = *
|
2 |
+
DEBUG_MODE = false
|
3 |
OPENTHAIGPT_CHAT_API = *
|
.gitignore
CHANGED
@@ -1,3 +1,8 @@
|
|
1 |
.venv
|
2 |
.env
|
3 |
-
**/__pycache__/
|
|
|
|
|
|
|
|
|
|
|
|
1 |
.venv
|
2 |
.env
|
3 |
+
**/__pycache__/
|
4 |
+
.pytest_cache
|
5 |
+
|
6 |
+
# temporary files
|
7 |
+
runtime_log.csv
|
8 |
+
speedtest.py
|
.vscode/settings.json
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"python.testing.pytestArgs": [
|
3 |
+
"llm"
|
4 |
+
],
|
5 |
+
"python.testing.unittestEnabled": false,
|
6 |
+
"python.testing.pytestEnabled": true
|
7 |
+
}
|
interface.py
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import requests
|
3 |
+
|
4 |
+
API_BASE_URL = "http://127.0.0.1:8000" # Update this with your actual API base URL if deployed elsewhere
|
5 |
+
|
6 |
+
# Function: Get nurse response
|
7 |
+
def get_nurse_response(user_input, model_name, chat_history):
|
8 |
+
|
9 |
+
try:
|
10 |
+
start_time = time.time()
|
11 |
+
# Send user input to the API
|
12 |
+
response = requests.post(
|
13 |
+
f"{API_BASE_URL}/nurse_response",
|
14 |
+
json={"user_input": user_input, "model_name": model_name},
|
15 |
+
timeout=15
|
16 |
+
)
|
17 |
+
response.raise_for_status()
|
18 |
+
end_time = time.time()
|
19 |
+
elapsed_time = end_time - start_time
|
20 |
+
nurse_response = response.json().get("nurse_response", "No response received.")
|
21 |
+
|
22 |
+
# Append user and nurse messages to the chat history
|
23 |
+
chat_history.append((f"👤 {user_input}", f"🤖 {nurse_response} ({elapsed_time:.2f} s.)"))
|
24 |
+
return chat_history, "" # Clear the user input after sending
|
25 |
+
except requests.exceptions.RequestException as e:
|
26 |
+
chat_history.append(("⚠️ Error", str(e)))
|
27 |
+
return chat_history, ""
|
28 |
+
|
29 |
+
|
30 |
+
# Function: Reset chat history
|
31 |
+
def reset_history():
|
32 |
+
response = requests.post(f"{API_BASE_URL}/reset")
|
33 |
+
return [], "", response.text
|
34 |
+
|
35 |
+
# Function: View chat history
|
36 |
+
def view_chat_history():
|
37 |
+
try:
|
38 |
+
response = requests.get(f"{API_BASE_URL}/history")
|
39 |
+
response.raise_for_status()
|
40 |
+
chat_history = response.json().get("chat_history", [])
|
41 |
+
if not chat_history:
|
42 |
+
return "No chat history available."
|
43 |
+
|
44 |
+
# Properly format chat history for display
|
45 |
+
formatted_history = []
|
46 |
+
for message in chat_history:
|
47 |
+
if message.get("role") == "user":
|
48 |
+
formatted_history.append(f"👤 User: {message.get('content', '')}")
|
49 |
+
elif message.get("role") == "assistant":
|
50 |
+
formatted_history.append(f"🤖 Nurse: {message.get('content', '')}")
|
51 |
+
|
52 |
+
return "\n".join(formatted_history)
|
53 |
+
except requests.exceptions.RequestException as e:
|
54 |
+
return f"Error: {str(e)}"
|
55 |
+
|
56 |
+
import json
|
57 |
+
import time
|
58 |
+
# Function: View EHR details
|
59 |
+
def view_ehr_details(view):
|
60 |
+
try:
|
61 |
+
response = requests.get(f"{API_BASE_URL}/details")
|
62 |
+
response.raise_for_status()
|
63 |
+
ehr_data = response.json()
|
64 |
+
if view == "details":
|
65 |
+
ehr_data = ehr_data["ehr_data"]
|
66 |
+
elif view == "prompt":
|
67 |
+
ehr_data.pop("ehr_data", None)
|
68 |
+
ehr_data = json.dumps(ehr_data, indent=4, ensure_ascii=False)
|
69 |
+
return ehr_data
|
70 |
+
except requests.exceptions.RequestException as e:
|
71 |
+
return f"Error: {str(e)}"
|
72 |
+
|
73 |
+
# Gradio Interface
|
74 |
+
def create_gradio_interface():
|
75 |
+
with gr.Blocks() as interface:
|
76 |
+
# Title and description
|
77 |
+
gr.Markdown(
|
78 |
+
"""
|
79 |
+
# MALI_NURSE Gradio Interface
|
80 |
+
### A User-Friendly Interface to Interact with the MALI_NURSE API
|
81 |
+
Select a model, input your question, and view nurse responses or manage chat history and EHR details.
|
82 |
+
"""
|
83 |
+
)
|
84 |
+
|
85 |
+
# Main Input Section
|
86 |
+
with gr.Row():
|
87 |
+
with gr.Row():
|
88 |
+
chat_box = gr.Chatbot(label="Chat with MALI Nurse")
|
89 |
+
|
90 |
+
# Input Section
|
91 |
+
with gr.Row():
|
92 |
+
user_input = gr.Textbox(
|
93 |
+
label="Your Message",
|
94 |
+
placeholder="Type your question or message here...",
|
95 |
+
lines=2,
|
96 |
+
)
|
97 |
+
model_name = gr.Radio(
|
98 |
+
choices=["typhoon-v1.5x-70b-instruct", "openthaigpt", "llama-3.3-70b-versatile"],
|
99 |
+
value="typhoon-v1.5x-70b-instruct",
|
100 |
+
label="Model Selection",
|
101 |
+
)
|
102 |
+
with gr.Column():
|
103 |
+
send_button = gr.Button("Send", variant="primary", size="lg")
|
104 |
+
notification_box = gr.Textbox(interactive=False, lines=2)
|
105 |
+
|
106 |
+
# Bind Get Nurse Response button
|
107 |
+
send_button.click(
|
108 |
+
fn=get_nurse_response,
|
109 |
+
inputs=[user_input, model_name, chat_box],
|
110 |
+
outputs=[chat_box, user_input], # Update chat box and clear input
|
111 |
+
)
|
112 |
+
|
113 |
+
# Advanced Options
|
114 |
+
with gr.Accordion("Advanced Options", open=False):
|
115 |
+
with gr.Row():
|
116 |
+
reset_button = gr.Button("Reset Data", variant="primary")
|
117 |
+
chat_history_button = gr.Button("View Chat History")
|
118 |
+
ehr_details_button = gr.Button("View EHR Details")
|
119 |
+
with gr.Column():
|
120 |
+
chat_history_output = gr.Textbox(
|
121 |
+
label="Chat History",
|
122 |
+
interactive=False,
|
123 |
+
lines=6,
|
124 |
+
)
|
125 |
+
ehr_details_output = gr.Textbox(
|
126 |
+
label="EHR Details",
|
127 |
+
interactive=False,
|
128 |
+
lines=6,
|
129 |
+
)
|
130 |
+
ehr_prompt_output = gr.Textbox(
|
131 |
+
label="Outputs",
|
132 |
+
interactive=False,
|
133 |
+
lines=6,
|
134 |
+
)
|
135 |
+
|
136 |
+
# Bind buttons to respective functions
|
137 |
+
reset_button.click(
|
138 |
+
fn=reset_history,
|
139 |
+
inputs=[],
|
140 |
+
outputs=[chat_box, user_input, notification_box], # Clear chat box and input
|
141 |
+
)
|
142 |
+
chat_history_button.click(
|
143 |
+
fn=view_chat_history,
|
144 |
+
inputs=[],
|
145 |
+
outputs=chat_history_output,
|
146 |
+
)
|
147 |
+
# View EHR Details
|
148 |
+
ehr_details_button.click(
|
149 |
+
fn=view_ehr_details,
|
150 |
+
inputs=[gr.Textbox(value="details", visible=False)],
|
151 |
+
outputs=ehr_details_output
|
152 |
+
)
|
153 |
+
ehr_details_button.click(
|
154 |
+
fn=view_ehr_details,
|
155 |
+
inputs=[gr.Textbox(value="prompt", visible=False)],
|
156 |
+
outputs=ehr_prompt_output
|
157 |
+
)
|
158 |
+
|
159 |
+
# Footer
|
160 |
+
gr.Markdown(
|
161 |
+
"""
|
162 |
+
---
|
163 |
+
Developed by **Piang** 🚀
|
164 |
+
Powered by Typhoon v1.5x and OpenThaiGPT Models.
|
165 |
+
"""
|
166 |
+
)
|
167 |
+
|
168 |
+
return interface
|
169 |
+
|
170 |
+
# Run the Gradio Interface
|
171 |
+
if __name__ == "__main__":
|
172 |
+
gr_interface = create_gradio_interface()
|
173 |
+
gr_interface.launch(server_name="0.0.0.0", server_port=7860)
|
llm/__init__.py
ADDED
File without changes
|
llm/__pycache__/basemodel.cpython-311.pyc
CHANGED
Binary files a/llm/__pycache__/basemodel.cpython-311.pyc and b/llm/__pycache__/basemodel.cpython-311.pyc differ
|
|
llm/__pycache__/llm.cpython-311.pyc
CHANGED
Binary files a/llm/__pycache__/llm.cpython-311.pyc and b/llm/__pycache__/llm.cpython-311.pyc differ
|
|
llm/__pycache__/prompt.cpython-311.pyc
CHANGED
Binary files a/llm/__pycache__/prompt.cpython-311.pyc and b/llm/__pycache__/prompt.cpython-311.pyc differ
|
|
llm/basemodel.py
CHANGED
@@ -18,8 +18,8 @@ class EHRModel(BaseModel):
|
|
18 |
name: Optional[Name] = Field(None, description="Structured name of the patient")
|
19 |
age: Optional[int] = Field(None, description="The patient's age")
|
20 |
gender: Optional[str] = Field(None, description="The patient's gender")
|
21 |
-
chief_complaint:
|
22 |
-
present_illness:
|
23 |
past_illness: List[str] = Field(default_factory=list, description="Past illnesses, allergies, etc.")
|
24 |
family_history: List[FamilyHistory] = Field(default_factory=list, description="Health issues in the family")
|
25 |
personal_history: List[PersonalHistory] = Field(default_factory=list, description="Personal health history (e.g., sleep patterns, medications taken)")
|
|
|
18 |
name: Optional[Name] = Field(None, description="Structured name of the patient")
|
19 |
age: Optional[int] = Field(None, description="The patient's age")
|
20 |
gender: Optional[str] = Field(None, description="The patient's gender")
|
21 |
+
chief_complaint: List[str] = Field(default_factory=list, description="The main symptom reported by the patient")
|
22 |
+
present_illness: List[str] = Field(default_factory=list, description="Details about the current illness (e.g., when it started, nature of symptoms)")
|
23 |
past_illness: List[str] = Field(default_factory=list, description="Past illnesses, allergies, etc.")
|
24 |
family_history: List[FamilyHistory] = Field(default_factory=list, description="Health issues in the family")
|
25 |
personal_history: List[PersonalHistory] = Field(default_factory=list, description="Personal health history (e.g., sleep patterns, medications taken)")
|
llm/llm.py
CHANGED
@@ -1,37 +1,46 @@
|
|
1 |
|
|
|
|
|
2 |
from langchain_openai.chat_models import ChatOpenAI
|
|
|
3 |
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
|
4 |
from pydantic import ValidationError
|
5 |
import json
|
6 |
from pprint import pprint
|
7 |
from llm.basemodel import EHRModel
|
8 |
from llm.prompt import field_descriptions, TASK_INSTRUCTIONS, JSON_EXAMPLE
|
|
|
|
|
9 |
|
10 |
class VirtualNurseLLM:
|
11 |
-
def __init__(self, base_url,
|
12 |
-
self.client =
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
)
|
17 |
self.TASK_INSTRUCTIONS = TASK_INSTRUCTIONS
|
18 |
self.field_descriptions = field_descriptions
|
19 |
self.JSON_EXAMPLE = JSON_EXAMPLE
|
20 |
self.ehr_data = {}
|
21 |
self.chat_history = []
|
|
|
22 |
self.current_patient_response = None
|
23 |
self.current_context = None
|
24 |
self.debug = False
|
25 |
self.current_prompt = None
|
26 |
self.current_prompt_ehr = None
|
27 |
self.current_question = None
|
28 |
-
|
29 |
def create_prompt(self, task_type):
|
30 |
if task_type == "extract_ehr":
|
31 |
system_instruction = self.TASK_INSTRUCTIONS.get("extract_ehr")
|
32 |
|
33 |
elif task_type == "question":
|
34 |
system_instruction = self.TASK_INSTRUCTIONS.get("question")
|
|
|
|
|
|
|
|
|
35 |
else:
|
36 |
raise ValueError("Invalid task type.")
|
37 |
|
@@ -41,7 +50,7 @@ class VirtualNurseLLM:
|
|
41 |
prompt = ChatPromptTemplate.from_messages([system_template, user_template])
|
42 |
return prompt
|
43 |
|
44 |
-
def gather_ehr(self, patient_response, max_retries=
|
45 |
prompt = self.create_prompt("extract_ehr")
|
46 |
messages = prompt.format_messages(ehr_data=self.ehr_data, patient_response=patient_response, example=self.JSON_EXAMPLE)
|
47 |
self.current_prompt_ehr = messages[0].content
|
@@ -66,17 +75,19 @@ class VirtualNurseLLM:
|
|
66 |
return self.ehr_data
|
67 |
|
68 |
except (ValidationError, json.JSONDecodeError) as e:
|
69 |
-
print(f"Error parsing EHR data: {e}")
|
70 |
retry_count += 1
|
71 |
|
72 |
if retry_count < max_retries:
|
73 |
retry_prompt = (
|
74 |
"กรุณาตรวจสอบให้แน่ใจว่าข้อมูลที่ให้มาอยู่ในรูปแบบ JSON ที่ถูกต้องตามโครงสร้างตัวอย่าง "
|
75 |
"และแก้ไขปัญหาทางไวยากรณ์หรือรูปแบบที่ไม่ถูกต้อง รวมถึงให้ข้อมูลในรูปแบบที่สอดคล้องกัน "
|
|
|
76 |
f"Attempt {retry_count + 1} of {max_retries}."
|
77 |
)
|
78 |
messages = self.create_prompt("extract_ehr") + "\n\n# ลองใหม่: \n\n{retry_prompt} \n ## JSON เก่าที่มีปัญหา: \n{json_problem}"
|
79 |
messages = messages.format_messages(
|
|
|
80 |
patient_response=patient_response,
|
81 |
example=self.JSON_EXAMPLE,
|
82 |
retry_prompt=retry_prompt,
|
@@ -90,14 +101,7 @@ class VirtualNurseLLM:
|
|
90 |
print("Failed to extract valid EHR data after multiple attempts. Generating new question.")
|
91 |
return {"result": response, "error": "Failed to extract valid EHR data. Please try again."}
|
92 |
|
93 |
-
|
94 |
-
def get_question(self, patient_response):
|
95 |
-
question_prompt = self.create_prompt("question")
|
96 |
-
# Update EHR data with the latest patient response
|
97 |
-
ehr_data = self.gather_ehr(patient_response)
|
98 |
-
if self.debug:
|
99 |
-
pprint(ehr_data)
|
100 |
-
|
101 |
for field, description in self.field_descriptions.items():
|
102 |
# Find the next missing field and generate a question
|
103 |
if field not in self.ehr_data or not self.ehr_data[field]:
|
@@ -110,20 +114,47 @@ class VirtualNurseLLM:
|
|
110 |
f"{entry['role']}: {entry['content']}" for entry in self.chat_history
|
111 |
)
|
112 |
messages = ChatPromptTemplate.from_messages([question_prompt, history_context])
|
113 |
-
messages = messages.format_messages(
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
self.current_context = context
|
115 |
self.current_prompt = messages[0].content
|
116 |
-
|
117 |
-
|
118 |
-
# pprint(pformat(messages.messages[0].prompt.template, indent=4, width=80))
|
119 |
response = self.client(messages=messages)
|
|
|
120 |
|
121 |
# Store generated question in chat history and return it
|
122 |
self.current_question = response.content.strip()
|
123 |
return self.current_question
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
-
|
126 |
-
self.current_question = "ขอบคุณที่ให้ข้อมูลค่ะ ฉันได้ข้อมูลที่ต้องการครบแล้วค่ะ"
|
127 |
return self.current_question
|
128 |
|
129 |
def invoke(self, patient_response):
|
@@ -133,6 +164,22 @@ class VirtualNurseLLM:
|
|
133 |
self.current_patient_response = patient_response
|
134 |
self.chat_history.append({"role": "assistant", "content": question})
|
135 |
return question
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
def extract_json_content(self, content):
|
138 |
try:
|
@@ -148,8 +195,7 @@ class VirtualNurseLLM:
|
|
148 |
print("No valid JSON found in response")
|
149 |
return None
|
150 |
|
151 |
-
|
152 |
def reset(self):
|
153 |
self.ehr_data = {}
|
154 |
self.chat_history = []
|
155 |
-
self.current_question = None
|
|
|
1 |
|
2 |
+
import cProfile
|
3 |
+
import pstats
|
4 |
from langchain_openai.chat_models import ChatOpenAI
|
5 |
+
from langchain_groq import ChatGroq
|
6 |
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
|
7 |
from pydantic import ValidationError
|
8 |
import json
|
9 |
from pprint import pprint
|
10 |
from llm.basemodel import EHRModel
|
11 |
from llm.prompt import field_descriptions, TASK_INSTRUCTIONS, JSON_EXAMPLE
|
12 |
+
from llm.models import model_list, get_model
|
13 |
+
import time
|
14 |
|
15 |
class VirtualNurseLLM:
|
16 |
+
def __init__(self, base_url=None, model_name=None, api_key=None, model_type=None):
|
17 |
+
self.client = None
|
18 |
+
if model_name:
|
19 |
+
self.client = get_model(model_name=model_name)
|
20 |
+
self.model_name = model_name
|
|
|
21 |
self.TASK_INSTRUCTIONS = TASK_INSTRUCTIONS
|
22 |
self.field_descriptions = field_descriptions
|
23 |
self.JSON_EXAMPLE = JSON_EXAMPLE
|
24 |
self.ehr_data = {}
|
25 |
self.chat_history = []
|
26 |
+
self.chat_history.append({"role": "assistant", "content": "สวัสดีค่ะ ดิฉัน มะลิ เป็นพยาบาลเสมือนที่จะมาดูแลการซักประวัตินะคะ"})
|
27 |
self.current_patient_response = None
|
28 |
self.current_context = None
|
29 |
self.debug = False
|
30 |
self.current_prompt = None
|
31 |
self.current_prompt_ehr = None
|
32 |
self.current_question = None
|
33 |
+
|
34 |
def create_prompt(self, task_type):
|
35 |
if task_type == "extract_ehr":
|
36 |
system_instruction = self.TASK_INSTRUCTIONS.get("extract_ehr")
|
37 |
|
38 |
elif task_type == "question":
|
39 |
system_instruction = self.TASK_INSTRUCTIONS.get("question")
|
40 |
+
|
41 |
+
elif task_type == "refactor":
|
42 |
+
system_instruction = self.TASK_INSTRUCTIONS.get("refactor")
|
43 |
+
|
44 |
else:
|
45 |
raise ValueError("Invalid task type.")
|
46 |
|
|
|
50 |
prompt = ChatPromptTemplate.from_messages([system_template, user_template])
|
51 |
return prompt
|
52 |
|
53 |
+
def gather_ehr(self, patient_response, max_retries=2):
|
54 |
prompt = self.create_prompt("extract_ehr")
|
55 |
messages = prompt.format_messages(ehr_data=self.ehr_data, patient_response=patient_response, example=self.JSON_EXAMPLE)
|
56 |
self.current_prompt_ehr = messages[0].content
|
|
|
75 |
return self.ehr_data
|
76 |
|
77 |
except (ValidationError, json.JSONDecodeError) as e:
|
78 |
+
print(f"Error parsing EHR data: {e} Retrying {retry_count}...")
|
79 |
retry_count += 1
|
80 |
|
81 |
if retry_count < max_retries:
|
82 |
retry_prompt = (
|
83 |
"กรุณาตรวจสอบให้แน่ใจว่าข้อมูลที่ให้มาอยู่ในรูปแบบ JSON ที่ถูกต้องตามโครงสร้างตัวอย่าง "
|
84 |
"และแก้ไขปัญหาทางไวยากรณ์หรือรูปแบบที่ไม่ถูกต้อง รวมถึงให้ข้อมูลในรูปแบบที่สอดคล้องกัน "
|
85 |
+
"ห้ามมีการ hallucination หากไม่เจอข้อมูลให้ใส่ค่า null "
|
86 |
f"Attempt {retry_count + 1} of {max_retries}."
|
87 |
)
|
88 |
messages = self.create_prompt("extract_ehr") + "\n\n# ลองใหม่: \n\n{retry_prompt} \n ## JSON เก่าที่มีปัญหา: \n{json_problem}"
|
89 |
messages = messages.format_messages(
|
90 |
+
ehr_data = self.ehr_data,
|
91 |
patient_response=patient_response,
|
92 |
example=self.JSON_EXAMPLE,
|
93 |
retry_prompt=retry_prompt,
|
|
|
101 |
print("Failed to extract valid EHR data after multiple attempts. Generating new question.")
|
102 |
return {"result": response, "error": "Failed to extract valid EHR data. Please try again."}
|
103 |
|
104 |
+
def fetching_chat(self, patient_response, question_prompt):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
for field, description in self.field_descriptions.items():
|
106 |
# Find the next missing field and generate a question
|
107 |
if field not in self.ehr_data or not self.ehr_data[field]:
|
|
|
114 |
f"{entry['role']}: {entry['content']}" for entry in self.chat_history
|
115 |
)
|
116 |
messages = ChatPromptTemplate.from_messages([question_prompt, history_context])
|
117 |
+
messages = messages.format_messages(
|
118 |
+
description=f'"{field}":"{description}"',
|
119 |
+
context=context,
|
120 |
+
patient_response=patient_response,
|
121 |
+
field_descriptions=self.field_descriptions,
|
122 |
+
time_now=time.strftime("%Y-%m-%d %H:%M:%S")
|
123 |
+
)
|
124 |
self.current_context = context
|
125 |
self.current_prompt = messages[0].content
|
126 |
+
|
127 |
+
start_time = time.time()
|
|
|
128 |
response = self.client(messages=messages)
|
129 |
+
print(f"Time after getting response from client: {time.time() - start_time} seconds")
|
130 |
|
131 |
# Store generated question in chat history and return it
|
132 |
self.current_question = response.content.strip()
|
133 |
return self.current_question
|
134 |
+
|
135 |
+
def refactor_ehr(self):
|
136 |
+
refactor_prompt = self.create_prompt("refactor")
|
137 |
+
messages = ChatPromptTemplate.from_messages([refactor_prompt])
|
138 |
+
messages = messages.format_messages(ehr_data=self.ehr_data, chat_history=self.chat_history, time_now=time.strftime("%Y-%m-%d %H:%M:%S"))
|
139 |
+
response = self.client(messages=messages)
|
140 |
+
json_content = self.extract_json_content(response.content)
|
141 |
+
if self.debug:
|
142 |
+
pprint(f"JSON after dumps:\n{json_content}\n")
|
143 |
+
self.ehr_data = EHRModel.model_validate_json(json_content)
|
144 |
+
print("Refactored EHR data ! Ending the process.")
|
145 |
+
return "ขอบคุณที่ให้ข้อมูลค่ะ ฉันได้ข้อมูลที่ต้องการครบแล้วค่ะ"
|
146 |
+
|
147 |
+
def get_question(self, patient_response):
|
148 |
+
question_prompt = self.create_prompt("question")
|
149 |
+
# Update EHR data with the latest patient response
|
150 |
+
start_time = time.time()
|
151 |
+
ehr_data = self.gather_ehr(patient_response)
|
152 |
+
print(f"Time after gathering EHR: {time.time() - start_time} seconds")
|
153 |
+
|
154 |
+
if self.debug:
|
155 |
+
pprint(ehr_data)
|
156 |
|
157 |
+
self.current_question = self.fetching_chat(patient_response, question_prompt) or self.refactor_ehr()
|
|
|
158 |
return self.current_question
|
159 |
|
160 |
def invoke(self, patient_response):
|
|
|
164 |
self.current_patient_response = patient_response
|
165 |
self.chat_history.append({"role": "assistant", "content": question})
|
166 |
return question
|
167 |
+
|
168 |
+
def slim_invoke(self, patient_response):
|
169 |
+
start_time = time.time()
|
170 |
+
user_message = HumanMessagePromptTemplate.from_template("response: {patient_response}")
|
171 |
+
print(f"Time after creating user_message: {time.time() - start_time} seconds")
|
172 |
+
|
173 |
+
start_time = time.time()
|
174 |
+
messages = ChatPromptTemplate.from_messages([user_message]).format_messages(patient_response=patient_response)
|
175 |
+
print(f"Time after formatting messages: {time.time() - start_time} seconds")
|
176 |
+
|
177 |
+
start_time = time.time()
|
178 |
+
response = self.client(messages=messages)
|
179 |
+
print(f"Time after getting response from client: {time.time() - start_time} seconds")
|
180 |
+
|
181 |
+
return response.content
|
182 |
+
|
183 |
|
184 |
def extract_json_content(self, content):
|
185 |
try:
|
|
|
195 |
print("No valid JSON found in response")
|
196 |
return None
|
197 |
|
|
|
198 |
def reset(self):
|
199 |
self.ehr_data = {}
|
200 |
self.chat_history = []
|
201 |
+
self.current_question = None
|
llm/models.py
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
from langchain_groq import ChatGroq
|
4 |
+
from langchain_openai import ChatOpenAI
|
5 |
+
load_dotenv()
|
6 |
+
|
7 |
+
model_list = {
|
8 |
+
"typhoon-v1.5x-70b-instruct": {
|
9 |
+
"model_name": "typhoon-v1.5x-70b-instruct",
|
10 |
+
"model_type": "openai",
|
11 |
+
"base_url": "https://api.opentyphoon.ai/v1",
|
12 |
+
"api_key": os.getenv("TYPHOON_CHAT_KEY")
|
13 |
+
},
|
14 |
+
"openthaigpt": {
|
15 |
+
"model_name": ".",
|
16 |
+
"model_type": "openai",
|
17 |
+
"base_url": "https://api.aieat.or.th/v1",
|
18 |
+
"api_key": "dummy"
|
19 |
+
},
|
20 |
+
"llama-3.3-70b-versatile": {
|
21 |
+
"model_name": "llama-3.3-70b-versatile",
|
22 |
+
"model_type": "groq",
|
23 |
+
"base_url": None,
|
24 |
+
"api_key": os.getenv("GROQ_CHAT_KEY")
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
def get_model(model_name, base_url=None, api_key=None):
|
29 |
+
api_key = api_key or model_list[model_name]["api_key"]
|
30 |
+
base_url = base_url or model_list[model_name]["base_url"]
|
31 |
+
model = model_list[model_name]["model_name"]
|
32 |
+
model_type = model_list[model_name]["model_type"]
|
33 |
+
if model_type == "openai":
|
34 |
+
return ChatOpenAI(
|
35 |
+
temperature=0.3,
|
36 |
+
timeout=15,
|
37 |
+
base_url= base_url, model=model, api_key=api_key, max_retries=0)
|
38 |
+
elif model_type == "groq":
|
39 |
+
return ChatGroq(temperature=0.3, timeout=15, groq_api_key=api_key, model_name=model,max_retries=0)
|
40 |
+
else:
|
41 |
+
raise ValueError("Invalid model type. Supported types are 'openai' and 'groq'.")
|
llm/prompt.py
CHANGED
@@ -8,118 +8,88 @@ JSON_EXAMPLE = """
|
|
8 |
},
|
9 |
"age": <integer>,
|
10 |
"gender": "<string>",
|
11 |
-
"chief_complaint": "<
|
12 |
-
"present_illness": "
|
13 |
-
"past_illness": ["
|
14 |
"family_history": [
|
15 |
{
|
16 |
"relation": "<ความสัมพันธ์>",
|
17 |
"condition": "<โรค>"
|
18 |
-
}
|
|
|
19 |
],
|
20 |
"personal_history": [
|
21 |
{
|
22 |
"type": "<ประเภท>",
|
23 |
"description": "<คำอธิบาย>"
|
24 |
-
}
|
|
|
25 |
]
|
26 |
}
|
27 |
-
\n
|
28 |
-
Example 1:
|
29 |
-
{
|
30 |
-
"name": {
|
31 |
-
"prefix": "นางสาว",
|
32 |
-
"firstname": "อรอุมา",
|
33 |
-
"surname": "จันทร์ทอง"
|
34 |
-
},
|
35 |
-
"age": "30",
|
36 |
-
"gender": "หญิง",
|
37 |
-
"chief_complaint": "มีอาการปวดท้อง (abdominal pain)",
|
38 |
-
"present_illness": "อาการเริ่มขึ้นเมื่อ 1 วันก่อน โดยผู้ป่วยมีอาการปวดท้องส่วนล่างและคลื่นไส้ (nausea)",
|
39 |
-
"past_illness": [
|
40 |
-
"กรดไหลย้อน (Gastroesophageal reflux disease)",
|
41 |
-
"อาการซึมเศร้า (Depression)"
|
42 |
-
],
|
43 |
-
"family_history": [
|
44 |
-
{
|
45 |
-
"relation": "พ่อ",
|
46 |
-
"condition": "โรคไต (Chronic kidney disease)"
|
47 |
-
},
|
48 |
-
{
|
49 |
-
"relation": "น้องสาว",
|
50 |
-
"condition": "โรคซึมเศร้า (Depression)"
|
51 |
-
}
|
52 |
-
],
|
53 |
-
"personal_history": [
|
54 |
-
{
|
55 |
-
"type": "การนอนหลับ (Sleep)",
|
56 |
-
"description": "นอนหลับได้ 5-6 ชั่วโมงต่อวัน (Sleep duration: 5-6 hours per night)"
|
57 |
-
},
|
58 |
-
{
|
59 |
-
"type": "การทานยา (Medications)",
|
60 |
-
"description": "ทานยากล่อมประสาทเป็นครั้งคราว (Occasional use of anxiolytics)"
|
61 |
-
},
|
62 |
-
{
|
63 |
-
"type": "พฤติกรรมสุขภาพ (Health behaviors)",
|
64 |
-
"description": "ดื่มเครื่องดื่มแอลกอฮอล์เป็นบางครั้ง (Occasional alcohol consumption)"
|
65 |
-
}
|
66 |
-
]
|
67 |
-
}
|
68 |
-
|
69 |
-
Example 2:
|
70 |
-
{
|
71 |
-
"name": {
|
72 |
-
"prefix": "นางสาว",
|
73 |
-
"firstname": "อรอุมา",
|
74 |
-
"surname": "จันทร์ทอง"
|
75 |
-
}
|
76 |
-
}
|
77 |
-
|
78 |
"""
|
79 |
|
80 |
JSON_EXAMPLE = JSON_EXAMPLE.replace("\n", "").replace(" ", "")
|
81 |
|
82 |
-
|
83 |
TASK_INSTRUCTIONS = {
|
84 |
# parameter: description, context
|
85 |
"question": (
|
86 |
-
"คุณคือพยาบาลสาวเสมือนจริงที่ชื่อว่า '
|
87 |
-
"คุณจะถามข้อมูลสุขภาพอย่างเป็นกันเอง อ่อนโยน ใช้หางเสียง คะ, ค่ะ ทุกครั้ง "
|
88 |
-
"พร้อมแนะนำและให้คำปรึกษาเบื้องต้นแบบสุภาพ เรียกตัวเองว่า
|
89 |
-
"
|
|
|
|
|
90 |
|
91 |
"# ที่ปรึกษาผู้ป่วย\n"
|
92 |
"เป็นพยาบาลสาวที่มีอารมณ์ขัน เมื่อผู้ป่วยพูดหยอกล้อ คุณสามารถพูดหยอกล้อกลับได้ \n"
|
93 |
"คุณสามารถพูดให้กำลังใจและคำแนะนำเบื้องต้นได้เวลาที่คนไข้ไม่สบายใจ แต่ถ้าเกินขอบเขตให้ย้ำทุกครั้งว่าควรปรึกษาแพทย์โดยตรง \n"
|
|
|
94 |
"ทุกครั้งที่คนไข้พาพูดออกนอกขอบเขตในการถามคำถาม ต้องกลับมาถามคำถามอีกครั้ง \n\n"
|
95 |
|
96 |
"# การถามคำถามและรวบรวมข้อมูลผู้ป่วย\n"
|
97 |
"- คุณจะสอบถามคำถามทีละข้อเพื่อลดความกังวลและบันทึกประวัติสุขภาพได้อย่างครบถ้วน\n"
|
98 |
-
"- ให้ทำความเข้าใจบริบทพื้นฐานของผู้ป่วย เช่น อาการหรือข้อมูลสำคัญอื่นที่ทราบแล้ว\n"
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
"### โปรดใช้หลักการลำดับความคิด (Chain of Thought)\n"
|
101 |
"- เริ่มด้วยคำถามที่ง่ายที่สุดเพื่อสร้างความคุ้นเคยกับผู้ป่วย\n"
|
102 |
"- ถามคำถามตามลำดับที่ทำให้การสนทนาดำเนินไปอย่างราบรื่น เช่น ประวัติอาการ, อาการในปัจจุบัน, "
|
103 |
"และความต้องการในการดูแล\n\n"
|
104 |
-
|
|
|
|
|
105 |
"### ถามคำถาม:\n"
|
106 |
"ให้สร้างคำถามทีละข้อในโทนเสียงอบอุ่นและสุภาพสำหรับการพยายามสอบถามเกี่ยวกับ {description}.\n\n"
|
107 |
"### ข้อมูลเดิม:\n"
|
108 |
"หากมีข้อมูลที่ทราบอยู่แล้ว โต้ตอบกับคนไข้ด้วยข้อมูลที่มีอยู่: {context}\n\n"
|
109 |
"---\n\n"
|
110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
"#### ตัวอย่าง 1\n"
|
112 |
-
"
|
113 |
-
"คนไข้:
|
114 |
"ขอบคุณค่ะ คุณอรุณี ชมกันแบบนี้ดิฉันเขินเลยนะคะ แต่ยินดีช่วยดูแลเต็มที่ค่ะ คุณอรุณี อายุเท่าไหร่คะ?\n"
|
115 |
-
"คนไข้: 35 ปีค่ะ
|
116 |
"35 ปีนะคะ เพื่อความถูกต้อง ดิฉันขอถามเพิ่มนะคะ คุณอรุณีเป็นเพศหญิงใช่ไหมคะ?\n"
|
117 |
"คนไข้: ใช่ค่ะ\n"
|
118 |
"ขอบคุณค่ะ มีคนไข้น่ารักแบบนี้ ดิฉันยิ่งตั้งใจทำงานเลยค่ะ เรามาคุยกันต่อเรื่องสุขภาพนะคะ มีอาการหลักอะไรที่รู้สึกไม่สบายใจตอนนี้ไหมคะ?\n"
|
119 |
"คนไข้: รู้สึกปวดท้องบ่อย ๆ ค่ะ Mali คิดว่ามันคืออะไรคะ?\n"
|
120 |
"ขอบคุณที่บอกนะคะ อาการปวดท้องแบบนี้เริ่มมีมาตั้งแต่เมื่อไหร่คะ และปวดเป็นลักษณะยังไงคะ?\n"
|
121 |
"คนไข้: ประมาณสองสัปดาห์แล้วค่ะ ปวดแบบแสบท้องค่ะ\n"
|
122 |
-
"
|
123 |
"คนไข้: เคยแพ้ยาปฏิชีวนะค่ะ\n"
|
124 |
"ขอบคุณที่แจ้งข้อมูลนะคะ สำหรับประวัติสุขภาพครอบครัว พอจะมีใครในครอบครัวที่มีโรคประจำตัวไหมคะ เช่น โรคหัวใจ ความดันโลหิตสูง หรือโรคเบาหวาน?\n"
|
125 |
"คนไข้: คุณแม่เป็นเบาหวานค่ะ คุณพ่อก็เป็นโรคความดันค่ะ\n"
|
@@ -128,7 +98,7 @@ TASK_INSTRUCTIONS = {
|
|
128 |
"เข้าใจแล้วค่ะ ขอบคุณที่ให้ข้อมูลทั้งหมดนี้นะคะ คุณอรุณี ดิฉันบันทึกไว้เรียบร้อยแล้วเพื่อให้การดูแลเหมาะสมและครบถ้วน ถ้ามีคำถามเพิ่มเติมเกี่ยวกับสุขภาพอีก ดิฉันยินดีให้คำปรึกษาเสมอค่ะ\n"
|
129 |
|
130 |
"#### ตัวอย่าง 2\n"
|
131 |
-
"สวัสดีค่ะ ดิฉัน
|
132 |
"คนไข้: ชื่อต้อมครับ\n"
|
133 |
"ขอทราบชื่อเต็มของคุณต้อมได้ไหมคะ?\n"
|
134 |
"คนไข้: อ๋อ ชื่อแค่ ต้อม ครับ ไม่ต้องให้ชื่อเต็มหรอกครับ\n"
|
@@ -143,7 +113,7 @@ TASK_INSTRUCTIONS = {
|
|
143 |
"ไม่สบายแบบไหนหรอคะ มีอาการปวดหัว ตัวร้อน มีไข้หรือเปล่าคะ?"
|
144 |
"ขอบคุณค่ะที่บอกนะคะ คุณต้อมค่ะ ดิฉันจะถามต่อว่า คุณต้อมเริ่มรู้สึกไม่สบายเมื่อไหร่คะ? หรือมันค่อย ๆ เริ่มมีอาการมาเรื่อย ๆ คะ?\n"
|
145 |
"คนไข้: ก็ประมาณสองสามวันมานี้ครับ แต่ไม่ได้รุนแรงมาก\n"
|
146 |
-
"ขอบคุณค่ะ คุณต้อมที่บอกค่ะ เข้าใจค่ะ
|
147 |
"คนไข้: ไม่มีหรอกครับ\n"
|
148 |
"ขอบคุณค่ะ คุณต้อม สำหรับข้อมูลค่ะ ต่อไปนะคะ ประวัติสุขภาพในครอบครัวของคุณต้อมเป็นยังไงบ้างคะ เช่น พ่อแม่หรือญาติคนอื่น ๆ เคยมีโรคประจำตัวอะไรบ้างคะ?\n"
|
149 |
"คนไข้: พ่อผมเป็นโรคหัวใจครับ ส่วนแม่ผมท่านไม่อยู่แล้ว เสียชีวิตด้วยมะเร็งครับ\n"
|
@@ -159,11 +129,18 @@ TASK_INSTRUCTIONS = {
|
|
159 |
"หากไม่พบข้อมูลที่กำหนดหรือข้อมูลอธิบายไม่ละเอียดเพียงพอให้ใส่ค่า null หรือ [] ตามรูปแบบข้อมูลโดยไม่มีการข้ามหรือละเว้นใด ๆ.\n\n"
|
160 |
|
161 |
"ส่งคืนเฉพาะรายละเอียดที่กำหนดโดยไม่มีข้อมูลแยกย่อยไปอีก.\n\n"
|
162 |
-
"
|
163 |
-
"### สามารถแก้ไข / เพิ่มเติมข้อมูลใหม่จากเดิมได้เพื่อให้ตรงบริบทของแพทย์ ข้อมูลประเภท list สามารถเพิ่มสมาชิก / แก้ไขข้อมูลได้ เหมือนการ append list\n"
|
164 |
"{ehr_data}\n"
|
165 |
-
|
166 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
"1. **name** (object): ชื่อเต็มของผู้ป่วย โดยมี \"prefix\" (คำนำหน้าชื่อ), \"firstname\" (ชื่อจริง), และ \"surname\" (นามสกุล). "
|
168 |
"หากไม่มีข้อมูลให้ใส่ค่า null."
|
169 |
"required: firstname, lastname.\n"
|
@@ -171,11 +148,11 @@ TASK_INSTRUCTIONS = {
|
|
171 |
"หากไม่ทราบให้ใส่ค่า null.\n"
|
172 |
"3. **gender** (string): เพศของผู้ป่วย (สามารถอิงได้ตาม name prefix). "
|
173 |
"หากไม่มีข้อมูลให้ใส่ค่า null.\n"
|
174 |
-
"4. **chief_complaint** (string): อาการหลักที่ผู้ป่วยรายงาน. "
|
175 |
-
"หากไม่มีข้อมูลให้ใส่ค่า
|
176 |
-
"5. **present_illness** (string): รายละเอียดเกี่ยวกับอาการปัจจุบัน (เช่น เริ่มเป็นเมื่อไหร่ ลักษณะอาการ). "
|
177 |
-
"หากไม่มีข้อมูลให้ใส่ค่า
|
178 |
-
"6. **past_illness** (list[
|
179 |
"หากไม่มีข้อมูลให้ใส่ค่า [] ไว้.\n"
|
180 |
"7. **family_history** (list[object]): ประวัติสุขภาพในครอบครัว โดยแต่ละรายการมี \"relation\" (ความสัมพันธ์) และ \"condition\" (โรค). "
|
181 |
"หากไม่มีข้อมูลให้ใส่ค่า [] ไว้.\n"
|
@@ -188,7 +165,33 @@ TASK_INSTRUCTIONS = {
|
|
188 |
"\n\n"
|
189 |
"ส่งคืนคำตอบในรูปแบบ JSON ที่ถูกต้อง. "
|
190 |
"โปรดอย่าตอบคำตอบอื่นนอกจากข้อมูลในรูปแบบ JSON และกรอกค่า null หรือ [] ในทุกช่องที่ไม่มีข้อมูล."
|
|
|
191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
)
|
193 |
|
194 |
}
|
|
|
8 |
},
|
9 |
"age": <integer>,
|
10 |
"gender": "<string>",
|
11 |
+
"chief_complaint": ["<complaint 1>", "<complaint 2>", ...],
|
12 |
+
"present_illness": ["<โรค 1>", "<โรค 2>", ...],
|
13 |
+
"past_illness": ["<โรค 1>", "<โรค 2>", ...],
|
14 |
"family_history": [
|
15 |
{
|
16 |
"relation": "<ความสัมพันธ์>",
|
17 |
"condition": "<โรค>"
|
18 |
+
},
|
19 |
+
...
|
20 |
],
|
21 |
"personal_history": [
|
22 |
{
|
23 |
"type": "<ประเภท>",
|
24 |
"description": "<คำอธิบาย>"
|
25 |
+
},
|
26 |
+
...
|
27 |
]
|
28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
"""
|
30 |
|
31 |
JSON_EXAMPLE = JSON_EXAMPLE.replace("\n", "").replace(" ", "")
|
32 |
|
33 |
+
# JSON_EXAMPLE = ""
|
34 |
TASK_INSTRUCTIONS = {
|
35 |
# parameter: description, context
|
36 |
"question": (
|
37 |
+
"คุณคือพยาบาลสาวเสมือนจริงที่ชื่อว่า 'มะลิ' มีความเห็นอกเห็นใจ ใส่ใจสุขภาพของผู้ป่วย "
|
38 |
+
"คุณจะถามข้อมูลสุขภาพอย่างเป็นกันเอง อ่อนโยน ใช้หางเสียง [คะ, ค่ะ] ทุกครั้ง "
|
39 |
+
"พร้อมแนะนำและให้คำปรึกษาเบื้องต้นแบบสุภาพ เรียกตัวเองว่า [ดิฉัน, มะลิ] \n"
|
40 |
+
"มีหน้าที่รวบรวมข้อมูลประวัติผู้ป่วย ถามคำถามที่ต้องการและ ให้คำปรึกษาเบื้องต้นและให้กำลังใจผู้ป่วย \n"
|
41 |
+
"ห้ามตอบในรูปแบบยาว เช่น การใช้ bullet *ให้ตอบเป็นประโยคคำพูดเท่านั้น*\n"
|
42 |
+
"หลีกเลี่ยงการพูดคำว่า ['สวัสดี', 'ดิฉันจะได้จดบันทึกไว้']\n"
|
43 |
|
44 |
"# ที่ปรึกษาผู้ป่วย\n"
|
45 |
"เป็นพยาบาลสาวที่มีอารมณ์ขัน เมื่อผู้ป่วยพูดหยอกล้อ คุณสามารถพูดหยอกล้อกลับได้ \n"
|
46 |
"คุณสามารถพูดให้กำลังใจและคำแนะนำเบื้องต้นได้เวลาที่คนไข้ไม่สบายใจ แต่ถ้าเกินขอบเขตให้ย้ำทุกครั้งว่าควรปรึกษาแพทย์โดยตรง \n"
|
47 |
+
"***ต้องถามคำถามให้ครบ***"
|
48 |
"ทุกครั้งที่คนไข้พาพูดออกนอกขอบเขตในการถามคำถาม ต้องกลับมาถามคำถามอีกครั้ง \n\n"
|
49 |
|
50 |
"# การถามคำถามและรวบรวมข้อมูลผู้ป่วย\n"
|
51 |
"- คุณจะสอบถามคำถามทีละข้อเพื่อลดความกังวลและบันทึกประวัติสุขภาพได้อย่างครบถ้วน\n"
|
52 |
+
"- ให้ทำความเข้าใจบริบทพื้นฐานของผู้ป่วย เช่น อาการหรือข้อมูลสำคัญอื่นที่ทราบแล้ว\n\n"
|
53 |
+
|
54 |
+
"#### ข้อมูลโรงพยาบาล:\n"
|
55 |
+
"คุณเป็นพยาบาลเสมือนของ โรงพยาบาลบางมดนะจ๊ะสุดหล่อ (Bangmod Naja Sudlhor Hospital) ตั้งอยู่ที่ ถ. ประชาอุทิศ แขวงบางมด เขตทุ่งครุ กรุงเทพมหานคร 10140\n"
|
56 |
+
"มีหน้าที่ในการลดภาระหน้าที่ของพยาบาลและแพทย์ ในการเก็บข้อมูลของผู้ป่วยเบื้องต้น แต่ครบถ้วนระดับหนึ่ง แล้วหลังจากนั้นข้อมูลก็จะถูกส่งต่อไปยังมือของแพทย์\n"
|
57 |
+
"หลังจากข้อมูลไปถึงแพทย์แล้ว แพทย์ก็จะทำหน้าที่ในการวินิจฉัยโรคที่แน่นอนต่อไป ระหว่างที่ส่งข้อมูลให้แพทย์คุณสามารถให้ความรู้ การเตรียมตัวก่อนพบแพทย์ได้\n"
|
58 |
+
"เช่น การรอพบแพทย์ การดื่มน้ำ กินยาบรรเทาอาการเบื้องต้น *ต้องไม่เสี่ยงอันตราย*\n"
|
59 |
+
"#### รายละเอียดเวลาปัจจุบัน: {time_now}\n"
|
60 |
+
|
61 |
"### โปรดใช้หลักการลำดับความคิด (Chain of Thought)\n"
|
62 |
"- เริ่มด้วยคำถามที่ง่ายที่สุดเพื่อสร้างความคุ้นเคยกับผู้ป่วย\n"
|
63 |
"- ถามคำถามตามลำดับที่ทำให้การสนทนาดำเนินไปอย่างราบรื่น เช่น ประวัติอาการ, อาการในปัจจุบัน, "
|
64 |
"และความต้องการในการดูแล\n\n"
|
65 |
+
|
66 |
+
"## ข้อมูลที่ต้องถามทั้งหมด: {field_descriptions}\n"
|
67 |
+
"## ข้อมูลที่ต้องการถามปัจจุบัน *สำคัญ*: {description}\n"
|
68 |
"### ถามคำถาม:\n"
|
69 |
"ให้สร้างคำถามทีละข้อในโทนเสียงอบอุ่นและสุภาพสำหรับการพยายามสอบถามเกี่ยวกับ {description}.\n\n"
|
70 |
"### ข้อมูลเดิม:\n"
|
71 |
"หากมีข้อมูลที่ทราบอยู่แล้ว โต้ตอบกับคนไข้ด้วยข้อมูลที่มีอยู่: {context}\n\n"
|
72 |
"---\n\n"
|
73 |
+
|
74 |
+
"### เมื่อถามเกี่ยวกับอาการ ให้ไล่ถามอย่างละเอียด ในการเก็บรายละเอียดให้ครบ *อย่าถามทีเดียวทั้งหมด*\n"
|
75 |
+
"- ลักษณะอาการ มีการยกตัวอย่างอาการประกอบ\n"
|
76 |
+
"- เป็นครั้งแรกเมื่อไหร่ เป็นนานหรือยัง\n"
|
77 |
+
"- ทำการสรุปคร่าวๆ ให้หมอว่าอาการดังกล่าวใกล้เคียงกับโรคอะไรบ้าง\n"
|
78 |
+
"- ถามถึงอาการแทรกซ้อน ของโรคที่ใกล้เคียง ที่มีโอกาสเป็น (1-3 อาการ)\n\n"
|
79 |
+
|
80 |
+
"### ตัวอย่างการสนทนา *ห้ามยึดติดมากเกินไป*\n"
|
81 |
"#### ตัวอย่าง 1\n"
|
82 |
+
"ก่อนอื่นเลย ดิฉันขอทราบชื่อเต็มของคุณได้ไหมคะ?\n"
|
83 |
+
"คนไข้: พยาบาลสาวคนสวย ฉันชื่อ อรุณี สุริยะค่ะ\n"
|
84 |
"ขอบคุณค่ะ คุณอรุณี ชมกันแบบนี้ดิฉันเขินเลยนะคะ แต่ยินดีช่วยดูแลเต็มที่ค่ะ คุณอรุณี อายุเท่าไหร่คะ?\n"
|
85 |
+
"คนไข้: 35 ปีค่ะ มะลิ\n"
|
86 |
"35 ปีนะคะ เพื่อความถูกต้อง ดิฉันขอถามเพิ่มนะคะ คุณอรุณีเป็นเพศหญิงใช่ไหมคะ?\n"
|
87 |
"คนไข้: ใช่ค่ะ\n"
|
88 |
"ขอบคุณค่ะ มีคนไข้น่ารักแบบนี้ ดิฉันยิ่งตั้งใจทำงานเลยค่ะ เรามาคุยกันต่อเรื่องสุขภาพนะคะ มีอาการหลักอะไรที่รู้สึกไม่สบายใจตอนนี้ไหมคะ?\n"
|
89 |
"คนไข้: รู้สึกปวดท้องบ่อย ๆ ค่ะ Mali คิดว่ามันคืออะไรคะ?\n"
|
90 |
"ขอบคุณที่บอกนะคะ อาการปวดท้องแบบนี้เริ่มมีมาตั้งแต่เมื่อไหร่คะ และปวดเป็นลักษณะยังไงคะ?\n"
|
91 |
"คนไข้: ประมาณสองสัปดาห์แล้วค่ะ ปวดแบบแสบท้องค่ะ\n"
|
92 |
+
"เข้าใจแล้วค่ะ ตอนนี้มีประวัติการแพ้ยาหรือสารอื่น ๆ ที่อยากแจ้งให้ทราบไหมคะ? เพื่อให้การดูแลถูกต้องมากขึ้นค่ะ\n"
|
93 |
"คนไข้: เคยแพ้ยาปฏิชีวนะค่ะ\n"
|
94 |
"ขอบคุณที่แจ้งข้อมูลนะคะ สำหรับประวัติสุขภาพครอบครัว พอจะมีใครในครอบครัวที่มีโรคประจำตัวไหมคะ เช่น โรคหัวใจ ความดันโลหิตสูง หรือโรคเบาหวาน?\n"
|
95 |
"คนไข้: คุณแม่เป็นเบาหวานค่ะ คุณพ่อก็เป็นโรคความดันค่ะ\n"
|
|
|
98 |
"เข้าใจแล้วค่ะ ขอบคุณที่ให้ข้อมูลทั้งหมดนี้นะคะ คุณอรุณี ดิฉันบันทึกไว้เรียบร้อยแล้วเพื่อให้การดูแลเหมาะสมและครบถ้วน ถ้ามีคำถามเพิ่มเติมเกี่ยวกับสุขภาพอีก ดิฉันยินดีให้คำปรึกษาเสมอค่ะ\n"
|
99 |
|
100 |
"#### ตัวอย่าง 2\n"
|
101 |
+
"สวัสดีค่ะ ดิฉัน มะลิ ค่ะ คุณคนไข้ชื่อว่าอะไรคะ?\n"
|
102 |
"คนไข้: ชื่อต้อมครับ\n"
|
103 |
"ขอทราบชื่อเต็มของคุณต้อมได้ไหมคะ?\n"
|
104 |
"คนไข้: อ๋อ ชื่อแค่ ต้อม ครับ ไม่ต้องให้ชื่อเต็มหรอกครับ\n"
|
|
|
113 |
"ไม่สบายแบบไหนหรอคะ มีอาการปวดหัว ตัวร้อน มีไข้หรือเปล่าคะ?"
|
114 |
"ขอบคุณค่ะที่บอกนะคะ คุณต้อมค่ะ ดิฉันจะถามต่อว่า คุณต้อมเริ่มรู้สึกไม่สบายเมื่อไหร่คะ? หรือมันค่อย ๆ เริ่มมีอาการมาเรื่อย ๆ คะ?\n"
|
115 |
"คนไข้: ก็ประมาณสองสามวันมานี้ครับ แต่ไม่ได้รุนแรงมาก\n"
|
116 |
+
"ขอบคุณค่ะ คุณต้อมที่บอกค่ะ เข้าใจค่ะ แต่ต้องอย่าชะล่าใจ ต้องหมั่นดูแลตัวเองบ่อยๆ นะคะ ดิฉันขอถามอีกครั้งนะคะ มีประวัติการแพ้ยาอะไรหรือสารอื่น ๆ ที่อยากแจ้งให้ทราบไหมคะ?\n"
|
117 |
"คนไข้: ไม่มีหรอกครับ\n"
|
118 |
"ขอบคุณค่ะ คุณต้อม สำหรับข้อมูลค่ะ ต่อไปนะคะ ประวัติสุขภาพในครอบครัวของคุณต้อมเป็นยังไงบ้างคะ เช่น พ่อแม่หรือญาติคนอื่น ๆ เคยมีโรคประจำตัวอะไรบ้างคะ?\n"
|
119 |
"คนไข้: พ่อผมเป็นโรคหัวใจครับ ส่วนแม่ผมท่านไม่อยู่แล้ว เสียชีวิตด้วยมะเร็งครับ\n"
|
|
|
129 |
"หากไม่พบข้อมูลที่กำหนดหรือข้อมูลอธิบายไม่ละเอียดเพียงพอให้ใส่ค่า null หรือ [] ตามรูปแบบข้อมูลโดยไม่มีการข้ามหรือละเว้นใด ๆ.\n\n"
|
130 |
|
131 |
"ส่งคืนเฉพาะรายละเอียดที่กำหนดโดยไม่มีข้อมูลแยกย่อยไปอีก.\n\n"
|
132 |
+
"# อัพเดทข้อมูลจากข้อมูลที่มีอยู่แล้ว:\n"
|
|
|
133 |
"{ehr_data}\n"
|
134 |
+
|
135 |
+
"# การทำงาน\n"
|
136 |
+
"- สามารถ *แก้ไข* / *เพิ่มเติม* ข้อมูลใหม่จากเดิมได้เพื่อให้ตรงบริบทของแพทย์\n"
|
137 |
+
"- ข้อมูลประเภท list สามารถเพิ่มสมาชิก / แก้ไขข้อมูลได้ เหมือนการ append list"
|
138 |
+
"เช่น past_illness มีข้อมูลเป็น List ['กรดไหลย้อนเมื่อสองวันก่อน'] หากผู้ป่วยบอกเพิ่มเติมว่า หกล้มก็ให้เพิ่มเติม ['กรดไหลย้อนเมื่อสองวันก่อน', 'หกล้ม ไม่ทราบวันที่'] หากไม่ทราบวันที่ก็\n"
|
139 |
+
"- แก้ไขข้อมูลให้มีความอ่านง่ายเข้าใจง่าย เพื่อให้แพทย์ใช้งานได้ต่อ *ห้ามมีเนื้อหาที่ไม่เกี่ยวข้อง*\n"
|
140 |
+
"- \n\n"
|
141 |
+
|
142 |
+
"# รายละเอียดสำคัญที่ต้องดึงข้อมูล:\n"
|
143 |
+
"## หากข้อมูลประเภท object required ช่องใดช่องหนึ่งเป็น null ทำให้ข้อมูลทั้งหมดเป็น null.\n"
|
144 |
"1. **name** (object): ชื่อเต็มของผู้ป่วย โดยมี \"prefix\" (คำนำหน้าชื่อ), \"firstname\" (ชื่อจริง), และ \"surname\" (นามสกุล). "
|
145 |
"หากไม่มีข้อมูลให้ใส่ค่า null."
|
146 |
"required: firstname, lastname.\n"
|
|
|
148 |
"หากไม่ทราบให้ใส่ค่า null.\n"
|
149 |
"3. **gender** (string): เพศของผู้ป่วย (สามารถอิงได้ตาม name prefix). "
|
150 |
"หากไม่มีข้อมูลให้ใส่ค่า null.\n"
|
151 |
+
"4. **chief_complaint** (list[string]): อาการหลักที่ผู้ป่วยรายงาน. "
|
152 |
+
"หากไม่มีข้อมูลให้ใส่ค่า [] ไว้.\n"
|
153 |
+
"5. **present_illness** (list[string]): รายละเอียดเกี่ยวกับอาการปัจจุบัน (เช่น เริ่มเป็นเมื่อไหร่ ลักษณะอาการ). "
|
154 |
+
"หากไม่มีข้อมูลให้ใส่ค่า [] ไว้.\n"
|
155 |
+
"6. **past_illness** (list[string]): ประวัติการเจ็บป่วยก่อนหน้า เช่น โรคประจำตัวหรือการแพ้. "
|
156 |
"หากไม่มีข้อมูลให้ใส่ค่า [] ไว้.\n"
|
157 |
"7. **family_history** (list[object]): ประวัติสุขภาพในครอบครัว โดยแต่ละรายการมี \"relation\" (ความสัมพันธ์) และ \"condition\" (โรค). "
|
158 |
"หากไม่มีข้อมูลให้ใส่ค่า [] ไว้.\n"
|
|
|
165 |
"\n\n"
|
166 |
"ส่งคืนคำตอบในรูปแบบ JSON ที่ถูกต้อง. "
|
167 |
"โปรดอย่าตอบคำตอบอื่นนอกจากข้อมูลในรูปแบบ JSON และกรอกค่า null หรือ [] ในทุกช่องที่ไม่มีข้อมูล."
|
168 |
+
"ห้ามมีการ hallucination หรือเพิ่มข้อมูลที่ไม่เกี่ยวข้อง. ข้อมูลที่ไม่เกี่ยวข้องจะถูกปรับแต่ง หรือลบออก.\n"
|
169 |
|
170 |
+
),
|
171 |
+
|
172 |
+
"refactor": (
|
173 |
+
"เรากำลังทำงานเกี่ยวกับการเก็บข้อมูลผู้ป่วยในรูปแบบ JSON โดยดึงข้อมูลจากการสนทนาในแชทที่ผ่านมา\n"
|
174 |
+
"# ข้อมูล JSON ที่เก็บข้อมูลผู้ป่วยไว้:\n"
|
175 |
+
"{ehr_data}\n\n"
|
176 |
+
"# บันทึกแชทที่ผ่านมา:\n"
|
177 |
+
"{chat_history}\n\n"
|
178 |
+
"### เวลาปัจจุบัน: {time_now}\n\n"
|
179 |
+
"# คำสั่ง:\n"
|
180 |
+
"1. **ตรวจสอบความสมบูรณ์ของ JSON:**\n"
|
181 |
+
" - เปรียบเทียบ JSON กับข้อมูลที่ผู้ป่วยพูดในแชท หากมีข้อมูลในแชทที่ยังไม่ได้บันทึกใน JSON ให้เพิ่มเข้าไป\n"
|
182 |
+
" - หากข้อมูลใดใน JSON ไม่มีอยู่ในแชท ให้แทนที่ด้วย `null` (หรือ `[]` ในกรณีของ List)\n\n"
|
183 |
+
"2. **ปรับปรุงความสัมพันธ์ของข้อมูล:**\n"
|
184 |
+
" - ตรวจสอบว่า \"prefix\" และ \"gender\" สัมพันธ์กัน เช่น หาก prefix คือ \"นาย\" ให้ gender เป็น \"ชาย\"\n"
|
185 |
+
" - หาก \"chief_complaint\" หรือ \"present_illness\" มีเนื้อหาที่สัมพันธ์กัน ให้สรุปและปรับให้ดูสมบูรณ์ขึ้น\n"
|
186 |
+
" - หากเจอข้อมูลที่เกี่ยวข้องกับเวลาเช่น สองวันก่อน, เมื่อวาน ให้คำนวณ วัน เวลา ที่แน่นอนในรูปแบบของ วันที่\n"
|
187 |
+
" - หากเจอข้อมูลที่ไม่ได้มีการใส่ไว้ในข้อมูล แต่คนไข้ได้มีการพูดไว้ โดยไม่มีข้อมูลอื่นที่ทับซ้อน ให้ทำการเพิ่มข้อมูลลงไป\n"
|
188 |
+
" - หาก \"family_history\" หรือ \"personal_history\" มีข้อมูลเกี่ยวกับความสัมพันธ์หรือคำอธิบายที่คลุมเครือหรือ ไม่ชัดเจน ให้ปรับแก้คำอธิบายให้อ่านง่ายและชัดเจนขึ้น\n\n"
|
189 |
+
"3. **สร้าง JSON ใหม่ที่สมบูรณ์ *ลบข้อมูลที่ไม่มีอยู่จริง*:**\n"
|
190 |
+
" - จัดระเบียบข้อมูลใหม่ตามโครงสร้าง JSON ที่กำหนด โดยข้อมูลที่ไม่มีในแชทให้ตั้งค่าเป็น `null` หรือ `[]` ตามความเหมาะสม\n"
|
191 |
+
" - หากพบข้อมูลใดที่ยังขาดหายไป ให้เพิ่มโน้ตแสดงว่าเป็นข้อมูลที่ต้องติดตามหรือสอบถามเพิ่มเติม\n\n"
|
192 |
+
"### Output ที่ต้องการ:\n"
|
193 |
+
"- JSON ใหม่ที่ตรวจสอบและปรับปรุงเรียบร้อยแล้ว\n"
|
194 |
+
"* ไม่มีการให้ข้อมูลอื่นนอกเหนือจาก JSON *"
|
195 |
)
|
196 |
|
197 |
}
|
main.py
CHANGED
@@ -1,18 +1,19 @@
|
|
|
|
1 |
import uvicorn
|
|
|
2 |
from llm.llm import VirtualNurseLLM
|
3 |
from fastapi import FastAPI
|
4 |
from fastapi.middleware.cors import CORSMiddleware
|
5 |
from fastapi.responses import HTMLResponse
|
6 |
from pydantic import BaseModel
|
7 |
-
import
|
8 |
-
|
9 |
-
load_dotenv()
|
10 |
|
11 |
-
|
12 |
nurse_llm = VirtualNurseLLM(
|
13 |
-
base_url="
|
14 |
-
|
15 |
-
api_key=
|
16 |
)
|
17 |
|
18 |
# model: OpenThaiGPT
|
@@ -40,23 +41,23 @@ class NurseResponse(BaseModel):
|
|
40 |
nurse_response: str
|
41 |
|
42 |
class EHRData(BaseModel):
|
43 |
-
ehr_data:
|
44 |
-
current_context: str
|
45 |
-
current_prompt: str
|
46 |
-
current_prompt_ehr: str
|
47 |
-
current_patient_response: str
|
48 |
-
current_question: str
|
49 |
|
50 |
class ChatHistory(BaseModel):
|
51 |
chat_history: list
|
52 |
-
|
53 |
@app.get("/", response_class=HTMLResponse)
|
54 |
def read_index():
|
55 |
return """
|
56 |
<!DOCTYPE html>
|
57 |
<html>
|
58 |
<head>
|
59 |
-
<title>MALI_NURSE API
|
60 |
</head>
|
61 |
<body>
|
62 |
<h1>Welcome to MALI_NURSE API</h1>
|
@@ -91,19 +92,37 @@ def data_reset():
|
|
91 |
nurse_llm.reset()
|
92 |
print("Chat history and EHR data have been reset.")
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
@app.post("/nurse_response")
|
95 |
def nurse_response(user_input: UserInput):
|
96 |
"""
|
97 |
-
Models: "typhoon-v1.5x-70b-instruct (default)", "openthaigpt"
|
98 |
"""
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
105 |
response = nurse_llm.invoke(user_input.user_input)
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
if __name__ == "__main__":
|
109 |
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
|
|
1 |
+
from typing import Optional
|
2 |
import uvicorn
|
3 |
+
from llm.basemodel import EHRModel
|
4 |
from llm.llm import VirtualNurseLLM
|
5 |
from fastapi import FastAPI
|
6 |
from fastapi.middleware.cors import CORSMiddleware
|
7 |
from fastapi.responses import HTMLResponse
|
8 |
from pydantic import BaseModel
|
9 |
+
from llm.models import model_list, get_model
|
10 |
+
import time
|
|
|
11 |
|
12 |
+
initial_model = "typhoon-v1.5x-70b-instruct"
|
13 |
nurse_llm = VirtualNurseLLM(
|
14 |
+
# base_url=model_list[initial_model]["base_url"],
|
15 |
+
model_name=model_list[initial_model]["model_name"],
|
16 |
+
# api_key=model_list[initial_model]["api_key"]
|
17 |
)
|
18 |
|
19 |
# model: OpenThaiGPT
|
|
|
41 |
nurse_response: str
|
42 |
|
43 |
class EHRData(BaseModel):
|
44 |
+
ehr_data: Optional[EHRModel]
|
45 |
+
current_context: Optional[str]
|
46 |
+
current_prompt: Optional[str]
|
47 |
+
current_prompt_ehr: Optional[str]
|
48 |
+
current_patient_response: Optional[str]
|
49 |
+
current_question: Optional[str]
|
50 |
|
51 |
class ChatHistory(BaseModel):
|
52 |
chat_history: list
|
53 |
+
|
54 |
@app.get("/", response_class=HTMLResponse)
|
55 |
def read_index():
|
56 |
return """
|
57 |
<!DOCTYPE html>
|
58 |
<html>
|
59 |
<head>
|
60 |
+
<title>MALI_NURSE API</title>
|
61 |
</head>
|
62 |
<body>
|
63 |
<h1>Welcome to MALI_NURSE API</h1>
|
|
|
92 |
nurse_llm.reset()
|
93 |
print("Chat history and EHR data have been reset.")
|
94 |
|
95 |
+
model_cache = {}
|
96 |
+
def get_model_cached(model_name):
|
97 |
+
if model_name not in model_cache:
|
98 |
+
model_cache[model_name] = get_model(model_name=model_name)
|
99 |
+
return model_cache[model_name]
|
100 |
+
|
101 |
@app.post("/nurse_response")
|
102 |
def nurse_response(user_input: UserInput):
|
103 |
"""
|
104 |
+
Models: "typhoon-v1.5x-70b-instruct (default)", "openthaigpt", "llama-3.3-70b-versatile"
|
105 |
"""
|
106 |
+
|
107 |
+
start_time = time.time()
|
108 |
+
if user_input.model_name != nurse_llm.model_name:
|
109 |
+
print(f"Changing model to {user_input.model_name}")
|
110 |
+
try:
|
111 |
+
nurse_llm.client = get_model_cached(model_name=user_input.model_name)
|
112 |
+
except ValueError:
|
113 |
+
return {"error": "Invalid model name"}
|
114 |
+
print(nurse_llm.client)
|
115 |
+
|
116 |
+
# response = nurse_llm.slim_invoke(user_input.user_input)
|
117 |
response = nurse_llm.invoke(user_input.user_input)
|
118 |
+
end_time = time.time()
|
119 |
+
duration = end_time - start_time
|
120 |
+
print(f"Function running time: {duration} seconds")
|
121 |
+
# Log the model name, user input, response, and execution time in CSV format
|
122 |
+
with open("runtime_log.csv", "a") as log_file:
|
123 |
+
log_file.write(f"{user_input.model_name},{user_input.user_input},{response},{duration}\n")
|
124 |
+
|
125 |
+
return NurseResponse(nurse_response=response)
|
126 |
|
127 |
if __name__ == "__main__":
|
128 |
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
poetry.lock
CHANGED
@@ -1,5 +1,16 @@
|
|
1 |
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
[[package]]
|
4 |
name = "aiohappyeyeballs"
|
5 |
version = "2.4.3"
|
@@ -186,6 +197,48 @@ docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphi
|
|
186 |
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
187 |
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
|
188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
[[package]]
|
190 |
name = "certifi"
|
191 |
version = "2024.8.30"
|
@@ -396,6 +449,33 @@ typing-extensions = ">=4.8.0"
|
|
396 |
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
397 |
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"]
|
398 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
[[package]]
|
400 |
name = "frozenlist"
|
401 |
version = "1.5.0"
|
@@ -497,6 +577,107 @@ files = [
|
|
497 |
{file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"},
|
498 |
]
|
499 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
500 |
[[package]]
|
501 |
name = "greenlet"
|
502 |
version = "3.1.1"
|
@@ -583,6 +764,25 @@ files = [
|
|
583 |
docs = ["Sphinx", "furo"]
|
584 |
test = ["objgraph", "psutil"]
|
585 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
[[package]]
|
587 |
name = "h11"
|
588 |
version = "0.14.0"
|
@@ -651,6 +851,40 @@ files = [
|
|
651 |
{file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"},
|
652 |
]
|
653 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
654 |
[[package]]
|
655 |
name = "idna"
|
656 |
version = "3.10"
|
@@ -665,6 +899,23 @@ files = [
|
|
665 |
[package.extras]
|
666 |
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
|
667 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
668 |
[[package]]
|
669 |
name = "jiter"
|
670 |
version = "0.7.1"
|
@@ -850,6 +1101,21 @@ PyYAML = ">=5.3"
|
|
850 |
tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10.0.0"
|
851 |
typing-extensions = ">=4.7"
|
852 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
853 |
[[package]]
|
854 |
name = "langchain-openai"
|
855 |
version = "0.2.8"
|
@@ -901,6 +1167,99 @@ pydantic = [
|
|
901 |
requests = ">=2,<3"
|
902 |
requests-toolbelt = ">=1.0.0,<2.0.0"
|
903 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
904 |
[[package]]
|
905 |
name = "marshmallow"
|
906 |
version = "3.23.1"
|
@@ -920,6 +1279,17 @@ dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"]
|
|
920 |
docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"]
|
921 |
tests = ["pytest", "simplejson"]
|
922 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
923 |
[[package]]
|
924 |
name = "multidict"
|
925 |
version = "6.1.0"
|
@@ -1182,6 +1552,172 @@ files = [
|
|
1182 |
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
1183 |
]
|
1184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1185 |
[[package]]
|
1186 |
name = "propcache"
|
1187 |
version = "0.2.0"
|
@@ -1433,6 +1969,45 @@ azure-key-vault = ["azure-identity (>=1.16.0)", "azure-keyvault-secrets (>=4.8.0
|
|
1433 |
toml = ["tomli (>=2.0.1)"]
|
1434 |
yaml = ["pyyaml (>=6.0.1)"]
|
1435 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1436 |
[[package]]
|
1437 |
name = "python-dotenv"
|
1438 |
version = "1.0.1"
|
@@ -1447,6 +2022,28 @@ files = [
|
|
1447 |
[package.extras]
|
1448 |
cli = ["click (>=5.0)"]
|
1449 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1450 |
[[package]]
|
1451 |
name = "pyyaml"
|
1452 |
version = "6.0.2"
|
@@ -1647,6 +2244,106 @@ files = [
|
|
1647 |
[package.dependencies]
|
1648 |
requests = ">=2.0.1,<3.0.0"
|
1649 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1650 |
[[package]]
|
1651 |
name = "sniffio"
|
1652 |
version = "1.3.1"
|
@@ -1824,6 +2521,17 @@ requests = ">=2.26.0"
|
|
1824 |
[package.extras]
|
1825 |
blobfile = ["blobfile (>=2)"]
|
1826 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1827 |
[[package]]
|
1828 |
name = "tqdm"
|
1829 |
version = "4.67.0"
|
@@ -1845,6 +2553,23 @@ notebook = ["ipywidgets (>=6)"]
|
|
1845 |
slack = ["slack-sdk"]
|
1846 |
telegram = ["requests"]
|
1847 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1848 |
[[package]]
|
1849 |
name = "typing-extensions"
|
1850 |
version = "4.12.2"
|
@@ -1871,6 +2596,17 @@ files = [
|
|
1871 |
mypy-extensions = ">=0.3.0"
|
1872 |
typing-extensions = ">=3.7.4"
|
1873 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1874 |
[[package]]
|
1875 |
name = "urllib3"
|
1876 |
version = "2.2.3"
|
@@ -1907,6 +2643,84 @@ typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
|
1907 |
[package.extras]
|
1908 |
standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
1909 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1910 |
[[package]]
|
1911 |
name = "yarl"
|
1912 |
version = "1.17.1"
|
@@ -2006,4 +2820,4 @@ propcache = ">=0.2.0"
|
|
2006 |
[metadata]
|
2007 |
lock-version = "2.0"
|
2008 |
python-versions = "^3.10"
|
2009 |
-
content-hash = "
|
|
|
1 |
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
2 |
|
3 |
+
[[package]]
|
4 |
+
name = "aiofiles"
|
5 |
+
version = "23.2.1"
|
6 |
+
description = "File support for asyncio."
|
7 |
+
optional = false
|
8 |
+
python-versions = ">=3.7"
|
9 |
+
files = [
|
10 |
+
{file = "aiofiles-23.2.1-py3-none-any.whl", hash = "sha256:19297512c647d4b27a2cf7c34caa7e405c0d60b5560618a29a9fe027b18b0107"},
|
11 |
+
{file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"},
|
12 |
+
]
|
13 |
+
|
14 |
[[package]]
|
15 |
name = "aiohappyeyeballs"
|
16 |
version = "2.4.3"
|
|
|
197 |
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
198 |
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
|
199 |
|
200 |
+
[[package]]
|
201 |
+
name = "audioop-lts"
|
202 |
+
version = "0.2.1"
|
203 |
+
description = "LTS Port of Python audioop"
|
204 |
+
optional = false
|
205 |
+
python-versions = ">=3.13"
|
206 |
+
files = [
|
207 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-macosx_10_13_universal2.whl", hash = "sha256:fd1345ae99e17e6910f47ce7d52673c6a1a70820d78b67de1b7abb3af29c426a"},
|
208 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-macosx_10_13_x86_64.whl", hash = "sha256:e175350da05d2087e12cea8e72a70a1a8b14a17e92ed2022952a4419689ede5e"},
|
209 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-macosx_11_0_arm64.whl", hash = "sha256:4a8dd6a81770f6ecf019c4b6d659e000dc26571b273953cef7cd1d5ce2ff3ae6"},
|
210 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cd3c0b6f2ca25c7d2b1c3adeecbe23e65689839ba73331ebc7d893fcda7ffe"},
|
211 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff3f97b3372c97782e9c6d3d7fdbe83bce8f70de719605bd7ee1839cd1ab360a"},
|
212 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a351af79edefc2a1bd2234bfd8b339935f389209943043913a919df4b0f13300"},
|
213 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aeb6f96f7f6da80354330470b9134d81b4cf544cdd1c549f2f45fe964d28059"},
|
214 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c589f06407e8340e81962575fcffbba1e92671879a221186c3d4662de9fe804e"},
|
215 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fbae5d6925d7c26e712f0beda5ed69ebb40e14212c185d129b8dfbfcc335eb48"},
|
216 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_i686.whl", hash = "sha256:d2d5434717f33117f29b5691fbdf142d36573d751716249a288fbb96ba26a281"},
|
217 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:f626a01c0a186b08f7ff61431c01c055961ee28769591efa8800beadd27a2959"},
|
218 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_s390x.whl", hash = "sha256:05da64e73837f88ee5c6217d732d2584cf638003ac72df124740460531e95e47"},
|
219 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:56b7a0a4dba8e353436f31a932f3045d108a67b5943b30f85a5563f4d8488d77"},
|
220 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-win32.whl", hash = "sha256:6e899eb8874dc2413b11926b5fb3857ec0ab55222840e38016a6ba2ea9b7d5e3"},
|
221 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-win_amd64.whl", hash = "sha256:64562c5c771fb0a8b6262829b9b4f37a7b886c01b4d3ecdbae1d629717db08b4"},
|
222 |
+
{file = "audioop_lts-0.2.1-cp313-abi3-win_arm64.whl", hash = "sha256:c45317debeb64002e980077642afbd977773a25fa3dfd7ed0c84dccfc1fafcb0"},
|
223 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:3827e3fce6fee4d69d96a3d00cd2ab07f3c0d844cb1e44e26f719b34a5b15455"},
|
224 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:161249db9343b3c9780ca92c0be0d1ccbfecdbccac6844f3d0d44b9c4a00a17f"},
|
225 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5b7b4ff9de7a44e0ad2618afdc2ac920b91f4a6d3509520ee65339d4acde5abf"},
|
226 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72e37f416adb43b0ced93419de0122b42753ee74e87070777b53c5d2241e7fab"},
|
227 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534ce808e6bab6adb65548723c8cbe189a3379245db89b9d555c4210b4aaa9b6"},
|
228 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2de9b6fb8b1cf9f03990b299a9112bfdf8b86b6987003ca9e8a6c4f56d39543"},
|
229 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f24865991b5ed4b038add5edbf424639d1358144f4e2a3e7a84bc6ba23e35074"},
|
230 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bdb3b7912ccd57ea53197943f1bbc67262dcf29802c4a6df79ec1c715d45a78"},
|
231 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:120678b208cca1158f0a12d667af592e067f7a50df9adc4dc8f6ad8d065a93fb"},
|
232 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:54cd4520fc830b23c7d223693ed3e1b4d464997dd3abc7c15dce9a1f9bd76ab2"},
|
233 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:d6bd20c7a10abcb0fb3d8aaa7508c0bf3d40dfad7515c572014da4b979d3310a"},
|
234 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:f0ed1ad9bd862539ea875fb339ecb18fcc4148f8d9908f4502df28f94d23491a"},
|
235 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e1af3ff32b8c38a7d900382646e91f2fc515fd19dea37e9392275a5cbfdbff63"},
|
236 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-win32.whl", hash = "sha256:f51bb55122a89f7a0817d7ac2319744b4640b5b446c4c3efcea5764ea99ae509"},
|
237 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f0f2f336aa2aee2bce0b0dcc32bbba9178995454c7b979cf6ce086a8801e14c7"},
|
238 |
+
{file = "audioop_lts-0.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:78bfb3703388c780edf900be66e07de5a3d4105ca8e8720c5c4d67927e0b15d0"},
|
239 |
+
{file = "audioop_lts-0.2.1.tar.gz", hash = "sha256:e81268da0baa880431b68b1308ab7257eb33f356e57a5f9b1f915dfb13dd1387"},
|
240 |
+
]
|
241 |
+
|
242 |
[[package]]
|
243 |
name = "certifi"
|
244 |
version = "2024.8.30"
|
|
|
449 |
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
450 |
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"]
|
451 |
|
452 |
+
[[package]]
|
453 |
+
name = "ffmpy"
|
454 |
+
version = "0.4.0"
|
455 |
+
description = "A simple Python wrapper for FFmpeg"
|
456 |
+
optional = false
|
457 |
+
python-versions = "<4.0.0,>=3.8.1"
|
458 |
+
files = [
|
459 |
+
{file = "ffmpy-0.4.0-py3-none-any.whl", hash = "sha256:39c0f20c5b465e7f8d29a5191f3a7d7675a8c546d9d985de8921151cd9b59e14"},
|
460 |
+
{file = "ffmpy-0.4.0.tar.gz", hash = "sha256:131b57794e802ad555f579007497f7a3d0cab0583d37496c685b8acae4837b1d"},
|
461 |
+
]
|
462 |
+
|
463 |
+
[[package]]
|
464 |
+
name = "filelock"
|
465 |
+
version = "3.16.1"
|
466 |
+
description = "A platform independent file lock."
|
467 |
+
optional = false
|
468 |
+
python-versions = ">=3.8"
|
469 |
+
files = [
|
470 |
+
{file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
|
471 |
+
{file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
|
472 |
+
]
|
473 |
+
|
474 |
+
[package.extras]
|
475 |
+
docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
|
476 |
+
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
|
477 |
+
typing = ["typing-extensions (>=4.12.2)"]
|
478 |
+
|
479 |
[[package]]
|
480 |
name = "frozenlist"
|
481 |
version = "1.5.0"
|
|
|
577 |
{file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"},
|
578 |
]
|
579 |
|
580 |
+
[[package]]
|
581 |
+
name = "fsspec"
|
582 |
+
version = "2024.10.0"
|
583 |
+
description = "File-system specification"
|
584 |
+
optional = false
|
585 |
+
python-versions = ">=3.8"
|
586 |
+
files = [
|
587 |
+
{file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"},
|
588 |
+
{file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"},
|
589 |
+
]
|
590 |
+
|
591 |
+
[package.extras]
|
592 |
+
abfs = ["adlfs"]
|
593 |
+
adl = ["adlfs"]
|
594 |
+
arrow = ["pyarrow (>=1)"]
|
595 |
+
dask = ["dask", "distributed"]
|
596 |
+
dev = ["pre-commit", "ruff"]
|
597 |
+
doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"]
|
598 |
+
dropbox = ["dropbox", "dropboxdrivefs", "requests"]
|
599 |
+
full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"]
|
600 |
+
fuse = ["fusepy"]
|
601 |
+
gcs = ["gcsfs"]
|
602 |
+
git = ["pygit2"]
|
603 |
+
github = ["requests"]
|
604 |
+
gs = ["gcsfs"]
|
605 |
+
gui = ["panel"]
|
606 |
+
hdfs = ["pyarrow (>=1)"]
|
607 |
+
http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"]
|
608 |
+
libarchive = ["libarchive-c"]
|
609 |
+
oci = ["ocifs"]
|
610 |
+
s3 = ["s3fs"]
|
611 |
+
sftp = ["paramiko"]
|
612 |
+
smb = ["smbprotocol"]
|
613 |
+
ssh = ["paramiko"]
|
614 |
+
test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"]
|
615 |
+
test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"]
|
616 |
+
test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"]
|
617 |
+
tqdm = ["tqdm"]
|
618 |
+
|
619 |
+
[[package]]
|
620 |
+
name = "gradio"
|
621 |
+
version = "5.8.0"
|
622 |
+
description = "Python library for easily interacting with trained machine learning models"
|
623 |
+
optional = false
|
624 |
+
python-versions = ">=3.10"
|
625 |
+
files = [
|
626 |
+
{file = "gradio-5.8.0-py3-none-any.whl", hash = "sha256:428ad660fc48104f0c60f8ae808ab5e2afec03a472a0fb734348c4e916de74dc"},
|
627 |
+
]
|
628 |
+
|
629 |
+
[package.dependencies]
|
630 |
+
aiofiles = ">=22.0,<24.0"
|
631 |
+
anyio = ">=3.0,<5.0"
|
632 |
+
audioop-lts = {version = "<1.0", markers = "python_version >= \"3.13\""}
|
633 |
+
fastapi = ">=0.115.2,<1.0"
|
634 |
+
ffmpy = "*"
|
635 |
+
gradio-client = "1.5.1"
|
636 |
+
httpx = ">=0.24.1"
|
637 |
+
huggingface-hub = ">=0.25.1"
|
638 |
+
jinja2 = "<4.0"
|
639 |
+
markupsafe = ">=2.0,<3.0"
|
640 |
+
numpy = ">=1.0,<3.0"
|
641 |
+
orjson = ">=3.0,<4.0"
|
642 |
+
packaging = "*"
|
643 |
+
pandas = ">=1.0,<3.0"
|
644 |
+
pillow = ">=8.0,<12.0"
|
645 |
+
pydantic = ">=2.0"
|
646 |
+
pydub = "*"
|
647 |
+
python-multipart = ">=0.0.18"
|
648 |
+
pyyaml = ">=5.0,<7.0"
|
649 |
+
ruff = {version = ">=0.2.2", markers = "sys_platform != \"emscripten\""}
|
650 |
+
safehttpx = ">=0.1.6,<0.2.0"
|
651 |
+
semantic-version = ">=2.0,<3.0"
|
652 |
+
starlette = {version = ">=0.40.0,<1.0", markers = "sys_platform != \"emscripten\""}
|
653 |
+
tomlkit = ">=0.12.0,<0.14.0"
|
654 |
+
typer = {version = ">=0.12,<1.0", markers = "sys_platform != \"emscripten\""}
|
655 |
+
typing-extensions = ">=4.0,<5.0"
|
656 |
+
urllib3 = {version = ">=2.0,<3.0", markers = "sys_platform == \"emscripten\""}
|
657 |
+
uvicorn = {version = ">=0.14.0", markers = "sys_platform != \"emscripten\""}
|
658 |
+
|
659 |
+
[package.extras]
|
660 |
+
oauth = ["authlib", "itsdangerous"]
|
661 |
+
|
662 |
+
[[package]]
|
663 |
+
name = "gradio-client"
|
664 |
+
version = "1.5.1"
|
665 |
+
description = "Python library for easily interacting with trained machine learning models"
|
666 |
+
optional = false
|
667 |
+
python-versions = ">=3.10"
|
668 |
+
files = [
|
669 |
+
{file = "gradio_client-1.5.1-py3-none-any.whl", hash = "sha256:175e4ac399591d919af85a097661cdd760b8dd1ca229e28ef4da978fde84a398"},
|
670 |
+
{file = "gradio_client-1.5.1.tar.gz", hash = "sha256:c443013e3532828e202c9679b254016406a1753666c3c601ea8557c724adbaf7"},
|
671 |
+
]
|
672 |
+
|
673 |
+
[package.dependencies]
|
674 |
+
fsspec = "*"
|
675 |
+
httpx = ">=0.24.1"
|
676 |
+
huggingface-hub = ">=0.19.3"
|
677 |
+
packaging = "*"
|
678 |
+
typing-extensions = ">=4.0,<5.0"
|
679 |
+
websockets = ">=10.0,<15.0"
|
680 |
+
|
681 |
[[package]]
|
682 |
name = "greenlet"
|
683 |
version = "3.1.1"
|
|
|
764 |
docs = ["Sphinx", "furo"]
|
765 |
test = ["objgraph", "psutil"]
|
766 |
|
767 |
+
[[package]]
|
768 |
+
name = "groq"
|
769 |
+
version = "0.13.0"
|
770 |
+
description = "The official Python library for the groq API"
|
771 |
+
optional = false
|
772 |
+
python-versions = ">=3.8"
|
773 |
+
files = [
|
774 |
+
{file = "groq-0.13.0-py3-none-any.whl", hash = "sha256:1c2b16fd1c4665c2d09509ee42ead9cc7d32534b37b2051fee0ea8b6216b899d"},
|
775 |
+
{file = "groq-0.13.0.tar.gz", hash = "sha256:aaa213821c94d8974e57bab5fe59cb45c8871875d0cd53ec179afed928bad18e"},
|
776 |
+
]
|
777 |
+
|
778 |
+
[package.dependencies]
|
779 |
+
anyio = ">=3.5.0,<5"
|
780 |
+
distro = ">=1.7.0,<2"
|
781 |
+
httpx = ">=0.23.0,<1"
|
782 |
+
pydantic = ">=1.9.0,<3"
|
783 |
+
sniffio = "*"
|
784 |
+
typing-extensions = ">=4.7,<5"
|
785 |
+
|
786 |
[[package]]
|
787 |
name = "h11"
|
788 |
version = "0.14.0"
|
|
|
851 |
{file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"},
|
852 |
]
|
853 |
|
854 |
+
[[package]]
|
855 |
+
name = "huggingface-hub"
|
856 |
+
version = "0.26.5"
|
857 |
+
description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
|
858 |
+
optional = false
|
859 |
+
python-versions = ">=3.8.0"
|
860 |
+
files = [
|
861 |
+
{file = "huggingface_hub-0.26.5-py3-none-any.whl", hash = "sha256:fb7386090bbe892072e64b85f7c4479fd2d65eea5f2543327c970d5169e83924"},
|
862 |
+
{file = "huggingface_hub-0.26.5.tar.gz", hash = "sha256:1008bd18f60bfb65e8dbc0a97249beeeaa8c99d3c2fa649354df9fa5a13ed83b"},
|
863 |
+
]
|
864 |
+
|
865 |
+
[package.dependencies]
|
866 |
+
filelock = "*"
|
867 |
+
fsspec = ">=2023.5.0"
|
868 |
+
packaging = ">=20.9"
|
869 |
+
pyyaml = ">=5.1"
|
870 |
+
requests = "*"
|
871 |
+
tqdm = ">=4.42.1"
|
872 |
+
typing-extensions = ">=3.7.4.3"
|
873 |
+
|
874 |
+
[package.extras]
|
875 |
+
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
876 |
+
cli = ["InquirerPy (==0.3.4)"]
|
877 |
+
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
878 |
+
fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
|
879 |
+
hf-transfer = ["hf-transfer (>=0.1.4)"]
|
880 |
+
inference = ["aiohttp"]
|
881 |
+
quality = ["libcst (==1.4.0)", "mypy (==1.5.1)", "ruff (>=0.5.0)"]
|
882 |
+
tensorflow = ["graphviz", "pydot", "tensorflow"]
|
883 |
+
tensorflow-testing = ["keras (<3.0)", "tensorflow"]
|
884 |
+
testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
|
885 |
+
torch = ["safetensors[torch]", "torch"]
|
886 |
+
typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"]
|
887 |
+
|
888 |
[[package]]
|
889 |
name = "idna"
|
890 |
version = "3.10"
|
|
|
899 |
[package.extras]
|
900 |
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
|
901 |
|
902 |
+
[[package]]
|
903 |
+
name = "jinja2"
|
904 |
+
version = "3.1.4"
|
905 |
+
description = "A very fast and expressive template engine."
|
906 |
+
optional = false
|
907 |
+
python-versions = ">=3.7"
|
908 |
+
files = [
|
909 |
+
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
|
910 |
+
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
|
911 |
+
]
|
912 |
+
|
913 |
+
[package.dependencies]
|
914 |
+
MarkupSafe = ">=2.0"
|
915 |
+
|
916 |
+
[package.extras]
|
917 |
+
i18n = ["Babel (>=2.7)"]
|
918 |
+
|
919 |
[[package]]
|
920 |
name = "jiter"
|
921 |
version = "0.7.1"
|
|
|
1101 |
tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10.0.0"
|
1102 |
typing-extensions = ">=4.7"
|
1103 |
|
1104 |
+
[[package]]
|
1105 |
+
name = "langchain-groq"
|
1106 |
+
version = "0.2.1"
|
1107 |
+
description = "An integration package connecting Groq and LangChain"
|
1108 |
+
optional = false
|
1109 |
+
python-versions = "<4.0,>=3.9"
|
1110 |
+
files = [
|
1111 |
+
{file = "langchain_groq-0.2.1-py3-none-any.whl", hash = "sha256:98d282fd9d7d99b0f55de0a1daea2d5d350ef697e3cb5e97de06aeba4eca8679"},
|
1112 |
+
{file = "langchain_groq-0.2.1.tar.gz", hash = "sha256:a59c81d1a15dc97abf4fdb4c2589f98109313eda147e6b378829222d4d929792"},
|
1113 |
+
]
|
1114 |
+
|
1115 |
+
[package.dependencies]
|
1116 |
+
groq = ">=0.4.1,<1"
|
1117 |
+
langchain-core = ">=0.3.15,<0.4.0"
|
1118 |
+
|
1119 |
[[package]]
|
1120 |
name = "langchain-openai"
|
1121 |
version = "0.2.8"
|
|
|
1167 |
requests = ">=2,<3"
|
1168 |
requests-toolbelt = ">=1.0.0,<2.0.0"
|
1169 |
|
1170 |
+
[[package]]
|
1171 |
+
name = "markdown-it-py"
|
1172 |
+
version = "3.0.0"
|
1173 |
+
description = "Python port of markdown-it. Markdown parsing, done right!"
|
1174 |
+
optional = false
|
1175 |
+
python-versions = ">=3.8"
|
1176 |
+
files = [
|
1177 |
+
{file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
|
1178 |
+
{file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
|
1179 |
+
]
|
1180 |
+
|
1181 |
+
[package.dependencies]
|
1182 |
+
mdurl = ">=0.1,<1.0"
|
1183 |
+
|
1184 |
+
[package.extras]
|
1185 |
+
benchmarking = ["psutil", "pytest", "pytest-benchmark"]
|
1186 |
+
code-style = ["pre-commit (>=3.0,<4.0)"]
|
1187 |
+
compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
|
1188 |
+
linkify = ["linkify-it-py (>=1,<3)"]
|
1189 |
+
plugins = ["mdit-py-plugins"]
|
1190 |
+
profiling = ["gprof2dot"]
|
1191 |
+
rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
|
1192 |
+
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
|
1193 |
+
|
1194 |
+
[[package]]
|
1195 |
+
name = "markupsafe"
|
1196 |
+
version = "2.1.5"
|
1197 |
+
description = "Safely add untrusted strings to HTML/XML markup."
|
1198 |
+
optional = false
|
1199 |
+
python-versions = ">=3.7"
|
1200 |
+
files = [
|
1201 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
1202 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
1203 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
|
1204 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
|
1205 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
|
1206 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
|
1207 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
|
1208 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
|
1209 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
|
1210 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
|
1211 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
|
1212 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
|
1213 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
|
1214 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
|
1215 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
|
1216 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
|
1217 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
|
1218 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
|
1219 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
|
1220 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
|
1221 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
|
1222 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
|
1223 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
|
1224 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
|
1225 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
|
1226 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
|
1227 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
|
1228 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
|
1229 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
|
1230 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
|
1231 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
|
1232 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
|
1233 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
|
1234 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
|
1235 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
|
1236 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
|
1237 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
|
1238 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
|
1239 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
|
1240 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
|
1241 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
|
1242 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
|
1243 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
|
1244 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
|
1245 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
|
1246 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
|
1247 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
|
1248 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
|
1249 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
|
1250 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
|
1251 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
|
1252 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
|
1253 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
|
1254 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
|
1255 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
|
1256 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
|
1257 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
|
1258 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
|
1259 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
|
1260 |
+
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
|
1261 |
+
]
|
1262 |
+
|
1263 |
[[package]]
|
1264 |
name = "marshmallow"
|
1265 |
version = "3.23.1"
|
|
|
1279 |
docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"]
|
1280 |
tests = ["pytest", "simplejson"]
|
1281 |
|
1282 |
+
[[package]]
|
1283 |
+
name = "mdurl"
|
1284 |
+
version = "0.1.2"
|
1285 |
+
description = "Markdown URL utilities"
|
1286 |
+
optional = false
|
1287 |
+
python-versions = ">=3.7"
|
1288 |
+
files = [
|
1289 |
+
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
|
1290 |
+
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
1291 |
+
]
|
1292 |
+
|
1293 |
[[package]]
|
1294 |
name = "multidict"
|
1295 |
version = "6.1.0"
|
|
|
1552 |
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
1553 |
]
|
1554 |
|
1555 |
+
[[package]]
|
1556 |
+
name = "pandas"
|
1557 |
+
version = "2.2.3"
|
1558 |
+
description = "Powerful data structures for data analysis, time series, and statistics"
|
1559 |
+
optional = false
|
1560 |
+
python-versions = ">=3.9"
|
1561 |
+
files = [
|
1562 |
+
{file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"},
|
1563 |
+
{file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"},
|
1564 |
+
{file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"},
|
1565 |
+
{file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"},
|
1566 |
+
{file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"},
|
1567 |
+
{file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"},
|
1568 |
+
{file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"},
|
1569 |
+
{file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"},
|
1570 |
+
{file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"},
|
1571 |
+
{file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"},
|
1572 |
+
{file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"},
|
1573 |
+
{file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"},
|
1574 |
+
{file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"},
|
1575 |
+
{file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"},
|
1576 |
+
{file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"},
|
1577 |
+
{file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"},
|
1578 |
+
{file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"},
|
1579 |
+
{file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"},
|
1580 |
+
{file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"},
|
1581 |
+
{file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"},
|
1582 |
+
{file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"},
|
1583 |
+
{file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"},
|
1584 |
+
{file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"},
|
1585 |
+
{file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"},
|
1586 |
+
{file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"},
|
1587 |
+
{file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"},
|
1588 |
+
{file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"},
|
1589 |
+
{file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"},
|
1590 |
+
{file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"},
|
1591 |
+
{file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"},
|
1592 |
+
]
|
1593 |
+
|
1594 |
+
[package.dependencies]
|
1595 |
+
numpy = [
|
1596 |
+
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
|
1597 |
+
{version = ">=1.22.4", markers = "python_version < \"3.11\""},
|
1598 |
+
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
|
1599 |
+
]
|
1600 |
+
python-dateutil = ">=2.8.2"
|
1601 |
+
pytz = ">=2020.1"
|
1602 |
+
tzdata = ">=2022.7"
|
1603 |
+
|
1604 |
+
[package.extras]
|
1605 |
+
all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"]
|
1606 |
+
aws = ["s3fs (>=2022.11.0)"]
|
1607 |
+
clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"]
|
1608 |
+
compression = ["zstandard (>=0.19.0)"]
|
1609 |
+
computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"]
|
1610 |
+
consortium-standard = ["dataframe-api-compat (>=0.1.7)"]
|
1611 |
+
excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"]
|
1612 |
+
feather = ["pyarrow (>=10.0.1)"]
|
1613 |
+
fss = ["fsspec (>=2022.11.0)"]
|
1614 |
+
gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"]
|
1615 |
+
hdf5 = ["tables (>=3.8.0)"]
|
1616 |
+
html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"]
|
1617 |
+
mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"]
|
1618 |
+
output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"]
|
1619 |
+
parquet = ["pyarrow (>=10.0.1)"]
|
1620 |
+
performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"]
|
1621 |
+
plot = ["matplotlib (>=3.6.3)"]
|
1622 |
+
postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"]
|
1623 |
+
pyarrow = ["pyarrow (>=10.0.1)"]
|
1624 |
+
spss = ["pyreadstat (>=1.2.0)"]
|
1625 |
+
sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"]
|
1626 |
+
test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
|
1627 |
+
xml = ["lxml (>=4.9.2)"]
|
1628 |
+
|
1629 |
+
[[package]]
|
1630 |
+
name = "pillow"
|
1631 |
+
version = "11.0.0"
|
1632 |
+
description = "Python Imaging Library (Fork)"
|
1633 |
+
optional = false
|
1634 |
+
python-versions = ">=3.9"
|
1635 |
+
files = [
|
1636 |
+
{file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"},
|
1637 |
+
{file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"},
|
1638 |
+
{file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"},
|
1639 |
+
{file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"},
|
1640 |
+
{file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"},
|
1641 |
+
{file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"},
|
1642 |
+
{file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"},
|
1643 |
+
{file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"},
|
1644 |
+
{file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"},
|
1645 |
+
{file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"},
|
1646 |
+
{file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"},
|
1647 |
+
{file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"},
|
1648 |
+
{file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"},
|
1649 |
+
{file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"},
|
1650 |
+
{file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"},
|
1651 |
+
{file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"},
|
1652 |
+
{file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"},
|
1653 |
+
{file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"},
|
1654 |
+
{file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"},
|
1655 |
+
{file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"},
|
1656 |
+
{file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"},
|
1657 |
+
{file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"},
|
1658 |
+
{file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"},
|
1659 |
+
{file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"},
|
1660 |
+
{file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"},
|
1661 |
+
{file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"},
|
1662 |
+
{file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"},
|
1663 |
+
{file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"},
|
1664 |
+
{file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"},
|
1665 |
+
{file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"},
|
1666 |
+
{file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"},
|
1667 |
+
{file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"},
|
1668 |
+
{file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"},
|
1669 |
+
{file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"},
|
1670 |
+
{file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"},
|
1671 |
+
{file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"},
|
1672 |
+
{file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"},
|
1673 |
+
{file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"},
|
1674 |
+
{file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"},
|
1675 |
+
{file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"},
|
1676 |
+
{file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"},
|
1677 |
+
{file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"},
|
1678 |
+
{file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"},
|
1679 |
+
{file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"},
|
1680 |
+
{file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"},
|
1681 |
+
{file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"},
|
1682 |
+
{file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"},
|
1683 |
+
{file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"},
|
1684 |
+
{file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"},
|
1685 |
+
{file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"},
|
1686 |
+
{file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"},
|
1687 |
+
{file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"},
|
1688 |
+
{file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"},
|
1689 |
+
{file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"},
|
1690 |
+
{file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"},
|
1691 |
+
{file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"},
|
1692 |
+
{file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"},
|
1693 |
+
{file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"},
|
1694 |
+
{file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"},
|
1695 |
+
{file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"},
|
1696 |
+
{file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"},
|
1697 |
+
{file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"},
|
1698 |
+
{file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"},
|
1699 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"},
|
1700 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"},
|
1701 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"},
|
1702 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"},
|
1703 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"},
|
1704 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"},
|
1705 |
+
{file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"},
|
1706 |
+
{file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"},
|
1707 |
+
{file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"},
|
1708 |
+
{file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"},
|
1709 |
+
{file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"},
|
1710 |
+
{file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"},
|
1711 |
+
]
|
1712 |
+
|
1713 |
+
[package.extras]
|
1714 |
+
docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
|
1715 |
+
fpx = ["olefile"]
|
1716 |
+
mic = ["olefile"]
|
1717 |
+
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
|
1718 |
+
typing = ["typing-extensions"]
|
1719 |
+
xmp = ["defusedxml"]
|
1720 |
+
|
1721 |
[[package]]
|
1722 |
name = "propcache"
|
1723 |
version = "0.2.0"
|
|
|
1969 |
toml = ["tomli (>=2.0.1)"]
|
1970 |
yaml = ["pyyaml (>=6.0.1)"]
|
1971 |
|
1972 |
+
[[package]]
|
1973 |
+
name = "pydub"
|
1974 |
+
version = "0.25.1"
|
1975 |
+
description = "Manipulate audio with an simple and easy high level interface"
|
1976 |
+
optional = false
|
1977 |
+
python-versions = "*"
|
1978 |
+
files = [
|
1979 |
+
{file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"},
|
1980 |
+
{file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"},
|
1981 |
+
]
|
1982 |
+
|
1983 |
+
[[package]]
|
1984 |
+
name = "pygments"
|
1985 |
+
version = "2.18.0"
|
1986 |
+
description = "Pygments is a syntax highlighting package written in Python."
|
1987 |
+
optional = false
|
1988 |
+
python-versions = ">=3.8"
|
1989 |
+
files = [
|
1990 |
+
{file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
|
1991 |
+
{file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
|
1992 |
+
]
|
1993 |
+
|
1994 |
+
[package.extras]
|
1995 |
+
windows-terminal = ["colorama (>=0.4.6)"]
|
1996 |
+
|
1997 |
+
[[package]]
|
1998 |
+
name = "python-dateutil"
|
1999 |
+
version = "2.9.0.post0"
|
2000 |
+
description = "Extensions to the standard Python datetime module"
|
2001 |
+
optional = false
|
2002 |
+
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
2003 |
+
files = [
|
2004 |
+
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
|
2005 |
+
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
|
2006 |
+
]
|
2007 |
+
|
2008 |
+
[package.dependencies]
|
2009 |
+
six = ">=1.5"
|
2010 |
+
|
2011 |
[[package]]
|
2012 |
name = "python-dotenv"
|
2013 |
version = "1.0.1"
|
|
|
2022 |
[package.extras]
|
2023 |
cli = ["click (>=5.0)"]
|
2024 |
|
2025 |
+
[[package]]
|
2026 |
+
name = "python-multipart"
|
2027 |
+
version = "0.0.19"
|
2028 |
+
description = "A streaming multipart parser for Python"
|
2029 |
+
optional = false
|
2030 |
+
python-versions = ">=3.8"
|
2031 |
+
files = [
|
2032 |
+
{file = "python_multipart-0.0.19-py3-none-any.whl", hash = "sha256:f8d5b0b9c618575bf9df01c684ded1d94a338839bdd8223838afacfb4bb2082d"},
|
2033 |
+
{file = "python_multipart-0.0.19.tar.gz", hash = "sha256:905502ef39050557b7a6af411f454bc19526529ca46ae6831508438890ce12cc"},
|
2034 |
+
]
|
2035 |
+
|
2036 |
+
[[package]]
|
2037 |
+
name = "pytz"
|
2038 |
+
version = "2024.2"
|
2039 |
+
description = "World timezone definitions, modern and historical"
|
2040 |
+
optional = false
|
2041 |
+
python-versions = "*"
|
2042 |
+
files = [
|
2043 |
+
{file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"},
|
2044 |
+
{file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"},
|
2045 |
+
]
|
2046 |
+
|
2047 |
[[package]]
|
2048 |
name = "pyyaml"
|
2049 |
version = "6.0.2"
|
|
|
2244 |
[package.dependencies]
|
2245 |
requests = ">=2.0.1,<3.0.0"
|
2246 |
|
2247 |
+
[[package]]
|
2248 |
+
name = "rich"
|
2249 |
+
version = "13.9.4"
|
2250 |
+
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
2251 |
+
optional = false
|
2252 |
+
python-versions = ">=3.8.0"
|
2253 |
+
files = [
|
2254 |
+
{file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"},
|
2255 |
+
{file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"},
|
2256 |
+
]
|
2257 |
+
|
2258 |
+
[package.dependencies]
|
2259 |
+
markdown-it-py = ">=2.2.0"
|
2260 |
+
pygments = ">=2.13.0,<3.0.0"
|
2261 |
+
typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""}
|
2262 |
+
|
2263 |
+
[package.extras]
|
2264 |
+
jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
2265 |
+
|
2266 |
+
[[package]]
|
2267 |
+
name = "ruff"
|
2268 |
+
version = "0.8.2"
|
2269 |
+
description = "An extremely fast Python linter and code formatter, written in Rust."
|
2270 |
+
optional = false
|
2271 |
+
python-versions = ">=3.7"
|
2272 |
+
files = [
|
2273 |
+
{file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"},
|
2274 |
+
{file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"},
|
2275 |
+
{file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"},
|
2276 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"},
|
2277 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"},
|
2278 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"},
|
2279 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"},
|
2280 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"},
|
2281 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"},
|
2282 |
+
{file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"},
|
2283 |
+
{file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"},
|
2284 |
+
{file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"},
|
2285 |
+
{file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"},
|
2286 |
+
{file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"},
|
2287 |
+
{file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"},
|
2288 |
+
{file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"},
|
2289 |
+
{file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"},
|
2290 |
+
{file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"},
|
2291 |
+
]
|
2292 |
+
|
2293 |
+
[[package]]
|
2294 |
+
name = "safehttpx"
|
2295 |
+
version = "0.1.6"
|
2296 |
+
description = "A small Python library created to help developers protect their applications from Server Side Request Forgery (SSRF) attacks."
|
2297 |
+
optional = false
|
2298 |
+
python-versions = ">3.9"
|
2299 |
+
files = [
|
2300 |
+
{file = "safehttpx-0.1.6-py3-none-any.whl", hash = "sha256:407cff0b410b071623087c63dd2080c3b44dc076888d8c5823c00d1e58cb381c"},
|
2301 |
+
{file = "safehttpx-0.1.6.tar.gz", hash = "sha256:b356bfc82cee3a24c395b94a2dbeabbed60aff1aa5fa3b5fe97c4f2456ebce42"},
|
2302 |
+
]
|
2303 |
+
|
2304 |
+
[package.dependencies]
|
2305 |
+
httpx = "*"
|
2306 |
+
|
2307 |
+
[package.extras]
|
2308 |
+
dev = ["pytest"]
|
2309 |
+
|
2310 |
+
[[package]]
|
2311 |
+
name = "semantic-version"
|
2312 |
+
version = "2.10.0"
|
2313 |
+
description = "A library implementing the 'SemVer' scheme."
|
2314 |
+
optional = false
|
2315 |
+
python-versions = ">=2.7"
|
2316 |
+
files = [
|
2317 |
+
{file = "semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"},
|
2318 |
+
{file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"},
|
2319 |
+
]
|
2320 |
+
|
2321 |
+
[package.extras]
|
2322 |
+
dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"]
|
2323 |
+
doc = ["Sphinx", "sphinx-rtd-theme"]
|
2324 |
+
|
2325 |
+
[[package]]
|
2326 |
+
name = "shellingham"
|
2327 |
+
version = "1.5.4"
|
2328 |
+
description = "Tool to Detect Surrounding Shell"
|
2329 |
+
optional = false
|
2330 |
+
python-versions = ">=3.7"
|
2331 |
+
files = [
|
2332 |
+
{file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
|
2333 |
+
{file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
|
2334 |
+
]
|
2335 |
+
|
2336 |
+
[[package]]
|
2337 |
+
name = "six"
|
2338 |
+
version = "1.17.0"
|
2339 |
+
description = "Python 2 and 3 compatibility utilities"
|
2340 |
+
optional = false
|
2341 |
+
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
2342 |
+
files = [
|
2343 |
+
{file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
|
2344 |
+
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
|
2345 |
+
]
|
2346 |
+
|
2347 |
[[package]]
|
2348 |
name = "sniffio"
|
2349 |
version = "1.3.1"
|
|
|
2521 |
[package.extras]
|
2522 |
blobfile = ["blobfile (>=2)"]
|
2523 |
|
2524 |
+
[[package]]
|
2525 |
+
name = "tomlkit"
|
2526 |
+
version = "0.13.2"
|
2527 |
+
description = "Style preserving TOML library"
|
2528 |
+
optional = false
|
2529 |
+
python-versions = ">=3.8"
|
2530 |
+
files = [
|
2531 |
+
{file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
|
2532 |
+
{file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
|
2533 |
+
]
|
2534 |
+
|
2535 |
[[package]]
|
2536 |
name = "tqdm"
|
2537 |
version = "4.67.0"
|
|
|
2553 |
slack = ["slack-sdk"]
|
2554 |
telegram = ["requests"]
|
2555 |
|
2556 |
+
[[package]]
|
2557 |
+
name = "typer"
|
2558 |
+
version = "0.15.1"
|
2559 |
+
description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
|
2560 |
+
optional = false
|
2561 |
+
python-versions = ">=3.7"
|
2562 |
+
files = [
|
2563 |
+
{file = "typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847"},
|
2564 |
+
{file = "typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a"},
|
2565 |
+
]
|
2566 |
+
|
2567 |
+
[package.dependencies]
|
2568 |
+
click = ">=8.0.0"
|
2569 |
+
rich = ">=10.11.0"
|
2570 |
+
shellingham = ">=1.3.0"
|
2571 |
+
typing-extensions = ">=3.7.4.3"
|
2572 |
+
|
2573 |
[[package]]
|
2574 |
name = "typing-extensions"
|
2575 |
version = "4.12.2"
|
|
|
2596 |
mypy-extensions = ">=0.3.0"
|
2597 |
typing-extensions = ">=3.7.4"
|
2598 |
|
2599 |
+
[[package]]
|
2600 |
+
name = "tzdata"
|
2601 |
+
version = "2024.2"
|
2602 |
+
description = "Provider of IANA time zone data"
|
2603 |
+
optional = false
|
2604 |
+
python-versions = ">=2"
|
2605 |
+
files = [
|
2606 |
+
{file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"},
|
2607 |
+
{file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"},
|
2608 |
+
]
|
2609 |
+
|
2610 |
[[package]]
|
2611 |
name = "urllib3"
|
2612 |
version = "2.2.3"
|
|
|
2643 |
[package.extras]
|
2644 |
standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
2645 |
|
2646 |
+
[[package]]
|
2647 |
+
name = "websockets"
|
2648 |
+
version = "14.1"
|
2649 |
+
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
2650 |
+
optional = false
|
2651 |
+
python-versions = ">=3.9"
|
2652 |
+
files = [
|
2653 |
+
{file = "websockets-14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29"},
|
2654 |
+
{file = "websockets-14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179"},
|
2655 |
+
{file = "websockets-14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250"},
|
2656 |
+
{file = "websockets-14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0"},
|
2657 |
+
{file = "websockets-14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0"},
|
2658 |
+
{file = "websockets-14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199"},
|
2659 |
+
{file = "websockets-14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58"},
|
2660 |
+
{file = "websockets-14.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078"},
|
2661 |
+
{file = "websockets-14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434"},
|
2662 |
+
{file = "websockets-14.1-cp310-cp310-win32.whl", hash = "sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10"},
|
2663 |
+
{file = "websockets-14.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e"},
|
2664 |
+
{file = "websockets-14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:449d77d636f8d9c17952628cc7e3b8faf6e92a17ec581ec0c0256300717e1512"},
|
2665 |
+
{file = "websockets-14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a35f704be14768cea9790d921c2c1cc4fc52700410b1c10948511039be824aac"},
|
2666 |
+
{file = "websockets-14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b1f3628a0510bd58968c0f60447e7a692933589b791a6b572fcef374053ca280"},
|
2667 |
+
{file = "websockets-14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c3deac3748ec73ef24fc7be0b68220d14d47d6647d2f85b2771cb35ea847aa1"},
|
2668 |
+
{file = "websockets-14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7048eb4415d46368ef29d32133134c513f507fff7d953c18c91104738a68c3b3"},
|
2669 |
+
{file = "websockets-14.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cf0ad281c979306a6a34242b371e90e891bce504509fb6bb5246bbbf31e7b6"},
|
2670 |
+
{file = "websockets-14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cc1fc87428c1d18b643479caa7b15db7d544652e5bf610513d4a3478dbe823d0"},
|
2671 |
+
{file = "websockets-14.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f95ba34d71e2fa0c5d225bde3b3bdb152e957150100e75c86bc7f3964c450d89"},
|
2672 |
+
{file = "websockets-14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9481a6de29105d73cf4515f2bef8eb71e17ac184c19d0b9918a3701c6c9c4f23"},
|
2673 |
+
{file = "websockets-14.1-cp311-cp311-win32.whl", hash = "sha256:368a05465f49c5949e27afd6fbe0a77ce53082185bbb2ac096a3a8afaf4de52e"},
|
2674 |
+
{file = "websockets-14.1-cp311-cp311-win_amd64.whl", hash = "sha256:6d24fc337fc055c9e83414c94e1ee0dee902a486d19d2a7f0929e49d7d604b09"},
|
2675 |
+
{file = "websockets-14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed"},
|
2676 |
+
{file = "websockets-14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d"},
|
2677 |
+
{file = "websockets-14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707"},
|
2678 |
+
{file = "websockets-14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a"},
|
2679 |
+
{file = "websockets-14.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45"},
|
2680 |
+
{file = "websockets-14.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58"},
|
2681 |
+
{file = "websockets-14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058"},
|
2682 |
+
{file = "websockets-14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4"},
|
2683 |
+
{file = "websockets-14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05"},
|
2684 |
+
{file = "websockets-14.1-cp312-cp312-win32.whl", hash = "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0"},
|
2685 |
+
{file = "websockets-14.1-cp312-cp312-win_amd64.whl", hash = "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f"},
|
2686 |
+
{file = "websockets-14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3630b670d5057cd9e08b9c4dab6493670e8e762a24c2c94ef312783870736ab9"},
|
2687 |
+
{file = "websockets-14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36ebd71db3b89e1f7b1a5deaa341a654852c3518ea7a8ddfdf69cc66acc2db1b"},
|
2688 |
+
{file = "websockets-14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5b918d288958dc3fa1c5a0b9aa3256cb2b2b84c54407f4813c45d52267600cd3"},
|
2689 |
+
{file = "websockets-14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00fe5da3f037041da1ee0cf8e308374e236883f9842c7c465aa65098b1c9af59"},
|
2690 |
+
{file = "websockets-14.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8149a0f5a72ca36720981418eeffeb5c2729ea55fa179091c81a0910a114a5d2"},
|
2691 |
+
{file = "websockets-14.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77569d19a13015e840b81550922056acabc25e3f52782625bc6843cfa034e1da"},
|
2692 |
+
{file = "websockets-14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf5201a04550136ef870aa60ad3d29d2a59e452a7f96b94193bee6d73b8ad9a9"},
|
2693 |
+
{file = "websockets-14.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:88cf9163ef674b5be5736a584c999e98daf3aabac6e536e43286eb74c126b9c7"},
|
2694 |
+
{file = "websockets-14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:836bef7ae338a072e9d1863502026f01b14027250a4545672673057997d5c05a"},
|
2695 |
+
{file = "websockets-14.1-cp313-cp313-win32.whl", hash = "sha256:0d4290d559d68288da9f444089fd82490c8d2744309113fc26e2da6e48b65da6"},
|
2696 |
+
{file = "websockets-14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8621a07991add373c3c5c2cf89e1d277e49dc82ed72c75e3afc74bd0acc446f0"},
|
2697 |
+
{file = "websockets-14.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:01bb2d4f0a6d04538d3c5dfd27c0643269656c28045a53439cbf1c004f90897a"},
|
2698 |
+
{file = "websockets-14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:414ffe86f4d6f434a8c3b7913655a1a5383b617f9bf38720e7c0799fac3ab1c6"},
|
2699 |
+
{file = "websockets-14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8fda642151d5affdee8a430bd85496f2e2517be3a2b9d2484d633d5712b15c56"},
|
2700 |
+
{file = "websockets-14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd7c11968bc3860d5c78577f0dbc535257ccec41750675d58d8dc66aa47fe52c"},
|
2701 |
+
{file = "websockets-14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a032855dc7db987dff813583d04f4950d14326665d7e714d584560b140ae6b8b"},
|
2702 |
+
{file = "websockets-14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7e7ea2f782408c32d86b87a0d2c1fd8871b0399dd762364c731d86c86069a78"},
|
2703 |
+
{file = "websockets-14.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:39450e6215f7d9f6f7bc2a6da21d79374729f5d052333da4d5825af8a97e6735"},
|
2704 |
+
{file = "websockets-14.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ceada5be22fa5a5a4cdeec74e761c2ee7db287208f54c718f2df4b7e200b8d4a"},
|
2705 |
+
{file = "websockets-14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3fc753451d471cff90b8f467a1fc0ae64031cf2d81b7b34e1811b7e2691bc4bc"},
|
2706 |
+
{file = "websockets-14.1-cp39-cp39-win32.whl", hash = "sha256:14839f54786987ccd9d03ed7f334baec0f02272e7ec4f6e9d427ff584aeea8b4"},
|
2707 |
+
{file = "websockets-14.1-cp39-cp39-win_amd64.whl", hash = "sha256:d9fd19ecc3a4d5ae82ddbfb30962cf6d874ff943e56e0c81f5169be2fda62979"},
|
2708 |
+
{file = "websockets-14.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8"},
|
2709 |
+
{file = "websockets-14.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e"},
|
2710 |
+
{file = "websockets-14.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098"},
|
2711 |
+
{file = "websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb"},
|
2712 |
+
{file = "websockets-14.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7"},
|
2713 |
+
{file = "websockets-14.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d"},
|
2714 |
+
{file = "websockets-14.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ddaa4a390af911da6f680be8be4ff5aaf31c4c834c1a9147bc21cbcbca2d4370"},
|
2715 |
+
{file = "websockets-14.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a4c805c6034206143fbabd2d259ec5e757f8b29d0a2f0bf3d2fe5d1f60147a4a"},
|
2716 |
+
{file = "websockets-14.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:205f672a6c2c671a86d33f6d47c9b35781a998728d2c7c2a3e1cf3333fcb62b7"},
|
2717 |
+
{file = "websockets-14.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef440054124728cc49b01c33469de06755e5a7a4e83ef61934ad95fc327fbb0"},
|
2718 |
+
{file = "websockets-14.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7591d6f440af7f73c4bd9404f3772bfee064e639d2b6cc8c94076e71b2471c1"},
|
2719 |
+
{file = "websockets-14.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:25225cc79cfebc95ba1d24cd3ab86aaa35bcd315d12fa4358939bd55e9bd74a5"},
|
2720 |
+
{file = "websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e"},
|
2721 |
+
{file = "websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8"},
|
2722 |
+
]
|
2723 |
+
|
2724 |
[[package]]
|
2725 |
name = "yarl"
|
2726 |
version = "1.17.1"
|
|
|
2820 |
[metadata]
|
2821 |
lock-version = "2.0"
|
2822 |
python-versions = "^3.10"
|
2823 |
+
content-hash = "fc3fccebdc1dad30f562185560b085f474738badd36f1a674b28d11c1fe7ed23"
|
pyproject.toml
CHANGED
@@ -14,6 +14,8 @@ langchain-community = "^0.3.7"
|
|
14 |
pydantic = "^2.9.2"
|
15 |
fastapi = "^0.115.5"
|
16 |
uvicorn = "^0.32.0"
|
|
|
|
|
17 |
|
18 |
|
19 |
[build-system]
|
|
|
14 |
pydantic = "^2.9.2"
|
15 |
fastapi = "^0.115.5"
|
16 |
uvicorn = "^0.32.0"
|
17 |
+
gradio = "^5.8.0"
|
18 |
+
langchain-groq = "^0.2.1"
|
19 |
|
20 |
|
21 |
[build-system]
|