-
Notifications
You must be signed in to change notification settings - Fork 281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add: Interior Designer App #339
Open
techmaharaj
wants to merge
1
commit into
gptscript-ai:main
Choose a base branch
from
techmaharaj:interior-designer
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Interior Designer | ||
|
||
It allows you to upload a picture of your room and describe how you want it redesigned. The app will first analyze the image and identify the items in it. Then, based on your description, it will suggest changes you can make to redesign your room, including the color scheme, furniture, objects you can add, etc. and search for products on the internet and share their links as well. | ||
|
||
## High-level overview | ||
|
||
- Users can upload a picture of a room and provide a description of how their room wants to be. | ||
- The Python backend takes this input and uses GPTScript’s Python module to execute the GPTScript. | ||
- The vision tool first analyzes the image, followed by a generation of ideas. | ||
- The output of both is sent to the search tool, which searches the Internet for products you can purchase and add to your room. | ||
- These are saved within a markdown file that is read and displayed on the screen. | ||
|
||
## Installation | ||
|
||
### Prerequisites | ||
|
||
- Python 3.8 or later | ||
- Flask | ||
- Python dependencies listed in `requirements.txt` respectively. | ||
|
||
### Steps | ||
|
||
1. Clone the repository: | ||
|
||
``` bash | ||
git clone https://github.com/gptscript-ai/gptscript.git | ||
``` | ||
|
||
2. Navigate to the `examples/interior-designer` directory and install the dependencies: | ||
|
||
Python: | ||
|
||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
|
||
3. Setup `OPENAI_API_KEY` (Eg: `export OPENAI_API_KEY="yourapikey123456"`). You can get your [API key here](https://platform.openai.com/api-keys). | ||
|
||
4. Run the Flask application using `flask run` or `python app.py` | ||
|
||
## Usage | ||
|
||
1. Open your web browser and navigate to `http://127.0.0.1:5000/`. | ||
2. Use the interface to provide upload an image and provide a description. | ||
3. The application will generate ideas to redesing your room. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from gptscript.command import stream_exec_file | ||
from flask import Flask, render_template, request, jsonify | ||
import os | ||
import uuid | ||
from werkzeug.utils import secure_filename | ||
|
||
app = Flask(__name__) | ||
|
||
# Setting the base directory | ||
base_dir = os.path.dirname(os.path.abspath(__file__)) | ||
app.config['PWD'] = base_dir | ||
SCRIPT_PATH = os.path.join(base_dir, 'designer.gpt') | ||
|
||
# The output file name | ||
def print_output(out, err): | ||
# Error stream has the debug info that is useful to see | ||
for line in err: | ||
print(line) | ||
for line in out: | ||
print(line) | ||
|
||
@app.route('/') | ||
def index(): | ||
return render_template('index.html') | ||
|
||
def save_image(image_file, image_file_name, request_id): | ||
# Save the uploaded image to the current directory | ||
image_path = os.path.join(app.config['PWD'], image_file_name) | ||
image_file.save(image_path) | ||
|
||
return image_path | ||
|
||
@app.route('/get-ideas', methods=['POST']) | ||
def get_ideas(): | ||
try: | ||
# Generate a unique request ID | ||
request_id = str(uuid.uuid4()) | ||
|
||
# Get the image file and prompt from the request | ||
image_file = request.files['image'] | ||
prompt = request.form['prompt'] | ||
|
||
# Generate an input image and output file name based on the request ID | ||
image_file_name = f"{request_id}_room.jpg" | ||
output_file_name = f"{request_id}_output.md" | ||
output_file_path = os.path.join(app.config['PWD'], output_file_name) | ||
|
||
# Save the image file to the current directory | ||
image_path = save_image(image_file, image_file_name, request_id) | ||
|
||
# Execute the script with the prompt, image path and outputfile name | ||
out, err, wait = stream_exec_file(SCRIPT_PATH, "--prompt " + prompt + " --outputfile "+output_file_name + " --imagefile "+image_file_name) | ||
print_output(out, err) | ||
wait() | ||
|
||
# Read the output file | ||
with open(output_file_path, 'r') as output_file: | ||
summary = output_file.read() | ||
|
||
# Return the summary content | ||
return summary | ||
except Exception as e: | ||
return jsonify({'error': str(e)}), 500 | ||
|
||
if __name__ == '__main__': | ||
app.run(debug=os.environ.get('FLASK_DEBUG', True), host='0.0.0.0') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
tools: sys.find, sys.read, sys.write, search, github.com/gptscript-ai/gpt4-v-vision | ||
args: prompt: Prompt from the user. | ||
args: outputfile: Name of the output file. | ||
args: imagefile: Name of the image file. | ||
|
||
You are an ace interior designer and decorater. For the image provided, analyse the image and prompt and perform the following steps in order: | ||
|
||
1. Call the vision tool and send a prompt to "Anaylse the image $(imagefilename) in the current directory and identify the objects in the image". | ||
2. Based on the above analysis and the prompt provided, suggest the changes that can be done in the room in terms of paint color, theme, wallpaper, objects, furniture that can be added to the room. | ||
3. If you feel that some of the identified objects can be resued, suggest them too. | ||
4. Search google for new furnitures and objects suggested for the room based on the prompt. | ||
5. Create a new md file named $(outputfile) and insert the $(imagefilename) image on the top followed by the analysis, recommendations, how to reuse some items and product links with proper headings, bullets etc. | ||
|
||
|
||
--- | ||
name: search | ||
description: Searches the internet for content | ||
args: query: The query to search for | ||
tools: sys.http.html2text? | ||
|
||
1. Search google "https://www.google.com/search?q={$query}" for products and download content. | ||
2. Look for the first 3 search results that have the products that relate to the room. | ||
3. Download each search result and look for product that would best answer the query ${query}. | ||
4. Return the link to products that one can buy. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Use the official Python image as the base image | ||
FROM python:3.9-slim | ||
|
||
# Set the working directory | ||
WORKDIR /app | ||
|
||
# Copy the requirements file | ||
COPY requirements.txt . | ||
|
||
# Install the Python dependencies | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
|
||
# Copy the Flask app code | ||
COPY . . | ||
|
||
# Expose the port | ||
EXPOSE 5000 | ||
|
||
# Set the environment variable | ||
ENV FLASK_APP=app.py | ||
|
||
# Set this to True/False to enable/disable debugging. | ||
ENV FLASK_DEBUG=False | ||
|
||
# Run app | ||
CMD ["flask", "run", "--host=0.0.0.0"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Flask==2.0.1 | ||
gptscript==0.4.1 | ||
Werkzeug==2.2.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* style.css */ | ||
body { | ||
background-color: #f8f2e6; | ||
font-family: 'Merriweather', serif; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
min-height: 100vh; | ||
} | ||
|
||
.container { | ||
max-width: 500px; | ||
width: 60%; | ||
padding: 0 10px; | ||
} | ||
|
||
.input, .button { | ||
border-radius: 0 !important; | ||
} | ||
|
||
.box { | ||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); | ||
border-radius: 0; | ||
padding: 30px; | ||
} | ||
|
||
.markdown-body { | ||
box-sizing: border-box; | ||
background-color: #f5f5f5; | ||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); | ||
border-radius: 0; | ||
padding: 30px; | ||
} | ||
|
||
.gpt-logo { | ||
height: 100%; | ||
width: 100%; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
.gpt-logo img { | ||
width: 15%; | ||
height: 15%; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// app.js | ||
new Vue({ | ||
el: '#app', | ||
data: { | ||
prompt: '', | ||
imageFile: null, | ||
imageUrl: null, | ||
showIdeas: false, | ||
ideasMarkdown: '', | ||
renderedMarkdown: '', | ||
isLoading: false | ||
}, | ||
methods: { | ||
handleImageUpload(event) { | ||
this.imageFile = event.target.files[0]; | ||
this.imageUrl = URL.createObjectURL(event.target.files[0]); | ||
}, | ||
getIdeas() { | ||
this.isLoading = true; | ||
const formData = new FormData(); | ||
formData.append('image', this.imageFile); | ||
formData.append('prompt', this.prompt); | ||
|
||
axios.post('/get-ideas', formData, { | ||
headers: { | ||
'Content-Type': 'multipart/form-data' | ||
} | ||
}) | ||
.then(response => { | ||
this.ideasMarkdown = response.data; | ||
this.renderedMarkdown = marked.parse(this.ideasMarkdown); | ||
this.showIdeas = true; | ||
}) | ||
.catch(error => { | ||
if (error.response && error.response.data && error.response.data.error) { | ||
alert('Error: ' + error.response.data.error); | ||
} else { | ||
alert('An unexpected error occurred. Please try again later.'); | ||
} | ||
}) | ||
.finally(() => { | ||
this.isLoading = false; | ||
}); | ||
} | ||
} | ||
}); | ||
|
||
// Initialize the marked library | ||
marked.setOptions({ | ||
renderer: new marked.Renderer(), | ||
highlight: function(code, language) { | ||
const hljs = require('highlight.js'); | ||
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'; | ||
return hljs.highlight(validLanguage, code).value; | ||
}, | ||
pedantic: false, | ||
gfm: true, | ||
breaks: false, | ||
sanitize: false, | ||
smartLists: true, | ||
smartypants: false, | ||
xhtml: false | ||
}); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<!-- index.html --> | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Interior Designer</title> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"> | ||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.min.css"> | ||
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&display=swap" rel="stylesheet"> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> | ||
</head> | ||
<body> | ||
<div id="app" class="container is-fluid"> | ||
<section class="hero is-primary is-medium is-bold" style="background-image: linear-gradient(to right, #dda77b, #945D5E);"> | ||
<div class="hero-body"> | ||
<h1 class="title">Interior Designer</h1> | ||
<h2 class="subtitle">Are you bored of how your room looks? Want some inspiration to redesign your room? Simply click a picutre of your room, add a prompt and upload it here and see the magic unfold!</h2> | ||
</div> | ||
</section> | ||
|
||
<div class="box"> | ||
<div class="field"> | ||
<label class="label">Image</label> | ||
<div class="control"> | ||
<input class="input" type="file" accept="image/*" ref="imageInput" @change="handleImageUpload"> | ||
</div> | ||
</div> | ||
<div class="field"> | ||
<label class="label">Describe your desired room style</label> | ||
<div class="control"> | ||
<textarea class="textarea" placeholder="I want a room that gives me summer chill vibes." v-model="prompt"></textarea> | ||
</div> | ||
</div> | ||
<button class="button is-primary is-medium" style="background-color: #37123C;" @click="getIdeas" :disabled="isLoading"> | ||
<span v-if="isLoading" class="icon is-medium"> | ||
<i class="fas fa-spinner fa-spin"></i> | ||
</span> | ||
<span v-else>Design My Room</span> | ||
</button> | ||
</div> | ||
<div class="box markdown-body" v-if="showIdeas"> | ||
<img :src="imageUrl" v-if="imageUrl" class="img-responsive" height="50%" width="50%" alt="Uploaded Image"> | ||
<div v-html="renderedMarkdown"></div> | ||
</div> | ||
<div class="gpt-logo"><a href="https://gptscript.ai" target="_blank"><img src="{{url_for('static', filename='made-with-gptscript.png')}}"/></a></div> | ||
</div> | ||
|
||
<script src="{{ url_for('static', filename='js/app.js') }}"></script> | ||
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script> | ||
</body> | ||
</html> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be named Dockerfile to follow convention.