Files
instagram-clone/app/database.py
OpenClaw Agent a3eca3b7da feat: implement Instagram clone SocialPhoto API
- FastAPI backend with SQLite database
- JWT authentication (register, login)
- User profiles with follow/unfollow
- Posts with image upload and likes/dislikes
- Comments with likes
- Global and personalized feed
- Comprehensive pytest test suite (37 tests)

TASK-ID: 758f4029-702
2026-04-16 03:20:48 +00:00

121 lines
3.5 KiB
Python

"""Database module for SocialPhoto."""
import sqlite3
from pathlib import Path
from typing import Optional
DATABASE_PATH = Path(__file__).parent.parent / "socialphoto.db"
def get_db_connection() -> sqlite3.Connection:
"""Get a database connection with row factory."""
conn = sqlite3.connect(DATABASE_PATH, check_same_thread=False)
conn.row_factory = sqlite3.Row
return conn
def get_db() -> sqlite3.Connection:
"""Dependency for FastAPI routes."""
conn = get_db_connection()
try:
yield conn
finally:
conn.close()
def init_db() -> None:
"""Initialize the database with all tables."""
conn = get_db_connection()
cursor = conn.cursor()
# Users table
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
avatar_url TEXT DEFAULT '/static/default-avatar.png',
bio TEXT DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
# Posts table
cursor.execute("""
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id),
image_path TEXT NOT NULL,
caption TEXT DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
# Comments table
cursor.execute("""
CREATE TABLE IF NOT EXISTS comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES posts(id),
user_id INTEGER NOT NULL REFERENCES users(id),
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
# Likes table
cursor.execute("""
CREATE TABLE IF NOT EXISTS likes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES posts(id),
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(post_id, user_id)
)
""")
# Dislikes table
cursor.execute("""
CREATE TABLE IF NOT EXISTS dislikes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES posts(id),
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(post_id, user_id)
)
""")
# Follows table
cursor.execute("""
CREATE TABLE IF NOT EXISTS follows (
id INTEGER PRIMARY KEY AUTOINCREMENT,
follower_id INTEGER NOT NULL REFERENCES users(id),
following_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(follower_id, following_id)
)
""")
# Comment likes table
cursor.execute("""
CREATE TABLE IF NOT EXISTS comment_likes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
comment_id INTEGER NOT NULL REFERENCES comments(id),
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(comment_id, user_id)
)
""")
conn.commit()
conn.close()
def row_to_dict(row: sqlite3.Row) -> dict:
"""Convert a sqlite Row to a dictionary."""
return dict(row)
if __name__ == "__main__":
init_db()
print("Database initialized successfully.")