├── input.csv ├── readme.txt ├── upscaleuploadimages.py ├── uploadimages.py ├── upscalecreateimages.py └── createimages.py /input.csv: -------------------------------------------------------------------------------- 1 | details 2 | Cartoon Cats in Space 3 | Cartoon Cats in Venice 4 | Cartoon Dogs in Pajamas 5 | Pastel Cartoon Cats in Paris 6 | 7 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Learn how to use this stuff: 2 | 3 | https://www.youtube.com/c/incomestreamsurfers 4 | 5 | 6 | **update** 7 | 8 | The beta stable diffusion 0.9 cannot be used for commercial use, use this engine until it's allowed for commercial use 9 | 10 | stable-diffusion-v1-5 11 | 12 | **update** 13 | 14 | Use upscalecreateimages.py 15 | upscaleuploadimages.py 16 | 17 | If you want better quality designs **costs more tokens** 18 | 19 | First go to https://beta.dreamstudio.ai/account and get your secret key 20 | Then go to openAI and get your secret key 21 | Finally go to printify and get your secret key https://try.printify.com/vi2c7btfi5fq 22 | Make a shopify development store shopify.pxf.io/anWAnR 23 | Connect your Shopify store and Printify shop together 24 | Get your Printify shop code Find your shop ID by running this in cmd: curl -X GET https://api.printify.com/v1/shops.json --header "Authorization: Bearer YOUR_SECRET_KEY" 25 | Add the shop code to YOUR_SHOP_ID 26 | Add the other secret keys where they need to be 27 | Change the product, it's currently set to upload wall art 28 | To change the product you need the blueprint id and print provider, to get that go to Printify, go to the product you want, and get the two codes from the URL 29 | Now you need the variant ID by running this into the cmd curl -X GET "https://api.printify.com/v1/catalog/blueprints/1098/print_providers/228/variants.json" "Authorization: Bearer YOUR_PRINTIFY_KEY" 30 | Now run python createimages.py 31 | Now run uploadimages.py 32 | 33 | You're now done! 34 | -------------------------------------------------------------------------------- /upscaleuploadimages.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import pandas as pd 3 | import base64 4 | import os 5 | 6 | # Set your API credentials 7 | access_token = "your_printful_api_key" 8 | 9 | # Find your shop ID by running this: curl -X GET https://api.printify.com/v1/shops.json --header "Authorization: Bearer YOUR_PRINTIFY_API_KEY" 10 | 11 | shop_id = "your_shop_Id" 12 | 13 | # Set the URL for the API endpoints 14 | base_url = "https://api.printify.com/v1" 15 | upload_url = f"{base_url}/uploads/images.json" 16 | product_url = f"{base_url}/shops/{shop_id}/products.json" 17 | 18 | # Load the CSV file 19 | csv_path = "product_information.csv" # Update this to your CSV file path 20 | image_df = pd.read_csv(csv_path) 21 | 22 | # Set headers for requests 23 | headers = { 24 | "Authorization": f"Bearer {access_token}", 25 | "Content-Type": "application/json" 26 | } 27 | 28 | for idx, row in image_df.iterrows(): 29 | # Convert the image to Base64 30 | with open(row['local_path'], "rb") as img_file: 31 | img_b64 = base64.b64encode(img_file.read()).decode('utf-8') 32 | 33 | # Upload the image to the Printify media library 34 | data = { 35 | "file_name": row['file_name'], 36 | "contents": img_b64 37 | } 38 | response = requests.post(upload_url, headers=headers, json=data) 39 | image_id = response.json()["id"] 40 | 41 | # To change the print object, use this to find the variant id curl -X GET "https://api.printify.com/v1/catalog/blueprints/852/print_providers/73/variants.json" -H "Authorization: Bearer YOUR_PRINTIFY_KEY" 42 | 43 | # Current settings are for cork art 44 | 45 | # Create the product with the uploaded image 46 | data = { 47 | "title": row['title'], 48 | "description": row['description'], 49 | "tags": row['tags'].split(', '), # Assuming tags are comma-separated in the CSV 50 | "blueprint_id": 480, # Replace with the actual blueprint ID 51 | "print_provider_id": 70, 52 | "variants": [ 53 | { 54 | "id": 71689, # Replace with the actual variant ID 55 | "price": 3999, 56 | "is_enabled": True 57 | } 58 | ], 59 | "print_areas": [ 60 | { 61 | "variant_ids": [71689], # Replace with the actual variant ID 62 | "placeholders": [ 63 | { 64 | "position": "front", 65 | "images": [ 66 | { 67 | "id": image_id, 68 | "x": 0.5, 69 | "y": 0.5, 70 | "scale": 1.0, 71 | "angle": 0 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | ] 78 | } 79 | response = requests.post(product_url, headers=headers, json=data) 80 | if response.status_code >= 200 and response.status_code < 300: 81 | print(f"Product {idx+1} created successfully!") 82 | else: 83 | print(f"Failed to create product {idx+1}. Server responded with: {response.text}") 84 | -------------------------------------------------------------------------------- /uploadimages.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import pandas as pd 3 | import base64 4 | import os 5 | 6 | # Set your API credentials 7 | access_token = "YOUR_ACCESS_TOKEN" 8 | 9 | # Find your shop ID by running this: curl -X GET https://api.printify.com/v1/shops.json --header "Authorization: Bearer YOUR_SECRET_KEY" 10 | 11 | shop_id = "YOUR_SHOP_ID" 12 | 13 | # Set the URL for the API endpoints 14 | base_url = "https://api.printify.com/v1" 15 | upload_url = f"{base_url}/uploads/images.json" 16 | product_url = f"{base_url}/shops/{shop_id}/products.json" 17 | 18 | # Load the CSV file 19 | csv_path = "product_information.csv" # Update this to your CSV file path 20 | image_df = pd.read_csv(csv_path) 21 | 22 | # Set headers for requests 23 | headers = { 24 | "Authorization": f"Bearer {access_token}", 25 | "Content-Type": "application/json" 26 | } 27 | 28 | for idx, row in image_df.iterrows(): 29 | # Convert the image to Base64 30 | with open(row['local_path'], "rb") as img_file: 31 | img_b64 = base64.b64encode(img_file.read()).decode('utf-8') 32 | 33 | # Upload the image to the Printify media library 34 | data = { 35 | "file_name": row['file_name'], 36 | "contents": img_b64 37 | } 38 | response = requests.post(upload_url, headers=headers, json=data) 39 | image_id = response.json()["id"] 40 | 41 | # To change the print object, use this to find the variant id curl -X GET "https://api.printify.com/v1/catalog/blueprints/1098/print_providers/228/variants.json" "Authorization: Bearer YOUR_PRINTIFY_KEY" 42 | 43 | # Current settings are for wall art 44 | 45 | # Create the product with the uploaded image 46 | data = { 47 | "title": row['title'], 48 | "description": row['description'], 49 | "tags": row['tags'].split(', '), # Assuming tags are comma-separated in the CSV 50 | "blueprint_id": 1098, # Replace with the actual blueprint ID 51 | "print_provider_id": 228, 52 | "variants": [ 53 | { 54 | "id": 82064, # Replace with the actual variant ID 55 | "price": 3999, 56 | "is_enabled": True 57 | } 58 | ], 59 | "print_areas": [ 60 | { 61 | "variant_ids": [82064], # Replace with the actual variant ID 62 | "placeholders": [ 63 | { 64 | "position": "front", 65 | "images": [ 66 | { 67 | "id": image_id, 68 | "x": 0.5, 69 | "y": 0.5, 70 | "scale": 1.5, 71 | "angle": 0 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | ] 78 | } 79 | response = requests.post(product_url, headers=headers, json=data) 80 | if response.status_code >= 200 and response.status_code < 300: 81 | print(f"Product {idx+1} created successfully!") 82 | else: 83 | print(f"Failed to create product {idx+1}. Server responded with: {response.text}") 84 | -------------------------------------------------------------------------------- /upscalecreateimages.py: -------------------------------------------------------------------------------- 1 | import os 2 | import openai 3 | import pandas as pd 4 | from tqdm import tqdm 5 | from PIL import Image 6 | import requests 7 | import io 8 | 9 | # Set OpenAI and Stability.ai API keys 10 | openai.api_key = 'YOUR_OPEN_AI_KEY' 11 | stability_ai_key = 'YOUR_STABILITY_AI_KEY' 12 | 13 | # Set Stability API key for image upscaling 14 | api_key = 'YOUR_STABILIT_AI_KEY' 15 | if api_key is None: 16 | raise Exception("Missing Stability API key.") 17 | api_host = os.getenv("API_HOST", "https://api.stability.ai") 18 | 19 | 20 | def generate_clickable_title(detail): 21 | prompt = f"Generate a catchy and clickable title for a Cork Back Coaster with the theme: '{detail}'. Maximum 50 characters. At the end of each title write Cork Back Coaster" 22 | response = openai.ChatCompletion.create( 23 | model="gpt-3.5-turbo", 24 | messages=[ 25 | {"role": "system", "content": "You are a helpful assistant."}, 26 | {"role": "user", "content": prompt} 27 | ] 28 | ) 29 | clickable_title = response['choices'][0]['message']['content'].strip() 30 | clickable_title = clickable_title.replace('"', '') # Remove double quotes 31 | return clickable_title 32 | 33 | def generate_description(detail): 34 | prompt = f"Generate a compelling description for a Cork Back Coaster with the theme: '{detail}'. Maximum 150 characters." 35 | response = openai.ChatCompletion.create( 36 | model="gpt-3.5-turbo", 37 | messages=[ 38 | {"role": "system", "content": "You are a helpful assistant."}, 39 | {"role": "user", "content": prompt} 40 | ] 41 | ) 42 | description = response['choices'][0]['message']['content'].strip() 43 | description = description.replace('"', '') # Remove double quotes 44 | description += """ 45 |

