Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 86 additions & 7 deletions bashful.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import json
import functions_framework
import os
import uuid
from models.http_models.bashful_http import Txt2ImgModel

import requests
from models.http_models.bashful_http import Img2SVGModel, RemoveBGRequest, Txt2ImgModel, Txt2SVGModel

from utils.http_utils import cors_decorator


from providers import airtable_service, ai_service, logger, response_headers, gcp_service
from providers import (
airtable_service,
ai_service,
logger,
response_headers,
gcp_service,
)
from utils.image_utils import convert_b64_to_bytes, replace_transparent_with_white
from PIL import Image
import io

from utils.img2img_utils import create_default_img2img_payload, merge_model_config, merge_request_and_default_img2img_payload
from utils.img2img_utils import (
create_default_img2img_payload,
merge_model_config,
merge_request_and_default_img2img_payload,
)


##################### PROJECT: Bashful-Photoshop #####################

Expand Down Expand Up @@ -53,7 +65,7 @@ def txt2img(request: Txt2ImgModel):
payload["upscale"] = model_config.get("upscale", "")
payload["steps"] = model_config.get("steps", "")
seed = payload.get("seed", None)

if seed:
del payload["seed"]

Expand Down Expand Up @@ -122,7 +134,7 @@ def img2img(request):

if not model_config:
return ({"error": "No model config found"}, 400, response_headers)

payload = merge_model_config(payload, model_config)

response = ai_service.img2img(byte_image, payload)
Expand Down Expand Up @@ -157,3 +169,70 @@ def img2img(request):
except Exception as e:
logger.error(e)
return ({"error": str(e)}, 500, response_headers)


def img2svg(request: Img2SVGModel):
image_url = request.image_url
if not image_url:
return ({"error": "Invalid image url"}, 400, response_headers)

response = requests.post(
"https://vectorizer.ai/api/v1/vectorize",
data={
"image.url": image_url,
# TODO: Add more upload options here
},
headers={
"Authorization": "Basic dmtjM3prbW44djM2ZmVkOjVzMXMzN2l2czRoZHNyazJjczVtZ2Uxa2ZwcjdtZmNuZzllbXM0czNpODdwZGZvczNpMHY="
},
)
if response.status_code == requests.codes.ok:
return (response.content, 200, response_headers)
else:
return ({"error": "Invalid image url"}, 400, response_headers)


def txt2svg(request: Txt2SVGModel | Txt2ImgModel):
try:
response = txt2img(request)
if response[1] != 200:
return response

img2svg_req = Img2SVGModel(image_url=response[0].get("url"))
img2svg_rep = img2svg(img2svg_req)
if img2svg_rep[1] != 200:
return img2svg_rep

upload_url = gcp_service.upload_svg_to_storage(
img2svg_rep[0], "bashful_api", f"svg/{uuid.uuid1()}.svg"
)


return (
{"svg_url": upload_url, "image_url": response[0].get("url")},
200,
response_headers,
)
except Exception as e:
logger.error(e)
return ({"error": str(e)}, 500, response_headers)


def remove_background(request: RemoveBGRequest):
data = request.json
img_response = requests.get(data.get("image_url"))

image_data = img_response.content

response = requests.post(
'https://sdk.photoroom.com/v1/segment',
headers={'x-api-key': 'eebb03f0afc9a8df9781f0c63c5c4d9edfbe9906'},
files={'image_file': image_data},
)

upload_url = gcp_service.upload_image_to_storage(
response.content, "bashful_api", f"remove_bg/{uuid.uuid1()}.png"
)


return ({"image_url": upload_url}, 200, response_headers)
24 changes: 1 addition & 23 deletions bashful_studio.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,26 +439,4 @@ def embed_watermark(request):
except Exception as e:
logger.error(e)
return ({"error": str(e)}, 500, response_headers)

def img2svg(request):

request_data = request.json
image_url = request_data.get("image_url")
if not image_url:
return ({"error": "Invalid image url"}, 400 , response_headers)

response = requests.post(
'https://vectorizer.ai/api/v1/vectorize',
data={
'image.url': image_url,
# TODO: Add more upload options here
},
headers={
'Authorization':
'Basic dmtjM3prbW44djM2ZmVkOjVzMXMzN2l2czRoZHNyazJjczVtZ2Uxa2ZwcjdtZmNuZzllbXM0czNpODdwZGZvczNpMHY='
},
)
if response.status_code == requests.codes.ok:
return (response.content, 200, response_headers)
else:
return ({"error": "Invalid image url"}, 400 , response_headers)

11 changes: 11 additions & 0 deletions chatbot/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def chat_bot():
while True:
user_input = input("You: ")
if user_input.lower() == 'exit':
break
else:
print("Bot: " + user_input)

if __name__ == "__main__":
print("Chat Bot is ready. Type 'exit' to end the conversation.")
chat_bot()
File renamed without changes.
File renamed without changes.
98 changes: 98 additions & 0 deletions chatbot/palm_based_chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import os
import re
from typing import Union
from langchain.tools import BaseTool, StructuredTool, Tool, tool
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatVertexAI, ChatOpenAI
from langchain import LLMMathChain
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
HumanMessage,
SystemMessage
)
from rembg import remove
from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser
from langchain.schema import AgentAction, AgentFinish, HumanMessage


chat = ChatVertexAI(project="shepard-379102")
# chat = ChatOpenAI()



