cryogenic22 commited on
Commit
65cf9e6
·
verified ·
1 Parent(s): 9aa28bf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +160 -325
app.py CHANGED
@@ -1,352 +1,187 @@
1
- # File: app.py
2
 
 
3
  import streamlit as st
4
  import json
5
  import os
6
- from selfapi_writer import SelfApiWriter
7
- from data_manager import DataManager
8
 
9
- class SelfApiApp:
10
  def __init__(self):
11
- """Initialize the Streamlit application"""
12
- st.set_page_config(
13
- page_title="Self.api Book Generator",
14
- page_icon="📚",
15
- layout="wide"
16
- )
17
-
18
- # Initialize data manager
19
- self.data_manager = DataManager()
20
 
21
- # Initialize session state
22
- self._initialize_session_state()
23
-
24
- def _initialize_session_state(self):
25
- """Initialize session state variables"""
26
- if 'current_tab' not in st.session_state:
27
- st.session_state.current_tab = 'Blueprint'
28
 
29
- if 'blueprint' not in st.session_state:
30
- st.session_state.blueprint = self.default_blueprint
31
 
32
- if 'book_content' not in st.session_state:
33
- st.session_state.book_content = {
34
- "introduction": "",
35
- "parts": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
 
37
 
38
- @property
39
- def default_blueprint(self):
40
- """Get default blueprint content"""
41
- return """# Editorial Blueprint: Self.api - A Modern Spiritual Operating System
42
-
43
- ## Core Editorial Vision
44
- Transform "Self.api" from a conceptual framework into a revolutionary guide that speaks to the modern seeker - the stressed executive who downloads meditation apps but can't stick to them, the engineering lead who understands distributed systems better than their own emotions, and the consultant who can optimize anything except their own life satisfaction.
45
-
46
- ### Target Reader Profile
47
- - Primary: Tech professionals, entrepreneurs, and knowledge workers (25-45)
48
- - Secondary: Anyone feeling disconnected in our hyper-connected world
49
- - Psychographic: Analytical minds seeking spiritual depth without the woo-woo
50
-
51
- ## Book Structure
52
- ### Introduction: "System Requirements: A Human's Guide to Being Human"
53
- - Opening hook: "In a world where we can Google anything except our own purpose..."
54
- - Key narrative: Author's journey from debugging code to debugging consciousness
55
-
56
- ### Part 1: The Human Input/Output System
57
- - Rate Limiting Your Reality
58
- - Debugging Your Attention Span
59
- - The Mindfulness Microservice
60
-
61
- ### Part 2: Your Internal Neural Network
62
- - Training Your Gut Algorithm
63
- - The Wisdom Cache
64
- - Pattern Recognition Beyond Logic
65
-
66
- ### Part 3: The Source Code of Being
67
- - Quantum Mechanics of Consciousness
68
- - The Purpose Protocol
69
- - Refactoring Your Reality
70
 
71
- ### Part 4: The Universal Runtime Environment
72
- - Distributed Consciousness Systems
73
- - The Empathy Protocol
74
- - Scaling Your Impact
75
 
76
- ## Style Guidelines
77
- 1. Technical Authenticity
78
- - Use API and tech metaphors naturally
79
- - Example: "Think of meditation as a daily health check for your consciousness microservices"
80
 
81
- 2. Voice & Tone
82
- - Witty But Wise
83
- - Blend humor with depth
84
- - Style: Think Douglas Adams meets Deepak Chopra
85
-
86
- 3. Chapter Structure
87
- - System Log (personal story)
88
- - Documentation (teaching)
89
- - Implementation Guide (practical steps)
90
-
91
- ## Content Requirements
92
- 1. Each chapter should have:
93
- - 3 "aha" moments
94
- - 2-3 quotable passages
95
- - Practical exercises every 5 pages
96
- - Balance: 60% practical, 40% philosophical
97
- - Links to both ancient wisdom and modern science"""
98
-
99
- def save_current_state(self):
100
- """Save current state to data directory"""
101
- try:
102
- # Save blueprint if it exists
103
- if st.session_state.blueprint:
104
- blueprint_file = self.data_manager.save_blueprint(st.session_state.blueprint)
105
- st.success(f"Blueprint saved: {blueprint_file}")
106
-
107
- # Save book content if it exists
108
- if st.session_state.book_content:
109
- content_file = self.data_manager.save_book_content(st.session_state.book_content)
110
- st.success(f"Book content saved: {content_file}")
111
 
112
- # Save individual chapters
113
- for part_idx, part in enumerate(st.session_state.book_content.get('parts', [])):
114
- for ch_idx, chapter in enumerate(part.get('chapters', [])):
115
- if chapter.get('content'):
116
- self.data_manager.save_chapter(part_idx, ch_idx, chapter)
117
 
118
  except Exception as e:
119
- st.error(f"Error saving state: {e}")
 
120
 
121
- def load_latest_state(self):
122
- """Load latest state from data directory"""
123
  try:
124
- # Load latest blueprint
125
- blueprint = self.data_manager.load_latest_blueprint()
126
- if blueprint:
127
- st.session_state.blueprint = blueprint
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
- # Load latest book content
130
- content = self.data_manager.load_latest_book_content()
131
- if content:
132
- st.session_state.book_content = content
133
-
134
- st.success("Latest state loaded successfully!")
135
 
136
  except Exception as e:
137
- st.error(f"Error loading state: {e}")
 
138
 
139
- def export_book(self):
140
- """Export book in markdown format"""
141
  try:
142
- # Export as markdown
143
- if st.session_state.book_content:
144
- filepath = self.data_manager.export_markdown(st.session_state.book_content)
145
- st.success(f"Book exported to: {filepath}")
146
-
147
- # Create download link
148
- with open(filepath, 'r') as f:
149
- markdown_content = f.read()
150
-
151
- st.download_button(
152
- label="Download Markdown",
153
- data=markdown_content,
154
- file_name="self_api_book.md",
155
- mime="text/markdown"
156
- )
157
- except Exception as e:
158
- st.error(f"Error exporting book: {e}")
159
-
160
- def render_blueprint_editor(self):
161
- """Render the blueprint editor interface"""
162
- st.header("📝 Editorial Blueprint Editor")
163
-
164
- col1, col2 = st.columns([7, 3])
165
-
166
- with col1:
167
- # Blueprint Editor
168
- edited_blueprint = st.text_area(
169
- "Edit Blueprint",
170
- value=st.session_state.blueprint,
171
- height=600
 
 
 
 
 
 
172
  )
173
 
174
- if edited_blueprint != st.session_state.blueprint:
175
- st.session_state.blueprint = edited_blueprint
176
-
177
- with col2:
178
- st.subheader("Blueprint Controls")
179
-
180
- # Reset Blueprint
181
- if st.button("Reset to Default"):
182
- st.session_state.blueprint = self.default_blueprint
183
- st.experimental_rerun()
184
-
185
- # Save Blueprint
186
- if st.button("Save Blueprint"):
187
- try:
188
- filename = self.data_manager.save_blueprint(st.session_state.blueprint)
189
- st.success(f"Blueprint saved as: {filename}")
190
- except Exception as e:
191
- st.error(f"Error saving blueprint: {e}")
192
-
193
- # Load Blueprint
194
- if st.button("Load Latest"):
195
- try:
196
- blueprint = self.data_manager.load_latest_blueprint()
197
- if blueprint:
198
- st.session_state.blueprint = blueprint
199
- st.success("Latest blueprint loaded!")
200
- st.experimental_rerun()
201
- except Exception as e:
202
- st.error(f"Error loading blueprint: {e}")
203
-
204
- def render_generator_interface(self):
205
- """Render the book generation interface"""
206
- st.header("⚙️ Content Generator")
207
-
208
- # Initialize writer if needed
209
- if 'writer' not in st.session_state:
210
- st.session_state.writer = SelfApiWriter()
211
-
212
- # Generation controls
213
- col1, col2 = st.columns([2, 1])
214
-
215
- with col1:
216
- st.subheader("Generation Controls")
217
-
218
- # Introduction Generation
219
- intro_col1, intro_col2 = st.columns([3, 1])
220
- with intro_col1:
221
- st.markdown("### Introduction")
222
- with intro_col2:
223
- if st.button("Generate Introduction"):
224
- with st.spinner("Generating introduction..."):
225
- intro_content = st.session_state.writer.write_introduction()
226
- st.session_state.book_content["introduction"] = intro_content
227
- self.save_current_state()
228
- st.success("Introduction generated!")
229
-
230
- # Parts and Chapters Generation
231
- for part_idx, part in enumerate(st.session_state.writer.book_structure["parts"]):
232
- st.markdown(f"### Part {part_idx + 1}: {part['title']}")
233
-
234
- for ch_idx, ch_title in enumerate(part["chapters"]):
235
- ch_col1, ch_col2 = st.columns([3, 1])
236
- with ch_col1:
237
- st.markdown(f"- {ch_title}")
238
- with ch_col2:
239
- if st.button(f"Generate", key=f"gen_{part_idx}_{ch_idx}"):
240
- with st.spinner(f"Generating {ch_title}..."):
241
- chapter_content = st.session_state.writer.write_chapter(part_idx, ch_idx)
242
-
243
- # Ensure part exists
244
- while len(st.session_state.book_content["parts"]) <= part_idx:
245
- st.session_state.book_content["parts"].append({
246
- "title": part["title"],
247
- "chapters": []
248
- })
249
-
250
- # Ensure chapter exists
251
- while len(st.session_state.book_content["parts"][part_idx]["chapters"]) <= ch_idx:
252
- st.session_state.book_content["parts"][part_idx]["chapters"].append({
253
- "title": "",
254
- "content": ""
255
- })
256
-
257
- # Update chapter
258
- st.session_state.book_content["parts"][part_idx]["chapters"][ch_idx] = {
259
- "title": ch_title,
260
- "content": chapter_content
261
- }
262
- self.save_current_state()
263
- st.success(f"{ch_title} generated!")
264
-
265
- with col2:
266
- st.subheader("Quick Actions")
267
 
268
- if st.button("Generate All"):
269
- with st.spinner("Generating entire book..."):
270
- # Generate introduction
271
- intro_content = st.session_state.writer.write_introduction()
272
- st.session_state.book_content["introduction"] = intro_content
273
-
274
- # Generate all chapters
275
- for part_idx, part in enumerate(st.session_state.writer.book_structure["parts"]):
276
- # Initialize part
277
- if len(st.session_state.book_content["parts"]) <= part_idx:
278
- st.session_state.book_content["parts"].append({
279
- "title": part["title"],
280
- "chapters": []
281
- })
282
-
283
- for ch_idx, ch_title in enumerate(part["chapters"]):
284
- chapter_content = st.session_state.writer.write_chapter(part_idx, ch_idx)
285
-
286
- # Ensure chapter exists
287
- while len(st.session_state.book_content["parts"][part_idx]["chapters"]) <= ch_idx:
288
- st.session_state.book_content["parts"][part_idx]["chapters"].append({
289
- "title": "",
290
- "content": ""
291
- })
292
-
293
- # Update chapter
294
- st.session_state.book_content["parts"][part_idx]["chapters"][ch_idx] = {
295
- "title": ch_title,
296
- "content": chapter_content
297
- }
298
-
299
- self.save_current_state()
300
- st.success("Full book generated!")
301
-
302
- def render_content_preview(self):
303
- """Render the book content preview"""
304
- st.header("📚 Generated Content Preview")
305
-
306
- # Display any generated content here
307
- if not st.session_state.book_content["introduction"] and not st.session_state.book_content["parts"]:
308
- st.info("No content generated yet. Use the Generator tab to create content.")
309
- else:
310
- # Add export button
311
- if st.button("Export Current Content"):
312
- self.export_book()
313
-
314
- # Show introduction if it exists
315
- if st.session_state.book_content["introduction"]:
316
- st.subheader("Introduction")
317
- with st.expander("View Introduction", expanded=True):
318
- st.markdown(st.session_state.book_content["introduction"])
319
-
320
- # Show generated parts and chapters
321
- for part_idx, part in enumerate(st.session_state.book_content["parts"]):
322
- st.subheader(f"Part {part_idx + 1}: {part['title']}")
323
- for chapter in part["chapters"]:
324
- if chapter["content"]:
325
- with st.expander(f"Chapter: {chapter['title']}", expanded=False):
326
- st.markdown(chapter["content"])
327
-
328
- def run(self):
329
- """Run the Streamlit application"""
330
- st.title("🚀 Self.api Book Generator")
331
-
332
- # Main navigation
333
- tabs = ["Blueprint", "Generator", "Preview"]
334
- selected_tab = st.radio("Navigation", tabs, horizontal=True)
335
- st.session_state.current_tab = selected_tab
336
-
337
- st.divider()
338
-
339
- # Render appropriate content based on selected tab
340
- if selected_tab == "Blueprint":
341
- self.render_blueprint_editor()
342
- elif selected_tab == "Generator":
343
- self.render_generator_interface()
344
- else:
345
- self.render_content_preview()
346
-
347
- def main():
348
- app = SelfApiApp()
349
- app.run()
350
-
351
- if __name__ == "__main__":
352
- main()
 
1
+ # File: selfapi_writer.py
2
 
3
+ import anthropic
4
  import streamlit as st
5
  import json
6
  import os
7
+ from typing import Dict, Any
 
8
 
9
+ class SelfApiWriter:
10
  def __init__(self):
11
+ """Initialize the Self.api writer"""
12
+ # Try to get API key from environment variables first, then from secrets
13
+ api_key = os.environ.get('ANTHROPIC_API_KEY')
 
 
 
 
 
 
14
 
15
+ if not api_key and hasattr(st, 'secrets'):
16
+ api_key = st.secrets.get('ANTHROPIC_API_KEY')
 
 
 
 
 
17
 
18
+ if not api_key:
19
+ raise ValueError("ANTHROPIC_API_KEY not found in environment variables or Streamlit secrets.")
20
 
21
+ # Print debug info (remove in production)
22
+ print("Environment variables available:", [k for k in os.environ.keys()])
23
+ print("API key found:", bool(api_key))
24
+
25
+ self.client = anthropic.Anthropic(
26
+ api_key=api_key
27
+ )
28
+ self.context = {}
29
+ self.book_structure = {
30
+ "introduction": "System Requirements: A Human's Guide to Being Human",
31
+ "parts": [
32
+ {
33
+ "title": "The Human Input/Output System",
34
+ "chapters": [
35
+ "Rate Limiting Your Reality",
36
+ "Debugging Your Attention Span",
37
+ "The Mindfulness Microservice"
38
+ ]
39
+ },
40
+ {
41
+ "title": "Your Internal Neural Network",
42
+ "chapters": [
43
+ "Training Your Gut Algorithm",
44
+ "The Wisdom Cache",
45
+ "Pattern Recognition Beyond Logic"
46
+ ]
47
+ },
48
+ {
49
+ "title": "The Source Code of Being",
50
+ "chapters": [
51
+ "Quantum Mechanics of Consciousness",
52
+ "The Purpose Protocol",
53
+ "Refactoring Your Reality"
54
+ ]
55
+ },
56
+ {
57
+ "title": "The Universal Runtime Environment",
58
+ "chapters": [
59
+ "Distributed Consciousness Systems",
60
+ "The Empathy Protocol",
61
+ "Scaling Your Impact"
62
+ ]
63
+ }
64
+ ]
65
+ }
66
+
67
+ def process_blueprint(self, blueprint: str) -> Dict[str, Any]:
68
+ """Process updated blueprint to generate new book structure"""
69
+ try:
70
+ system_prompt = """You are an expert book planner analyzing a blueprint for 'Self.api: A Modern Spiritual Operating System'.
71
+ Extract and organize the book structure from the provided blueprint.
72
+ Return a JSON structure with the following format:
73
+ {
74
+ "introduction": "Introduction title",
75
+ "parts": [
76
+ {
77
+ "title": "Part title",
78
+ "chapters": ["Chapter 1 title", "Chapter 2 title", ...]
79
+ }
80
+ ]
81
  }
82
+ Ensure all sections from the blueprint are included and properly organized."""
83
 
84
+ prompt = f"""Analyze this book blueprint and extract the structure:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+ {blueprint}
 
 
 
87
 
88
+ Return only the JSON structure with no additional text."""
 
 
 
89
 
90
+ response = self.client.messages.create(
91
+ model="claude-3-sonnet-20240229",
92
+ max_tokens=2000,
93
+ temperature=0,
94
+ system=system_prompt,
95
+ messages=[{"role": "user", "content": prompt}]
96
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
+ new_structure = json.loads(response.content[0].text)
99
+ self.book_structure = new_structure
100
+ return new_structure
 
 
101
 
102
  except Exception as e:
103
+ st.error(f"Error processing blueprint: {str(e)}")
104
+ return self.book_structure # Return existing structure on error
105
 
106
+ def write_introduction(self) -> str:
107
+ """Generate the book's introduction"""
108
  try:
109
+ system_prompt = """You are writing the introduction to 'Self.api: A Modern Spiritual Operating System'.
110
+ The introduction should hook tech professionals by speaking their language while introducing the book's core premise.
111
+ Include the author's journey from debugging code to debugging consciousness."""
112
+
113
+ intro_prompt = """Write the introduction "System Requirements: A Human's Guide to Being Human"
114
+
115
+ Key elements to include:
116
+ 1. Opening hook: "In a world where we can Google anything except our own purpose..."
117
+ 2. Author's personal journey
118
+ 3. The core premise of viewing spirituality through an API/systems lens
119
+ 4. Overview of the book's structure and approach
120
+ 5. What readers will gain from this "operating manual for the human spirit"
121
+
122
+ Make it compelling, technical yet accessible, and set the tone for the entire book."""
123
+
124
+ response = self.client.messages.create(
125
+ model="claude-3-sonnet-20240229",
126
+ max_tokens=4000,
127
+ temperature=0.7,
128
+ system=system_prompt,
129
+ messages=[{"role": "user", "content": intro_prompt}]
130
+ )
131
 
132
+ intro_content = response.content[0].text
133
+ self.context['introduction'] = intro_content
134
+ return intro_content
 
 
 
135
 
136
  except Exception as e:
137
+ st.error(f"Error generating introduction: {str(e)}")
138
+ return f"Error generating introduction: {str(e)}"
139
 
140
+ def write_chapter(self, part_idx: int, chapter_idx: int) -> str:
141
+ """Generate a specific chapter"""
142
  try:
143
+ part = self.book_structure["parts"][part_idx]
144
+ chapter_title = part["chapters"][chapter_idx]
145
+ part_title = part["title"]
146
+ previous_chapter = self.context.get(f'part_{part_idx}_chapter_{chapter_idx-1}', '')
147
+
148
+ system_prompt = """You are writing 'Self.api: A Modern Spiritual Operating System', a book that bridges technology and spirituality for tech professionals.
149
+ Follow these guidelines:
150
+ - Use API and technical metaphors naturally and accurately
151
+ - Maintain a voice that's witty but wise (Douglas Adams meets Deepak Chopra)
152
+ - Structure each chapter with: System Log (personal story), Documentation (teaching), Implementation Guide (practical steps)
153
+ - Balance is 60% practical, 40% philosophical
154
+ - Include 3 "aha" moments and 2-3 quotable passages
155
+ - Ensure every concept links to both ancient wisdom and modern science
156
+ - Write for analytical minds seeking spiritual depth without woo-woo
157
+ - Include practical exercises every few pages"""
158
+
159
+ chapter_prompt = f"""
160
+ Write Chapter: "{chapter_title}" in Part {part_idx + 1}: "{part_title}"
161
+
162
+ Previous Chapter Context: {previous_chapter[:1000] if previous_chapter else 'Starting new part'}
163
+
164
+ Requirements:
165
+ 1. Open with a compelling "System Log" that relates to {chapter_title}
166
+ 2. Use technically accurate API/programming metaphors
167
+ 3. Include at least two practical exercises
168
+ 4. End with clear implementation steps
169
+ 5. Maintain the tech-spiritual bridge throughout
170
+
171
+ Begin writing the complete chapter now."""
172
+
173
+ response = self.client.messages.create(
174
+ model="claude-3-sonnet-20240229",
175
+ max_tokens=4000,
176
+ temperature=0.7,
177
+ system=system_prompt,
178
+ messages=[{"role": "user", "content": chapter_prompt}]
179
  )
180
 
181
+ chapter_content = response.content[0].text
182
+ self.context[f'part_{part_idx}_chapter_{chapter_idx}'] = chapter_content
183
+ return chapter_content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
+ except Exception as e:
186
+ st.error(f"Error generating chapter: {str(e)}")
187
+ return f"Error generating chapter {chapter_title}: {str(e)}"