aminskjen commited on
Commit
b617391
Β·
verified Β·
1 Parent(s): bccf708

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -54
app.py CHANGED
@@ -1,25 +1,27 @@
1
  import os
2
  import logging
3
- from flask import Flask, render_template, request, jsonify, session, redirect, url_for, flash
 
 
 
 
4
  from flask_sqlalchemy import SQLAlchemy
5
  from flask_login import LoginManager, login_user, logout_user, login_required, current_user
6
  from sqlalchemy.orm import DeclarativeBase
7
  import cohere
8
- import requests
9
- import uuid
10
- from datetime import datetime
11
 
12
- # Setup logging
 
13
  logging.basicConfig(level=logging.INFO)
14
 
15
  class Base(DeclarativeBase):
16
  pass
17
 
18
- # βœ… Use writable instance_path to avoid PermissionError
19
- app = Flask(__name__, instance_path='/tmp/instance')
20
  app.secret_key = os.environ.get("SESSION_SECRET", os.urandom(24).hex())
21
 
22
- # Database config
 
23
  app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DATABASE_URL", "sqlite:///inkboard.db")
24
  app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
25
  app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
@@ -29,32 +31,37 @@ app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
29
 
30
  db = SQLAlchemy(app, model_class=Base)
31
 
32
- # Flask-Login setup
 
33
  login_manager = LoginManager()
34
  login_manager.init_app(app)
35
  login_manager.login_view = 'login'
36
  login_manager.login_message = 'Please log in to access InkBoard'
37
 
38
- # API keys
39
- API_KEY = os.environ.get("API_KEY")
 
40
  HUGGINGFACE_API_KEY = os.environ.get("HUGGINGFACE_API_KEY")
41
- HF_IMAGE_MODEL = "stabilityai/stable-diffusion-2-1"
42
 
43
  cohere_client = cohere.Client(API_KEY) if API_KEY else None
44
- logging.info(f"Received prompt: {scene_idea}")
 
 
 
45
 
46
  @login_manager.user_loader
47
  def load_user(user_id):
48
- from models import User
49
  return User.query.get(int(user_id))
50
 
 
 
51
  @app.route('/')
52
  def index():
53
  return render_template('dashboard.html', user=current_user) if current_user.is_authenticated else render_template('index.html')
54
 
 
55
  @app.route('/register', methods=['GET', 'POST'])
56
  def register():
57
- from models import User
58
  if request.method == 'POST':
59
  data = request.get_json() if request.is_json else request.form
60
  username, email, password = data.get('username', '').strip(), data.get('email', '').strip(), data.get('password', '').strip()
@@ -76,12 +83,13 @@ def register():
76
 
77
  return render_template('register.html')
78
 
 
79
  @app.route('/login', methods=['GET', 'POST'])
80
  def login():
81
- from models import User
82
  if request.method == 'POST':
83
  data = request.get_json() if request.is_json else request.form
84
- username, password = data.get('username', '').strip(), data.get('password', '').strip()
 
85
 
86
  user = User.query.filter((User.username == username) | (User.email == username)).first()
87
 
@@ -93,6 +101,7 @@ def login():
93
 
94
  return render_template('login.html')
95
 
 
96
  @app.route('/logout')
97
  @login_required
98
  def logout():
@@ -103,29 +112,20 @@ def logout():
103
  @app.route('/generate', methods=['POST'])
104
  @login_required
105
  def generate_content():
106
- from models import Creation
107
-
108
- # 1. βœ… Logging for debugging
109
  logging.info("⚑ generate_content() called")
110
-
111
- # 2. βœ… Extract prompt
112
  data = request.get_json()
113
  scene_idea = data.get('scene_idea', '').strip()
114
  logging.info(f"πŸ“₯ Received prompt: {scene_idea}")
115
 
116
  if not scene_idea:
117
- logging.warning("❗ No scene idea provided")
118
  return jsonify({'error': 'Please provide a scene idea'}), 400
119
 
120
  if not cohere_client:
121
- logging.error("❌ Cohere client is not configured. Check your API_KEY.")
122
- return jsonify({'error': 'Text generation is unavailable'}), 500
123
 
124
- # 3. βœ… Try generating story
125
  try:
126
  story_prompt = f"""Transform this scene idea into a vivid paragraph:\nScene idea: {scene_idea}"""
127
- logging.info("🧠 Sending prompt to Cohere")
128
-
129
  story_response = cohere_client.generate(
130
  model='command',
131
  prompt=story_prompt,
@@ -133,25 +133,18 @@ def generate_content():
133
  temperature=0.7,
134
  k=0
135
  )
136
-
137
- logging.info("βœ… Cohere response received")
138
-
139
  expanded_story = story_response.generations[0].text.strip()
140
- logging.info(f"πŸ“ Generated story: {expanded_story[:60]}...")
141
-
142
  except Exception as e:
143
  logging.error(f"❌ Cohere generation error: {str(e)}")