def remove_background(message: str):
input_path = 'with_background_2.png'
output_path = 'without_background_2.png'

with open(input_path, 'rb') as i:
with open(output_path, 'wb') as o:
input = i.read()
output = remove(input)
o.write(output)

def get_image_location(message: str):
path = os.path.join(os.path.dirname(__file__), message)
return path

def get_this_file_location(message: str):
# Return the location of this file
return os.path.dirname(__file__)

tools = [
Tool.from_function(
func=remove_background,
name = "Background Remover",
description="This removes the backgrounds from images."
# coroutine= ... <- you can specify an async method if desired as well
),
Tool.from_function(
func=get_image_location,
name = "Image Location Getter",
description="This builds the location of the image on the server."
# coroutine= ... <- you can specify an async method if desired as well
),
Tool.from_function(
func=get_this_file_location,
name = "Image Location Getter",
description="This builds the location of the image on the server."
# coroutine= ... <- you can specify an async method if desired as well
),
]

class CustomOutputParser(AgentOutputParser):

def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:
print("llm_output:\n\n", llm_output)
# Check if agent should finish
if "Final Answer:" in llm_output:
return AgentFinish(
# Return values is generally always a dictionary with a single `output` key
# It is not recommended to try anything else at the moment :)
return_values={"output": llm_output.split("Final Answer:")[-1].strip()},
log=llm_output,
)
# Parse out the action and action input
regex = r"Action: (.*?)[\n]*Action Input:[\s]*(.*)"
match = re.search(regex, llm_output, re.DOTALL)
if not match:
raise ValueError(f"Could not parse LLM output: `{llm_output}`")
action = match.group(1).strip()
action_input = match.group(2)
# Return the action and action input
return AgentAction(tool=action, tool_input=action_input.strip(" ").strip('"'), log=llm_output)


messages = [
SystemMessage(content="You are a helpful assistant that builds prompts for text to image generators iteratively by gathering requirements from chatting with users. You edit the prompts and the AI generates images. You edit the images based on the edits the users asks for."),
HumanMessage(content="Remove the background from this image at where this script is running, the name of the file is with_background_2.png."),
]
agent = initialize_agent(tools, chat, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
result = agent.run(messages)
print(result)
# result = chat(messages)
# print(result)

10 changes: 10 additions & 0 deletions chatbot/remove_background.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from rembg import remove

input_path = 'with_background_2.png'
output_path = 'without_background_2.png'

with open(input_path, 'rb') as i:
with open(output_path, 'wb') as o:
input = i.read()
output = remove(input)
o.write(output)
71 changes: 71 additions & 0 deletions chatbot/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import re
from langchain.agents import Tool, AgentExecutor, BaseSingleActionAgent, BaseMultiActionAgent
from langchain.schema import AgentAction, AgentFinish
from typing import List, Tuple, Any, Union

class FileReader:
def read_file(self, location: str) -> str:
with open(location, 'r') as f:
return f.read()

class BackgroundRemover:
def remove_background(self, image_path: str) -> str:
# code to remove background from image
return "background removed from " + image_path

class Joker:
def make_joke(self, image_path: str) -> str:
# code to remove background from image
return "background removed from " + image_path

file_reader = FileReader()
background_remover = BackgroundRemover()
joker = Joker()

tools = [
Tool(
name="Read File",
func=file_reader.read_file,
description="reads a file given a location"
),
Tool(
name="Remove Background",
func=background_remover.remove_background,
description="removes the background from an image"
),
Tool(
name="Make Joke",
func=joker.make_joke,
description="removes the background from an image"
)
]

class CustomAgent(BaseMultiActionAgent):
@property
def input_keys(self):
return ["message"]

def plan(
self, intermediate_steps: List[Tuple[AgentAction, str]], **kwargs: Any
) -> Union[AgentAction, AgentFinish]:
file_path = re.search(r'remove background from (.+)', kwargs["message"]).group(1)
return AgentAction(tool="Read File", tool_input=file_path, log="")

def aplan(
self, intermediate_steps: List[Tuple[AgentAction, str]], **kwargs: Any
) -> Union[AgentAction, AgentFinish]:
file_path = re.search(r'remove background from (.+)', kwargs["message"]).group(1)
return AgentAction(tool="Read File", tool_input=file_path, log="")

agent = CustomAgent()

# agent = LLMSingleActionAgent(
# llm_chain=llm_chain,
# output_parser=output_parser,
# stop=["\nObservation:"],
# allowed_tools=tool_names
# )
agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)

result = agent_executor.run("remove background from yolo.txt")
print(result)
Binary file added chatbot/with_background_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions chatbot/yolo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Sup
6 changes: 6 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@
VECTORIZER_AI_URL = (
os.environ.get("VECTORIZER_AI_URL") or "https://vectorizer.ai/api/v1/vectorize"
)
TRAINING_DB_URL = (
os.environ.get("TRAINING_DB_URL") or "http://localhost:1337/"
)
BASHFUL_STUDIO_API_URL = (
os.environ.get("BASHFUL_STUDIO_API_URL") or "http://localhost:1337/"
)
2 changes: 1 addition & 1 deletion local_dev_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ def route_func(*args, **kwargs):
app.add_url_rule(f'/{name}', name, route_func, methods=['POST', 'GET', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'])

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
app.run(host="0.0.0.0", debug=True, port=8080)
Loading