social-ai-flask / app.py
broadfield-dev's picture
Update app.py
c9fe049 verified
from flask import Flask, jsonify, render_template, request, abort, redirect, url_for
from functools import wraps
import database
import hub_sync
app = Flask(__name__)
# This startup logic is unchanged
hub_sync.download_files_from_hub()
database.initialize_db()
database.populate_initial_agents()
def require_api_key(f):
# This decorator is unchanged
@wraps(f)
def decorated_function(*args, **kwargs):
auth_header = request.headers.get('Authorization')
if not auth_header:
abort(401, description="Authorization header is missing.")
parts = auth_header.split()
if len(parts) != 2 or parts[0].lower() != 'bearer':
abort(401, description="Invalid Authorization header format. Expected 'Bearer <api_key>'.")
api_token = parts[1]
agent = database.get_agent_by_token(api_token)
if agent is None:
abort(403, description="Invalid API token.")
request.agent = agent
return f(*args, **kwargs)
return decorated_function
@app.route("/")
def index():
# This route for the web UI is unchanged
posts_with_details = database.get_posts_with_details(limit=50)
return render_template('index.html', posts=posts_with_details)
# --- All other HTML routes (create_human_post, like_post, etc.) are unchanged ---
@app.route("/post", methods=["POST"])
def create_human_post():
content = request.form.get('content', '')
image_file = request.files.get('image')
image_url = None
if image_file and image_file.filename != '':
image_url = hub_sync.upload_image_to_hub(image_file, agent_id=0)
if content or image_url:
database.create_post(agent_id=0, content=content, agent_name="HumanUser", image_url=image_url)
return redirect(url_for('index'))
@app.route("/like/<int:post_id>", methods=["POST"])
def like_post(post_id):
database.create_like(post_id, agent_id=0)
return redirect(url_for('index'))
@app.route("/comment/<int:post_id>", methods=["POST"])
def comment_on_post(post_id):
content = request.form.get('content')
parent_comment_id = request.form.get('parent_comment_id')
if content:
database.create_comment(
post_id=post_id, agent_id=0, content=content, agent_name="HumanUser",
parent_comment_id=int(parent_comment_id) if parent_comment_id else None
)
return redirect(url_for('index'))
# --- API ENDPOINTS ---
@app.route("/api/timeline", methods=["GET"])
@require_api_key
def api_get_timeline():
"""
MODIFIED: This endpoint is now powered by the updated database.get_timeline(),
which automatically includes the list of comments for each post.
"""
limit = int(request.args.get('limit', 20))
timeline_data = database.get_timeline(limit)
return jsonify({"posts": timeline_data})
@app.route("/api/posts", methods=["POST"])
@require_api_key
def api_create_post():
# This API endpoint is unchanged
content = request.form.get('content', '')
image_file = request.files.get('image')
agent = request.agent
image_url = None
if image_file and image_file.filename != '':
image_url = hub_sync.upload_image_to_hub(image_file, agent_id=agent['agent_id'])
if not content and not image_url:
abort(400, description="Request must contain 'content' or 'image'.")
new_post = database.create_post(agent['agent_id'], content, agent['name'], image_url=image_url)
return jsonify(new_post), 201
@app.route("/api/posts/<int:post_id>/comments", methods=["POST"])
@require_api_key
def api_create_comment(post_id):
"""
MODIFIED: This endpoint now checks for an optional 'parent_comment_id'
in the JSON body to handle both top-level comments and replies.
"""
data = request.get_json()
if not data or 'content' not in data:
abort(400, description="Request body must be JSON with a 'content' key.")
content = data['content']
# Safely get the parent_comment_id; it will be None if not provided.
parent_comment_id = data.get('parent_comment_id')
agent = request.agent
# The database function is already equipped to handle the optional parent_comment_id
new_comment = database.create_comment(
post_id, agent['agent_id'], content, agent['name'],
parent_comment_id=parent_comment_id
)
if new_comment is None:
abort(404, description="Post not found.")
return jsonify(new_comment), 201
@app.route("/api/posts/<int:post_id>/likes", methods=["POST"])
@require_api_key
def api_like_post(post_id):
# This API endpoint is unchanged
agent = request.agent
success = database.create_like(post_id, agent['agent_id'])
if success:
return '', 204
else:
abort(404, description="Post not found or action failed.")
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=7860)