144
  return jsonify({'error': 'Failed to generate story'}), 500
145
 
146
- # 4. βœ… Generate image (optional)
147
  image_url = None
148
  try:
149
  image_url = generate_image_hf(scene_idea, expanded_story)
150
- logging.info(f"πŸ–ΌοΈ Image generated: {image_url[:50]}...")
151
  except Exception as e:
152
  logging.warning(f"⚠️ Image generation failed: {e}")
153
 
154
- # 5. βœ… Save to DB
155
  creation_id = str(uuid.uuid4())
156
  creation = Creation(
157
  id=creation_id,
@@ -174,21 +167,23 @@ def generate_content():
174
  @app.route('/save_journal', methods=['POST'])
175
  @login_required
176
  def save_journal():
177
- from models import Creation
178
  data = request.get_json()
179
- creation_id, journal_entry = data.get('creation_id'), data.get('journal_entry', '').strip()
 
 
180
  creation = Creation.query.filter_by(id=creation_id, user_id=current_user.id).first()
181
  if not creation:
182
  return jsonify({'error': 'Not found'}), 404
 
183
  creation.journal_entry = journal_entry
184
  creation.updated_at = datetime.utcnow()
185
  db.session.commit()
186
  return jsonify({'success': True})
187
 
 
188
  @app.route('/get_creations')
189
  @login_required
190
  def get_creations():
191
- from models import Creation
192
  creations = Creation.query.filter_by(user_id=current_user.id).order_by(Creation.created_at.desc()).all()
193
  return jsonify({'creations': [{
194
  'id': c.id,
@@ -199,7 +194,13 @@ def get_creations():
199
  'created_at': c.created_at.isoformat()
200
  } for c in creations]})
201
 
 
 
 
202
  def generate_image_hf(scene_idea, story):
 
 
 
203
  prompt = f"An artistic illustration of: {scene_idea}, dreamy and vivid"
204
  models = [
205
  "runwayml/stable-diffusion-v1-5",
@@ -209,32 +210,24 @@ def generate_image_hf(scene_idea, story):
209
 
210
  for model in models:
211
  try:
212
- logging.info(f"Trying model: {model}")
213
  res = requests.post(
214
  f"https://api-inference.huggingface.co/models/{model}",
215
  headers={"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"},
216
  json={"inputs": prompt},
217
- timeout=15 # 15 seconds max
218
  )
219
-
220
- logging.info(f"Status: {res.status_code}")
221
  if res.status_code == 200:
222
- import base64
223
  return f"data:image/png;base64,{base64.b64encode(res.content).decode()}"
 
 
224
 
225
- else:
226
- logging.warning(f"Model {model} failed: {res.status_code} - {res.text[:200]}")
227
 
228
- except Exception as e:
229
- logging.error(f"Error from model {model}: {e}")
230
- continue
231
 
232
- return generate_svg_placeholder(scene_idea, story)
233
-
234
- # DB setup
235
- from models import User, Creation
236
  with app.app_context():
237
  db.create_all()
238
 
239
  if __name__ == '__main__':
240
- app.run(host='0.0.0.0', port=5000, debug=True)
 
1
  import os
2
  import logging
3
+ import uuid
4
+ import base64
5
+ import requests
6
+ from datetime import datetime
7
+ from flask import Flask, render_template, request, jsonify, redirect, url_for, flash
8
  from flask_sqlalchemy import SQLAlchemy
9
  from flask_login import LoginManager, login_user, logout_user, login_required, current_user
10
  from sqlalchemy.orm import DeclarativeBase
11
  import cohere
 
 
 
12
 
13
+ # ------------------ Setup ------------------
14
+
15
  logging.basicConfig(level=logging.INFO)
16
 
17
  class Base(DeclarativeBase):
18
  pass
19
 
20
+ app = Flask(__name__)
 
21
  app.secret_key = os.environ.get("SESSION_SECRET", os.urandom(24).hex())
22
 
23
+ # ------------------ Database ------------------
24
+
25
  app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DATABASE_URL", "sqlite:///inkboard.db")
26
  app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
27
  app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
 
31
 
32
  db = SQLAlchemy(app, model_class=Base)
33
 
34
+ # ------------------ Flask-Login ------------------
35
+
36
  login_manager = LoginManager()
37
  login_manager.init_app(app)
38
  login_manager.login_view = 'login'
39
  login_manager.login_message = 'Please log in to access InkBoard'
40
 
41
+ # ------------------ API Keys ------------------
42
+
43
+ API_KEY = os.environ.get("API_KEY") # Make sure this is your cohere key name
44
  HUGGINGFACE_API_KEY = os.environ.get("HUGGINGFACE_API_KEY")
 
45
 
46
  cohere_client = cohere.Client(API_KEY) if API_KEY else None
47
+
48
+ # ------------------ Models ------------------
49
+
50
+ from models import User, Creation
51
 
52
  @login_manager.user_loader
53
  def load_user(user_id):
 
54
  return User.query.get(int(user_id))
55
 
56
+ # ------------------ Routes ------------------
57
+
58
  @app.route('/')
59
  def index():
60
  return render_template('dashboard.html', user=current_user) if current_user.is_authenticated else render_template('index.html')
61
 
62
+
63
  @app.route('/register', methods=['GET', 'POST'])
64
  def register():
 
65
  if request.method == 'POST':
66
  data = request.get_json() if request.is_json else request.form
67
  username, email, password = data.get('username', '').strip(), data.get('email', '').strip(), data.get('password', '').strip()
 
83
 
84
  return render_template('register.html')
85
 
86
+
87
  @app.route('/login', methods=['GET', 'POST'])
88
  def login():
 
89
  if request.method == 'POST':
90
  data = request.get_json() if request.is_json else request.form
91
+ username = data.get('username', '').strip()
92
+ password = data.get('password', '').strip()
93
 
94
  user = User.query.filter((User.username == username) | (User.email == username)).first()
95
 
 
101
 
102
  return render_template('login.html')
103
 
104
+
105
  @app.route('/logout')
106
  @login_required
107
  def logout():
 
112
  @app.route('/generate', methods=['POST'])
113
  @login_required
114
  def generate_content():
 
 
 
115
  logging.info("⚑ generate_content() called")
 
 
116
  data = request.get_json()
117
  scene_idea = data.get('scene_idea', '').strip()
118
  logging.info(f"πŸ“₯ Received prompt: {scene_idea}")
119
 
120
  if not scene_idea:
 
121
  return jsonify({'error': 'Please provide a scene idea'}), 400
122
 
123
  if not cohere_client:
124
+ logging.error("❌ Cohere client not configured")
125
+ return jsonify({'error': 'Text generation unavailable'}), 500
126
 
 
127
  try:
128
  story_prompt = f"""Transform this scene idea into a vivid paragraph:\nScene idea: {scene_idea}"""
 
 
129
  story_response = cohere_client.generate(
130
  model='command',
131
  prompt=story_prompt,
 
133
  temperature=0.7,
134
  k=0
135
  )
 
 
 
136
  expanded_story = story_response.generations[0].text.strip()
137
+ logging.info("βœ… Story generated")
 
138
  except Exception as e:
139
  logging.error(f"❌ Cohere generation error: {str(e)}")
140
  return jsonify({'error': 'Failed to generate story'}), 500
141
 
 
142
  image_url = None
143
  try:
144
  image_url = generate_image_hf(scene_idea, expanded_story)
 
145
  except Exception as e:
146
  logging.warning(f"⚠️ Image generation failed: {e}")
147
 
 
148
  creation_id = str(uuid.uuid4())
149
  creation = Creation(
150
  id=creation_id,
 
167
  @app.route('/save_journal', methods=['POST'])
168
  @login_required
169
  def save_journal():
 
170
  data = request.get_json()
171
+ creation_id = data.get('creation_id')
172
+ journal_entry = data.get('journal_entry', '').strip()
173
+
174
  creation = Creation.query.filter_by(id=creation_id, user_id=current_user.id).first()
175
  if not creation:
176
  return jsonify({'error': 'Not found'}), 404
177
+
178
  creation.journal_entry = journal_entry
179
  creation.updated_at = datetime.utcnow()
180
  db.session.commit()
181
  return jsonify({'success': True})
182
 
183
+
184
  @app.route('/get_creations')
185
  @login_required
186
  def get_creations():
 
187
  creations = Creation.query.filter_by(user_id=current_user.id).order_by(Creation.created_at.desc()).all()
188
  return jsonify({'creations': [{
189
  'id': c.id,
 
194
  'created_at': c.created_at.isoformat()
195
  } for c in creations]})
196
 
197
+
198
+ # ------------------ Image Generation ------------------
199
+
200
  def generate_image_hf(scene_idea, story):
201
+ if not HUGGINGFACE_API_KEY:
202
+ return None
203
+
204
  prompt = f"An artistic illustration of: {scene_idea}, dreamy and vivid"
205
  models = [
206
  "runwayml/stable-diffusion-v1-5",
 
210
 
211
  for model in models:
212
  try:
 
213
  res = requests.post(
214
  f"https://api-inference.huggingface.co/models/{model}",
215
  headers={"Authorization": f"Bearer {HUGGINGFACE_API_KEY}"},
216
  json={"inputs": prompt},
217
+ timeout=60
218
  )
 
 
219
  if res.status_code == 200:
 
220
  return f"data:image/png;base64,{base64.b64encode(res.content).decode()}"
221
+ except Exception as e:
222
+ logging.warning(f"Model {model} failed: {str(e)}")
223
 
224
+ return "<svg>SVG fallback</svg>"
 
225
 
 
 
 
226
 
227
+ # ------------------ Run App ------------------
228
+
 
 
229
  with app.app_context():
230
  db.create_all()
231
 
232
  if __name__ == '__main__':
233
+ app.run(host='0.0.0.0', port=5000)