Spaces:
Sleeping
Sleeping
Seth
commited on
Commit
·
aabbd76
1
Parent(s):
9c014c6
update
Browse files- README.md +28 -2
- backend/app/__init__.py +0 -1
- backend/app/database.py +59 -0
- backend/app/main.py +14 -0
- backend/app/models.py +1 -3
README.md
CHANGED
|
@@ -59,8 +59,9 @@ CANVA_ACCESS_TOKEN=your_canva_access_token
|
|
| 59 |
LINKEDIN_ACCESS_TOKEN=your_linkedin_access_token
|
| 60 |
LINKEDIN_PERSON_URN=your_linkedin_person_urn
|
| 61 |
|
| 62 |
-
# Database (
|
| 63 |
-
|
|
|
|
| 64 |
```
|
| 65 |
|
| 66 |
### Local Development
|
|
@@ -130,9 +131,12 @@ docker run -p 7860:7860 --env-file .env postgen
|
|
| 130 |
2. Add the following secrets:
|
| 131 |
- `OPENAI_API_KEY`: Your OpenAI API key
|
| 132 |
- `OPENAI_MODEL`: gpt-4o (or your preferred model)
|
|
|
|
| 133 |
- `CANVA_ACCESS_TOKEN`: (Optional, can be set per user)
|
| 134 |
- `LINKEDIN_ACCESS_TOKEN`: (Optional, can be set per user)
|
| 135 |
|
|
|
|
|
|
|
| 136 |
### Step 4: Connect Your Repository
|
| 137 |
|
| 138 |
1. In Space settings, connect your Git repository
|
|
@@ -213,6 +217,28 @@ PostGen/
|
|
| 213 |
└── README.md
|
| 214 |
```
|
| 215 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
## Next Steps After Deployment
|
| 217 |
|
| 218 |
1. **Connect Integrations**:
|
|
|
|
| 59 |
LINKEDIN_ACCESS_TOKEN=your_linkedin_access_token
|
| 60 |
LINKEDIN_PERSON_URN=your_linkedin_person_urn
|
| 61 |
|
| 62 |
+
# Database (CockroachDB connection string)
|
| 63 |
+
# Format: postgresql://username:password@host:port/database?sslmode=verify-full
|
| 64 |
+
DATABASE_URL=postgresql://seth:YOUR_PASSWORD@ezofis-11210.jxf.gcp-us-east1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full
|
| 65 |
```
|
| 66 |
|
| 67 |
### Local Development
|
|
|
|
| 131 |
2. Add the following secrets:
|
| 132 |
- `OPENAI_API_KEY`: Your OpenAI API key
|
| 133 |
- `OPENAI_MODEL`: gpt-4o (or your preferred model)
|
| 134 |
+
- `DATABASE_URL`: Your CockroachDB connection string (format: `postgresql://username:password@host:port/database?sslmode=verify-full`)
|
| 135 |
- `CANVA_ACCESS_TOKEN`: (Optional, can be set per user)
|
| 136 |
- `LINKEDIN_ACCESS_TOKEN`: (Optional, can be set per user)
|
| 137 |
|
| 138 |
+
**Note**: The app will work with dummy/mock data if `DATABASE_URL` is not set. As you implement features, they will gradually use the database instead of mock data.
|
| 139 |
+
|
| 140 |
### Step 4: Connect Your Repository
|
| 141 |
|
| 142 |
1. In Space settings, connect your Git repository
|
|
|
|
| 217 |
└── README.md
|
| 218 |
```
|
| 219 |
|
| 220 |
+
## Database Setup (CockroachDB)
|
| 221 |
+
|
| 222 |
+
### Setting Up CockroachDB Connection
|
| 223 |
+
|
| 224 |
+
1. **Get Your Connection String**:
|
| 225 |
+
- From your CockroachDB dashboard, copy the connection string
|
| 226 |
+
- Format: `postgresql://username:password@host:port/database?sslmode=verify-full`
|
| 227 |
+
- Example: `postgresql://seth:YOUR_PASSWORD@ezofis-11210.jxf.gcp-us-east1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full`
|
| 228 |
+
|
| 229 |
+
2. **Add to HuggingFace Spaces**:
|
| 230 |
+
- Go to your Space settings → "Variables and secrets"
|
| 231 |
+
- Add `DATABASE_URL` with your connection string
|
| 232 |
+
|
| 233 |
+
3. **Database Tables**:
|
| 234 |
+
- Tables are automatically created on first startup
|
| 235 |
+
- The app will initialize: `users`, `integrations`, `assets`, `posts`, `campaigns`
|
| 236 |
+
|
| 237 |
+
4. **Dummy Data**:
|
| 238 |
+
- The app currently uses dummy/mock data for all endpoints
|
| 239 |
+
- As features are implemented, they will gradually use the database
|
| 240 |
+
- Dummy data will be removed feature by feature as database integration is completed
|
| 241 |
+
|
| 242 |
## Next Steps After Deployment
|
| 243 |
|
| 244 |
1. **Connect Integrations**:
|
backend/app/__init__.py
CHANGED
|
@@ -1,2 +1 @@
|
|
| 1 |
# PostGen Backend Application
|
| 2 |
-
|
|
|
|
| 1 |
# PostGen Backend Application
|
|
|
backend/app/database.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from sqlalchemy import create_engine, text
|
| 3 |
+
from sqlalchemy.orm import sessionmaker, declarative_base
|
| 4 |
+
from sqlalchemy.pool import NullPool
|
| 5 |
+
|
| 6 |
+
# Get database URL from environment variable
|
| 7 |
+
# Default to SQLite for local development if not set
|
| 8 |
+
DATABASE_URL = os.getenv(
|
| 9 |
+
"DATABASE_URL",
|
| 10 |
+
"sqlite:///./postgen.db"
|
| 11 |
+
)
|
| 12 |
+
|
| 13 |
+
# For CockroachDB, we need to handle SSL and connection pooling
|
| 14 |
+
if DATABASE_URL.startswith("postgresql://") or DATABASE_URL.startswith("postgres://"):
|
| 15 |
+
# CockroachDB connection - use NullPool to avoid connection issues
|
| 16 |
+
# CockroachDB requires SSL, so we ensure sslmode is set
|
| 17 |
+
if "sslmode" not in DATABASE_URL:
|
| 18 |
+
separator = "&" if "?" in DATABASE_URL else "?"
|
| 19 |
+
DATABASE_URL = f"{DATABASE_URL}{separator}sslmode=verify-full"
|
| 20 |
+
|
| 21 |
+
engine = create_engine(
|
| 22 |
+
DATABASE_URL,
|
| 23 |
+
poolclass=NullPool, # CockroachDB works better with NullPool
|
| 24 |
+
echo=False # Set to True for SQL query debugging
|
| 25 |
+
)
|
| 26 |
+
else:
|
| 27 |
+
# SQLite for local development
|
| 28 |
+
engine = create_engine(
|
| 29 |
+
DATABASE_URL,
|
| 30 |
+
connect_args={"check_same_thread": False} if "sqlite" in DATABASE_URL else {}
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
| 34 |
+
|
| 35 |
+
Base = declarative_base()
|
| 36 |
+
|
| 37 |
+
def get_db():
|
| 38 |
+
"""Dependency to get database session"""
|
| 39 |
+
db = SessionLocal()
|
| 40 |
+
try:
|
| 41 |
+
yield db
|
| 42 |
+
finally:
|
| 43 |
+
db.close()
|
| 44 |
+
|
| 45 |
+
def init_db():
|
| 46 |
+
"""Initialize database tables"""
|
| 47 |
+
try:
|
| 48 |
+
from app.models import User, Integration, Asset, Post, Campaign
|
| 49 |
+
# Test connection first
|
| 50 |
+
with engine.connect() as conn:
|
| 51 |
+
conn.execute(text("SELECT 1"))
|
| 52 |
+
conn.commit()
|
| 53 |
+
# Create tables if connection successful
|
| 54 |
+
Base.metadata.create_all(bind=engine)
|
| 55 |
+
return True
|
| 56 |
+
except Exception as e:
|
| 57 |
+
print(f"Database connection failed: {e}")
|
| 58 |
+
return False
|
| 59 |
+
|
backend/app/main.py
CHANGED
|
@@ -15,6 +15,8 @@ from app.schemas import (
|
|
| 15 |
from app.services.canva_service import CanvaService
|
| 16 |
from app.services.linkedin_service import LinkedInService
|
| 17 |
from app.services.ai_service import AIService
|
|
|
|
|
|
|
| 18 |
|
| 19 |
app = FastAPI(title="PostGen API", version="1.0.0")
|
| 20 |
|
|
@@ -26,6 +28,18 @@ app.add_middleware(
|
|
| 26 |
allow_headers=["*"],
|
| 27 |
)
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
# Services
|
| 30 |
ai_service = AIService()
|
| 31 |
|
|
|
|
| 15 |
from app.services.canva_service import CanvaService
|
| 16 |
from app.services.linkedin_service import LinkedInService
|
| 17 |
from app.services.ai_service import AIService
|
| 18 |
+
from app.database import init_db, get_db
|
| 19 |
+
from sqlalchemy.orm import Session
|
| 20 |
|
| 21 |
app = FastAPI(title="PostGen API", version="1.0.0")
|
| 22 |
|
|
|
|
| 28 |
allow_headers=["*"],
|
| 29 |
)
|
| 30 |
|
| 31 |
+
# Initialize database on startup
|
| 32 |
+
@app.on_event("startup")
|
| 33 |
+
async def startup_event():
|
| 34 |
+
"""Initialize database tables on startup"""
|
| 35 |
+
db_initialized = init_db()
|
| 36 |
+
if db_initialized:
|
| 37 |
+
print("✓ Database initialized successfully")
|
| 38 |
+
else:
|
| 39 |
+
print("⚠ Database not available - using mock data")
|
| 40 |
+
print("⚠ App will function normally with dummy content")
|
| 41 |
+
print("⚠ To connect to database, set DATABASE_URL environment variable")
|
| 42 |
+
|
| 43 |
# Services
|
| 44 |
ai_service = AIService()
|
| 45 |
|
backend/app/models.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
| 1 |
from sqlalchemy import Column, Integer, String, DateTime, Boolean, JSON, Text, ForeignKey
|
| 2 |
-
from sqlalchemy.ext.declarative import declarative_base
|
| 3 |
from sqlalchemy.orm import relationship
|
| 4 |
from datetime import datetime
|
| 5 |
-
|
| 6 |
-
Base = declarative_base()
|
| 7 |
|
| 8 |
class User(Base):
|
| 9 |
__tablename__ = "users"
|
|
|
|
| 1 |
from sqlalchemy import Column, Integer, String, DateTime, Boolean, JSON, Text, ForeignKey
|
|
|
|
| 2 |
from sqlalchemy.orm import relationship
|
| 3 |
from datetime import datetime
|
| 4 |
+
from app.database import Base
|
|
|
|
| 5 |
|
| 6 |
class User(Base):
|
| 7 |
__tablename__ = "users"
|