Spaces:
Running
Running
Commit
·
c55fe6a
1
Parent(s):
9e822e4
feat: working gradio demo
Browse files- agent.py +42 -43
- app.py +2 -7
- gradio_app.py +162 -0
- poetry.lock +488 -64
- pyproject.toml +1 -0
- src/agents/image-edit-agent.py +21 -23
- src/agents/mask_generation_agent.py +41 -41
- src/hopter/client.py +17 -19
- src/services/generate_mask.py +5 -5
- src/utils.py +11 -0
agent.py
CHANGED
@@ -1,19 +1,12 @@
|
|
1 |
-
from openai import OpenAI
|
2 |
import streamlit as st
|
3 |
-
from typing import TypedDict, Literal
|
4 |
-
from pydantic import BaseModel
|
5 |
-
import base64
|
6 |
from pydantic_ai.messages import (
|
7 |
-
ModelMessage,
|
8 |
ModelRequest,
|
9 |
ModelResponse,
|
10 |
-
SystemPromptPart,
|
11 |
UserPromptPart,
|
12 |
TextPart,
|
13 |
ToolCallPart,
|
14 |
ToolReturnPart,
|
15 |
-
RetryPromptPart,
|
16 |
-
ModelMessagesTypeAdapter
|
17 |
)
|
18 |
import asyncio
|
19 |
from src.agents.mask_generation_agent import mask_generation_agent, ImageEditDeps
|
@@ -21,14 +14,22 @@ from src.hopter.client import Hopter, Environment
|
|
21 |
import os
|
22 |
from src.services.generate_mask import GenerateMaskService
|
23 |
from dotenv import load_dotenv
|
24 |
-
|
25 |
load_dotenv()
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
hopter = Hopter(
|
28 |
api_key=os.getenv("HOPTER_API_KEY"),
|
29 |
environment=Environment.STAGING
|
30 |
)
|
31 |
mask_service = GenerateMaskService(hopter=hopter)
|
|
|
32 |
|
33 |
class ChatMessage(TypedDict):
|
34 |
"""Format of messages sent to the browser/API."""
|
@@ -57,6 +58,16 @@ def display_message_part(part):
|
|
57 |
with st.chat_message("assistant"):
|
58 |
st.markdown(part.content)
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
async def run_agent(user_input: str, image_b64: str):
|
61 |
messages = [
|
62 |
{
|
@@ -99,15 +110,10 @@ async def run_agent(user_input: str, image_b64: str):
|
|
99 |
st.session_state.messages.append(
|
100 |
ModelResponse(parts=[TextPart(content=partial_text)])
|
101 |
)
|
|
|
102 |
|
103 |
async def main():
|
104 |
-
st.title("
|
105 |
-
|
106 |
-
def encode_image(uploaded_file):
|
107 |
-
# Read the file directly from the UploadedFile object
|
108 |
-
return base64.b64encode(uploaded_file.read()).decode("utf-8")
|
109 |
-
|
110 |
-
image = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
|
111 |
|
112 |
if "openai_model" not in st.session_state:
|
113 |
st.session_state["openai_model"] = "gpt-4o"
|
@@ -118,42 +124,35 @@ async def main():
|
|
118 |
if "image" not in st.session_state:
|
119 |
st.session_state.image = None
|
120 |
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
# Chat input for the user
|
130 |
-
user_input = st.chat_input("What would you like to edit your image?")
|
131 |
-
|
132 |
-
if user_input:
|
133 |
-
if image is not None:
|
134 |
-
st.session_state.image = image
|
135 |
-
|
136 |
-
# We append a new request to the conversation explicitly
|
137 |
st.session_state.messages.append(
|
138 |
ModelRequest(parts=[UserPromptPart(content=user_input)])
|
139 |
)
|
140 |
-
|
141 |
-
# Display user prompt in the UI
|
142 |
-
with st.chat_message("user"):
|
143 |
-
if st.session_state.image:
|
144 |
-
st.image(st.session_state.image)
|
145 |
-
st.markdown(user_input)
|
146 |
|
147 |
# Display the assistant's partial response while streaming
|
148 |
with st.chat_message("assistant"):
|
149 |
# Actually run the agent now, streaming the text
|
150 |
-
|
151 |
-
|
152 |
-
image_url = f"data:image/jpeg;base64,{image_data}"
|
153 |
-
await run_agent(user_input, image_url)
|
154 |
-
else:
|
155 |
-
await run_agent(user_input)
|
156 |
-
|
157 |
|
158 |
if __name__ == "__main__":
|
159 |
asyncio.run(main())
|
|
|
|
|
1 |
import streamlit as st
|
2 |
+
from typing import TypedDict, Literal
|
|
|
|
|
3 |
from pydantic_ai.messages import (
|
|
|
4 |
ModelRequest,
|
5 |
ModelResponse,
|
|
|
6 |
UserPromptPart,
|
7 |
TextPart,
|
8 |
ToolCallPart,
|
9 |
ToolReturnPart,
|
|
|
|
|
10 |
)
|
11 |
import asyncio
|
12 |
from src.agents.mask_generation_agent import mask_generation_agent, ImageEditDeps
|
|
|
14 |
import os
|
15 |
from src.services.generate_mask import GenerateMaskService
|
16 |
from dotenv import load_dotenv
|
17 |
+
from src.utils import image_path_to_uri
|
18 |
load_dotenv()
|
19 |
|
20 |
+
st.set_page_config(
|
21 |
+
page_title="Conversational Image Editor",
|
22 |
+
page_icon="🧊",
|
23 |
+
layout="wide",
|
24 |
+
initial_sidebar_state="collapsed"
|
25 |
+
)
|
26 |
+
|
27 |
hopter = Hopter(
|
28 |
api_key=os.getenv("HOPTER_API_KEY"),
|
29 |
environment=Environment.STAGING
|
30 |
)
|
31 |
mask_service = GenerateMaskService(hopter=hopter)
|
32 |
+
user_msg_input_key = "input_user_msg"
|
33 |
|
34 |
class ChatMessage(TypedDict):
|
35 |
"""Format of messages sent to the browser/API."""
|
|
|
58 |
with st.chat_message("assistant"):
|
59 |
st.markdown(part.content)
|
60 |
|
61 |
+
# tool call
|
62 |
+
elif part.part_kind == 'tool-call':
|
63 |
+
with st.chat_message("assistant"):
|
64 |
+
st.markdown(f"**{part.tool_name}**: {part.args}")
|
65 |
+
|
66 |
+
# tool return
|
67 |
+
elif part.part_kind == 'tool-return':
|
68 |
+
with st.chat_message("assistant"):
|
69 |
+
st.markdown(f"**{part.tool_name}**: {part.content}")
|
70 |
+
|
71 |
async def run_agent(user_input: str, image_b64: str):
|
72 |
messages = [
|
73 |
{
|
|
|
110 |
st.session_state.messages.append(
|
111 |
ModelResponse(parts=[TextPart(content=partial_text)])
|
112 |
)
|
113 |
+
st.rerun()
|
114 |
|
115 |
async def main():
|
116 |
+
st.title("Conversational Image Editor")
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
if "openai_model" not in st.session_state:
|
119 |
st.session_state["openai_model"] = "gpt-4o"
|
|
|
124 |
if "image" not in st.session_state:
|
125 |
st.session_state.image = None
|
126 |
|
127 |
+
chat_col, image_col = st.columns(2)
|
128 |
+
with chat_col:
|
129 |
+
# Display all messages from the conversation so far
|
130 |
+
# Each message is either a ModelRequest or ModelResponse.
|
131 |
+
# We iterate over their parts to decide how to display them.
|
132 |
+
for msg in st.session_state.messages:
|
133 |
+
if isinstance(msg, ModelRequest) or isinstance(msg, ModelResponse) or isinstance(msg, ToolCallPart) or isinstance(msg, ToolReturnPart):
|
134 |
+
for part in msg.parts:
|
135 |
+
display_message_part(part)
|
136 |
+
|
137 |
+
with image_col:
|
138 |
+
st.session_state.image = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
|
139 |
+
if st.session_state.image:
|
140 |
+
st.image(st.session_state.image)
|
141 |
+
else:
|
142 |
+
st.write("Upload an image to get started")
|
143 |
|
144 |
# Chat input for the user
|
145 |
+
user_input = st.chat_input("What would you like to edit your image?", disabled=not st.session_state.image)
|
146 |
+
if user_input and st.session_state.image:
|
|
|
|
|
|
|
|
|
|
|
147 |
st.session_state.messages.append(
|
148 |
ModelRequest(parts=[UserPromptPart(content=user_input)])
|
149 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
# Display the assistant's partial response while streaming
|
152 |
with st.chat_message("assistant"):
|
153 |
# Actually run the agent now, streaming the text
|
154 |
+
image_url = image_path_to_uri(st.session_state.image)
|
155 |
+
await run_agent(user_input, image_url)
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
if __name__ == "__main__":
|
158 |
asyncio.run(main())
|
app.py
CHANGED
@@ -1,13 +1,9 @@
|
|
1 |
from openai import OpenAI
|
2 |
import streamlit as st
|
3 |
-
import
|
4 |
|
5 |
st.title("ChatGPT-like clone")
|
6 |
|
7 |
-
def encode_image(uploaded_file):
|
8 |
-
# Read the file directly from the UploadedFile object
|
9 |
-
return base64.b64encode(uploaded_file.read()).decode("utf-8")
|
10 |
-
|
11 |
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
12 |
image = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
|
13 |
|
@@ -33,8 +29,7 @@ if prompt := st.chat_input("What is up?"):
|
|
33 |
if image is not None:
|
34 |
st.session_state.image = image
|
35 |
if st.session_state.image:
|
36 |
-
|
37 |
-
image_url = f"data:image/jpeg;base64,{image_data}"
|
38 |
st.session_state.messages.append({"role": "user", "content": [
|
39 |
{"type": "text", "text": prompt},
|
40 |
{"type": "image_url", "image_url": {"url": image_url}}
|
|
|
1 |
from openai import OpenAI
|
2 |
import streamlit as st
|
3 |
+
from src.utils import image_path_to_uri
|
4 |
|
5 |
st.title("ChatGPT-like clone")
|
6 |
|
|
|
|
|
|
|
|
|
7 |
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
8 |
image = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
|
9 |
|
|
|
29 |
if image is not None:
|
30 |
st.session_state.image = image
|
31 |
if st.session_state.image:
|
32 |
+
image_url = image_path_to_uri(st.session_state.image)
|
|
|
33 |
st.session_state.messages.append({"role": "user", "content": [
|
34 |
{"type": "text", "text": prompt},
|
35 |
{"type": "image_url", "image_url": {"url": image_url}}
|
gradio_app.py
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from src.agents.mask_generation_agent import mask_generation_agent, ImageEditDeps
|
3 |
+
import os
|
4 |
+
from src.hopter.client import Hopter, Environment
|
5 |
+
from src.services.generate_mask import GenerateMaskService
|
6 |
+
from dotenv import load_dotenv
|
7 |
+
from src.utils import image_path_to_uri
|
8 |
+
from pydantic_ai.messages import (
|
9 |
+
ToolCallPart,
|
10 |
+
ToolReturnPart
|
11 |
+
)
|
12 |
+
from src.agents.mask_generation_agent import EditImageResult
|
13 |
+
from pydantic_ai.agent import Agent
|
14 |
+
from pydantic_ai.models.openai import OpenAIModel
|
15 |
+
|
16 |
+
model = OpenAIModel(
|
17 |
+
"gpt-4o",
|
18 |
+
api_key=os.environ.get("OPENAI_API_KEY"),
|
19 |
+
)
|
20 |
+
|
21 |
+
simple_agent = Agent(
|
22 |
+
model,
|
23 |
+
system_prompt="You are a helpful assistant that can answer questions and help with tasks.",
|
24 |
+
deps_type=ImageEditDeps
|
25 |
+
)
|
26 |
+
|
27 |
+
load_dotenv()
|
28 |
+
|
29 |
+
def build_user_message(chat_input):
|
30 |
+
text = chat_input["text"]
|
31 |
+
images = chat_input["files"]
|
32 |
+
messages = [
|
33 |
+
{
|
34 |
+
"role": "user",
|
35 |
+
"content": text
|
36 |
+
}
|
37 |
+
]
|
38 |
+
if images:
|
39 |
+
messages.extend([
|
40 |
+
{
|
41 |
+
"role": "user",
|
42 |
+
"content": {"path": image}
|
43 |
+
}
|
44 |
+
for image in images
|
45 |
+
])
|
46 |
+
return messages
|
47 |
+
|
48 |
+
async def stream_from_agent(chat_input, chatbot, past_messages):
|
49 |
+
chatbot.extend(build_user_message(chat_input))
|
50 |
+
# Clear the input immediately after submission
|
51 |
+
yield {"text": "", "files": []}, chatbot, gr.skip
|
52 |
+
|
53 |
+
# for agent
|
54 |
+
text = chat_input["text"]
|
55 |
+
images = [image_path_to_uri(image) for image in chat_input["files"]]
|
56 |
+
messages = [
|
57 |
+
{
|
58 |
+
"type": "text",
|
59 |
+
"text": text
|
60 |
+
},
|
61 |
+
]
|
62 |
+
if images:
|
63 |
+
messages.extend([
|
64 |
+
{"type": "image_url", "image_url": {"url": image}}
|
65 |
+
for image in images
|
66 |
+
])
|
67 |
+
|
68 |
+
hopter = Hopter(os.environ.get("HOPTER_API_KEY"), environment=Environment.STAGING)
|
69 |
+
mask_service = GenerateMaskService(hopter=hopter)
|
70 |
+
deps = ImageEditDeps(
|
71 |
+
edit_instruction=text,
|
72 |
+
image_url=images[0],
|
73 |
+
hopter_client=hopter,
|
74 |
+
mask_service=mask_service
|
75 |
+
)
|
76 |
+
async with mask_generation_agent.run_stream(
|
77 |
+
messages,
|
78 |
+
deps=deps
|
79 |
+
) as result:
|
80 |
+
for message in result.new_messages():
|
81 |
+
for call in message.parts:
|
82 |
+
if isinstance(call, ToolCallPart):
|
83 |
+
call_args = (
|
84 |
+
call.args.args_json
|
85 |
+
if hasattr(call.args, 'args_json')
|
86 |
+
else call.args
|
87 |
+
)
|
88 |
+
metadata = {
|
89 |
+
'title': f'🛠️ Using {call.tool_name}',
|
90 |
+
}
|
91 |
+
if call.tool_call_id is not None:
|
92 |
+
metadata['id'] = call.tool_call_id
|
93 |
+
|
94 |
+
gr_message = {
|
95 |
+
'role': 'assistant',
|
96 |
+
'content': 'Parameters: ' + call_args,
|
97 |
+
'metadata': metadata,
|
98 |
+
}
|
99 |
+
chatbot.append(gr_message)
|
100 |
+
if isinstance(call, ToolReturnPart):
|
101 |
+
for gr_message in chatbot:
|
102 |
+
if (
|
103 |
+
gr_message.get('metadata', {}).get('id', '')
|
104 |
+
== call.tool_call_id
|
105 |
+
):
|
106 |
+
if isinstance(call.content, EditImageResult):
|
107 |
+
chatbot.append({
|
108 |
+
"role": "assistant",
|
109 |
+
"content": gr.Image(call.content.edited_image_url),
|
110 |
+
"files": [call.content.edited_image_url]
|
111 |
+
})
|
112 |
+
else:
|
113 |
+
gr_message['content'] += (
|
114 |
+
f'\nOutput: {call.content}'
|
115 |
+
)
|
116 |
+
yield gr.skip(), chatbot, gr.skip()
|
117 |
+
|
118 |
+
chatbot.append({'role': 'assistant', 'content': ''})
|
119 |
+
async for message in result.stream_text():
|
120 |
+
chatbot[-1]['content'] = message
|
121 |
+
yield gr.skip(), chatbot, gr.skip()
|
122 |
+
past_messages = result.all_messages()
|
123 |
+
|
124 |
+
yield gr.Textbox(interactive=True), gr.skip(), past_messages
|
125 |
+
|
126 |
+
with gr.Blocks() as demo:
|
127 |
+
gr.HTML(
|
128 |
+
"""
|
129 |
+
<div style="display: flex; justify-content: center; align-items: center; gap: 2rem; padding: 1rem; width: 100%">
|
130 |
+
<img src="https://ai.pydantic.dev/img/logo-white.svg" style="max-width: 200px; height: auto">
|
131 |
+
<div>
|
132 |
+
<h1 style="margin: 0 0 1rem 0">Image Editing Assistant</h1>
|
133 |
+
<h3 style="margin: 0 0 0.5rem 0">
|
134 |
+
This assistant edits images according to your instructions.
|
135 |
+
</h3>
|
136 |
+
</div>
|
137 |
+
</div>
|
138 |
+
"""
|
139 |
+
)
|
140 |
+
|
141 |
+
past_messages = gr.State([])
|
142 |
+
chatbot = gr.Chatbot(
|
143 |
+
label='Image Editing Assistant',
|
144 |
+
type='messages',
|
145 |
+
avatar_images=(None, 'https://ai.pydantic.dev/img/logo-white.svg'),
|
146 |
+
)
|
147 |
+
with gr.Row():
|
148 |
+
chat_input = gr.MultimodalTextbox(
|
149 |
+
interactive=True,
|
150 |
+
file_count="multiple",
|
151 |
+
show_label=False,
|
152 |
+
placeholder='How would you like to edit this image?',
|
153 |
+
sources=["upload", "microphone"]
|
154 |
+
)
|
155 |
+
generation = chat_input.submit(
|
156 |
+
stream_from_agent,
|
157 |
+
inputs=[chat_input, chatbot, past_messages],
|
158 |
+
outputs=[chat_input, chatbot, past_messages],
|
159 |
+
)
|
160 |
+
|
161 |
+
if __name__ == '__main__':
|
162 |
+
demo.launch()
|
poetry.lock
CHANGED
@@ -1,5 +1,16 @@
|
|
1 |
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
[[package]]
|
4 |
name = "altair"
|
5 |
version = "5.5.0"
|
@@ -351,6 +362,26 @@ files = [
|
|
351 |
[package.extras]
|
352 |
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"]
|
353 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
[[package]]
|
355 |
name = "fastavro"
|
356 |
version = "1.10.0"
|
@@ -397,6 +428,17 @@ lz4 = ["lz4"]
|
|
397 |
snappy = ["cramjam"]
|
398 |
zstandard = ["zstandard"]
|
399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
[[package]]
|
401 |
name = "filelock"
|
402 |
version = "3.17.0"
|
@@ -525,6 +567,67 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4
|
|
525 |
[package.extras]
|
526 |
grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"]
|
527 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
528 |
[[package]]
|
529 |
name = "griffe"
|
530 |
version = "1.5.7"
|
@@ -924,72 +1027,71 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
|
|
924 |
|
925 |
[[package]]
|
926 |
name = "markupsafe"
|
927 |
-
version = "
|
928 |
description = "Safely add untrusted strings to HTML/XML markup."
|
929 |
optional = false
|
930 |
-
python-versions = ">=3.
|
931 |
files = [
|
932 |
-
{file = "MarkupSafe-
|
933 |
-
{file = "MarkupSafe-
|
934 |
-
{file = "MarkupSafe-
|
935 |
-
{file = "MarkupSafe-
|
936 |
-
{file = "MarkupSafe-
|
937 |
-
{file = "MarkupSafe-
|
938 |
-
{file = "MarkupSafe-
|
939 |
-
{file = "MarkupSafe-
|
940 |
-
{file = "MarkupSafe-
|
941 |
-
{file = "MarkupSafe-
|
942 |
-
{file = "MarkupSafe-
|
943 |
-
{file = "MarkupSafe-
|
944 |
-
{file = "MarkupSafe-
|
945 |
-
{file = "MarkupSafe-
|
946 |
-
{file = "MarkupSafe-
|
947 |
-
{file = "MarkupSafe-
|
948 |
-
{file = "MarkupSafe-
|
949 |
-
{file = "MarkupSafe-
|
950 |
-
{file = "MarkupSafe-
|
951 |
-
{file = "MarkupSafe-
|
952 |
-
{file = "MarkupSafe-
|
953 |
-
{file = "MarkupSafe-
|
954 |
-
{file = "MarkupSafe-
|
955 |
-
{file = "MarkupSafe-
|
956 |
-
{file = "MarkupSafe-
|
957 |
-
{file = "MarkupSafe-
|
958 |
-
{file = "MarkupSafe-
|
959 |
-
{file = "MarkupSafe-
|
960 |
-
{file = "MarkupSafe-
|
961 |
-
{file = "MarkupSafe-
|
962 |
-
{file = "MarkupSafe-
|
963 |
-
{file = "MarkupSafe-
|
964 |
-
{file = "MarkupSafe-
|
965 |
-
{file = "MarkupSafe-
|
966 |
-
{file = "MarkupSafe-
|
967 |
-
{file = "MarkupSafe-
|
968 |
-
{file = "MarkupSafe-
|
969 |
-
{file = "MarkupSafe-
|
970 |
-
{file = "MarkupSafe-
|
971 |
-
{file = "MarkupSafe-
|
972 |
-
{file = "MarkupSafe-
|
973 |
-
{file = "MarkupSafe-
|
974 |
-
{file = "MarkupSafe-
|
975 |
-
{file = "MarkupSafe-
|
976 |
-
{file = "MarkupSafe-
|
977 |
-
{file = "MarkupSafe-
|
978 |
-
{file = "MarkupSafe-
|
979 |
-
{file = "MarkupSafe-
|
980 |
-
{file = "MarkupSafe-
|
981 |
-
{file = "MarkupSafe-
|
982 |
-
{file = "MarkupSafe-
|
983 |
-
{file = "MarkupSafe-
|
984 |
-
{file = "MarkupSafe-
|
985 |
-
{file = "MarkupSafe-
|
986 |
-
{file = "MarkupSafe-
|
987 |
-
{file = "MarkupSafe-
|
988 |
-
{file = "MarkupSafe-
|
989 |
-
{file = "MarkupSafe-
|
990 |
-
{file = "MarkupSafe-
|
991 |
-
{file = "MarkupSafe-
|
992 |
-
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
|
993 |
]
|
994 |
|
995 |
[[package]]
|
@@ -1262,6 +1364,94 @@ files = [
|
|
1262 |
deprecated = ">=1.2.6"
|
1263 |
opentelemetry-api = "1.30.0"
|
1264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1265 |
[[package]]
|
1266 |
name = "packaging"
|
1267 |
version = "24.2"
|
@@ -1762,6 +1952,17 @@ numpy = ">=1.16.4"
|
|
1762 |
carto = ["pydeck-carto"]
|
1763 |
jupyter = ["ipykernel (>=5.1.2)", "ipython (>=5.8.0)", "ipywidgets (>=7,<8)", "traitlets (>=4.3.2)"]
|
1764 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1765 |
[[package]]
|
1766 |
name = "pygments"
|
1767 |
version = "2.19.1"
|
@@ -1804,6 +2005,17 @@ files = [
|
|
1804 |
[package.extras]
|
1805 |
cli = ["click (>=5.0)"]
|
1806 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1807 |
[[package]]
|
1808 |
name = "pytz"
|
1809 |
version = "2025.1"
|
@@ -2059,6 +2271,76 @@ files = [
|
|
2059 |
[package.dependencies]
|
2060 |
pyasn1 = ">=0.1.3"
|
2061 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2062 |
[[package]]
|
2063 |
name = "six"
|
2064 |
version = "1.17.0"
|
@@ -2092,6 +2374,23 @@ files = [
|
|
2092 |
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
2093 |
]
|
2094 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2095 |
[[package]]
|
2096 |
name = "streamlit"
|
2097 |
version = "1.42.0"
|
@@ -2226,6 +2525,17 @@ files = [
|
|
2226 |
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
|
2227 |
]
|
2228 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2229 |
[[package]]
|
2230 |
name = "tornado"
|
2231 |
version = "6.4.2"
|
@@ -2267,6 +2577,23 @@ notebook = ["ipywidgets (>=6)"]
|
|
2267 |
slack = ["slack-sdk"]
|
2268 |
telegram = ["requests"]
|
2269 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2270 |
[[package]]
|
2271 |
name = "types-requests"
|
2272 |
version = "2.32.0.20241016"
|
@@ -2335,6 +2662,25 @@ h2 = ["h2 (>=4,<5)"]
|
|
2335 |
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
2336 |
zstd = ["zstandard (>=0.18.0)"]
|
2337 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2338 |
[[package]]
|
2339 |
name = "watchdog"
|
2340 |
version = "6.0.0"
|
@@ -2377,6 +2723,84 @@ files = [
|
|
2377 |
[package.extras]
|
2378 |
watchmedo = ["PyYAML (>=3.10)"]
|
2379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2380 |
[[package]]
|
2381 |
name = "wrapt"
|
2382 |
version = "1.17.2"
|
@@ -2487,4 +2911,4 @@ type = ["pytest-mypy"]
|
|
2487 |
[metadata]
|
2488 |
lock-version = "2.0"
|
2489 |
python-versions = "3.10"
|
2490 |
-
content-hash = "
|
|
|
1 |
# This file is automatically @generated by Poetry 1.8.3 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 = "altair"
|
16 |
version = "5.5.0"
|
|
|
362 |
[package.extras]
|
363 |
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"]
|
364 |
|
365 |
+
[[package]]
|
366 |
+
name = "fastapi"
|
367 |
+
version = "0.115.8"
|
368 |
+
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
369 |
+
optional = false
|
370 |
+
python-versions = ">=3.8"
|
371 |
+
files = [
|
372 |
+
{file = "fastapi-0.115.8-py3-none-any.whl", hash = "sha256:753a96dd7e036b34eeef8babdfcfe3f28ff79648f86551eb36bfc1b0bf4a8cbf"},
|
373 |
+
{file = "fastapi-0.115.8.tar.gz", hash = "sha256:0ce9111231720190473e222cdf0f07f7206ad7e53ea02beb1d2dc36e2f0741e9"},
|
374 |
+
]
|
375 |
+
|
376 |
+
[package.dependencies]
|
377 |
+
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
|
378 |
+
starlette = ">=0.40.0,<0.46.0"
|
379 |
+
typing-extensions = ">=4.8.0"
|
380 |
+
|
381 |
+
[package.extras]
|
382 |
+
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "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)"]
|
383 |
+
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
|
384 |
+
|
385 |
[[package]]
|
386 |
name = "fastavro"
|
387 |
version = "1.10.0"
|
|
|
428 |
snappy = ["cramjam"]
|
429 |
zstandard = ["zstandard"]
|
430 |
|
431 |
+
[[package]]
|
432 |
+
name = "ffmpy"
|
433 |
+
version = "0.5.0"
|
434 |
+
description = "A simple Python wrapper for FFmpeg"
|
435 |
+
optional = false
|
436 |
+
python-versions = "<4.0,>=3.8"
|
437 |
+
files = [
|
438 |
+
{file = "ffmpy-0.5.0-py3-none-any.whl", hash = "sha256:df3799cf5816daa56d4959a023630ee53c6768b66009dae6d131519ba4b80233"},
|
439 |
+
{file = "ffmpy-0.5.0.tar.gz", hash = "sha256:277e131f246d18e9dcfee9bb514c50749031c43582ce5ef82c57b51e3d3955c3"},
|
440 |
+
]
|
441 |
+
|
442 |
[[package]]
|
443 |
name = "filelock"
|
444 |
version = "3.17.0"
|
|
|
567 |
[package.extras]
|
568 |
grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"]
|
569 |
|
570 |
+
[[package]]
|
571 |
+
name = "gradio"
|
572 |
+
version = "5.16.1"
|
573 |
+
description = "Python library for easily interacting with trained machine learning models"
|
574 |
+
optional = false
|
575 |
+
python-versions = ">=3.10"
|
576 |
+
files = [
|
577 |
+
{file = "gradio-5.16.1-py3-none-any.whl", hash = "sha256:a49f194ca314a09e4f7655a8fbcf8efae961a2bbf37877afc546fb506027f4dd"},
|
578 |
+
]
|
579 |
+
|
580 |
+
[package.dependencies]
|
581 |
+
aiofiles = ">=22.0,<24.0"
|
582 |
+
anyio = ">=3.0,<5.0"
|
583 |
+
fastapi = ">=0.115.2,<1.0"
|
584 |
+
ffmpy = "*"
|
585 |
+
gradio-client = "1.7.0"
|
586 |
+
httpx = ">=0.24.1"
|
587 |
+
huggingface-hub = ">=0.28.1"
|
588 |
+
jinja2 = "<4.0"
|
589 |
+
markupsafe = ">=2.0,<3.0"
|
590 |
+
numpy = ">=1.0,<3.0"
|
591 |
+
orjson = ">=3.0,<4.0"
|
592 |
+
packaging = "*"
|
593 |
+
pandas = ">=1.0,<3.0"
|
594 |
+
pillow = ">=8.0,<12.0"
|
595 |
+
pydantic = ">=2.0"
|
596 |
+
pydub = "*"
|
597 |
+
python-multipart = ">=0.0.18"
|
598 |
+
pyyaml = ">=5.0,<7.0"
|
599 |
+
ruff = {version = ">=0.9.3", markers = "sys_platform != \"emscripten\""}
|
600 |
+
safehttpx = ">=0.1.6,<0.2.0"
|
601 |
+
semantic-version = ">=2.0,<3.0"
|
602 |
+
starlette = {version = ">=0.40.0,<1.0", markers = "sys_platform != \"emscripten\""}
|
603 |
+
tomlkit = ">=0.12.0,<0.14.0"
|
604 |
+
typer = {version = ">=0.12,<1.0", markers = "sys_platform != \"emscripten\""}
|
605 |
+
typing-extensions = ">=4.0,<5.0"
|
606 |
+
urllib3 = {version = ">=2.0,<3.0", markers = "sys_platform == \"emscripten\""}
|
607 |
+
uvicorn = {version = ">=0.14.0", markers = "sys_platform != \"emscripten\""}
|
608 |
+
|
609 |
+
[package.extras]
|
610 |
+
oauth = ["authlib", "itsdangerous"]
|
611 |
+
|
612 |
+
[[package]]
|
613 |
+
name = "gradio-client"
|
614 |
+
version = "1.7.0"
|
615 |
+
description = "Python library for easily interacting with trained machine learning models"
|
616 |
+
optional = false
|
617 |
+
python-versions = ">=3.10"
|
618 |
+
files = [
|
619 |
+
{file = "gradio_client-1.7.0-py3-none-any.whl", hash = "sha256:b403570c67f121ebbbc19ac1f0afa2ab1bab085ce60d96eb190832fe871aa946"},
|
620 |
+
{file = "gradio_client-1.7.0.tar.gz", hash = "sha256:87f6ade197951f38bac0431b2a436a8ebb2f33b2ceba2ef8e1e5bef8d8b238e4"},
|
621 |
+
]
|
622 |
+
|
623 |
+
[package.dependencies]
|
624 |
+
fsspec = "*"
|
625 |
+
httpx = ">=0.24.1"
|
626 |
+
huggingface-hub = ">=0.19.3"
|
627 |
+
packaging = "*"
|
628 |
+
typing-extensions = ">=4.0,<5.0"
|
629 |
+
websockets = ">=10.0,<15.0"
|
630 |
+
|
631 |
[[package]]
|
632 |
name = "griffe"
|
633 |
version = "1.5.7"
|
|
|
1027 |
|
1028 |
[[package]]
|
1029 |
name = "markupsafe"
|
1030 |
+
version = "2.1.5"
|
1031 |
description = "Safely add untrusted strings to HTML/XML markup."
|
1032 |
optional = false
|
1033 |
+
python-versions = ">=3.7"
|
1034 |
files = [
|
1035 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
1036 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
1037 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
|
1038 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
|
1039 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
|
1040 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
|
1041 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
|
1042 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
|
1043 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
|
1044 |
+
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
|
1045 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
|
1046 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
|
1047 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
|
1048 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
|
1049 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
|
1050 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
|
1051 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
|
1052 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
|
1053 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
|
1054 |
+
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
|
1055 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
|
1056 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
|
1057 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
|
1058 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
|
1059 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
|
1060 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
|
1061 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
|
1062 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
|
1063 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
|
1064 |
+
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
|
1065 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
|
1066 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
|
1067 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
|
1068 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
|
1069 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
|
1070 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
|
1071 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
|
1072 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
|
1073 |
+
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
|
1074 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
|
1075 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
|
1076 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
|
1077 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
|
1078 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
|
1079 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
|
1080 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
|
1081 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
|
1082 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
|
1083 |
+
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
|
1084 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
|
1085 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
|
1086 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
|
1087 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
|
1088 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
|
1089 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
|
1090 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
|
1091 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
|
1092 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
|
1093 |
+
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
|
1094 |
+
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
|
|
|
1095 |
]
|
1096 |
|
1097 |
[[package]]
|
|
|
1364 |
deprecated = ">=1.2.6"
|
1365 |
opentelemetry-api = "1.30.0"
|
1366 |
|
1367 |
+
[[package]]
|
1368 |
+
name = "orjson"
|
1369 |
+
version = "3.10.15"
|
1370 |
+
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
1371 |
+
optional = false
|
1372 |
+
python-versions = ">=3.8"
|
1373 |
+
files = [
|
1374 |
+
{file = "orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04"},
|
1375 |
+
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8"},
|
1376 |
+
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c2c79fa308e6edb0ffab0a31fd75a7841bf2a79a20ef08a3c6e3b26814c8ca8"},
|
1377 |
+
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cb85490aa6bf98abd20607ab5c8324c0acb48d6da7863a51be48505646c814"},
|
1378 |
+
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763dadac05e4e9d2bc14938a45a2d0560549561287d41c465d3c58aec818b164"},
|
1379 |
+
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a330b9b4734f09a623f74a7490db713695e13b67c959713b78369f26b3dee6bf"},
|
1380 |
+
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a61a4622b7ff861f019974f73d8165be1bd9a0855e1cad18ee167acacabeb061"},
|
1381 |
+
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd271247691574416b3228db667b84775c497b245fa275c6ab90dc1ffbbd2b3"},
|
1382 |
+
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4759b109c37f635aa5c5cc93a1b26927bfde24b254bcc0e1149a9fada253d2d"},
|
1383 |
+
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e992fd5cfb8b9f00bfad2fd7a05a4299db2bbe92e6440d9dd2fab27655b3182"},
|
1384 |
+
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95fb363d79366af56c3f26b71df40b9a583b07bbaaf5b317407c4d58497852e"},
|
1385 |
+
{file = "orjson-3.10.15-cp310-cp310-win32.whl", hash = "sha256:f9875f5fea7492da8ec2444839dcc439b0ef298978f311103d0b7dfd775898ab"},
|
1386 |
+
{file = "orjson-3.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:17085a6aa91e1cd70ca8533989a18b5433e15d29c574582f76f821737c8d5806"},
|
1387 |
+
{file = "orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6"},
|
1388 |
+
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef"},
|
1389 |
+
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334"},
|
1390 |
+
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d"},
|
1391 |
+
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0"},
|
1392 |
+
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13"},
|
1393 |
+
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5"},
|
1394 |
+
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b"},
|
1395 |
+
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399"},
|
1396 |
+
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388"},
|
1397 |
+
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c"},
|
1398 |
+
{file = "orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e"},
|
1399 |
+
{file = "orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e"},
|
1400 |
+
{file = "orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a"},
|
1401 |
+
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d"},
|
1402 |
+
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0"},
|
1403 |
+
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4"},
|
1404 |
+
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767"},
|
1405 |
+
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41"},
|
1406 |
+
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514"},
|
1407 |
+
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17"},
|
1408 |
+
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b"},
|
1409 |
+
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7"},
|
1410 |
+
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a"},
|
1411 |
+
{file = "orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665"},
|
1412 |
+
{file = "orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa"},
|
1413 |
+
{file = "orjson-3.10.15-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bae0e6ec2b7ba6895198cd981b7cca95d1487d0147c8ed751e5632ad16f031a6"},
|
1414 |
+
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f93ce145b2db1252dd86af37d4165b6faa83072b46e3995ecc95d4b2301b725a"},
|
1415 |
+
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c203f6f969210128af3acae0ef9ea6aab9782939f45f6fe02d05958fe761ef9"},
|
1416 |
+
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8918719572d662e18b8af66aef699d8c21072e54b6c82a3f8f6404c1f5ccd5e0"},
|
1417 |
+
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f71eae9651465dff70aa80db92586ad5b92df46a9373ee55252109bb6b703307"},
|
1418 |
+
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e117eb299a35f2634e25ed120c37c641398826c2f5a3d3cc39f5993b96171b9e"},
|
1419 |
+
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13242f12d295e83c2955756a574ddd6741c81e5b99f2bef8ed8d53e47a01e4b7"},
|
1420 |
+
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7946922ada8f3e0b7b958cc3eb22cfcf6c0df83d1fe5521b4a100103e3fa84c8"},
|
1421 |
+
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b7155eb1623347f0f22c38c9abdd738b287e39b9982e1da227503387b81b34ca"},
|
1422 |
+
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:208beedfa807c922da4e81061dafa9c8489c6328934ca2a562efa707e049e561"},
|
1423 |
+
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eca81f83b1b8c07449e1d6ff7074e82e3fd6777e588f1a6632127f286a968825"},
|
1424 |
+
{file = "orjson-3.10.15-cp313-cp313-win32.whl", hash = "sha256:c03cd6eea1bd3b949d0d007c8d57049aa2b39bd49f58b4b2af571a5d3833d890"},
|
1425 |
+
{file = "orjson-3.10.15-cp313-cp313-win_amd64.whl", hash = "sha256:fd56a26a04f6ba5fb2045b0acc487a63162a958ed837648c5781e1fe3316cfbf"},
|
1426 |
+
{file = "orjson-3.10.15-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5e8afd6200e12771467a1a44e5ad780614b86abb4b11862ec54861a82d677746"},
|
1427 |
+
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da9a18c500f19273e9e104cca8c1f0b40a6470bcccfc33afcc088045d0bf5ea6"},
|
1428 |
+
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb00b7bfbdf5d34a13180e4805d76b4567025da19a197645ca746fc2fb536586"},
|
1429 |
+
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33aedc3d903378e257047fee506f11e0833146ca3e57a1a1fb0ddb789876c1e1"},
|
1430 |
+
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0099ae6aed5eb1fc84c9eb72b95505a3df4267e6962eb93cdd5af03be71c98"},
|
1431 |
+
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c864a80a2d467d7786274fce0e4f93ef2a7ca4ff31f7fc5634225aaa4e9e98c"},
|
1432 |
+
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c25774c9e88a3e0013d7d1a6c8056926b607a61edd423b50eb5c88fd7f2823ae"},
|
1433 |
+
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e78c211d0074e783d824ce7bb85bf459f93a233eb67a5b5003498232ddfb0e8a"},
|
1434 |
+
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:43e17289ffdbbac8f39243916c893d2ae41a2ea1a9cbb060a56a4d75286351ae"},
|
1435 |
+
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:781d54657063f361e89714293c095f506c533582ee40a426cb6489c48a637b81"},
|
1436 |
+
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6875210307d36c94873f553786a808af2788e362bd0cf4c8e66d976791e7b528"},
|
1437 |
+
{file = "orjson-3.10.15-cp38-cp38-win32.whl", hash = "sha256:305b38b2b8f8083cc3d618927d7f424349afce5975b316d33075ef0f73576b60"},
|
1438 |
+
{file = "orjson-3.10.15-cp38-cp38-win_amd64.whl", hash = "sha256:5dd9ef1639878cc3efffed349543cbf9372bdbd79f478615a1c633fe4e4180d1"},
|
1439 |
+
{file = "orjson-3.10.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ffe19f3e8d68111e8644d4f4e267a069ca427926855582ff01fc012496d19969"},
|
1440 |
+
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d433bf32a363823863a96561a555227c18a522a8217a6f9400f00ddc70139ae2"},
|
1441 |
+
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da03392674f59a95d03fa5fb9fe3a160b0511ad84b7a3914699ea5a1b3a38da2"},
|
1442 |
+
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a63bb41559b05360ded9132032239e47983a39b151af1201f07ec9370715c82"},
|
1443 |
+
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3766ac4702f8f795ff3fa067968e806b4344af257011858cc3d6d8721588b53f"},
|
1444 |
+
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1c73dcc8fadbd7c55802d9aa093b36878d34a3b3222c41052ce6b0fc65f8e8"},
|
1445 |
+
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b299383825eafe642cbab34be762ccff9fd3408d72726a6b2a4506d410a71ab3"},
|
1446 |
+
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:abc7abecdbf67a173ef1316036ebbf54ce400ef2300b4e26a7b843bd446c2480"},
|
1447 |
+
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:3614ea508d522a621384c1d6639016a5a2e4f027f3e4a1c93a51867615d28829"},
|
1448 |
+
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:295c70f9dc154307777ba30fe29ff15c1bcc9dfc5c48632f37d20a607e9ba85a"},
|
1449 |
+
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:63309e3ff924c62404923c80b9e2048c1f74ba4b615e7584584389ada50ed428"},
|
1450 |
+
{file = "orjson-3.10.15-cp39-cp39-win32.whl", hash = "sha256:a2f708c62d026fb5340788ba94a55c23df4e1869fec74be455e0b2f5363b8507"},
|
1451 |
+
{file = "orjson-3.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:efcf6c735c3d22ef60c4aa27a5238f1a477df85e9b15f2142f9d669beb2d13fd"},
|
1452 |
+
{file = "orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e"},
|
1453 |
+
]
|
1454 |
+
|
1455 |
[[package]]
|
1456 |
name = "packaging"
|
1457 |
version = "24.2"
|
|
|
1952 |
carto = ["pydeck-carto"]
|
1953 |
jupyter = ["ipykernel (>=5.1.2)", "ipython (>=5.8.0)", "ipywidgets (>=7,<8)", "traitlets (>=4.3.2)"]
|
1954 |
|
1955 |
+
[[package]]
|
1956 |
+
name = "pydub"
|
1957 |
+
version = "0.25.1"
|
1958 |
+
description = "Manipulate audio with an simple and easy high level interface"
|
1959 |
+
optional = false
|
1960 |
+
python-versions = "*"
|
1961 |
+
files = [
|
1962 |
+
{file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"},
|
1963 |
+
{file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"},
|
1964 |
+
]
|
1965 |
+
|
1966 |
[[package]]
|
1967 |
name = "pygments"
|
1968 |
version = "2.19.1"
|
|
|
2005 |
[package.extras]
|
2006 |
cli = ["click (>=5.0)"]
|
2007 |
|
2008 |
+
[[package]]
|
2009 |
+
name = "python-multipart"
|
2010 |
+
version = "0.0.20"
|
2011 |
+
description = "A streaming multipart parser for Python"
|
2012 |
+
optional = false
|
2013 |
+
python-versions = ">=3.8"
|
2014 |
+
files = [
|
2015 |
+
{file = "python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104"},
|
2016 |
+
{file = "python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13"},
|
2017 |
+
]
|
2018 |
+
|
2019 |
[[package]]
|
2020 |
name = "pytz"
|
2021 |
version = "2025.1"
|
|
|
2271 |
[package.dependencies]
|
2272 |
pyasn1 = ">=0.1.3"
|
2273 |
|
2274 |
+
[[package]]
|
2275 |
+
name = "ruff"
|
2276 |
+
version = "0.9.6"
|
2277 |
+
description = "An extremely fast Python linter and code formatter, written in Rust."
|
2278 |
+
optional = false
|
2279 |
+
python-versions = ">=3.7"
|
2280 |
+
files = [
|
2281 |
+
{file = "ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba"},
|
2282 |
+
{file = "ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504"},
|
2283 |
+
{file = "ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83"},
|
2284 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc"},
|
2285 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b"},
|
2286 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e"},
|
2287 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666"},
|
2288 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5"},
|
2289 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5"},
|
2290 |
+
{file = "ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217"},
|
2291 |
+
{file = "ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6"},
|
2292 |
+
{file = "ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897"},
|
2293 |
+
{file = "ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08"},
|
2294 |
+
{file = "ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656"},
|
2295 |
+
{file = "ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d"},
|
2296 |
+
{file = "ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa"},
|
2297 |
+
{file = "ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a"},
|
2298 |
+
{file = "ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9"},
|
2299 |
+
]
|
2300 |
+
|
2301 |
+
[[package]]
|
2302 |
+
name = "safehttpx"
|
2303 |
+
version = "0.1.6"
|
2304 |
+
description = "A small Python library created to help developers protect their applications from Server Side Request Forgery (SSRF) attacks."
|
2305 |
+
optional = false
|
2306 |
+
python-versions = ">3.9"
|
2307 |
+
files = [
|
2308 |
+
{file = "safehttpx-0.1.6-py3-none-any.whl", hash = "sha256:407cff0b410b071623087c63dd2080c3b44dc076888d8c5823c00d1e58cb381c"},
|
2309 |
+
{file = "safehttpx-0.1.6.tar.gz", hash = "sha256:b356bfc82cee3a24c395b94a2dbeabbed60aff1aa5fa3b5fe97c4f2456ebce42"},
|
2310 |
+
]
|
2311 |
+
|
2312 |
+
[package.dependencies]
|
2313 |
+
httpx = "*"
|
2314 |
+
|
2315 |
+
[package.extras]
|
2316 |
+
dev = ["pytest"]
|
2317 |
+
|
2318 |
+
[[package]]
|
2319 |
+
name = "semantic-version"
|
2320 |
+
version = "2.10.0"
|
2321 |
+
description = "A library implementing the 'SemVer' scheme."
|
2322 |
+
optional = false
|
2323 |
+
python-versions = ">=2.7"
|
2324 |
+
files = [
|
2325 |
+
{file = "semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"},
|
2326 |
+
{file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"},
|
2327 |
+
]
|
2328 |
+
|
2329 |
+
[package.extras]
|
2330 |
+
dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"]
|
2331 |
+
doc = ["Sphinx", "sphinx-rtd-theme"]
|
2332 |
+
|
2333 |
+
[[package]]
|
2334 |
+
name = "shellingham"
|
2335 |
+
version = "1.5.4"
|
2336 |
+
description = "Tool to Detect Surrounding Shell"
|
2337 |
+
optional = false
|
2338 |
+
python-versions = ">=3.7"
|
2339 |
+
files = [
|
2340 |
+
{file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
|
2341 |
+
{file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
|
2342 |
+
]
|
2343 |
+
|
2344 |
[[package]]
|
2345 |
name = "six"
|
2346 |
version = "1.17.0"
|
|
|
2374 |
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
|
2375 |
]
|
2376 |
|
2377 |
+
[[package]]
|
2378 |
+
name = "starlette"
|
2379 |
+
version = "0.45.3"
|
2380 |
+
description = "The little ASGI library that shines."
|
2381 |
+
optional = false
|
2382 |
+
python-versions = ">=3.9"
|
2383 |
+
files = [
|
2384 |
+
{file = "starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d"},
|
2385 |
+
{file = "starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f"},
|
2386 |
+
]
|
2387 |
+
|
2388 |
+
[package.dependencies]
|
2389 |
+
anyio = ">=3.6.2,<5"
|
2390 |
+
|
2391 |
+
[package.extras]
|
2392 |
+
full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"]
|
2393 |
+
|
2394 |
[[package]]
|
2395 |
name = "streamlit"
|
2396 |
version = "1.42.0"
|
|
|
2525 |
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
|
2526 |
]
|
2527 |
|
2528 |
+
[[package]]
|
2529 |
+
name = "tomlkit"
|
2530 |
+
version = "0.13.2"
|
2531 |
+
description = "Style preserving TOML library"
|
2532 |
+
optional = false
|
2533 |
+
python-versions = ">=3.8"
|
2534 |
+
files = [
|
2535 |
+
{file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
|
2536 |
+
{file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
|
2537 |
+
]
|
2538 |
+
|
2539 |
[[package]]
|
2540 |
name = "tornado"
|
2541 |
version = "6.4.2"
|
|
|
2577 |
slack = ["slack-sdk"]
|
2578 |
telegram = ["requests"]
|
2579 |
|
2580 |
+
[[package]]
|
2581 |
+
name = "typer"
|
2582 |
+
version = "0.15.1"
|
2583 |
+
description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
|
2584 |
+
optional = false
|
2585 |
+
python-versions = ">=3.7"
|
2586 |
+
files = [
|
2587 |
+
{file = "typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847"},
|
2588 |
+
{file = "typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a"},
|
2589 |
+
]
|
2590 |
+
|
2591 |
+
[package.dependencies]
|
2592 |
+
click = ">=8.0.0"
|
2593 |
+
rich = ">=10.11.0"
|
2594 |
+
shellingham = ">=1.3.0"
|
2595 |
+
typing-extensions = ">=3.7.4.3"
|
2596 |
+
|
2597 |
[[package]]
|
2598 |
name = "types-requests"
|
2599 |
version = "2.32.0.20241016"
|
|
|
2662 |
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
2663 |
zstd = ["zstandard (>=0.18.0)"]
|
2664 |
|
2665 |
+
[[package]]
|
2666 |
+
name = "uvicorn"
|
2667 |
+
version = "0.34.0"
|
2668 |
+
description = "The lightning-fast ASGI server."
|
2669 |
+
optional = false
|
2670 |
+
python-versions = ">=3.9"
|
2671 |
+
files = [
|
2672 |
+
{file = "uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4"},
|
2673 |
+
{file = "uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9"},
|
2674 |
+
]
|
2675 |
+
|
2676 |
+
[package.dependencies]
|
2677 |
+
click = ">=7.0"
|
2678 |
+
h11 = ">=0.8"
|
2679 |
+
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
2680 |
+
|
2681 |
+
[package.extras]
|
2682 |
+
standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
2683 |
+
|
2684 |
[[package]]
|
2685 |
name = "watchdog"
|
2686 |
version = "6.0.0"
|
|
|
2723 |
[package.extras]
|
2724 |
watchmedo = ["PyYAML (>=3.10)"]
|
2725 |
|
2726 |
+
[[package]]
|
2727 |
+
name = "websockets"
|
2728 |
+
version = "14.2"
|
2729 |
+
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
2730 |
+
optional = false
|
2731 |
+
python-versions = ">=3.9"
|
2732 |
+
files = [
|
2733 |
+
{file = "websockets-14.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e8179f95323b9ab1c11723e5d91a89403903f7b001828161b480a7810b334885"},
|
2734 |
+
{file = "websockets-14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d8c3e2cdb38f31d8bd7d9d28908005f6fa9def3324edb9bf336d7e4266fd397"},
|
2735 |
+
{file = "websockets-14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:714a9b682deb4339d39ffa674f7b674230227d981a37d5d174a4a83e3978a610"},
|
2736 |
+
{file = "websockets-14.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2e53c72052f2596fb792a7acd9704cbc549bf70fcde8a99e899311455974ca3"},
|
2737 |
+
{file = "websockets-14.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3fbd68850c837e57373d95c8fe352203a512b6e49eaae4c2f4088ef8cf21980"},
|
2738 |
+
{file = "websockets-14.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b27ece32f63150c268593d5fdb82819584831a83a3f5809b7521df0685cd5d8"},
|
2739 |
+
{file = "websockets-14.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4daa0faea5424d8713142b33825fff03c736f781690d90652d2c8b053345b0e7"},
|
2740 |
+
{file = "websockets-14.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bc63cee8596a6ec84d9753fd0fcfa0452ee12f317afe4beae6b157f0070c6c7f"},
|
2741 |
+
{file = "websockets-14.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a570862c325af2111343cc9b0257b7119b904823c675b22d4ac547163088d0d"},
|
2742 |
+
{file = "websockets-14.2-cp310-cp310-win32.whl", hash = "sha256:75862126b3d2d505e895893e3deac0a9339ce750bd27b4ba515f008b5acf832d"},
|
2743 |
+
{file = "websockets-14.2-cp310-cp310-win_amd64.whl", hash = "sha256:cc45afb9c9b2dc0852d5c8b5321759cf825f82a31bfaf506b65bf4668c96f8b2"},
|
2744 |
+
{file = "websockets-14.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3bdc8c692c866ce5fefcaf07d2b55c91d6922ac397e031ef9b774e5b9ea42166"},
|
2745 |
+
{file = "websockets-14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c93215fac5dadc63e51bcc6dceca72e72267c11def401d6668622b47675b097f"},
|
2746 |
+
{file = "websockets-14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c9b6535c0e2cf8a6bf938064fb754aaceb1e6a4a51a80d884cd5db569886910"},
|
2747 |
+
{file = "websockets-14.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a52a6d7cf6938e04e9dceb949d35fbdf58ac14deea26e685ab6368e73744e4c"},
|
2748 |
+
{file = "websockets-14.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f05702e93203a6ff5226e21d9b40c037761b2cfb637187c9802c10f58e40473"},
|
2749 |
+
{file = "websockets-14.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22441c81a6748a53bfcb98951d58d1af0661ab47a536af08920d129b4d1c3473"},
|
2750 |
+
{file = "websockets-14.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd9b868d78b194790e6236d9cbc46d68aba4b75b22497eb4ab64fa640c3af56"},
|
2751 |
+
{file = "websockets-14.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1a5a20d5843886d34ff8c57424cc65a1deda4375729cbca4cb6b3353f3ce4142"},
|
2752 |
+
{file = "websockets-14.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:34277a29f5303d54ec6468fb525d99c99938607bc96b8d72d675dee2b9f5bf1d"},
|
2753 |
+
{file = "websockets-14.2-cp311-cp311-win32.whl", hash = "sha256:02687db35dbc7d25fd541a602b5f8e451a238ffa033030b172ff86a93cb5dc2a"},
|
2754 |
+
{file = "websockets-14.2-cp311-cp311-win_amd64.whl", hash = "sha256:862e9967b46c07d4dcd2532e9e8e3c2825e004ffbf91a5ef9dde519ee2effb0b"},
|
2755 |
+
{file = "websockets-14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c"},
|
2756 |
+
{file = "websockets-14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967"},
|
2757 |
+
{file = "websockets-14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990"},
|
2758 |
+
{file = "websockets-14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda"},
|
2759 |
+
{file = "websockets-14.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95"},
|
2760 |
+
{file = "websockets-14.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3"},
|
2761 |
+
{file = "websockets-14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9"},
|
2762 |
+
{file = "websockets-14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267"},
|
2763 |
+
{file = "websockets-14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe"},
|
2764 |
+
{file = "websockets-14.2-cp312-cp312-win32.whl", hash = "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205"},
|
2765 |
+
{file = "websockets-14.2-cp312-cp312-win_amd64.whl", hash = "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce"},
|
2766 |
+
{file = "websockets-14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f1372e511c7409a542291bce92d6c83320e02c9cf392223272287ce55bc224e"},
|
2767 |
+
{file = "websockets-14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4da98b72009836179bb596a92297b1a61bb5a830c0e483a7d0766d45070a08ad"},
|
2768 |
+
{file = "websockets-14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8a86a269759026d2bde227652b87be79f8a734e582debf64c9d302faa1e9f03"},
|
2769 |
+
{file = "websockets-14.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86cf1aaeca909bf6815ea714d5c5736c8d6dd3a13770e885aafe062ecbd04f1f"},
|
2770 |
+
{file = "websockets-14.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b0f6c3ba3b1240f602ebb3971d45b02cc12bd1845466dd783496b3b05783a5"},
|
2771 |
+
{file = "websockets-14.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669c3e101c246aa85bc8534e495952e2ca208bd87994650b90a23d745902db9a"},
|
2772 |
+
{file = "websockets-14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eabdb28b972f3729348e632ab08f2a7b616c7e53d5414c12108c29972e655b20"},
|
2773 |
+
{file = "websockets-14.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2066dc4cbcc19f32c12a5a0e8cc1b7ac734e5b64ac0a325ff8353451c4b15ef2"},
|
2774 |
+
{file = "websockets-14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab95d357cd471df61873dadf66dd05dd4709cae001dd6342edafc8dc6382f307"},
|
2775 |
+
{file = "websockets-14.2-cp313-cp313-win32.whl", hash = "sha256:a9e72fb63e5f3feacdcf5b4ff53199ec8c18d66e325c34ee4c551ca748623bbc"},
|
2776 |
+
{file = "websockets-14.2-cp313-cp313-win_amd64.whl", hash = "sha256:b439ea828c4ba99bb3176dc8d9b933392a2413c0f6b149fdcba48393f573377f"},
|
2777 |
+
{file = "websockets-14.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7cd5706caec1686c5d233bc76243ff64b1c0dc445339bd538f30547e787c11fe"},
|
2778 |
+
{file = "websockets-14.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ec607328ce95a2f12b595f7ae4c5d71bf502212bddcea528290b35c286932b12"},
|
2779 |
+
{file = "websockets-14.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da85651270c6bfb630136423037dd4975199e5d4114cae6d3066641adcc9d1c7"},
|
2780 |
+
{file = "websockets-14.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ecadc7ce90accf39903815697917643f5b7cfb73c96702318a096c00aa71f5"},
|
2781 |
+
{file = "websockets-14.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1979bee04af6a78608024bad6dfcc0cc930ce819f9e10342a29a05b5320355d0"},
|
2782 |
+
{file = "websockets-14.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dddacad58e2614a24938a50b85969d56f88e620e3f897b7d80ac0d8a5800258"},
|
2783 |
+
{file = "websockets-14.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:89a71173caaf75fa71a09a5f614f450ba3ec84ad9fca47cb2422a860676716f0"},
|
2784 |
+
{file = "websockets-14.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6af6a4b26eea4fc06c6818a6b962a952441e0e39548b44773502761ded8cc1d4"},
|
2785 |
+
{file = "websockets-14.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:80c8efa38957f20bba0117b48737993643204645e9ec45512579132508477cfc"},
|
2786 |
+
{file = "websockets-14.2-cp39-cp39-win32.whl", hash = "sha256:2e20c5f517e2163d76e2729104abc42639c41cf91f7b1839295be43302713661"},
|
2787 |
+
{file = "websockets-14.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4c8cef610e8d7c70dea92e62b6814a8cd24fbd01d7103cc89308d2bfe1659ef"},
|
2788 |
+
{file = "websockets-14.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d7d9cafbccba46e768be8a8ad4635fa3eae1ffac4c6e7cb4eb276ba41297ed29"},
|
2789 |
+
{file = "websockets-14.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c76193c1c044bd1e9b3316dcc34b174bbf9664598791e6fb606d8d29000e070c"},
|
2790 |
+
{file = "websockets-14.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd475a974d5352390baf865309fe37dec6831aafc3014ffac1eea99e84e83fc2"},
|
2791 |
+
{file = "websockets-14.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c6c0097a41968b2e2b54ed3424739aab0b762ca92af2379f152c1aef0187e1c"},
|
2792 |
+
{file = "websockets-14.2-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d7ff794c8b36bc402f2e07c0b2ceb4a2424147ed4785ff03e2a7af03711d60a"},
|
2793 |
+
{file = "websockets-14.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dec254fcabc7bd488dab64846f588fc5b6fe0d78f641180030f8ea27b76d72c3"},
|
2794 |
+
{file = "websockets-14.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bbe03eb853e17fd5b15448328b4ec7fb2407d45fb0245036d06a3af251f8e48f"},
|
2795 |
+
{file = "websockets-14.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3c4aa3428b904d5404a0ed85f3644d37e2cb25996b7f096d77caeb0e96a3b42"},
|
2796 |
+
{file = "websockets-14.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:577a4cebf1ceaf0b65ffc42c54856214165fb8ceeba3935852fc33f6b0c55e7f"},
|
2797 |
+
{file = "websockets-14.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad1c1d02357b7665e700eca43a31d52814ad9ad9b89b58118bdabc365454b574"},
|
2798 |
+
{file = "websockets-14.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f390024a47d904613577df83ba700bd189eedc09c57af0a904e5c39624621270"},
|
2799 |
+
{file = "websockets-14.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3c1426c021c38cf92b453cdf371228d3430acd775edee6bac5a4d577efc72365"},
|
2800 |
+
{file = "websockets-14.2-py3-none-any.whl", hash = "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b"},
|
2801 |
+
{file = "websockets-14.2.tar.gz", hash = "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5"},
|
2802 |
+
]
|
2803 |
+
|
2804 |
[[package]]
|
2805 |
name = "wrapt"
|
2806 |
version = "1.17.2"
|
|
|
2911 |
[metadata]
|
2912 |
lock-version = "2.0"
|
2913 |
python-versions = "3.10"
|
2914 |
+
content-hash = "83c3d0c47f98107284fb95080f8f9a6ba3c17d9a89f13ccbd66b73ca99863b4d"
|
pyproject.toml
CHANGED
@@ -13,6 +13,7 @@ watchdog = "^6.0.0"
|
|
13 |
pydantic-ai = "^0.0.24"
|
14 |
python-dotenv = "^1.0.1"
|
15 |
logfire = "^3.5.3"
|
|
|
16 |
|
17 |
|
18 |
[build-system]
|
|
|
13 |
pydantic-ai = "^0.0.24"
|
14 |
python-dotenv = "^1.0.1"
|
15 |
logfire = "^3.5.3"
|
16 |
+
gradio = "^5.16.1"
|
17 |
|
18 |
|
19 |
[build-system]
|
src/agents/image-edit-agent.py
CHANGED
@@ -4,7 +4,7 @@ from pydantic_ai.models.openai import OpenAIModel
|
|
4 |
from dotenv import load_dotenv
|
5 |
import os
|
6 |
import asyncio
|
7 |
-
import
|
8 |
from dataclasses import dataclass
|
9 |
|
10 |
load_dotenv()
|
@@ -76,31 +76,29 @@ async def generate_mask(ctx: RunContext[ImageEditDeps], mask_subject: str) -> st
|
|
76 |
|
77 |
async def main():
|
78 |
image_file_path = "./assets/lakeview.jpg"
|
79 |
-
|
80 |
-
|
81 |
-
image_base64 = base64.b64encode(image_bytes).decode("utf-8")
|
82 |
-
image_url = f"data:image/jpeg;base64,{image_base64}"
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
}
|
95 |
}
|
96 |
-
|
|
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
|
105 |
|
106 |
if __name__ == "__main__":
|
|
|
4 |
from dotenv import load_dotenv
|
5 |
import os
|
6 |
import asyncio
|
7 |
+
from src.utils import image_path_to_base64
|
8 |
from dataclasses import dataclass
|
9 |
|
10 |
load_dotenv()
|
|
|
76 |
|
77 |
async def main():
|
78 |
image_file_path = "./assets/lakeview.jpg"
|
79 |
+
image_base64 = image_path_to_base64(image_file_path)
|
80 |
+
image_url = f"data:image/jpeg;base64,{image_base64}"
|
|
|
|
|
81 |
|
82 |
+
prompt = "remove the light post"
|
83 |
+
messages = [
|
84 |
+
{
|
85 |
+
"type": "text",
|
86 |
+
"text": prompt
|
87 |
+
},
|
88 |
+
{
|
89 |
+
"type": "image_url",
|
90 |
+
"image_url": {
|
91 |
+
"url": image_url
|
|
|
92 |
}
|
93 |
+
}
|
94 |
+
]
|
95 |
|
96 |
+
deps = ImageEditDeps(
|
97 |
+
edit_instruction=prompt,
|
98 |
+
image_url=image_url
|
99 |
+
)
|
100 |
+
r = await mask_generation_agent.run(messages, deps=deps)
|
101 |
+
print(r.data)
|
102 |
|
103 |
|
104 |
if __name__ == "__main__":
|
src/agents/mask_generation_agent.py
CHANGED
@@ -3,11 +3,12 @@ from pydantic_ai.models.openai import OpenAIModel
|
|
3 |
from dotenv import load_dotenv
|
4 |
import os
|
5 |
import asyncio
|
6 |
-
import base64
|
7 |
from dataclasses import dataclass
|
8 |
import logfire
|
9 |
from src.services.generate_mask import GenerateMaskService
|
10 |
from src.hopter.client import Hopter, Environment, MagicReplaceInput
|
|
|
|
|
11 |
|
12 |
load_dotenv()
|
13 |
|
@@ -38,7 +39,7 @@ class MaskGenerationResult:
|
|
38 |
|
39 |
@dataclass
|
40 |
class EditImageResult:
|
41 |
-
|
42 |
|
43 |
mask_generation_agent = Agent(
|
44 |
model,
|
@@ -74,53 +75,52 @@ async def edit_object(ctx: RunContext[ImageEditDeps]) -> EditImageResult:
|
|
74 |
|
75 |
# Generate mask
|
76 |
print("Generating mask")
|
77 |
-
mask_instruction =
|
78 |
-
mask =
|
79 |
|
80 |
# Magic replace
|
81 |
input = MagicReplaceInput(image=image_url, mask=mask, prompt=mask_instruction.target_caption)
|
82 |
-
result =
|
83 |
print("Exiting edit_object tool: ", result)
|
84 |
-
|
|
|
|
|
85 |
|
86 |
async def main():
|
87 |
image_file_path = "./assets/lakeview.jpg"
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
"type": "image_url",
|
101 |
-
"image_url": {
|
102 |
-
"url": image_url
|
103 |
-
}
|
104 |
}
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
124 |
|
125 |
|
126 |
if __name__ == "__main__":
|
|
|
3 |
from dotenv import load_dotenv
|
4 |
import os
|
5 |
import asyncio
|
|
|
6 |
from dataclasses import dataclass
|
7 |
import logfire
|
8 |
from src.services.generate_mask import GenerateMaskService
|
9 |
from src.hopter.client import Hopter, Environment, MagicReplaceInput
|
10 |
+
from src.services.image_uploader import ImageUploader
|
11 |
+
from src.utils import image_path_to_uri
|
12 |
|
13 |
load_dotenv()
|
14 |
|
|
|
39 |
|
40 |
@dataclass
|
41 |
class EditImageResult:
|
42 |
+
edited_image_url: str
|
43 |
|
44 |
mask_generation_agent = Agent(
|
45 |
model,
|
|
|
75 |
|
76 |
# Generate mask
|
77 |
print("Generating mask")
|
78 |
+
mask_instruction = mask_service.get_mask_generation_instruction(edit_instruction, image_url)
|
79 |
+
mask = mask_service.generate_mask(mask_instruction, image_url)
|
80 |
|
81 |
# Magic replace
|
82 |
input = MagicReplaceInput(image=image_url, mask=mask, prompt=mask_instruction.target_caption)
|
83 |
+
result = hopter_client.magic_replace(input)
|
84 |
print("Exiting edit_object tool: ", result)
|
85 |
+
uploader = ImageUploader(os.environ.get("IMG_BB_API_KEY"))
|
86 |
+
uploaded_image = uploader.upload_url(result.base64_image)
|
87 |
+
return EditImageResult(edited_image_url=uploaded_image.data.url)
|
88 |
|
89 |
async def main():
|
90 |
image_file_path = "./assets/lakeview.jpg"
|
91 |
+
image_url = image_path_to_uri(image_file_path)
|
92 |
+
|
93 |
+
prompt = "remove the light post"
|
94 |
+
messages = [
|
95 |
+
{
|
96 |
+
"type": "text",
|
97 |
+
"text": prompt
|
98 |
+
},
|
99 |
+
{
|
100 |
+
"type": "image_url",
|
101 |
+
"image_url": {
|
102 |
+
"url": image_url
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
+
}
|
105 |
+
]
|
106 |
+
|
107 |
+
# Initialize services
|
108 |
+
hopter = Hopter(api_key=os.environ.get("HOPTER_API_KEY"), environment=Environment.STAGING)
|
109 |
+
mask_service = GenerateMaskService(hopter=hopter)
|
110 |
+
|
111 |
+
# Initialize dependencies
|
112 |
+
deps = ImageEditDeps(
|
113 |
+
edit_instruction=prompt,
|
114 |
+
image_url=image_url,
|
115 |
+
hopter_client=hopter,
|
116 |
+
mask_service=mask_service
|
117 |
+
)
|
118 |
+
async with mask_generation_agent.run_stream(
|
119 |
+
messages,
|
120 |
+
deps=deps
|
121 |
+
) as result:
|
122 |
+
async for message in result.stream():
|
123 |
+
print(message)
|
124 |
|
125 |
|
126 |
if __name__ == "__main__":
|
src/hopter/client.py
CHANGED
@@ -1,8 +1,7 @@
|
|
1 |
import asyncio
|
2 |
import httpx
|
3 |
from enum import Enum
|
4 |
-
from src.
|
5 |
-
import base64
|
6 |
from dotenv import load_dotenv
|
7 |
import os
|
8 |
from pydantic import BaseModel, Field
|
@@ -48,12 +47,12 @@ class Hopter:
|
|
48 |
):
|
49 |
self.api_key = api_key
|
50 |
self.base_url = environment.base_url
|
51 |
-
self.client = httpx.
|
52 |
|
53 |
-
|
54 |
print(f"Generating mask with input: {input.text_prompt}")
|
55 |
try:
|
56 |
-
response =
|
57 |
f"{self.base_url}/api/v1/services/ram-grounded-sam-api/predictions",
|
58 |
headers={
|
59 |
"Authorization": f"Bearer {self.api_key}",
|
@@ -61,7 +60,8 @@ class Hopter:
|
|
61 |
},
|
62 |
json={
|
63 |
"input": input.model_dump()
|
64 |
-
}
|
|
|
65 |
)
|
66 |
response.raise_for_status() # Raise an error for bad responses
|
67 |
instance = response.json().get("output").get("instances")[0]
|
@@ -72,10 +72,10 @@ class Hopter:
|
|
72 |
except Exception as exc:
|
73 |
print(f"An unexpected error occurred: {exc}")
|
74 |
|
75 |
-
|
76 |
print(f"Magic replacing with input: {input.prompt}")
|
77 |
try:
|
78 |
-
response =
|
79 |
f"{self.base_url}/api/v1/services/sdxl-magic-replace/predictions",
|
80 |
headers={
|
81 |
"Authorization": f"Bearer {self.api_key}",
|
@@ -83,9 +83,9 @@ class Hopter:
|
|
83 |
},
|
84 |
json={
|
85 |
"input": input.model_dump()
|
86 |
-
}
|
|
|
87 |
)
|
88 |
-
print(response)
|
89 |
response.raise_for_status() # Raise an error for bad responses
|
90 |
instance = response.json().get("output")
|
91 |
print("Magic replaced.")
|
@@ -100,7 +100,7 @@ async def test_generate_mask(hopter: Hopter, image_url: str) -> str:
|
|
100 |
text_prompt="pole",
|
101 |
image_b64=image_url
|
102 |
)
|
103 |
-
mask =
|
104 |
return mask.mask_b64
|
105 |
|
106 |
async def test_magic_replace(hopter: Hopter, image_url: str, mask: str, prompt: str) -> str:
|
@@ -109,7 +109,7 @@ async def test_magic_replace(hopter: Hopter, image_url: str, mask: str, prompt:
|
|
109 |
mask=mask,
|
110 |
prompt=prompt
|
111 |
)
|
112 |
-
result =
|
113 |
return result.base64_image
|
114 |
|
115 |
async def main():
|
@@ -118,13 +118,11 @@ async def main():
|
|
118 |
environment=Environment.STAGING
|
119 |
)
|
120 |
image_file_path = "./assets/lakeview.jpg"
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
|
|
125 |
|
126 |
-
mask = await test_generate_mask(hopter, image_url)
|
127 |
-
magic_replace_result = await test_magic_replace(hopter, image_url, mask, "remove the pole")
|
128 |
-
print(magic_replace_result)
|
129 |
if __name__ == "__main__":
|
130 |
asyncio.run(main())
|
|
|
1 |
import asyncio
|
2 |
import httpx
|
3 |
from enum import Enum
|
4 |
+
from src.utils import image_path_to_uri
|
|
|
5 |
from dotenv import load_dotenv
|
6 |
import os
|
7 |
from pydantic import BaseModel, Field
|
|
|
47 |
):
|
48 |
self.api_key = api_key
|
49 |
self.base_url = environment.base_url
|
50 |
+
self.client = httpx.Client()
|
51 |
|
52 |
+
def generate_mask(self, input: RamGroundedSamInput) -> RamGroundedSamResult:
|
53 |
print(f"Generating mask with input: {input.text_prompt}")
|
54 |
try:
|
55 |
+
response = self.client.post(
|
56 |
f"{self.base_url}/api/v1/services/ram-grounded-sam-api/predictions",
|
57 |
headers={
|
58 |
"Authorization": f"Bearer {self.api_key}",
|
|
|
60 |
},
|
61 |
json={
|
62 |
"input": input.model_dump()
|
63 |
+
},
|
64 |
+
timeout=None
|
65 |
)
|
66 |
response.raise_for_status() # Raise an error for bad responses
|
67 |
instance = response.json().get("output").get("instances")[0]
|
|
|
72 |
except Exception as exc:
|
73 |
print(f"An unexpected error occurred: {exc}")
|
74 |
|
75 |
+
def magic_replace(self, input: MagicReplaceInput) -> MagicReplaceResult:
|
76 |
print(f"Magic replacing with input: {input.prompt}")
|
77 |
try:
|
78 |
+
response = self.client.post(
|
79 |
f"{self.base_url}/api/v1/services/sdxl-magic-replace/predictions",
|
80 |
headers={
|
81 |
"Authorization": f"Bearer {self.api_key}",
|
|
|
83 |
},
|
84 |
json={
|
85 |
"input": input.model_dump()
|
86 |
+
},
|
87 |
+
timeout=None
|
88 |
)
|
|
|
89 |
response.raise_for_status() # Raise an error for bad responses
|
90 |
instance = response.json().get("output")
|
91 |
print("Magic replaced.")
|
|
|
100 |
text_prompt="pole",
|
101 |
image_b64=image_url
|
102 |
)
|
103 |
+
mask = hopter.generate_mask(input)
|
104 |
return mask.mask_b64
|
105 |
|
106 |
async def test_magic_replace(hopter: Hopter, image_url: str, mask: str, prompt: str) -> str:
|
|
|
109 |
mask=mask,
|
110 |
prompt=prompt
|
111 |
)
|
112 |
+
result = hopter.magic_replace(input)
|
113 |
return result.base64_image
|
114 |
|
115 |
async def main():
|
|
|
118 |
environment=Environment.STAGING
|
119 |
)
|
120 |
image_file_path = "./assets/lakeview.jpg"
|
121 |
+
image_url = image_path_to_uri(image_file_path)
|
122 |
+
|
123 |
+
mask = await test_generate_mask(hopter, image_url)
|
124 |
+
magic_replace_result = await test_magic_replace(hopter, image_url, mask, "remove the pole")
|
125 |
+
print(magic_replace_result)
|
126 |
|
|
|
|
|
|
|
127 |
if __name__ == "__main__":
|
128 |
asyncio.run(main())
|
src/services/generate_mask.py
CHANGED
@@ -46,7 +46,7 @@ class GenerateMaskService:
|
|
46 |
self.openai_file_upload = OpenAIFileUpload()
|
47 |
self.hopter = hopter
|
48 |
|
49 |
-
|
50 |
messages = [
|
51 |
{
|
52 |
"role": "system",
|
@@ -77,7 +77,7 @@ class GenerateMaskService:
|
|
77 |
instruction = response.choices[0].message.parsed
|
78 |
return instruction
|
79 |
|
80 |
-
|
81 |
"""
|
82 |
Generate a mask for the image editing instruction.
|
83 |
|
@@ -91,7 +91,7 @@ class GenerateMaskService:
|
|
91 |
text_prompt=mask_instruction.subject,
|
92 |
image_b64=image_url
|
93 |
)
|
94 |
-
generate_mask_result =
|
95 |
return generate_mask_result.mask_b64
|
96 |
|
97 |
async def main():
|
@@ -101,9 +101,9 @@ async def main():
|
|
101 |
with open(image_file_path, "rb") as image_file:
|
102 |
image_url = service.openai_file_upload.upload_image(image_file.read(), "vision")
|
103 |
|
104 |
-
instruction =
|
105 |
print(instruction)
|
106 |
-
mask =
|
107 |
print(mask)
|
108 |
|
109 |
if __name__ == "__main__":
|
|
|
46 |
self.openai_file_upload = OpenAIFileUpload()
|
47 |
self.hopter = hopter
|
48 |
|
49 |
+
def get_mask_generation_instruction(self, edit_instruction: str, image_url: str) -> GenerateMaskInstruction:
|
50 |
messages = [
|
51 |
{
|
52 |
"role": "system",
|
|
|
77 |
instruction = response.choices[0].message.parsed
|
78 |
return instruction
|
79 |
|
80 |
+
def generate_mask(self, mask_instruction: GenerateMaskInstruction, image_url: str) -> str:
|
81 |
"""
|
82 |
Generate a mask for the image editing instruction.
|
83 |
|
|
|
91 |
text_prompt=mask_instruction.subject,
|
92 |
image_b64=image_url
|
93 |
)
|
94 |
+
generate_mask_result = self.hopter.generate_mask(input)
|
95 |
return generate_mask_result.mask_b64
|
96 |
|
97 |
async def main():
|
|
|
101 |
with open(image_file_path, "rb") as image_file:
|
102 |
image_url = service.openai_file_upload.upload_image(image_file.read(), "vision")
|
103 |
|
104 |
+
instruction = service.get_mask_generation_instruction(edit_instruction, image_url)
|
105 |
print(instruction)
|
106 |
+
mask = service.generate_mask(instruction, image_url)
|
107 |
print(mask)
|
108 |
|
109 |
if __name__ == "__main__":
|
src/utils.py
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
from fastapi import UploadFile
|
3 |
+
def image_path_to_base64(image_path: str) -> str:
|
4 |
+
with open(image_path, "rb") as image_file:
|
5 |
+
return base64.b64encode(image_file.read()).decode("utf-8")
|
6 |
+
|
7 |
+
def upload_file_to_base64(file: UploadFile) -> str:
|
8 |
+
return base64.b64encode(file.file.read()).decode("utf-8")
|
9 |
+
|
10 |
+
def image_path_to_uri(image_path: str) -> str:
|
11 |
+
return f"data:image/jpeg;base64,{image_path_to_base64(image_path)}"
|