-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupload_to_gcs.py
More file actions
247 lines (205 loc) · 8.07 KB
/
upload_to_gcs.py
File metadata and controls
247 lines (205 loc) · 8.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#!/usr/bin/env python3
"""
Upload images to Google Cloud Storage
This script uploads all images from static/images/ to Google Cloud Storage
and creates a mapping file for the Flask app to use.
Prerequisites:
1. Create a Google Cloud account (free tier available)
2. Create a GCS bucket
3. Set up service account credentials
4. Install: pip install google-cloud-storage
"""
import os
import json
import glob
from google.cloud import storage
from google.cloud.exceptions import NotFound, GoogleCloudError
def setup_gcs_client():
"""Set up GCS client with credentials."""
try:
# Try to get credentials from environment variable or default location
credentials_path = os.getenv('GOOGLE_APPLICATION_CREDENTIALS')
if credentials_path and os.path.exists(credentials_path):
client = storage.Client.from_service_account_json(credentials_path)
else:
# Try default authentication (gcloud auth application-default login)
client = storage.Client()
# Test the connection
list(client.list_buckets())
return client
except Exception as e:
print(f"❌ Error setting up GCS client: {e}")
print("Please ensure you have valid Google Cloud credentials")
return None
def upload_image_to_gcs(gcs_client, bucket_name, image_path, gcs_path):
"""Upload a single image to GCS."""
try:
bucket = gcs_client.bucket(bucket_name)
blob = bucket.blob(gcs_path)
# Upload with public read access
blob.upload_from_filename(
image_path,
content_type='image/jpeg'
)
# Make the blob publicly readable
blob.make_public()
# Generate public URL
public_url = f"https://storage.googleapis.com/{bucket_name}/{gcs_path}"
return public_url
except GoogleCloudError as e:
print(f"Error uploading {image_path}: {e}")
return None
def upload_all_images():
"""Upload all images from static/images/ to GCS."""
images_dir = "static/images"
if not os.path.exists(images_dir):
print(f"Images directory {images_dir} not found!")
return
# Set up GCS client
gcs_client = setup_gcs_client()
if not gcs_client:
return
# Get bucket name from environment
bucket_name = os.getenv('GCS_BUCKET_NAME')
if not bucket_name:
print("❌ GCS_BUCKET_NAME environment variable not set!")
print("Please set your GCS bucket name")
return
# Verify bucket exists
try:
bucket = gcs_client.bucket(bucket_name)
bucket.reload() # Test access
print(f"✅ Using GCS bucket: {bucket_name}")
except NotFound:
print(f"❌ Bucket {bucket_name} not found!")
print("Please create the bucket first")
return
except Exception as e:
print(f"❌ Error accessing bucket {bucket_name}: {e}")
return
# Create image mapping
image_mapping = {}
# Get all JPG files
image_files = glob.glob(os.path.join(images_dir, "*.jpg"))
total_files = len(image_files)
print(f"Found {total_files} images to upload to GCS...")
for i, image_path in enumerate(image_files, 1):
filename = os.path.basename(image_path)
gcs_path = f"sref-images/{filename}"
print(f"Uploading {i}/{total_files}: {filename}")
public_url = upload_image_to_gcs(gcs_client, bucket_name, image_path, gcs_path)
if public_url:
# Get file size
file_size = os.path.getsize(image_path)
image_mapping[filename] = {
'url': public_url,
'gcs_path': gcs_path,
'size': file_size
}
print(f" ✅ Uploaded: {public_url}")
else:
print(f" ❌ Failed to upload {filename}")
# Save mapping to file
mapping_file = "gcs_image_mapping.json"
with open(mapping_file, 'w') as f:
json.dump(image_mapping, f, indent=2)
print(f"\n✅ Upload complete!")
print(f"📁 {len(image_mapping)} images uploaded successfully")
print(f"📄 Mapping saved to {mapping_file}")
return image_mapping
def create_env_template():
"""Create a .env template file."""
env_template = """# Google Cloud Storage Configuration
# Path to your service account JSON file
GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/service-account-key.json
# Your GCS bucket name
GCS_BUCKET_NAME=your-bucket-name-here
"""
with open('.env.template', 'w') as f:
f.write(env_template)
print("📄 Created .env.template file")
print("Copy this to .env and fill in your GCS credentials")
def create_gcs_setup_instructions():
"""Print instructions for setting up GCS."""
print("\n📋 Google Cloud Storage Setup Instructions:")
print("1. Go to https://console.cloud.google.com/")
print("2. Create a new project or select existing one")
print("3. Enable Cloud Storage API")
print("4. Go to Cloud Storage → Buckets")
print("5. Click 'Create bucket'")
print("6. Choose a unique bucket name (e.g., 'sref-library-images')")
print("7. Select a location (e.g., 'us-central1')")
print("8. Choose 'Uniform' access control")
print("9. Create bucket")
print("\n🔐 Service Account Setup:")
print("1. Go to IAM & Admin → Service Accounts")
print("2. Click 'Create Service Account'")
print("3. Name: 'sref-uploader'")
print("4. Grant role: 'Storage Admin'")
print("5. Create and download JSON key file")
print("6. Set GOOGLE_APPLICATION_CREDENTIALS to the JSON file path")
print("\n🚀 Alternative: Use gcloud CLI")
print("1. Install gcloud CLI")
print("2. Run: gcloud auth application-default login")
print("3. This will use your user credentials automatically")
def create_bucket_public_policy():
"""Create a script to make bucket publicly readable."""
script_content = '''#!/bin/bash
# Make GCS bucket publicly readable for images
BUCKET_NAME="your-bucket-name-here"
# Create a public access policy
cat > public_policy.json << EOF
{
"bindings": [
{
"members": ["allUsers"],
"role": "roles/storage.objectViewer"
}
]
}
EOF
# Apply the policy
gsutil iam set public_policy.json gs://$BUCKET_NAME
echo "Bucket $BUCKET_NAME is now publicly readable"
'''
with open('make_bucket_public.sh', 'w') as f:
f.write(script_content)
os.chmod('make_bucket_public.sh', 0o755)
print("📄 Created make_bucket_public.sh script")
print("Run this after creating your bucket to make it publicly readable")
if __name__ == "__main__":
print("☁️ Google Cloud Storage Image Uploader")
print("=" * 50)
# Check if google-cloud-storage is installed
try:
from google.cloud import storage
print("✅ Google Cloud Storage SDK found")
except ImportError:
print("❌ Google Cloud Storage SDK not found.")
print("Please install: pip install google-cloud-storage")
exit(1)
# Create environment template and instructions
create_env_template()
create_gcs_setup_instructions()
create_bucket_public_policy()
# Check for environment variables
if not os.getenv('GCS_BUCKET_NAME'):
print("\n⚠️ GCS bucket name not found!")
print("Please set GCS_BUCKET_NAME environment variable")
print("See .env.template for required variables")
exit(1)
# Upload images
mapping = upload_all_images()
if mapping:
print("\n🎉 Setup complete!")
print("\nNext steps:")
print("1. Update your Flask app to use GCS URLs")
print("2. Deploy your app to Vercel")
print("3. Images will be served from Google Cloud Storage")
print("\nOptional: Set up Cloud CDN for faster delivery")
print("\nBenefits:")
print("✅ 5GB free storage (free tier)")
print("✅ 1GB free egress per month")
print("✅ Google's global infrastructure")
print("✅ Can add Cloud CDN later")
print("✅ Industry standard reliability")