This personalized photo coaster helps you market yourself the right way or uplift any table with a custom touch. Each round and square coaster is made with a high-gloss, polyester-coated hardboard top, and features a genuine cork bottom to prevent sliding.

46 |

.: Material: Genuine cork bottom finished with a glossy white top made of polyester-coated hardboard
.: Size: 3.75″ x 3.75″ (Square) and 4″ x 4″ (Round)
.: High-gloss top
.: NB! One coaster per listing
.: Assembled in the USA from globally sourced parts

47 | """ 48 | return description 49 | 50 | def generate_tags(detail): 51 | prompt = f"Generate relevant tags for a Cork Back Coaster with the theme: '{detail}'. Separate the tags with commas." 52 | response = openai.ChatCompletion.create( 53 | model="gpt-3.5-turbo", 54 | messages=[ 55 | {"role": "system", "content": "You are a helpful assistant."}, 56 | {"role": "user", "content": prompt} 57 | ] 58 | ) 59 | tag = response['choices'][0]['message']['content'].strip() 60 | tag = tag.replace('"', '') # Remove double quotes 61 | return tag 62 | 63 | csv_path = "input.csv" 64 | df = pd.read_csv(csv_path) 65 | 66 | file_names = [] 67 | local_paths = [] 68 | titles = [] 69 | descriptions = [] 70 | tags = [] 71 | 72 | for idx, row in tqdm(df.iterrows(), total=df.shape[0]): 73 | detail = row['details'] 74 | title = generate_clickable_title(detail) 75 | description = generate_description(detail) 76 | tag = generate_tags(detail) 77 | 78 | # Use the detail from the CSV as the image prompt 79 | image_prompt = detail 80 | 81 | # Generate the image using stable diffusion 82 | 83 | url = "https://api.stability.ai/v1/generation/stable-diffusion-v1-5/text-to-image" 84 | headers = {"Authorization": f"Bearer {stability_ai_key}", "Accept": "image/png"} 85 | data = { 86 | "width": 512, 87 | "height": 512, 88 | "text_prompts": [ 89 | { 90 | "text": image_prompt, 91 | "weight": 0.5, 92 | 93 | } 94 | ] 95 | } 96 | response = requests.post(url, headers=headers, json=data) 97 | image_data = response.content 98 | image = Image.open(io.BytesIO(image_data)) 99 | file_name = f"image_{idx}.png" 100 | local_path = f"{file_name}" 101 | image.save(local_path) 102 | 103 | # Upscale the image using the "esrgan-v1-x2plus" engine 104 | response = requests.post( 105 | f"{api_host}/v1/generation/esrgan-v1-x2plus/image-to-image/upscale", 106 | headers={ 107 | "Accept": "image/png", 108 | "Authorization": f"Bearer {api_key}" 109 | }, 110 | files={ 111 | "image": open(local_path, "rb") 112 | }, 113 | data={ 114 | "width": 2048, 115 | } 116 | ) 117 | 118 | if response.status_code != 200: 119 | raise Exception("Non-200 response: " + str(response.text)) 120 | 121 | upscaled_path = f"upscaled_{file_name}" 122 | with open(upscaled_path, "wb") as f: 123 | f.write(response.content) 124 | local_paths.append(upscaled_path) 125 | 126 | file_names.append(file_name) 127 | titles.append(title) 128 | descriptions.append(description) 129 | tags.append(tag) 130 | 131 | output_df = pd.DataFrame({ 132 | "file_name": file_names, 133 | "local_path": local_paths, 134 | "title": titles, 135 | "description": descriptions, 136 | "tags": tags 137 | }) 138 | 139 | output_df.to_csv("product_information.csv", index=False) 140 | -------------------------------------------------------------------------------- /createimages.py: -------------------------------------------------------------------------------- 1 | import os 2 | import openai 3 | import pandas as pd 4 | from tqdm import tqdm 5 | from PIL import Image 6 | import requests 7 | import io 8 | from PIL import Image, ImageDraw 9 | 10 | 11 | # Set OpenAI and Stability.ai API keys https://platform.openai.com/account/api-keys AND https://beta.dreamstudio.ai/account 12 | openai.api_key = 'YOUR_OPEN_AI_KEY' 13 | stability_ai_key = 'YOUR_STABILITY_AI_KEY' 14 | 15 | # Function to generate a clickable title using GPT-3.5-turbo 16 | 17 | # Change this prompt if you are changing the product type, right now it's Acrylic Wall Art Panels 18 | 19 | def generate_clickable_title(detail): 20 | print("Generating clickable title...") 21 | prompt = f"Generate a catchy and clickable title for a T-shirt with the theme: '{detail}'. Maximum 50 characters. At the end of each title write Acrylic Wall Art Panels" 22 | response = openai.ChatCompletion.create( 23 | model="gpt-3.5-turbo", 24 | messages=[ 25 | {"role": "system", "content": "You are a helpful assistant."}, 26 | {"role": "user", "content": prompt} 27 | ] 28 | ) 29 | clickable_title = response['choices'][0]['message']['content'].strip() 30 | clickable_title = clickable_title.replace('"', '') # Remove double quotes 31 | print("Clickable title generated...") 32 | return clickable_title 33 | 34 | # Function to generate a description 35 | def generate_description(detail): 36 | print("Generating description...") 37 | prompt = f"Generate a compelling description for a T-shirt with the theme: '{detail}'. Maximum 150 characters." 38 | response = openai.ChatCompletion.create( 39 | model="gpt-3.5-turbo", 40 | messages=[ 41 | {"role": "system", "content": "You are a helpful assistant."}, 42 | {"role": "user", "content": prompt} 43 | ] 44 | ) 45 | description = response['choices'][0]['message']['content'].strip() 46 | description = description.replace('"', '') # Remove double quotes 47 | 48 | # Append the predefined paragraph to the generated description 49 | description += """ 50 |

