Update app.py
Browse files
app.py
CHANGED
|
@@ -1,23 +1,37 @@
|
|
| 1 |
import os
|
| 2 |
import tempfile
|
| 3 |
import requests
|
|
|
|
| 4 |
from fastapi import FastAPI, Form
|
| 5 |
from instagrapi import Client
|
| 6 |
from PIL import Image
|
| 7 |
import uvicorn
|
| 8 |
|
|
|
|
| 9 |
app = FastAPI()
|
|
|
|
|
|
|
| 10 |
cl = Client()
|
| 11 |
|
|
|
|
| 12 |
IG_USERNAME = os.getenv("USERNAME")
|
| 13 |
IG_PASSWORD = os.getenv("PASSWORD")
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
def login():
|
| 16 |
try:
|
| 17 |
cl.login(IG_USERNAME, IG_PASSWORD)
|
| 18 |
-
|
| 19 |
except Exception as e:
|
| 20 |
-
|
| 21 |
raise
|
| 22 |
|
| 23 |
def fix_google_drive_url(url: str) -> str:
|
|
@@ -27,17 +41,19 @@ def fix_google_drive_url(url: str) -> str:
|
|
| 27 |
return f"https://drive.google.com/uc?export=download&id={file_id}"
|
| 28 |
return url
|
| 29 |
|
| 30 |
-
|
| 31 |
-
def upload_post(photo_url: str = Form(...), caption: str = Form(...)):
|
| 32 |
try:
|
| 33 |
if not cl.user_id:
|
| 34 |
login()
|
| 35 |
|
| 36 |
photo_url = fix_google_drive_url(photo_url)
|
|
|
|
| 37 |
|
| 38 |
response = requests.get(photo_url, stream=True)
|
| 39 |
if response.status_code != 200:
|
| 40 |
-
|
|
|
|
|
|
|
| 41 |
|
| 42 |
tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg")
|
| 43 |
tmp_file.write(response.content)
|
|
@@ -46,18 +62,49 @@ def upload_post(photo_url: str = Form(...), caption: str = Form(...)):
|
|
| 46 |
try:
|
| 47 |
Image.open(tmp_file.name).verify()
|
| 48 |
except Exception:
|
| 49 |
-
|
|
|
|
|
|
|
| 50 |
|
| 51 |
cl.photo_upload(tmp_file.name, caption)
|
|
|
|
| 52 |
return {"status": "success", "message": "Photo uploaded successfully!"}
|
| 53 |
|
| 54 |
except Exception as e:
|
|
|
|
| 55 |
return {"status": "error", "message": str(e)}
|
| 56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
@app.get("/")
|
| 58 |
def root():
|
| 59 |
return {"status": "ok", "message": "Instagram uploader is running π"}
|
| 60 |
|
| 61 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
if __name__ == "__main__":
|
| 63 |
-
|
|
|
|
| 1 |
import os
|
| 2 |
import tempfile
|
| 3 |
import requests
|
| 4 |
+
import gradio as gr
|
| 5 |
from fastapi import FastAPI, Form
|
| 6 |
from instagrapi import Client
|
| 7 |
from PIL import Image
|
| 8 |
import uvicorn
|
| 9 |
|
| 10 |
+
# FastAPI app (for API)
|
| 11 |
app = FastAPI()
|
| 12 |
+
|
| 13 |
+
# Instagram client
|
| 14 |
cl = Client()
|
| 15 |
|
| 16 |
+
# Instagram credentials from Hugging Face Secrets
|
| 17 |
IG_USERNAME = os.getenv("USERNAME")
|
| 18 |
IG_PASSWORD = os.getenv("PASSWORD")
|
| 19 |
|
| 20 |
+
# Store logs in memory
|
| 21 |
+
logs = []
|
| 22 |
+
|
| 23 |
+
def log(message: str):
|
| 24 |
+
print(message)
|
| 25 |
+
logs.append(message)
|
| 26 |
+
if len(logs) > 50: # keep last 50 logs
|
| 27 |
+
logs.pop(0)
|
| 28 |
+
|
| 29 |
def login():
|
| 30 |
try:
|
| 31 |
cl.login(IG_USERNAME, IG_PASSWORD)
|
| 32 |
+
log("β
Logged into Instagram as " + IG_USERNAME)
|
| 33 |
except Exception as e:
|
| 34 |
+
log(f"β οΈ Login failed: {e}")
|
| 35 |
raise
|
| 36 |
|
| 37 |
def fix_google_drive_url(url: str) -> str:
|
|
|
|
| 41 |
return f"https://drive.google.com/uc?export=download&id={file_id}"
|
| 42 |
return url
|
| 43 |
|
| 44 |
+
def process_upload(photo_url: str, caption: str):
|
|
|
|
| 45 |
try:
|
| 46 |
if not cl.user_id:
|
| 47 |
login()
|
| 48 |
|
| 49 |
photo_url = fix_google_drive_url(photo_url)
|
| 50 |
+
log(f"π₯ Downloading from {photo_url}")
|
| 51 |
|
| 52 |
response = requests.get(photo_url, stream=True)
|
| 53 |
if response.status_code != 200:
|
| 54 |
+
msg = f"Invalid image URL: {response.status_code}"
|
| 55 |
+
log("β " + msg)
|
| 56 |
+
return {"status": "error", "message": msg}
|
| 57 |
|
| 58 |
tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg")
|
| 59 |
tmp_file.write(response.content)
|
|
|
|
| 62 |
try:
|
| 63 |
Image.open(tmp_file.name).verify()
|
| 64 |
except Exception:
|
| 65 |
+
msg = "Downloaded file is not a valid image."
|
| 66 |
+
log("β " + msg)
|
| 67 |
+
return {"status": "error", "message": msg}
|
| 68 |
|
| 69 |
cl.photo_upload(tmp_file.name, caption)
|
| 70 |
+
log("β
Photo uploaded successfully with caption: " + caption)
|
| 71 |
return {"status": "success", "message": "Photo uploaded successfully!"}
|
| 72 |
|
| 73 |
except Exception as e:
|
| 74 |
+
log("β οΈ Exception: " + str(e))
|
| 75 |
return {"status": "error", "message": str(e)}
|
| 76 |
|
| 77 |
+
# ----------------------------
|
| 78 |
+
# FastAPI Endpoint (for Sheets)
|
| 79 |
+
# ----------------------------
|
| 80 |
+
@app.post("/upload")
|
| 81 |
+
def upload_post(photo_url: str = Form(...), caption: str = Form(...)):
|
| 82 |
+
return process_upload(photo_url, caption)
|
| 83 |
+
|
| 84 |
@app.get("/")
|
| 85 |
def root():
|
| 86 |
return {"status": "ok", "message": "Instagram uploader is running π"}
|
| 87 |
|
| 88 |
+
# ----------------------------
|
| 89 |
+
# Gradio UI (for testing/debug)
|
| 90 |
+
# ----------------------------
|
| 91 |
+
def gradio_upload(photo_url, caption):
|
| 92 |
+
result = process_upload(photo_url, caption)
|
| 93 |
+
return result["status"], result["message"], "\n".join(logs)
|
| 94 |
+
|
| 95 |
+
with gr.Blocks() as demo:
|
| 96 |
+
gr.Markdown("## πΈ Instagram Auto Uploader")
|
| 97 |
+
with gr.Row():
|
| 98 |
+
photo_url_in = gr.Textbox(label="Photo URL", placeholder="Paste image link (Google Drive supported)")
|
| 99 |
+
caption_in = gr.Textbox(label="Caption", placeholder="Enter your caption")
|
| 100 |
+
upload_btn = gr.Button("π Upload to Instagram")
|
| 101 |
+
|
| 102 |
+
status_out = gr.Textbox(label="Status")
|
| 103 |
+
message_out = gr.Textbox(label="Message")
|
| 104 |
+
logs_out = gr.Textbox(label="Logs (last 50)", lines=15)
|
| 105 |
+
|
| 106 |
+
upload_btn.click(fn=gradio_upload, inputs=[photo_url_in, caption_in], outputs=[status_out, message_out, logs_out])
|
| 107 |
+
|
| 108 |
+
# πΉ Run Gradio + FastAPI
|
| 109 |
if __name__ == "__main__":
|
| 110 |
+
demo.launch(server_name="0.0.0.0", server_port=7860)
|