Spaces:
Sleeping
Sleeping
Commit
·
28f26e5
1
Parent(s):
44e85d0
update to support user schema
Browse files- .gitignore +10 -2
- app.py +32 -25
- llm_api/anthropic_api.py +29 -23
- llm_api/anthropic_vertex_api.py +114 -0
- llm_api/langchain_api.py +1 -1
- llm_api/native_api.py +1 -0
- llm_api/openai_api.py +2 -2
- read_schema_free.py +0 -57
- read_schema_structured.py +0 -301
- requirements.txt +3 -1
- schema_free.py +146 -1
.gitignore
CHANGED
|
@@ -48,11 +48,19 @@ Thumbs.db
|
|
| 48 |
*.mov
|
| 49 |
*.wmv
|
| 50 |
|
|
|
|
|
|
|
| 51 |
env/
|
| 52 |
__pycache__/
|
| 53 |
-
|
| 54 |
*.ipynb
|
| 55 |
server.crt
|
| 56 |
server.key
|
| 57 |
server.csr
|
| 58 |
-
sample_data.json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
*.mov
|
| 49 |
*.wmv
|
| 50 |
|
| 51 |
+
.env
|
| 52 |
+
|
| 53 |
env/
|
| 54 |
__pycache__/
|
| 55 |
+
testset/
|
| 56 |
*.ipynb
|
| 57 |
server.crt
|
| 58 |
server.key
|
| 59 |
server.csr
|
| 60 |
+
sample_data.json
|
| 61 |
+
|
| 62 |
+
test_result
|
| 63 |
+
|
| 64 |
+
read_schema_free.py
|
| 65 |
+
read_schema_structured.py
|
| 66 |
+
dev.py
|
app.py
CHANGED
|
@@ -5,46 +5,54 @@ from llm_api.exceptions import RefusalError
|
|
| 5 |
# from llm_api.langchain_api import extract_info, follow_structure
|
| 6 |
from llm_api.native_api import extract_info, follow_structure
|
| 7 |
from openai import BadRequestError
|
| 8 |
-
|
| 9 |
|
| 10 |
load_dotenv('.env', override=True)
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
def extract_free_fn(gallery, provider, schema):
|
|
|
|
|
|
|
| 13 |
# write schema to file before calling extract_free_properties
|
| 14 |
try:
|
| 15 |
-
img_paths = [item[0] for item in gallery]
|
| 16 |
-
# request_id = log_input('extract', img_paths, provider, schema)
|
| 17 |
if schema is not None and isinstance(schema, str) and 'import' not in schema.replace("'import'", '').replace("'important'", ''):
|
| 18 |
with open('schema_free.py', 'r') as f:
|
| 19 |
default_schema = f.read()
|
| 20 |
import_part = default_schema.split('#####')[0]
|
| 21 |
print('Executing freestyle schema...')
|
| 22 |
full_schema = import_part + schema
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
with open('read_schema_free.py', 'w') as f:
|
| 24 |
f.write(full_schema)
|
| 25 |
-
exec(
|
| 26 |
print('Executed freestyle schema')
|
| 27 |
else:
|
| 28 |
print('SCHEMA ELSE')
|
| 29 |
raise Exception('Invalid schema')
|
| 30 |
except Exception as e:
|
| 31 |
-
|
|
|
|
| 32 |
|
| 33 |
try:
|
| 34 |
-
free_attributes = extract_info(img_paths, provider, Garment)
|
| 35 |
free_attributes = free_attributes.model_dump_json()
|
| 36 |
except RefusalError as e:
|
| 37 |
-
return
|
| 38 |
except BadRequestError as e:
|
| 39 |
-
return
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
# log_output(request_id, str(free_attributes))
|
| 43 |
-
return f'OK - provider: {provider}', free_attributes, [1] * 100
|
| 44 |
|
| 45 |
def follow_schema_fn(free_attributes, provider, probs, schema):
|
| 46 |
try:
|
| 47 |
-
# request_id = log_input('follow', None, provider, schema)
|
| 48 |
if schema is not None and isinstance(schema, str) and 'import' not in schema.replace("'import'", '').replace("'important'", ''):
|
| 49 |
with open('schema_structured.py', 'r') as f:
|
| 50 |
default_schema = f.read()
|
|
@@ -58,21 +66,19 @@ def follow_schema_fn(free_attributes, provider, probs, schema):
|
|
| 58 |
else:
|
| 59 |
print('SCHEMA ELSE')
|
| 60 |
raise Exception('Invalid schema')
|
| 61 |
-
except
|
| 62 |
-
return
|
| 63 |
|
| 64 |
try:
|
| 65 |
-
schema_attributes = follow_structure(free_attributes, provider, Garment)
|
| 66 |
schema_attributes = schema_attributes.model_dump_json()
|
| 67 |
except RefusalError as e:
|
| 68 |
-
return
|
| 69 |
except BadRequestError as e:
|
| 70 |
-
return
|
| 71 |
-
except Exception as e:
|
| 72 |
-
return f"ERROR: {e}", {}
|
| 73 |
|
| 74 |
-
|
| 75 |
-
|
| 76 |
|
| 77 |
with gr.Blocks(title='Internal Demo for Attribution') as demo:
|
| 78 |
with gr.Row():
|
|
@@ -83,6 +89,7 @@ with gr.Blocks(title='Internal Demo for Attribution') as demo:
|
|
| 83 |
# gr.Markdown('''<div style="text-align: left; font-size: 18px;">Upload images of a garment and click Extract Freestyle</div>''')
|
| 84 |
gallery = gr.Gallery(label='Images', type='filepath')
|
| 85 |
probs_text = gr.Textbox(label='Probabilities', placeholder='Probabilities', visible=False)
|
|
|
|
| 86 |
provider = gr.Dropdown(label='Provider', choices=['openai', 'anthropic'], value='openai')
|
| 87 |
button_extract = gr.Button(value='Extract Freestyle')
|
| 88 |
with gr.Column(scale=4):
|
|
@@ -105,8 +112,8 @@ with gr.Blocks(title='Internal Demo for Attribution') as demo:
|
|
| 105 |
free_schema = gr.TextArea(label='Freestyle Schema', placeholder='Freestyle Schema', visible=True, value=schema_free_text, interactive=True)
|
| 106 |
structured_schema = gr.TextArea(label='Structured Schema', placeholder='Schema', visible=True, value=schema_structured_text, interactive=True)
|
| 107 |
|
| 108 |
-
button_extract.click(extract_free_fn, [gallery, provider, free_schema], [status_free_text, free_attributes, probs_text])
|
| 109 |
-
button_follow.click(follow_schema_fn, [free_attributes, provider, probs_text, structured_schema], [status_structured_text, schema_attributes])
|
| 110 |
|
| 111 |
# demo.launch(server_name="0.0.0.0", server_port=7688, share=False, ssl_verify=True, ssl_certfile=None, ssl_keyfile=None, auth=None)
|
| 112 |
# demo.launch(server_name="0.0.0.0", server_port=7860, share=False, ssl_verify=False, ssl_certfile="server.crt", ssl_keyfile="server.key", auth=None)
|
|
|
|
| 5 |
# from llm_api.langchain_api import extract_info, follow_structure
|
| 6 |
from llm_api.native_api import extract_info, follow_structure
|
| 7 |
from openai import BadRequestError
|
| 8 |
+
|
| 9 |
|
| 10 |
load_dotenv('.env', override=True)
|
| 11 |
+
garment_categories = ['Auto', 'Upper Garment', 'Lower Garment', 'Hat', 'Luggage', 'Handbag', 'Makeup', 'Chair', 'Carpet', 'Watch', 'Cookware', 'Tableware', 'Sleepware', 'BathroomItem']
|
| 12 |
+
schema_categories = ['Auto', 'UpperGarmentProperties', 'LowerGarmentProperties', 'HatProperties', 'LuggageProperties', 'HandbagProperties', 'MakeupProperties', 'ChairProperties', 'CarpetProperties', 'WatchProperties', 'CookwareProperties', 'TablewareProperties', 'SleepwareProperties', 'BathroomItemProperties']
|
| 13 |
|
| 14 |
+
def extract_free_fn(gallery, category, provider, schema):
|
| 15 |
+
img_paths = [item[0] for item in gallery]
|
| 16 |
+
category_schema = schema_categories[garment_categories.index(category)]
|
| 17 |
# write schema to file before calling extract_free_properties
|
| 18 |
try:
|
|
|
|
|
|
|
| 19 |
if schema is not None and isinstance(schema, str) and 'import' not in schema.replace("'import'", '').replace("'important'", ''):
|
| 20 |
with open('schema_free.py', 'r') as f:
|
| 21 |
default_schema = f.read()
|
| 22 |
import_part = default_schema.split('#####')[0]
|
| 23 |
print('Executing freestyle schema...')
|
| 24 |
full_schema = import_part + schema
|
| 25 |
+
|
| 26 |
+
# dynamically change the last line of the schema to include the category schema
|
| 27 |
+
if category_schema in schema_categories[1:]:
|
| 28 |
+
print('Dynamic schema activated')
|
| 29 |
+
schema_lines = full_schema.split('\n')
|
| 30 |
+
schema_lines[-1] = f' properties: {category_schema}'
|
| 31 |
+
full_schema = '\n'.join(schema_lines)
|
| 32 |
+
|
| 33 |
with open('read_schema_free.py', 'w') as f:
|
| 34 |
f.write(full_schema)
|
| 35 |
+
exec(full_schema, globals())
|
| 36 |
print('Executed freestyle schema')
|
| 37 |
else:
|
| 38 |
print('SCHEMA ELSE')
|
| 39 |
raise Exception('Invalid schema')
|
| 40 |
except Exception as e:
|
| 41 |
+
print(e)
|
| 42 |
+
return 'Invalid schema! Please check the schema or Reload this page to restore default settings', {}, []
|
| 43 |
|
| 44 |
try:
|
| 45 |
+
status_code, free_attributes = extract_info(img_paths, provider, Garment)
|
| 46 |
free_attributes = free_attributes.model_dump_json()
|
| 47 |
except RefusalError as e:
|
| 48 |
+
return e.message, {}, []
|
| 49 |
except BadRequestError as e:
|
| 50 |
+
return e.message, {}, []
|
| 51 |
+
|
| 52 |
+
return f'status: {status_code} - provider: {provider}', free_attributes, [1] * 100
|
|
|
|
|
|
|
| 53 |
|
| 54 |
def follow_schema_fn(free_attributes, provider, probs, schema):
|
| 55 |
try:
|
|
|
|
| 56 |
if schema is not None and isinstance(schema, str) and 'import' not in schema.replace("'import'", '').replace("'important'", ''):
|
| 57 |
with open('schema_structured.py', 'r') as f:
|
| 58 |
default_schema = f.read()
|
|
|
|
| 66 |
else:
|
| 67 |
print('SCHEMA ELSE')
|
| 68 |
raise Exception('Invalid schema')
|
| 69 |
+
except:
|
| 70 |
+
return 'Invalid schema! Please check the schema or Reload this page to restore default settings', {}
|
| 71 |
|
| 72 |
try:
|
| 73 |
+
status_code, schema_attributes = follow_structure(free_attributes, provider, Garment)
|
| 74 |
schema_attributes = schema_attributes.model_dump_json()
|
| 75 |
except RefusalError as e:
|
| 76 |
+
return e.message, {}
|
| 77 |
except BadRequestError as e:
|
| 78 |
+
return e.message, {}
|
|
|
|
|
|
|
| 79 |
|
| 80 |
+
return f'status {status_code} - provider: {provider}', schema_attributes
|
| 81 |
+
|
| 82 |
|
| 83 |
with gr.Blocks(title='Internal Demo for Attribution') as demo:
|
| 84 |
with gr.Row():
|
|
|
|
| 89 |
# gr.Markdown('''<div style="text-align: left; font-size: 18px;">Upload images of a garment and click Extract Freestyle</div>''')
|
| 90 |
gallery = gr.Gallery(label='Images', type='filepath')
|
| 91 |
probs_text = gr.Textbox(label='Probabilities', placeholder='Probabilities', visible=False)
|
| 92 |
+
category = gr.Dropdown(label='Category', choices=garment_categories, value=garment_categories[0])
|
| 93 |
provider = gr.Dropdown(label='Provider', choices=['openai', 'anthropic'], value='openai')
|
| 94 |
button_extract = gr.Button(value='Extract Freestyle')
|
| 95 |
with gr.Column(scale=4):
|
|
|
|
| 112 |
free_schema = gr.TextArea(label='Freestyle Schema', placeholder='Freestyle Schema', visible=True, value=schema_free_text, interactive=True)
|
| 113 |
structured_schema = gr.TextArea(label='Structured Schema', placeholder='Schema', visible=True, value=schema_structured_text, interactive=True)
|
| 114 |
|
| 115 |
+
button_extract.click(extract_free_fn, [gallery, category,provider, free_schema], [status_free_text, free_attributes, probs_text])
|
| 116 |
+
button_follow.click(follow_schema_fn, [free_attributes, category, provider, probs_text, structured_schema], [status_structured_text, schema_attributes])
|
| 117 |
|
| 118 |
# demo.launch(server_name="0.0.0.0", server_port=7688, share=False, ssl_verify=True, ssl_certfile=None, ssl_keyfile=None, auth=None)
|
| 119 |
# demo.launch(server_name="0.0.0.0", server_port=7860, share=False, ssl_verify=False, ssl_certfile="server.crt", ssl_keyfile="server.key", auth=None)
|
llm_api/anthropic_api.py
CHANGED
|
@@ -2,6 +2,7 @@ from anthropic import Anthropic
|
|
| 2 |
from dotenv import load_dotenv
|
| 3 |
from llm_api.utils import get_data_format, get_image_data
|
| 4 |
from .constants import EXTRACT_INFO_HUMAN_MESSAGE, EXTRACT_INFO_SYSTEM_MESSAGE,FOLLOW_SCHEMA_HUMAN_MESSAGE, FOLLOW_SCHEMA_SYSTEM_MESSAGE
|
|
|
|
| 5 |
|
| 6 |
load_dotenv(override=True)
|
| 7 |
client = Anthropic()
|
|
@@ -47,23 +48,26 @@ def extract_info(img_paths, schema):
|
|
| 47 |
}
|
| 48 |
]
|
| 49 |
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
for content in response.content:
|
| 62 |
if content.type == 'tool_use':
|
| 63 |
# print(content.input)
|
| 64 |
# print(type(content.input))
|
| 65 |
print('Found tool_use!')
|
| 66 |
-
return schema.model_validate(content.input)
|
| 67 |
|
| 68 |
print('ERROR: No tool_use found!')
|
| 69 |
|
|
@@ -99,17 +103,19 @@ def follow_structure(json_info, schema):
|
|
| 99 |
"content": text_messages
|
| 100 |
}
|
| 101 |
]
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
|
|
|
|
|
|
| 113 |
|
| 114 |
for content in response.content:
|
| 115 |
if content.type == 'tool_use':
|
|
@@ -117,6 +123,6 @@ def follow_structure(json_info, schema):
|
|
| 117 |
# print(type(content.input))
|
| 118 |
print('Found tool_use!***********************')
|
| 119 |
print(content.input)
|
| 120 |
-
return schema.model_validate(content.input['json_info'])
|
| 121 |
|
| 122 |
print('ERROR: No tool_use found!')
|
|
|
|
| 2 |
from dotenv import load_dotenv
|
| 3 |
from llm_api.utils import get_data_format, get_image_data
|
| 4 |
from .constants import EXTRACT_INFO_HUMAN_MESSAGE, EXTRACT_INFO_SYSTEM_MESSAGE,FOLLOW_SCHEMA_HUMAN_MESSAGE, FOLLOW_SCHEMA_SYSTEM_MESSAGE
|
| 5 |
+
from anthropic import APIStatusError
|
| 6 |
|
| 7 |
load_dotenv(override=True)
|
| 8 |
client = Anthropic()
|
|
|
|
| 48 |
}
|
| 49 |
]
|
| 50 |
|
| 51 |
+
try:
|
| 52 |
+
response = client.messages.create(
|
| 53 |
+
model="claude-3-5-sonnet-20240620",
|
| 54 |
+
extra_headers={
|
| 55 |
+
"anthropic-beta": "prompt-caching-2024-07-31"
|
| 56 |
+
},
|
| 57 |
+
max_tokens=2048,
|
| 58 |
+
system=system_message,
|
| 59 |
+
tools=tools,
|
| 60 |
+
messages=messages
|
| 61 |
+
)
|
| 62 |
+
except APIStatusError as e:
|
| 63 |
+
return e.status_code, None
|
| 64 |
|
| 65 |
for content in response.content:
|
| 66 |
if content.type == 'tool_use':
|
| 67 |
# print(content.input)
|
| 68 |
# print(type(content.input))
|
| 69 |
print('Found tool_use!')
|
| 70 |
+
return 200, schema.model_validate(content.input)
|
| 71 |
|
| 72 |
print('ERROR: No tool_use found!')
|
| 73 |
|
|
|
|
| 103 |
"content": text_messages
|
| 104 |
}
|
| 105 |
]
|
| 106 |
+
try:
|
| 107 |
+
response = client.messages.create(
|
| 108 |
+
model="claude-3-5-sonnet-20240620",
|
| 109 |
+
extra_headers={
|
| 110 |
+
"anthropic-beta": "prompt-caching-2024-07-31"
|
| 111 |
+
},
|
| 112 |
+
max_tokens=2048,
|
| 113 |
+
system=system_message,
|
| 114 |
+
tools=tools,
|
| 115 |
+
messages=messages
|
| 116 |
+
)
|
| 117 |
+
except APIStatusError as e:
|
| 118 |
+
return e.status_code, None
|
| 119 |
|
| 120 |
for content in response.content:
|
| 121 |
if content.type == 'tool_use':
|
|
|
|
| 123 |
# print(type(content.input))
|
| 124 |
print('Found tool_use!***********************')
|
| 125 |
print(content.input)
|
| 126 |
+
return 200, schema.model_validate(content.input['json_info'])
|
| 127 |
|
| 128 |
print('ERROR: No tool_use found!')
|
llm_api/anthropic_vertex_api.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from anthropic import AnthropicVertex as Anthropic
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
+
from llm_api.utils import get_data_format, get_image_data
|
| 4 |
+
from .constants import EXTRACT_INFO_HUMAN_MESSAGE, EXTRACT_INFO_SYSTEM_MESSAGE,FOLLOW_SCHEMA_HUMAN_MESSAGE, FOLLOW_SCHEMA_SYSTEM_MESSAGE
|
| 5 |
+
|
| 6 |
+
load_dotenv(override=True)
|
| 7 |
+
client = Anthropic()
|
| 8 |
+
|
| 9 |
+
def extract_info(img_paths, schema):
|
| 10 |
+
print('Extracting info via Anthropic...')
|
| 11 |
+
tools = [
|
| 12 |
+
{
|
| 13 |
+
"name": "extract_garment_info",
|
| 14 |
+
"description": "Extracts key information from the image.",
|
| 15 |
+
"input_schema": schema.model_json_schema()
|
| 16 |
+
}
|
| 17 |
+
]
|
| 18 |
+
|
| 19 |
+
image_messages = [
|
| 20 |
+
{
|
| 21 |
+
"type": "image",
|
| 22 |
+
"source": {
|
| 23 |
+
"type": "base64",
|
| 24 |
+
"media_type": f"image/{get_data_format(img_path)}",
|
| 25 |
+
"data": get_image_data(img_path)
|
| 26 |
+
}
|
| 27 |
+
} for img_path in img_paths
|
| 28 |
+
]
|
| 29 |
+
|
| 30 |
+
system_message = [
|
| 31 |
+
{
|
| 32 |
+
"type": "text",
|
| 33 |
+
"text": EXTRACT_INFO_SYSTEM_MESSAGE
|
| 34 |
+
}
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
text_messages = [{
|
| 38 |
+
"type": "text",
|
| 39 |
+
"text": EXTRACT_INFO_HUMAN_MESSAGE,
|
| 40 |
+
}]
|
| 41 |
+
|
| 42 |
+
messages=[
|
| 43 |
+
{
|
| 44 |
+
"role": "user",
|
| 45 |
+
"content": text_messages + image_messages
|
| 46 |
+
}
|
| 47 |
+
]
|
| 48 |
+
|
| 49 |
+
response = client.messages.create(
|
| 50 |
+
model="claude-3-5-sonnet@20240620",
|
| 51 |
+
max_tokens=2048,
|
| 52 |
+
system=system_message,
|
| 53 |
+
tools=tools,
|
| 54 |
+
messages=messages
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
for content in response.content:
|
| 58 |
+
if content.type == 'tool_use':
|
| 59 |
+
# print(content.input)
|
| 60 |
+
# print(type(content.input))
|
| 61 |
+
print('Found tool_use!')
|
| 62 |
+
return schema.model_validate(content.input)
|
| 63 |
+
|
| 64 |
+
print('ERROR: No tool_use found!')
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def follow_structure(json_info, schema):
|
| 68 |
+
print('Following structure via Anthropic...')
|
| 69 |
+
tools = [
|
| 70 |
+
{
|
| 71 |
+
"name": "extract_garment_info",
|
| 72 |
+
"description": FOLLOW_SCHEMA_HUMAN_MESSAGE,
|
| 73 |
+
"input_schema": schema.model_json_schema()
|
| 74 |
+
}
|
| 75 |
+
]
|
| 76 |
+
|
| 77 |
+
print('DEBUG: human message**************************')
|
| 78 |
+
print(FOLLOW_SCHEMA_HUMAN_MESSAGE.format(json_info=json_info))
|
| 79 |
+
text_messages = [{
|
| 80 |
+
"type": "text",
|
| 81 |
+
"text": FOLLOW_SCHEMA_HUMAN_MESSAGE.format(json_info=json_info),
|
| 82 |
+
}]
|
| 83 |
+
|
| 84 |
+
system_message = [
|
| 85 |
+
{
|
| 86 |
+
"type": "text",
|
| 87 |
+
"text": FOLLOW_SCHEMA_SYSTEM_MESSAGE
|
| 88 |
+
}
|
| 89 |
+
]
|
| 90 |
+
|
| 91 |
+
messages=[
|
| 92 |
+
{
|
| 93 |
+
"role": "user",
|
| 94 |
+
"content": text_messages
|
| 95 |
+
}
|
| 96 |
+
]
|
| 97 |
+
|
| 98 |
+
response = client.messages.create(
|
| 99 |
+
model="claude-3-5-sonnet@20240620",
|
| 100 |
+
max_tokens=2048,
|
| 101 |
+
system=system_message,
|
| 102 |
+
tools=tools,
|
| 103 |
+
messages=messages
|
| 104 |
+
)
|
| 105 |
+
|
| 106 |
+
for content in response.content:
|
| 107 |
+
if content.type == 'tool_use':
|
| 108 |
+
# print(content.input)
|
| 109 |
+
# print(type(content.input))
|
| 110 |
+
print('Found tool_use!***********************')
|
| 111 |
+
print(content.input)
|
| 112 |
+
return schema.model_validate(content.input['json_info'])
|
| 113 |
+
|
| 114 |
+
print('ERROR: No tool_use found!')
|
llm_api/langchain_api.py
CHANGED
|
@@ -11,7 +11,7 @@ load_dotenv()
|
|
| 11 |
|
| 12 |
|
| 13 |
anthropic_llm = ChatAnthropic(
|
| 14 |
-
model="claude-3-5-sonnet-
|
| 15 |
temperature=0,
|
| 16 |
max_tokens=1024,
|
| 17 |
timeout=None,
|
|
|
|
| 11 |
|
| 12 |
|
| 13 |
anthropic_llm = ChatAnthropic(
|
| 14 |
+
model="claude-3-5-sonnet-20241022",
|
| 15 |
temperature=0,
|
| 16 |
max_tokens=1024,
|
| 17 |
timeout=None,
|
llm_api/native_api.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import base64
|
|
|
|
| 2 |
from . import openai_api as openai_info_extractor
|
| 3 |
from . import anthropic_api as anthropic_extractor
|
| 4 |
|
|
|
|
| 1 |
import base64
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
from . import openai_api as openai_info_extractor
|
| 4 |
from . import anthropic_api as anthropic_extractor
|
| 5 |
|
llm_api/openai_api.py
CHANGED
|
@@ -52,7 +52,7 @@ def extract_info(img_paths, schema):
|
|
| 52 |
parsed_data = json.loads(content)
|
| 53 |
model_data = schema.model_validate(parsed_data)
|
| 54 |
|
| 55 |
-
return model_data
|
| 56 |
|
| 57 |
|
| 58 |
def follow_structure(json_info, schema):
|
|
@@ -90,5 +90,5 @@ def follow_structure(json_info, schema):
|
|
| 90 |
parsed_data = json.loads(content)
|
| 91 |
model_data = schema.model_validate(parsed_data)
|
| 92 |
|
| 93 |
-
return model_data
|
| 94 |
|
|
|
|
| 52 |
parsed_data = json.loads(content)
|
| 53 |
model_data = schema.model_validate(parsed_data)
|
| 54 |
|
| 55 |
+
return 200, model_data
|
| 56 |
|
| 57 |
|
| 58 |
def follow_structure(json_info, schema):
|
|
|
|
| 90 |
parsed_data = json.loads(content)
|
| 91 |
model_data = schema.model_validate(parsed_data)
|
| 92 |
|
| 93 |
+
return 200, model_data
|
| 94 |
|
read_schema_free.py
DELETED
|
@@ -1,57 +0,0 @@
|
|
| 1 |
-
from enum import Enum
|
| 2 |
-
from typing import Union
|
| 3 |
-
from pydantic import BaseModel, Field
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
# avoid using the 'import' string, including words like 'important', etc.
|
| 7 |
-
class UpperGarmentProperties(BaseModel):
|
| 8 |
-
upper_category: str
|
| 9 |
-
neck: str
|
| 10 |
-
sleeve: str
|
| 11 |
-
shoulder: str
|
| 12 |
-
waist: str
|
| 13 |
-
length: str
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
class LowerGarmentProperties(BaseModel):
|
| 17 |
-
lower_category: str
|
| 18 |
-
waist: str
|
| 19 |
-
hip: str
|
| 20 |
-
rise: str
|
| 21 |
-
leg: str
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
class HatProperties(BaseModel):
|
| 25 |
-
style: str
|
| 26 |
-
brim: str
|
| 27 |
-
|
| 28 |
-
class TargetAudience(BaseModel):
|
| 29 |
-
age_range: str
|
| 30 |
-
style_preference: str
|
| 31 |
-
lifestyle: str
|
| 32 |
-
|
| 33 |
-
class Closure(BaseModel):
|
| 34 |
-
color: str
|
| 35 |
-
type: str
|
| 36 |
-
location: str
|
| 37 |
-
|
| 38 |
-
class Pattern(BaseModel):
|
| 39 |
-
type: str
|
| 40 |
-
color: list[str]
|
| 41 |
-
|
| 42 |
-
class Garment(BaseModel): # don't rename this class
|
| 43 |
-
category: str = Field(..., description='Category of the garment')
|
| 44 |
-
gender: str
|
| 45 |
-
material: str
|
| 46 |
-
color: list[str] = Field(..., description='Color of the garment')
|
| 47 |
-
pattern: Pattern
|
| 48 |
-
style: str
|
| 49 |
-
closure: Closure
|
| 50 |
-
fit: str = Field(..., description='Should be one of slim fit, regular fit, loose fit')
|
| 51 |
-
season: list[str]
|
| 52 |
-
occasion: list[str]
|
| 53 |
-
special_occasion: list[str] = Field(..., description='List up to three special occasions, such as weddings, halloween or graduation')
|
| 54 |
-
usage: list[str]
|
| 55 |
-
pairing: list[str]
|
| 56 |
-
target_audience: list[TargetAudience]
|
| 57 |
-
properties: Union[UpperGarmentProperties, LowerGarmentProperties, HatProperties]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
read_schema_structured.py
DELETED
|
@@ -1,301 +0,0 @@
|
|
| 1 |
-
from enum import Enum
|
| 2 |
-
from typing import Union
|
| 3 |
-
from pydantic import BaseModel, Field
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
# avoid using the 'import' string, including words like 'important', etc.
|
| 8 |
-
class NeckType(str, Enum):
|
| 9 |
-
ROUND = "Round neck"
|
| 10 |
-
V_NECK = "V-neck"
|
| 11 |
-
COLLAR = "Collar"
|
| 12 |
-
OFF_SHOULDER = "Off-shoulder"
|
| 13 |
-
HALTER = "Halter"
|
| 14 |
-
OTHER = "Other"
|
| 15 |
-
|
| 16 |
-
class Color(str, Enum):
|
| 17 |
-
SCARLET = "Scarlet" # A bright red color
|
| 18 |
-
AZURE = "Azure" # A bright blue color
|
| 19 |
-
EMERALD = "Emerald" # A bright green color
|
| 20 |
-
AMBER = "Amber" # A yellow-orange color
|
| 21 |
-
EBONY = "Ebony" # A dark black color
|
| 22 |
-
IVORY = "Ivory" # A creamy white color
|
| 23 |
-
FUCHSIA = "Fuchsia" # A bright pink-purple color
|
| 24 |
-
VIOLET = "Violet" # A purple color
|
| 25 |
-
TANGERINE = "Tangerine" # A bright orange color
|
| 26 |
-
CHESTNUT = "Chestnut" # A reddish-brown color
|
| 27 |
-
SLATE = "Slate" # A gray color
|
| 28 |
-
NAVY = "Navy" # A dark blue color
|
| 29 |
-
SILVER = "Silver" # A metallic gray color
|
| 30 |
-
GOLD = "Gold" # A metallic yellow color
|
| 31 |
-
BEIGE = "Beige" # A light brown color
|
| 32 |
-
MULTI = "Multicolor" # Multiple colors
|
| 33 |
-
OTHER = "Other" # Any other color
|
| 34 |
-
|
| 35 |
-
# class Color(str, Enum):
|
| 36 |
-
# RED = "Red"
|
| 37 |
-
# ORANGE = "Orange"
|
| 38 |
-
# YELLOW = "Yellow"
|
| 39 |
-
# GREEN = "Green"
|
| 40 |
-
# BLUE = "Blue"
|
| 41 |
-
# PURPLE = "Purple"
|
| 42 |
-
# PINK = "Pink"
|
| 43 |
-
# BROWN = "Brown"
|
| 44 |
-
# BLACK = "Black"
|
| 45 |
-
# WHITE = "White"
|
| 46 |
-
# GRAY = "Gray"
|
| 47 |
-
# # OTHER = "Other"
|
| 48 |
-
|
| 49 |
-
class Sleeve(str, Enum):
|
| 50 |
-
SHORT = "Short"
|
| 51 |
-
LONG = "Long"
|
| 52 |
-
SLEEVELESS = "Sleeveless"
|
| 53 |
-
OTHER = "Other"
|
| 54 |
-
|
| 55 |
-
class Shoulder(str, Enum):
|
| 56 |
-
REGULAR = "Regular"
|
| 57 |
-
DROP = "Drop"
|
| 58 |
-
PUFF = "Puff"
|
| 59 |
-
COLD_SHOULDER = "Cold shoulder"
|
| 60 |
-
OTHER = "Other"
|
| 61 |
-
|
| 62 |
-
class Waist(str, Enum):
|
| 63 |
-
REGULAR = "Regular"
|
| 64 |
-
HIGH = "High"
|
| 65 |
-
LOW = "Low"
|
| 66 |
-
OTHER = "Other"
|
| 67 |
-
|
| 68 |
-
class UpperLength(str, Enum):
|
| 69 |
-
CROPPED = "Cropped"
|
| 70 |
-
REGULAR = "Regular"
|
| 71 |
-
LONG = "Long"
|
| 72 |
-
OTHER = "Other"
|
| 73 |
-
|
| 74 |
-
class UpperGarmentSubcategory(str, Enum):
|
| 75 |
-
T_SHIRT = "T-shirt"
|
| 76 |
-
BLOUSE = "Blouse"
|
| 77 |
-
SHIRT = "Shirt"
|
| 78 |
-
SWEATER = "Sweater"
|
| 79 |
-
JACKET = "Jacket"
|
| 80 |
-
HOODIE = "Hoodie"
|
| 81 |
-
DRESS = "Dress"
|
| 82 |
-
OTHER = "Other"
|
| 83 |
-
|
| 84 |
-
class LowerGarmentCategory(str, Enum):
|
| 85 |
-
SHORTS = "Shorts"
|
| 86 |
-
PANTS = "Pants"
|
| 87 |
-
SKIRT = "Skirt"
|
| 88 |
-
JEANS = "Jeans"
|
| 89 |
-
OTHER = "Other"
|
| 90 |
-
|
| 91 |
-
class PatternType(str, Enum):
|
| 92 |
-
SOLID = "Solid"
|
| 93 |
-
STRIPED = "Striped"
|
| 94 |
-
CHECKERED = "Checkered"
|
| 95 |
-
FLORAL = "Floral"
|
| 96 |
-
POLKA_DOT = "Polka dot"
|
| 97 |
-
OTHER = "Other"
|
| 98 |
-
|
| 99 |
-
class Pattern(BaseModel):
|
| 100 |
-
type: PatternType
|
| 101 |
-
color: list[Color]
|
| 102 |
-
|
| 103 |
-
class HipSize(str, Enum):
|
| 104 |
-
REGULAR = "Regular"
|
| 105 |
-
WIDE = "Wide"
|
| 106 |
-
SKINNY = "Skinny"
|
| 107 |
-
OTHER = "Other"
|
| 108 |
-
|
| 109 |
-
class Rise(str, Enum):
|
| 110 |
-
REGULAR = "Regular"
|
| 111 |
-
HIGH = "High"
|
| 112 |
-
LOW = "Low"
|
| 113 |
-
OTHER = "Other"
|
| 114 |
-
|
| 115 |
-
class LegWidth(str, Enum):
|
| 116 |
-
REGULAR = "Regular"
|
| 117 |
-
WIDE = "Wide"
|
| 118 |
-
SKINNY = "Skinny"
|
| 119 |
-
OTHER = "Other"
|
| 120 |
-
|
| 121 |
-
class UpperGarmentProperties(BaseModel):
|
| 122 |
-
upper_category: UpperGarmentSubcategory
|
| 123 |
-
neck: NeckType
|
| 124 |
-
sleeve: Sleeve
|
| 125 |
-
shoulder: Shoulder
|
| 126 |
-
waist: Waist
|
| 127 |
-
length: UpperLength
|
| 128 |
-
|
| 129 |
-
class LowerGarmentProperties(BaseModel):
|
| 130 |
-
lower_category: LowerGarmentCategory
|
| 131 |
-
waist: Waist
|
| 132 |
-
hip: HipSize
|
| 133 |
-
rise: Rise
|
| 134 |
-
leg: LegWidth
|
| 135 |
-
|
| 136 |
-
class HatStyle(str, Enum):
|
| 137 |
-
BEANIE = "Beanie"
|
| 138 |
-
BERET = "Beret"
|
| 139 |
-
BUCKET = "Bucket"
|
| 140 |
-
CAP = "Cap"
|
| 141 |
-
FEDORA = "Fedora"
|
| 142 |
-
VISOR = "Visor"
|
| 143 |
-
OTHER = "Other"
|
| 144 |
-
|
| 145 |
-
class Brim(str, Enum):
|
| 146 |
-
NONE = "None"
|
| 147 |
-
SHORT = "Short"
|
| 148 |
-
MEDIUM = "Medium"
|
| 149 |
-
LONG = "Long"
|
| 150 |
-
OTHER = "Other"
|
| 151 |
-
|
| 152 |
-
class HatProperties(BaseModel):
|
| 153 |
-
style: HatStyle
|
| 154 |
-
brim: Brim
|
| 155 |
-
|
| 156 |
-
class Category(str, Enum):
|
| 157 |
-
UPPER_GARMENT = "Upper garment"
|
| 158 |
-
LOWER_GARMENT = "Lower garment"
|
| 159 |
-
HAT = "Hat"
|
| 160 |
-
OTHER = "Other"
|
| 161 |
-
|
| 162 |
-
class Gender(str, Enum):
|
| 163 |
-
MALE = "Male"
|
| 164 |
-
FEMALE = "Female"
|
| 165 |
-
UNISEX = "Unisex"
|
| 166 |
-
OTHER = "Other"
|
| 167 |
-
|
| 168 |
-
class Material(str, Enum):
|
| 169 |
-
COTTON = "Cotton"
|
| 170 |
-
POLYESTER = "Polyester"
|
| 171 |
-
WOOL = "Wool"
|
| 172 |
-
SILK = "Silk"
|
| 173 |
-
LINEN = "Linen"
|
| 174 |
-
LEATHER = "Leather"
|
| 175 |
-
DENIM = "Denim"
|
| 176 |
-
OTHER = "Other"
|
| 177 |
-
|
| 178 |
-
class TargetAudienceAgeRange(str, Enum):
|
| 179 |
-
KIDS = "Kids"
|
| 180 |
-
TEENS = "Teens"
|
| 181 |
-
ADULTS = "Adults"
|
| 182 |
-
SENIORS = "Seniors"
|
| 183 |
-
OTHER = "Other"
|
| 184 |
-
|
| 185 |
-
class TargetAudienceStylePreference(str, Enum):
|
| 186 |
-
TRENDY = "Trendy"
|
| 187 |
-
CLASSIC = "Classic"
|
| 188 |
-
VINTAGE = "Vintage"
|
| 189 |
-
BOHEMIAN = "Bohemian"
|
| 190 |
-
OTHER = "Other"
|
| 191 |
-
|
| 192 |
-
class TargetAudienceLifestyle(str, Enum):
|
| 193 |
-
ACTIVE = "Active"
|
| 194 |
-
CASUAL = "Casual"
|
| 195 |
-
FORMAL = "Formal"
|
| 196 |
-
PARTY = "Party"
|
| 197 |
-
OTHER = "Other"
|
| 198 |
-
|
| 199 |
-
class TargetAudience(BaseModel):
|
| 200 |
-
age_range: TargetAudienceAgeRange
|
| 201 |
-
style_preference: TargetAudienceStylePreference
|
| 202 |
-
lifestyle: TargetAudienceLifestyle
|
| 203 |
-
|
| 204 |
-
class Style(str, Enum):
|
| 205 |
-
CASUAL = "Casual"
|
| 206 |
-
FORMAL = "Formal"
|
| 207 |
-
SPORTS = "Sports"
|
| 208 |
-
PARTY = "Party"
|
| 209 |
-
OTHER = "Other"
|
| 210 |
-
|
| 211 |
-
class ClosureType(str, Enum):
|
| 212 |
-
BUTTON = "Button"
|
| 213 |
-
ZIPPER = "Zipper"
|
| 214 |
-
LACE = "Lace"
|
| 215 |
-
HOOK = "Hook"
|
| 216 |
-
TIE = "Tie"
|
| 217 |
-
VELCRO = "Velcro"
|
| 218 |
-
BUCKLE = "Buckle"
|
| 219 |
-
NONE = "None"
|
| 220 |
-
OTHER = "Other"
|
| 221 |
-
|
| 222 |
-
class ClosureLocation(str, Enum):
|
| 223 |
-
FRONT = "Front"
|
| 224 |
-
BACK = "Back"
|
| 225 |
-
SIDE = "Side"
|
| 226 |
-
NECK = "Neck"
|
| 227 |
-
WAIST = "Waist"
|
| 228 |
-
OTHER = "Other"
|
| 229 |
-
|
| 230 |
-
class Closure(BaseModel):
|
| 231 |
-
color: Color
|
| 232 |
-
type: ClosureType
|
| 233 |
-
location: ClosureLocation
|
| 234 |
-
|
| 235 |
-
class Fit(str, Enum):
|
| 236 |
-
REGULAR = "Regular"
|
| 237 |
-
SLIM = "Slim"
|
| 238 |
-
LOOSE = "Loose"
|
| 239 |
-
OTHER = "Other"
|
| 240 |
-
|
| 241 |
-
class Season(str, Enum):
|
| 242 |
-
ALL_SEASONS = "All seasons"
|
| 243 |
-
SPRING = "Spring"
|
| 244 |
-
SUMMER = "Summer"
|
| 245 |
-
FALL = "Fall"
|
| 246 |
-
WINTER = "Winter"
|
| 247 |
-
|
| 248 |
-
class Occasion(str, Enum):
|
| 249 |
-
CASUAL = "Casual"
|
| 250 |
-
FORMAL = "Formal"
|
| 251 |
-
PARTY = "Party"
|
| 252 |
-
SPORTS = "Sports"
|
| 253 |
-
WORK = "Work"
|
| 254 |
-
OTHER = "Other"
|
| 255 |
-
|
| 256 |
-
class Usage(str, Enum):
|
| 257 |
-
DAILY = "Daily"
|
| 258 |
-
SPECIAL = "Special"
|
| 259 |
-
WORKOUT = "Workout"
|
| 260 |
-
SLEEP = "Sleep"
|
| 261 |
-
PARTY = "Party"
|
| 262 |
-
OTHER = "Other"
|
| 263 |
-
|
| 264 |
-
class Pairing(str, Enum):
|
| 265 |
-
JEANS = "Jeans"
|
| 266 |
-
SHORTS = "Shorts"
|
| 267 |
-
SKIRT = "Skirt"
|
| 268 |
-
LEGGINGS = "Leggings"
|
| 269 |
-
TROUSERS = "Trousers"
|
| 270 |
-
DRESS = "Dress"
|
| 271 |
-
CLUTCH = "Clutch"
|
| 272 |
-
HEELS = "Heels"
|
| 273 |
-
SANDALS = "Sandals"
|
| 274 |
-
JEWELRY = "Jewelry"
|
| 275 |
-
OTHER = "Other"
|
| 276 |
-
|
| 277 |
-
class SpecialOccasion(str, Enum):
|
| 278 |
-
WEDDING = "Wedding"
|
| 279 |
-
PROM = "Prom"
|
| 280 |
-
HALLOWEEN = "Halloween"
|
| 281 |
-
GRADUATION = "Graduation"
|
| 282 |
-
BIRTHDAY = "Birthday"
|
| 283 |
-
BRUNCH = "Brunch"
|
| 284 |
-
OTHER = "Other"
|
| 285 |
-
|
| 286 |
-
class Garment(BaseModel): # don't rename this class
|
| 287 |
-
category: Category
|
| 288 |
-
gender: Gender
|
| 289 |
-
material: Material
|
| 290 |
-
color: list[Color]
|
| 291 |
-
pattern: Pattern
|
| 292 |
-
style: Style
|
| 293 |
-
closure: Closure
|
| 294 |
-
fit: Fit
|
| 295 |
-
season: list[Season]
|
| 296 |
-
occasion: list[Occasion]
|
| 297 |
-
special_occasion: list[SpecialOccasion] = Field(..., description='List up to three special occasions, such as weddings, halloween or graduation')
|
| 298 |
-
usage: list[Usage]
|
| 299 |
-
pairing: list[Pairing]
|
| 300 |
-
target_audience: list[TargetAudience]
|
| 301 |
-
properties: Union[UpperGarmentProperties, LowerGarmentProperties, HatProperties]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
|
@@ -1,4 +1,6 @@
|
|
| 1 |
openai
|
| 2 |
anthropic
|
| 3 |
pydantic
|
| 4 |
-
python-dotenv
|
|
|
|
|
|
|
|
|
| 1 |
openai
|
| 2 |
anthropic
|
| 3 |
pydantic
|
| 4 |
+
python-dotenv
|
| 5 |
+
google-cloud-aiplatform
|
| 6 |
+
anthropic[vertex]
|
schema_free.py
CHANGED
|
@@ -39,6 +39,147 @@ class Pattern(BaseModel):
|
|
| 39 |
type: str
|
| 40 |
color: list[str]
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
class Garment(BaseModel): # don't rename this class
|
| 43 |
category: str = Field(..., description='Category of the garment')
|
| 44 |
gender: str
|
|
@@ -53,5 +194,9 @@ class Garment(BaseModel): # don't rename this class
|
|
| 53 |
special_occasion: list[str] = Field(..., description='List up to three special occasions, such as weddings, halloween or graduation')
|
| 54 |
usage: list[str]
|
| 55 |
pairing: list[str]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
target_audience: list[TargetAudience]
|
| 57 |
-
properties: Union[UpperGarmentProperties, LowerGarmentProperties, HatProperties]
|
|
|
|
| 39 |
type: str
|
| 40 |
color: list[str]
|
| 41 |
|
| 42 |
+
class LuggageProperties(BaseModel):
|
| 43 |
+
luggage_type: str = Field(..., description="Type of luggage, e.g., suitcase, duffel, backpack, etc.")
|
| 44 |
+
size: str = Field(..., description="Size of the luggage, e.g., carry-on, large, extra-large")
|
| 45 |
+
material: str = Field(..., description="Material used, e.g., leather, polyester, polycarbonate")
|
| 46 |
+
color: list[str] = Field(..., description="Color of the luggage")
|
| 47 |
+
weight: str = Field(..., description="Weight of the luggage in kg or lbs")
|
| 48 |
+
compartments: int = Field(..., description="Number of compartments")
|
| 49 |
+
wheels: str = Field(..., description="Wheel type, e.g., 2-wheel, 4-wheel, or spinner")
|
| 50 |
+
handle_type: str = Field(..., description="Type of handle, e.g., retractable, fixed, or no handle")
|
| 51 |
+
closure: Closure = Field(..., description="Closure details like type, color, and location")
|
| 52 |
+
lock_type: str = Field(..., description="Lock type, e.g., TSA, combination, or none")
|
| 53 |
+
expandable: bool = Field(..., description="Whether the luggage is expandable")
|
| 54 |
+
waterproof: bool = Field(..., description="Whether the luggage is waterproof or water-resistant")
|
| 55 |
+
|
| 56 |
+
class HandbagProperties(BaseModel):
|
| 57 |
+
handbag_type: str = Field(..., description="Type of handbag, e.g., tote, crossbody, clutch, etc.")
|
| 58 |
+
size: str = Field(..., description="Size of the handbag, e.g., small, medium, large")
|
| 59 |
+
material: str = Field(..., description="Material used, e.g., leather, canvas, suede")
|
| 60 |
+
color: list[str] = Field(..., description="Color of the handbag")
|
| 61 |
+
weight: str = Field(..., description="Weight of the handbag in kg or lbs")
|
| 62 |
+
compartments: int = Field(..., description="Number of compartments in the handbag")
|
| 63 |
+
strap_type: str = Field(..., description="Type of strap, e.g., adjustable, removable, fixed")
|
| 64 |
+
handle_type: str = Field(..., description="Type of handle, e.g., top handle, shoulder strap, none")
|
| 65 |
+
closure: Closure = Field(..., description="Closure details like type, color, and location")
|
| 66 |
+
lock_type: str = Field(..., description="Lock type, e.g., magnetic, zipper, clasp, or none")
|
| 67 |
+
pattern: Pattern = Field(..., description="Pattern details")
|
| 68 |
+
occasion: list[str] = Field(..., description="Occasions suitable for the handbag, e.g., formal, casual, evening")
|
| 69 |
+
waterproof: bool = Field(..., description="Whether the handbag is waterproof or water-resistant")
|
| 70 |
+
|
| 71 |
+
class MakeupProperties(BaseModel):
|
| 72 |
+
makeup_type: str = Field(..., description="Type of makeup, e.g., foundation, lipstick, eyeshadow, mascara, etc.")
|
| 73 |
+
shade: str = Field(..., description="Shade of the makeup product")
|
| 74 |
+
finish: str = Field(..., description="Finish of the product, e.g., matte, dewy, satin, glossy, etc.")
|
| 75 |
+
texture: str = Field(..., description="Texture of the product, e.g., creamy, powder, liquid")
|
| 76 |
+
skin_type_compatibility: list[str] = Field(..., description="Skin types compatible with the product, e.g., dry, oily, combination")
|
| 77 |
+
waterproof: bool = Field(..., description="Whether the product is waterproof or not")
|
| 78 |
+
long_wear: bool = Field(..., description="Whether the product is long-wearing")
|
| 79 |
+
cruelty_free: bool = Field(..., description="Whether the product is cruelty-free")
|
| 80 |
+
vegan: bool = Field(..., description="Whether the product is vegan")
|
| 81 |
+
ingredients: list[str] = Field(..., description="Key ingredients in the product")
|
| 82 |
+
packaging_type: str = Field(..., description="Type of packaging, e.g., compact, tube, pump bottle")
|
| 83 |
+
application_method: str = Field(..., description="How the product is applied, e.g., brush, sponge, fingers, applicator")
|
| 84 |
+
ingredients: list[str] = Field(..., description="If visible in images, what ingredients are in the product")
|
| 85 |
+
|
| 86 |
+
class ChairProperties(BaseModel):
|
| 87 |
+
chair_type: str = Field(..., description="Type of chair, e.g., office chair, dining chair, lounge chair")
|
| 88 |
+
material: str = Field(..., description="Material used, e.g., wood, metal, fabric")
|
| 89 |
+
upholstery_material: str = Field(..., description="Upholstery material, e.g., leather, fabric, mesh, none")
|
| 90 |
+
color: list[str] = Field(..., description="Color of the chair")
|
| 91 |
+
weight_capacity: str = Field(..., description="Maximum weight capacity of the chair in kg or lbs")
|
| 92 |
+
dimensions: str = Field(..., description="Dimensions of the chair, e.g., height, width, depth")
|
| 93 |
+
adjustable: bool = Field(..., description="Whether the chair is adjustable")
|
| 94 |
+
swivel: bool = Field(..., description="Whether the chair can swivel")
|
| 95 |
+
wheels: bool = Field(..., description="Whether the chair has wheels")
|
| 96 |
+
ergonomic: bool = Field(..., description="Whether the chair is ergonomically designed")
|
| 97 |
+
|
| 98 |
+
class CarpetProperties(BaseModel):
|
| 99 |
+
carpet_type: str = Field(..., description="Type of carpet, e.g., area rug, runner, mat")
|
| 100 |
+
material: str = Field(..., description="Material used, e.g., wool, synthetic, cotton")
|
| 101 |
+
color: list[str] = Field(..., description="Color of the carpet")
|
| 102 |
+
dimensions: str = Field(..., description="Dimensions of the carpet, e.g., length and width")
|
| 103 |
+
pile_height: str = Field(..., description="Pile height of the carpet in mm or inches")
|
| 104 |
+
pattern: Pattern = Field(..., description="Pattern details of the carpet")
|
| 105 |
+
anti_slip: bool = Field(..., description="Whether the carpet has anti-slip backing")
|
| 106 |
+
washable: bool = Field(..., description="Whether the carpet is washable")
|
| 107 |
+
indoor_outdoor: str = Field(..., description="Whether the carpet is meant for indoor or outdoor use")
|
| 108 |
+
|
| 109 |
+
class WatchProperties(BaseModel):
|
| 110 |
+
watch_type: str = Field(..., description="Type of watch, e.g., analog, digital, smart watch, hybrid")
|
| 111 |
+
movement_type: str = Field(..., description="Type of movement, e.g., quartz, mechanical, automatic, digital")
|
| 112 |
+
material: str = Field(..., description="Material of the watch case, e.g., stainless steel, titanium, plastic")
|
| 113 |
+
strap_material: str = Field(..., description="Material of the strap, e.g., leather, rubber, metal, nylon")
|
| 114 |
+
strap_color: list[str] = Field(..., description="Color of the watch strap")
|
| 115 |
+
dial_color: str = Field(..., description="Color of the watch dial")
|
| 116 |
+
water_resistant: bool = Field(..., description="Whether the watch is water-resistant")
|
| 117 |
+
water_resistance_depth: str = Field(..., description="Depth rating for water resistance in meters or feet")
|
| 118 |
+
features: list[str] = Field(..., description="Special features like GPS, heart rate monitor, chronograph, etc.")
|
| 119 |
+
case_diameter: str = Field(..., description="Diameter of the watch case in mm or inches")
|
| 120 |
+
case_thickness: str = Field(..., description="Thickness of the watch case in mm or inches")
|
| 121 |
+
weight: str = Field(..., description="Weight of the watch")
|
| 122 |
+
display_type: str = Field(..., description="Display type for smart/digital watches, e.g., LED, AMOLED, LCD")
|
| 123 |
+
battery_life: str = Field(..., description="Battery life for digital or smart watches")
|
| 124 |
+
clasp_type: str = Field(..., description="Type of clasp or buckle, e.g., deployant, tang buckle, folding clasp")
|
| 125 |
+
|
| 126 |
+
class SleepwareProperties(BaseModel):
|
| 127 |
+
sleepware_type: str = Field(..., description="Type of sleepware, e.g., pillow, duvet, mattress, mattress topper, blanket")
|
| 128 |
+
material: str = Field(..., description="Material used, e.g., cotton, down, memory foam, microfiber")
|
| 129 |
+
filling_material: str = Field(..., description="Filling material for pillows or duvets, e.g., down, feather, polyester")
|
| 130 |
+
firmness: str = Field(..., description="Firmness level for pillows or mattresses, e.g., soft, medium, firm")
|
| 131 |
+
size: str = Field(..., description="Size of the sleepware, e.g., queen, king, standard")
|
| 132 |
+
weight: str = Field(..., description="Weight of the sleepware (mainly for duvets and blankets)")
|
| 133 |
+
temperature_regulation: bool = Field(..., description="Whether the item has temperature regulation properties")
|
| 134 |
+
hypoallergenic: bool = Field(..., description="Whether the item is hypoallergenic")
|
| 135 |
+
machine_washable: bool = Field(..., description="Whether the item is machine washable")
|
| 136 |
+
thread_count: str = Field(..., description="Thread count for items like sheets or pillowcases")
|
| 137 |
+
moisture_wicking: bool = Field(..., description="Whether the material wicks away moisture")
|
| 138 |
+
|
| 139 |
+
class TablewareProperties(BaseModel):
|
| 140 |
+
tableware_type: str = Field(..., description="Type of tableware, e.g., dinner plate, salad bowl, mug, cup, saucer")
|
| 141 |
+
material: str = Field(..., description="Material of the tableware, e.g., porcelain, ceramic, glass, stoneware")
|
| 142 |
+
color: list[str] = Field(..., description="Color of the tableware")
|
| 143 |
+
pattern: Pattern = Field(..., description="Pattern details if applicable")
|
| 144 |
+
diameter: str = Field(..., description="Diameter of the tableware (for plates or bowls)")
|
| 145 |
+
volume: str = Field(..., description="Volume capacity for bowls, cups, mugs in ml or oz")
|
| 146 |
+
dishwasher_safe: bool = Field(..., description="Whether the tableware is dishwasher safe")
|
| 147 |
+
microwave_safe: bool = Field(..., description="Whether the tableware is microwave safe")
|
| 148 |
+
oven_safe: bool = Field(..., description="Whether the tableware is oven safe")
|
| 149 |
+
stackable: bool = Field(..., description="Whether the tableware is stackable")
|
| 150 |
+
chip_resistant: bool = Field(..., description="Whether the tableware is chip-resistant")
|
| 151 |
+
|
| 152 |
+
class CookwareProperties(BaseModel):
|
| 153 |
+
cookware_type: str = Field(..., description="Type of cookware, e.g., skillet, saucepan, stockpot, frying pan")
|
| 154 |
+
material: str = Field(..., description="Material of the cookware, e.g., stainless steel, cast iron, non-stick, aluminum")
|
| 155 |
+
diameter: str = Field(..., description="Diameter of the cookware in cm or inches")
|
| 156 |
+
depth: str = Field(..., description="Depth of the cookware in cm or inches")
|
| 157 |
+
weight: str = Field(..., description="Weight of the cookware in kg or lbs")
|
| 158 |
+
non_stick: bool = Field(..., description="Whether the cookware is non-stick")
|
| 159 |
+
induction_safe: bool = Field(..., description="Whether the cookware is safe for induction stoves")
|
| 160 |
+
oven_safe: bool = Field(..., description="Whether the cookware is oven safe")
|
| 161 |
+
max_oven_temperature: str = Field(..., description="Maximum temperature in Celsius or Fahrenheit for oven use")
|
| 162 |
+
dishwasher_safe: bool = Field(..., description="Whether the cookware is dishwasher safe")
|
| 163 |
+
handle_material: str = Field(..., description="Material of the handle, e.g., stainless steel, silicone, wood")
|
| 164 |
+
lid_included: bool = Field(..., description="Whether the cookware comes with a lid")
|
| 165 |
+
heat_distribution: str = Field(..., description="Heat distribution technology, e.g., tri-ply, aluminum core")
|
| 166 |
+
|
| 167 |
+
class BathroomItemProperties(BaseModel):
|
| 168 |
+
item_type: str = Field(..., description="Type of bathroom item, e.g., towel, bath mat, shower curtain")
|
| 169 |
+
material: str = Field(..., description="Material of the item, e.g., cotton, microfiber, bamboo")
|
| 170 |
+
size: str = Field(..., description="Size of the item, e.g., bath towel, hand towel, washcloth")
|
| 171 |
+
gsm: str = Field(..., description="Grams per square meter (GSM) which indicates the density of the towel fabric")
|
| 172 |
+
color: list[str] = Field(..., description="Color of the bathroom item")
|
| 173 |
+
absorbency: str = Field(..., description="Absorbency level, e.g., high, medium, low")
|
| 174 |
+
quick_dry: bool = Field(..., description="Whether the towel has quick-dry properties")
|
| 175 |
+
softness: str = Field(..., description="Softness rating, e.g., ultra-soft, soft, firm")
|
| 176 |
+
machine_washable: bool = Field(..., description="Whether the item is machine washable")
|
| 177 |
+
pattern: Pattern = Field(..., description="Pattern details if applicable")
|
| 178 |
+
anti_bacterial: bool = Field(..., description="Whether the towel has anti-bacterial properties")
|
| 179 |
+
hypoallergenic: bool = Field(..., description="Whether the towel is hypoallergenic")
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
|
| 183 |
class Garment(BaseModel): # don't rename this class
|
| 184 |
category: str = Field(..., description='Category of the garment')
|
| 185 |
gender: str
|
|
|
|
| 194 |
special_occasion: list[str] = Field(..., description='List up to three special occasions, such as weddings, halloween or graduation')
|
| 195 |
usage: list[str]
|
| 196 |
pairing: list[str]
|
| 197 |
+
microtrends: list[str]
|
| 198 |
+
silhouette: list[str]
|
| 199 |
+
aesthetic: list[str]
|
| 200 |
+
dressing_style: list[str]
|
| 201 |
target_audience: list[TargetAudience]
|
| 202 |
+
properties: Union[UpperGarmentProperties, LowerGarmentProperties, HatProperties, LuggageProperties, HandbagProperties, MakeupProperties, ChairProperties, CarpetProperties, WatchProperties, CookwareProperties, TablewareProperties, SleepwareProperties, BathroomItemProperties ] = Field(..., description="Specific properties for different product categories")
|