Acrylic art panels are a modern way to display beautiful and vibrant art that looks like it's embedded in clear glass. They have a clear, glossy acrylic surface and a white vinyl backing. Four silver stand-offs make it very easy to mount to the wall. Make your own original designs and print them on any (or all) of the seven available panel sizes in horizontal and vertical orientations. Square dimensions are available.

51 |

.: Material: Clear acrylic with white vinyl backing
.: Clear, glossy surface
.: Seven sizes to choose from
.: Horizontal, vertical and square options available
.: NB! For indoor use only

52 | """ 53 | print("Description generated...") 54 | return description 55 | 56 | 57 | # Function to generate an image prompt 58 | def generate_image_prompt(detail): 59 | print("Generating image prompt...") 60 | prompt = f"Generate a creative prompt for an image for a T-shirt with the theme: '{detail}'. Maximum 75 characters." 61 | response = openai.ChatCompletion.create( 62 | model="gpt-3.5-turbo", 63 | messages=[ 64 | {"role": "system", "content": "You are a helpful assistant."}, 65 | {"role": "user", "content": prompt} 66 | ] 67 | ) 68 | image_prompt = response['choices'][0]['message']['content'].strip() 69 | image_prompt = image_prompt.replace('"', '') # Remove double quotes 70 | print("Image prompt generated...") 71 | return image_prompt 72 | 73 | # Function to generate tags 74 | def generate_tags(detail): 75 | print("Generating tags...") 76 | prompt = f"Generate relevant tags for a T-shirt with the theme: '{detail}'. Separate the tags with commas." 77 | response = openai.ChatCompletion.create( 78 | model="gpt-3.5-turbo", 79 | messages=[ 80 | {"role": "system", "content": "You are a helpful assistant."}, 81 | {"role": "user", "content": prompt} 82 | ] 83 | ) 84 | tag = response['choices'][0]['message']['content'].strip() 85 | tag = tag.replace('"', '') # Remove double quotes 86 | print("Tags generated...") 87 | return tag 88 | 89 | # Load the input CSV file 90 | csv_path = "input.csv" 91 | df = pd.read_csv(csv_path) 92 | 93 | # Initialize empty lists for the new columns 94 | file_names = [] 95 | local_paths = [] 96 | titles = [] 97 | descriptions = [] 98 | tags = [] 99 | 100 | # Loop over the rows in the DataFrame to generate the title, description, prompt, and tags 101 | for idx, row in tqdm(df.iterrows(), total=df.shape[0]): 102 | detail = row['details'] 103 | 104 | # Generate the title, description, prompt, and tags using the OpenAI API 105 | title = generate_clickable_title(detail) 106 | description = generate_description(detail) 107 | image_prompt = generate_image_prompt(detail) 108 | tag = generate_tags(detail) 109 | 110 | 111 | 112 | # Generate the image using the Stability.ai API 113 | url = "https://api.stability.ai/v1/generation/stable-diffusion-v1-5/text-to-image" 114 | headers = {"Authorization": f"Bearer {stability_ai_key}", "Accept": "image/png"} 115 | data = { 116 | "width": 512, 117 | "height": 512, 118 | "text_prompts": [ 119 | { 120 | "text": image_prompt, 121 | "weight": 0.5 122 | } 123 | ] 124 | } 125 | response = requests.post(url, headers=headers, json=data) 126 | image_data = response.content 127 | image = Image.open(io.BytesIO(image_data)) 128 | file_name = f"image_{idx}.png" 129 | local_path = f"{file_name}" # Save the image in the same directory 130 | image.save(local_path) 131 | 132 | # Append the generated data to the lists 133 | file_names.append(file_name) 134 | local_paths.append(local_path) 135 | titles.append(title) 136 | descriptions.append(description) 137 | tags.append(tag) 138 | 139 | # Create a new DataFrame with the generated data 140 | output_df = pd.DataFrame({ 141 | "file_name": file_names, 142 | "local_path": local_paths, 143 | "title": titles, 144 | "description": descriptions, 145 | "tags": tags 146 | }) 147 | 148 | # Save the DataFrame to a new CSV file 149 | output_df.to_csv("product_information.csv", index=False) 150 | --------------------------------------------------------------------------------