InstaUpload2 / app.py
nagasurendra's picture
Update app.py
3151572 verified
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)