Spaces:
Runtime error
Runtime error
File size: 5,747 Bytes
768f623 d271aa1 768f623 d271aa1 768f623 d271aa1 768f623 d271aa1 3151572 d271aa1 3151572 768f623 3151572 768f623 d271aa1 3151572 d271aa1 768f623 3151572 768f623 3151572 768f623 3151572 768f623 3151572 768f623 d271aa1 768f623 d271aa1 768f623 3151572 | 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 | from flask import Flask, render_template, request, jsonify
import os
import requests
import json
import http.server
import socketserver
import threading
import subprocess
import time
import socket
from dotenv import load_dotenv
from PIL import Image
import io
from transformers import pipeline
import base64
app = Flask(__name__)
load_dotenv()
# Configuration
INSTAGRAM_ACCESS_TOKEN = os.getenv('INSTAGRAM_ACCESS_TOKEN')
INSTAGRAM_USER_ID = os.getenv('INSTAGRAM_USER_ID')
HUGGINGFACE_API_TOKEN = os.getenv('HUGGINGFACE_API_TOKEN')
UPLOAD_FOLDER = 'uploads'
PORT = 8000
httpd = None
ngrok_process = None
# Ensure upload folder exists
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
# Check if port is available
def is_port_available(port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('localhost', port)) != 0
# Start local HTTP server to serve images
def start_http_server():
global httpd
Handler = http.server.SimpleHTTPRequestHandler
port = PORT
max_attempts = 5
for i in range(max_attempts):
if is_port_available(port):
try:
httpd = socketserver.TCPServer(("", port), Handler)
server_thread = threading.Thread(target=httpd.serve_forever)
server_thread.daemon = True
server_thread.start()
print(f"HTTP server started on port {port}")
return port
except Exception as e:
print(f"Failed to start HTTP server on port {port}: {e}")
raise
else:
print(f"Port {port} is in use, trying port {port + 1}")
port += 1
raise OSError("No available ports found after multiple attempts")
# Start ngrok to create a public URL
def start_ngrok(port):
global ngrok_process
try:
ngrok_process = subprocess.Popen(["ngrok", "http", str(port)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(2) # Wait for ngrok to start
resp = requests.get("http://localhost:4040/api/tunnels")
public_url = resp.json()["tunnels"][0]["public_url"]
print(f"Ngrok tunnel started at {public_url}")
return public_url
except Exception as e:
print(f"Failed to start ngrok: {e}")
raise
# Hugging Face captioning pipeline
try:
caption_pipeline = pipeline("image-to-text", model="Salesforce/blip-image-captioning-base")
except Exception as e:
print(f"Failed to initialize Hugging Face pipeline: {e}")
caption_pipeline = None
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_image():
global ngrok_process
try:
# Get base64 image from request
image_data = request.json['image'].split(',')[1]
image_bytes = base64.b64decode(image_data)
# Save image to uploads folder
image_path = os.path.join(UPLOAD_FOLDER, 'captured_image.jpg')
with open(image_path, 'wb') as f:
f.write(image_bytes)
# Generate caption using Hugging Face
caption = "Default caption: Uploaded image"
if caption_pipeline:
try:
image = Image.open(io.BytesIO(image_bytes))
caption_result = caption_pipeline(image)
caption = caption_result[0]['generated_text']
except Exception as e:
print(f"Failed to generate caption: {e}")
# Get public URL from ngrok
port = start_http_server()
public_url = start_ngrok(port)
image_url = f"{public_url}/uploads/captured_image.jpg"
# Create Instagram media container
create_url = f"https://graph.facebook.com/v20.0/{INSTAGRAM_USER_ID}/media"
payload = {
"image_url": image_url,
"caption": caption,
"access_token": INSTAGRAM_ACCESS_TOKEN
}
response = requests.post(create_url, params=payload)
result = response.json()
if 'id' in result:
creation_id = result['id']
# Publish the media
publish_url = f"https://graph.facebook.com/v20.0/{INSTAGRAM_USER_ID}/media_publish"
publish_payload = {
"creation_id": creation_id,
"access_token": INSTAGRAM_ACCESS_TOKEN
}
publish_response = requests.post(publish_url, params=publish_payload)
publish_result = publish_response.json()
if 'id' in publish_result:
return jsonify({"status": "success", "message": "Image posted to Instagram", "caption": caption})
else:
return jsonify({"status": "error", "message": publish_result.get('error', {}).get('message', 'Failed to publish')})
else:
return jsonify({"status": "error", "message": result.get('error', {}).get('message', 'Failed to create media container')})
except Exception as e:
return jsonify({"status": "error", "message": str(e)})
finally:
# Clean up ngrok
if ngrok_process:
ngrok_process.terminate()
ngrok_process = None
@app.route('/shutdown', methods=['POST'])
def shutdown():
global httpd, ngrok_process
try:
if httpd:
httpd.shutdown()
httpd.server_close()
print("HTTP server shut down")
if ngrok_process:
ngrok_process.terminate()
ngrok_process = None
print("Ngrok shut down")
return jsonify({"status": "success", "message": "Server shutdown"})
except Exception as e:
return jsonify({"status": "error", "message": str(e)})
if __name__ == '__main__':
app.run(debug=True) |