kollabor 0.4.9__py3-none-any.whl → 0.4.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agents/__init__.py +2 -0
- agents/coder/__init__.py +0 -0
- agents/coder/agent.json +4 -0
- agents/coder/api-integration.md +2150 -0
- agents/coder/cli-pretty.md +765 -0
- agents/coder/code-review.md +1092 -0
- agents/coder/database-design.md +1525 -0
- agents/coder/debugging.md +1102 -0
- agents/coder/dependency-management.md +1397 -0
- agents/coder/git-workflow.md +1099 -0
- agents/coder/refactoring.md +1454 -0
- agents/coder/security-hardening.md +1732 -0
- agents/coder/system_prompt.md +1448 -0
- agents/coder/tdd.md +1367 -0
- agents/creative-writer/__init__.py +0 -0
- agents/creative-writer/agent.json +4 -0
- agents/creative-writer/character-development.md +1852 -0
- agents/creative-writer/dialogue-craft.md +1122 -0
- agents/creative-writer/plot-structure.md +1073 -0
- agents/creative-writer/revision-editing.md +1484 -0
- agents/creative-writer/system_prompt.md +690 -0
- agents/creative-writer/worldbuilding.md +2049 -0
- agents/data-analyst/__init__.py +30 -0
- agents/data-analyst/agent.json +4 -0
- agents/data-analyst/data-visualization.md +992 -0
- agents/data-analyst/exploratory-data-analysis.md +1110 -0
- agents/data-analyst/pandas-data-manipulation.md +1081 -0
- agents/data-analyst/sql-query-optimization.md +881 -0
- agents/data-analyst/statistical-analysis.md +1118 -0
- agents/data-analyst/system_prompt.md +928 -0
- agents/default/__init__.py +0 -0
- agents/default/agent.json +4 -0
- agents/default/dead-code.md +794 -0
- agents/default/explore-agent-system.md +585 -0
- agents/default/system_prompt.md +1448 -0
- agents/kollabor/__init__.py +0 -0
- agents/kollabor/analyze-plugin-lifecycle.md +175 -0
- agents/kollabor/analyze-terminal-rendering.md +388 -0
- agents/kollabor/code-review.md +1092 -0
- agents/kollabor/debug-mcp-integration.md +521 -0
- agents/kollabor/debug-plugin-hooks.md +547 -0
- agents/kollabor/debugging.md +1102 -0
- agents/kollabor/dependency-management.md +1397 -0
- agents/kollabor/git-workflow.md +1099 -0
- agents/kollabor/inspect-llm-conversation.md +148 -0
- agents/kollabor/monitor-event-bus.md +558 -0
- agents/kollabor/profile-performance.md +576 -0
- agents/kollabor/refactoring.md +1454 -0
- agents/kollabor/system_prompt copy.md +1448 -0
- agents/kollabor/system_prompt.md +757 -0
- agents/kollabor/trace-command-execution.md +178 -0
- agents/kollabor/validate-config.md +879 -0
- agents/research/__init__.py +0 -0
- agents/research/agent.json +4 -0
- agents/research/architecture-mapping.md +1099 -0
- agents/research/codebase-analysis.md +1077 -0
- agents/research/dependency-audit.md +1027 -0
- agents/research/performance-profiling.md +1047 -0
- agents/research/security-review.md +1359 -0
- agents/research/system_prompt.md +492 -0
- agents/technical-writer/__init__.py +0 -0
- agents/technical-writer/agent.json +4 -0
- agents/technical-writer/api-documentation.md +2328 -0
- agents/technical-writer/changelog-management.md +1181 -0
- agents/technical-writer/readme-writing.md +1360 -0
- agents/technical-writer/style-guide.md +1410 -0
- agents/technical-writer/system_prompt.md +653 -0
- agents/technical-writer/tutorial-creation.md +1448 -0
- core/__init__.py +0 -2
- core/application.py +343 -88
- core/cli.py +229 -10
- core/commands/menu_renderer.py +463 -59
- core/commands/registry.py +14 -9
- core/commands/system_commands.py +2461 -14
- core/config/loader.py +151 -37
- core/config/service.py +18 -6
- core/events/bus.py +29 -9
- core/events/executor.py +205 -75
- core/events/models.py +27 -8
- core/fullscreen/command_integration.py +20 -24
- core/fullscreen/components/__init__.py +10 -1
- core/fullscreen/components/matrix_components.py +1 -2
- core/fullscreen/components/space_shooter_components.py +654 -0
- core/fullscreen/plugin.py +5 -0
- core/fullscreen/renderer.py +52 -13
- core/fullscreen/session.py +52 -15
- core/io/__init__.py +29 -5
- core/io/buffer_manager.py +6 -1
- core/io/config_status_view.py +7 -29
- core/io/core_status_views.py +267 -347
- core/io/input/__init__.py +25 -0
- core/io/input/command_mode_handler.py +711 -0
- core/io/input/display_controller.py +128 -0
- core/io/input/hook_registrar.py +286 -0
- core/io/input/input_loop_manager.py +421 -0
- core/io/input/key_press_handler.py +502 -0
- core/io/input/modal_controller.py +1011 -0
- core/io/input/paste_processor.py +339 -0
- core/io/input/status_modal_renderer.py +184 -0
- core/io/input_errors.py +5 -1
- core/io/input_handler.py +211 -2452
- core/io/key_parser.py +7 -0
- core/io/layout.py +15 -3
- core/io/message_coordinator.py +111 -2
- core/io/message_renderer.py +129 -4
- core/io/status_renderer.py +147 -607
- core/io/terminal_renderer.py +97 -51
- core/io/terminal_state.py +21 -4
- core/io/visual_effects.py +816 -165
- core/llm/agent_manager.py +1063 -0
- core/llm/api_adapters/__init__.py +44 -0
- core/llm/api_adapters/anthropic_adapter.py +432 -0
- core/llm/api_adapters/base.py +241 -0
- core/llm/api_adapters/openai_adapter.py +326 -0
- core/llm/api_communication_service.py +167 -113
- core/llm/conversation_logger.py +322 -16
- core/llm/conversation_manager.py +556 -30
- core/llm/file_operations_executor.py +84 -32
- core/llm/llm_service.py +934 -103
- core/llm/mcp_integration.py +541 -57
- core/llm/message_display_service.py +135 -18
- core/llm/plugin_sdk.py +1 -2
- core/llm/profile_manager.py +1183 -0
- core/llm/response_parser.py +274 -56
- core/llm/response_processor.py +16 -3
- core/llm/tool_executor.py +6 -1
- core/logging/__init__.py +2 -0
- core/logging/setup.py +34 -6
- core/models/resume.py +54 -0
- core/plugins/__init__.py +4 -2
- core/plugins/base.py +127 -0
- core/plugins/collector.py +23 -161
- core/plugins/discovery.py +37 -3
- core/plugins/factory.py +6 -12
- core/plugins/registry.py +5 -17
- core/ui/config_widgets.py +128 -28
- core/ui/live_modal_renderer.py +2 -1
- core/ui/modal_actions.py +5 -0
- core/ui/modal_overlay_renderer.py +0 -60
- core/ui/modal_renderer.py +268 -7
- core/ui/modal_state_manager.py +29 -4
- core/ui/widgets/base_widget.py +7 -0
- core/updates/__init__.py +10 -0
- core/updates/version_check_service.py +348 -0
- core/updates/version_comparator.py +103 -0
- core/utils/config_utils.py +685 -526
- core/utils/plugin_utils.py +1 -1
- core/utils/session_naming.py +111 -0
- fonts/LICENSE +21 -0
- fonts/README.md +46 -0
- fonts/SymbolsNerdFont-Regular.ttf +0 -0
- fonts/SymbolsNerdFontMono-Regular.ttf +0 -0
- fonts/__init__.py +44 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/METADATA +54 -4
- kollabor-0.4.15.dist-info/RECORD +228 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/top_level.txt +2 -0
- plugins/agent_orchestrator/__init__.py +39 -0
- plugins/agent_orchestrator/activity_monitor.py +181 -0
- plugins/agent_orchestrator/file_attacher.py +77 -0
- plugins/agent_orchestrator/message_injector.py +135 -0
- plugins/agent_orchestrator/models.py +48 -0
- plugins/agent_orchestrator/orchestrator.py +403 -0
- plugins/agent_orchestrator/plugin.py +976 -0
- plugins/agent_orchestrator/xml_parser.py +191 -0
- plugins/agent_orchestrator_plugin.py +9 -0
- plugins/enhanced_input/box_styles.py +1 -0
- plugins/enhanced_input/color_engine.py +19 -4
- plugins/enhanced_input/config.py +2 -2
- plugins/enhanced_input_plugin.py +61 -11
- plugins/fullscreen/__init__.py +6 -2
- plugins/fullscreen/example_plugin.py +1035 -222
- plugins/fullscreen/setup_wizard_plugin.py +592 -0
- plugins/fullscreen/space_shooter_plugin.py +131 -0
- plugins/hook_monitoring_plugin.py +436 -78
- plugins/query_enhancer_plugin.py +66 -30
- plugins/resume_conversation_plugin.py +1494 -0
- plugins/save_conversation_plugin.py +98 -32
- plugins/system_commands_plugin.py +70 -56
- plugins/tmux_plugin.py +154 -78
- plugins/workflow_enforcement_plugin.py +94 -92
- system_prompt/default.md +952 -886
- core/io/input_mode_manager.py +0 -402
- core/io/modal_interaction_handler.py +0 -315
- core/io/raw_input_processor.py +0 -946
- core/storage/__init__.py +0 -5
- core/storage/state_manager.py +0 -84
- core/ui/widget_integration.py +0 -222
- core/utils/key_reader.py +0 -171
- kollabor-0.4.9.dist-info/RECORD +0 -128
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/WHEEL +0 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/entry_points.txt +0 -0
- {kollabor-0.4.9.dist-info → kollabor-0.4.15.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,1448 @@
|
|
|
1
|
+
<!-- Tutorial Creation skill - write effective step-by-step tutorials -->
|
|
2
|
+
|
|
3
|
+
tutorial-creation mode: LEARN BY DOING
|
|
4
|
+
|
|
5
|
+
when this skill is active, you follow tutorial writing best practices.
|
|
6
|
+
this is a comprehensive guide to creating effective technical tutorials.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
PHASE 0: AUDIENCE ANALYSIS
|
|
10
|
+
|
|
11
|
+
before writing ANY tutorial, understand who will read it.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
identify target audience
|
|
15
|
+
|
|
16
|
+
ask these questions:
|
|
17
|
+
|
|
18
|
+
[ ] what is their skill level?
|
|
19
|
+
beginner - needs explanations of basic concepts
|
|
20
|
+
intermediate - knows basics, needs practical application
|
|
21
|
+
advanced - needs optimization and edge cases
|
|
22
|
+
|
|
23
|
+
[ ] what is their goal?
|
|
24
|
+
learn a new technology
|
|
25
|
+
solve a specific problem
|
|
26
|
+
build a complete project
|
|
27
|
+
integrate with existing system
|
|
28
|
+
|
|
29
|
+
[ ] what do they already know?
|
|
30
|
+
programming languages
|
|
31
|
+
frameworks or tools
|
|
32
|
+
domain knowledge
|
|
33
|
+
related technologies
|
|
34
|
+
|
|
35
|
+
[ ] what is their learning style?
|
|
36
|
+
hands-on learners prefer code examples
|
|
37
|
+
conceptual learners prefer explanations
|
|
38
|
+
visual learners prefer diagrams
|
|
39
|
+
|
|
40
|
+
[ ] how much time do they have?
|
|
41
|
+
quick tutorial: 15-30 minutes
|
|
42
|
+
medium tutorial: 1-2 hours
|
|
43
|
+
long tutorial: half-day or multiple sessions
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
create audience persona
|
|
47
|
+
|
|
48
|
+
define a specific reader:
|
|
49
|
+
|
|
50
|
+
target audience:
|
|
51
|
+
- role: junior developer
|
|
52
|
+
- experience: 1-2 years
|
|
53
|
+
- knows: python basics, git fundamentals
|
|
54
|
+
- doesn't know: web frameworks, api design
|
|
55
|
+
- goal: build first rest api
|
|
56
|
+
- available time: ~2 hours
|
|
57
|
+
|
|
58
|
+
write for this persona specifically.
|
|
59
|
+
when you try to write for everyone, you write for no one.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
check for existing tutorials
|
|
63
|
+
|
|
64
|
+
<terminal>find docs -name "*tutorial*" -o -name "*guide*" 2>/dev/null</terminal>
|
|
65
|
+
<terminal>find docs -name "*getting*started*" 2>/dev/null</terminal>
|
|
66
|
+
<terminal>ls docs/tutorials/ 2>/dev/null || echo "no tutorials directory"</terminal>
|
|
67
|
+
|
|
68
|
+
read existing tutorials to understand:
|
|
69
|
+
- format and structure in use
|
|
70
|
+
- writing style and tone
|
|
71
|
+
- what topics are covered
|
|
72
|
+
- what's missing
|
|
73
|
+
|
|
74
|
+
fill gaps, don't duplicate.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
check for related documentation
|
|
78
|
+
|
|
79
|
+
<terminal>find docs -name "README*" -o -name "architecture*" -o -name "api*" 2>/dev/null</terminal>
|
|
80
|
+
|
|
81
|
+
link to related docs:
|
|
82
|
+
- API reference
|
|
83
|
+
- architecture documentation
|
|
84
|
+
- conceptual guides
|
|
85
|
+
- troubleshooting guides
|
|
86
|
+
|
|
87
|
+
tutorials should complement, not replace, reference docs.
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
PHASE 1: TUTORIAL OBJECTIVES
|
|
91
|
+
|
|
92
|
+
define clear, measurable learning objectives.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
define the goal
|
|
96
|
+
|
|
97
|
+
what will the reader be able to DO after completing the tutorial?
|
|
98
|
+
|
|
99
|
+
good objectives:
|
|
100
|
+
- build a rest api with user authentication
|
|
101
|
+
- deploy a serverless function to aws
|
|
102
|
+
- create a real-time chat application
|
|
103
|
+
- integrate payment processing
|
|
104
|
+
|
|
105
|
+
bad objectives:
|
|
106
|
+
- learn about frameworks (too vague)
|
|
107
|
+
- understand the system (not actionable)
|
|
108
|
+
- know everything (impossible)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
write SMART objectives
|
|
112
|
+
|
|
113
|
+
[ ] Specific - exact skill to be learned
|
|
114
|
+
[ ] Measurable - can test if achieved
|
|
115
|
+
[ ] Achievable - realistic for the time
|
|
116
|
+
[ ] Relevant - valuable to the reader
|
|
117
|
+
[ ] Time-bound - fits in promised duration
|
|
118
|
+
|
|
119
|
+
example:
|
|
120
|
+
after this tutorial, you will:
|
|
121
|
+
[ ] create a fastapi project from scratch
|
|
122
|
+
[ ] define 5 rest endpoints with proper http methods
|
|
123
|
+
[ ] implement jwt authentication
|
|
124
|
+
[ ] write tests for all endpoints
|
|
125
|
+
[ ] deploy to a cloud platform
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
define prerequisites
|
|
129
|
+
|
|
130
|
+
be explicit about what readers need before starting:
|
|
131
|
+
|
|
132
|
+
prerequisites:
|
|
133
|
+
knowledge:
|
|
134
|
+
[ ] python programming basics
|
|
135
|
+
[ ] understanding of http methods (get, post, put, delete)
|
|
136
|
+
[ ] basic git commands
|
|
137
|
+
|
|
138
|
+
tools:
|
|
139
|
+
[ ] python 3.11 or later installed
|
|
140
|
+
[ ] code editor (vs code, pycharm, etc.)
|
|
141
|
+
[ ] git installed
|
|
142
|
+
[ ] postman or similar api testing tool
|
|
143
|
+
|
|
144
|
+
accounts:
|
|
145
|
+
[ ] github account
|
|
146
|
+
[ ] free tier cloud account
|
|
147
|
+
|
|
148
|
+
setup instructions for prerequisites:
|
|
149
|
+
<terminal>python --version</terminal>
|
|
150
|
+
<terminal>git --version</terminal>
|
|
151
|
+
|
|
152
|
+
if any check fails, provide setup links.
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
define scope
|
|
156
|
+
|
|
157
|
+
what will and won't be covered:
|
|
158
|
+
|
|
159
|
+
in scope:
|
|
160
|
+
- building a rest api with fastapi
|
|
161
|
+
- sqlite database with sqlalchemy
|
|
162
|
+
- jwt authentication
|
|
163
|
+
- docker containerization
|
|
164
|
+
- basic deployment
|
|
165
|
+
|
|
166
|
+
out of scope:
|
|
167
|
+
- production database setup
|
|
168
|
+
- advanced authentication (oauth, 2fa)
|
|
169
|
+
- caching strategies
|
|
170
|
+
- monitoring and logging
|
|
171
|
+
- ci/cd pipelines
|
|
172
|
+
|
|
173
|
+
link to resources for out-of-scope topics.
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
PHASE 2: TUTORIAL STRUCTURE
|
|
177
|
+
|
|
178
|
+
effective tutorials follow a proven structure.
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
the tutorial outline
|
|
182
|
+
|
|
183
|
+
title: [clear, action-oriented]
|
|
184
|
+
subtitle: [what will be built and how long it takes]
|
|
185
|
+
|
|
186
|
+
introduction:
|
|
187
|
+
- what you'll build
|
|
188
|
+
- why it matters
|
|
189
|
+
- who it's for
|
|
190
|
+
- what you'll learn
|
|
191
|
+
- time estimate
|
|
192
|
+
|
|
193
|
+
prerequisites:
|
|
194
|
+
- knowledge needed
|
|
195
|
+
- tools required
|
|
196
|
+
- setup instructions
|
|
197
|
+
|
|
198
|
+
overview:
|
|
199
|
+
- high-level architecture
|
|
200
|
+
- components to be built
|
|
201
|
+
- final result preview
|
|
202
|
+
|
|
203
|
+
steps (progressive):
|
|
204
|
+
1. project setup
|
|
205
|
+
2. basic implementation
|
|
206
|
+
3. core functionality
|
|
207
|
+
4. advanced features
|
|
208
|
+
5. testing
|
|
209
|
+
6. deployment
|
|
210
|
+
|
|
211
|
+
summary:
|
|
212
|
+
- what was accomplished
|
|
213
|
+
- next steps
|
|
214
|
+
- related tutorials
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
introduction section
|
|
218
|
+
|
|
219
|
+
hook the reader immediately:
|
|
220
|
+
|
|
221
|
+
what you'll build
|
|
222
|
+
---------------
|
|
223
|
+
in this tutorial, you'll build a complete rest api for a task
|
|
224
|
+
management application. users will be able to:
|
|
225
|
+
|
|
226
|
+
- create accounts and authenticate
|
|
227
|
+
- create, read, update, and delete tasks
|
|
228
|
+
- organize tasks by project
|
|
229
|
+
- set due dates and priorities
|
|
230
|
+
|
|
231
|
+
by the end, you'll have a production-ready api deployed to the cloud.
|
|
232
|
+
|
|
233
|
+
why this matters
|
|
234
|
+
---------------
|
|
235
|
+
building apis is a fundamental skill for backend development.
|
|
236
|
+
the patterns you'll learn here apply to any api project:
|
|
237
|
+
|
|
238
|
+
- proper endpoint design
|
|
239
|
+
- authentication and authorization
|
|
240
|
+
- data validation
|
|
241
|
+
- error handling
|
|
242
|
+
- testing and deployment
|
|
243
|
+
|
|
244
|
+
who this is for
|
|
245
|
+
--------------
|
|
246
|
+
this tutorial is for developers who:
|
|
247
|
+
|
|
248
|
+
- know python basics
|
|
249
|
+
- want to learn backend development
|
|
250
|
+
- need to build apis for their projects
|
|
251
|
+
- have 2-3 hours to complete it
|
|
252
|
+
|
|
253
|
+
what you'll learn
|
|
254
|
+
-----------------
|
|
255
|
+
- fastapi framework fundamentals
|
|
256
|
+
- database modeling with sqlalchemy
|
|
257
|
+
- jwt authentication implementation
|
|
258
|
+
- input validation and error handling
|
|
259
|
+
- unit and integration testing
|
|
260
|
+
- containerization with docker
|
|
261
|
+
- cloud deployment basics
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
PHASE 3: THE FIRST STEP
|
|
265
|
+
|
|
266
|
+
the first step determines if readers continue.
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
project setup
|
|
270
|
+
|
|
271
|
+
make setup foolproof with verification:
|
|
272
|
+
|
|
273
|
+
step 1: create the project
|
|
274
|
+
---------------------------
|
|
275
|
+
|
|
276
|
+
create a new directory for your project:
|
|
277
|
+
|
|
278
|
+
<terminal>mkdir task-api</terminal>
|
|
279
|
+
<terminal>cd task-api</terminal>
|
|
280
|
+
|
|
281
|
+
create a virtual environment:
|
|
282
|
+
|
|
283
|
+
<terminal>python -m venv venv</terminal>
|
|
284
|
+
|
|
285
|
+
activate it:
|
|
286
|
+
|
|
287
|
+
on mac/linux:
|
|
288
|
+
<terminal>source venv/bin/activate</terminal>
|
|
289
|
+
|
|
290
|
+
on windows:
|
|
291
|
+
<terminal>venv\Scripts\activate</terminal>
|
|
292
|
+
|
|
293
|
+
verify activation:
|
|
294
|
+
<terminal>which python</terminal>
|
|
295
|
+
|
|
296
|
+
you should see the path to your venv python, not the system python.
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
install dependencies
|
|
300
|
+
|
|
301
|
+
create a requirements.txt file:
|
|
302
|
+
|
|
303
|
+
<create>
|
|
304
|
+
<file>requirements.txt</file>
|
|
305
|
+
<content>
|
|
306
|
+
fastapi==0.109.0
|
|
307
|
+
uvicorn[standard]==0.27.0
|
|
308
|
+
sqlalchemy==2.0.25
|
|
309
|
+
pydantic==2.5.3
|
|
310
|
+
pydantic-settings==2.1.0
|
|
311
|
+
python-jose[cryptography]==3.3.0
|
|
312
|
+
passlib[bcrypt]==1.7.4
|
|
313
|
+
python-multipart==0.0.6
|
|
314
|
+
pytest==7.4.4
|
|
315
|
+
httpx==0.26.0
|
|
316
|
+
</content>
|
|
317
|
+
</create>
|
|
318
|
+
|
|
319
|
+
install dependencies:
|
|
320
|
+
|
|
321
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
322
|
+
|
|
323
|
+
verify installation:
|
|
324
|
+
|
|
325
|
+
<terminal>pip list | grep fastapi</terminal>
|
|
326
|
+
<terminal>pip list | grep uvicorn</terminal>
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
create project structure
|
|
330
|
+
|
|
331
|
+
<terminal>mkdir -p app/{api,core,models,schemas,services}</terminal>
|
|
332
|
+
<terminal>mkdir -p tests</terminal>
|
|
333
|
+
|
|
334
|
+
your directory should now look like:
|
|
335
|
+
|
|
336
|
+
task-api/
|
|
337
|
+
├── app/
|
|
338
|
+
│ ├── api/ # api endpoints
|
|
339
|
+
│ ├── core/ # configuration
|
|
340
|
+
│ ├── models/ # database models
|
|
341
|
+
│ ├── schemas/ # pydantic schemas
|
|
342
|
+
│ └── services/ # business logic
|
|
343
|
+
├── tests/ # tests
|
|
344
|
+
└── requirements.txt
|
|
345
|
+
|
|
346
|
+
verify structure:
|
|
347
|
+
|
|
348
|
+
<terminal>ls -r app/</terminal>
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
create a hello world
|
|
352
|
+
|
|
353
|
+
start with something that works:
|
|
354
|
+
|
|
355
|
+
create the main application file:
|
|
356
|
+
|
|
357
|
+
<create>
|
|
358
|
+
<file>app/main.py</file>
|
|
359
|
+
<content>
|
|
360
|
+
from fastapi import fastapi
|
|
361
|
+
|
|
362
|
+
app = fastapi(title="task api")
|
|
363
|
+
|
|
364
|
+
@app.get("/")
|
|
365
|
+
def read_root():
|
|
366
|
+
return {"message": "welcome to task api"}
|
|
367
|
+
</content>
|
|
368
|
+
</create>
|
|
369
|
+
|
|
370
|
+
run the application:
|
|
371
|
+
|
|
372
|
+
<terminal>uvicorn app.main:app --reload</terminal>
|
|
373
|
+
|
|
374
|
+
you should see:
|
|
375
|
+
|
|
376
|
+
info: started server process
|
|
377
|
+
info: waiting for application startup.
|
|
378
|
+
info: application startup complete.
|
|
379
|
+
info: uvicorn running on http://127.0.0.1:8000
|
|
380
|
+
|
|
381
|
+
open http://127.0.0.1:8000 in your browser.
|
|
382
|
+
|
|
383
|
+
you should see:
|
|
384
|
+
{"message": "welcome to task api"}
|
|
385
|
+
|
|
386
|
+
[ok] if you see this message, you're ready to continue!
|
|
387
|
+
[x] if you see an error, check the troubleshooting section below.
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
verify each step
|
|
391
|
+
|
|
392
|
+
after every step, provide a verification:
|
|
393
|
+
|
|
394
|
+
verification:
|
|
395
|
+
<terminal>curl http://127.0.0.1:8000/</terminal>
|
|
396
|
+
|
|
397
|
+
expected output:
|
|
398
|
+
{"message":"welcome to task api"}
|
|
399
|
+
|
|
400
|
+
[ ] if this works, continue to the next step
|
|
401
|
+
[ ] if not, see troubleshooting below
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
troubleshooting for step 1
|
|
405
|
+
|
|
406
|
+
problem: "module not found" error
|
|
407
|
+
solution: make sure virtual environment is activated
|
|
408
|
+
<terminal>source venv/bin/activate</terminal>
|
|
409
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
410
|
+
|
|
411
|
+
problem: port 8000 already in use
|
|
412
|
+
solution: use a different port
|
|
413
|
+
<terminal>uvicorn app.main:app --reload --port 8001</terminal>
|
|
414
|
+
|
|
415
|
+
problem: command not found: uvicorn
|
|
416
|
+
solution: install uvicorn
|
|
417
|
+
<terminal>pip install uvicorn[standard]</terminal>
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
PHASE 4: BUILDING PROGRESSIVELY
|
|
421
|
+
|
|
422
|
+
each step builds on the previous.
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
complexity progression
|
|
426
|
+
|
|
427
|
+
step 1: hello world (5 min)
|
|
428
|
+
- verify setup works
|
|
429
|
+
|
|
430
|
+
step 2: single endpoint (10 min)
|
|
431
|
+
- create one read endpoint
|
|
432
|
+
- understand the request/response cycle
|
|
433
|
+
|
|
434
|
+
step 3: full crud (20 min)
|
|
435
|
+
- create, read, update, delete operations
|
|
436
|
+
- understand http methods
|
|
437
|
+
|
|
438
|
+
step 4: database integration (20 min)
|
|
439
|
+
- connect to database
|
|
440
|
+
- persist data
|
|
441
|
+
|
|
442
|
+
step 5: data models (15 min)
|
|
443
|
+
- define proper schema
|
|
444
|
+
- add relationships
|
|
445
|
+
|
|
446
|
+
step 6: validation (15 min)
|
|
447
|
+
- input validation
|
|
448
|
+
- error handling
|
|
449
|
+
|
|
450
|
+
step 7: authentication (20 min)
|
|
451
|
+
- user registration
|
|
452
|
+
- login and tokens
|
|
453
|
+
|
|
454
|
+
step 8: authorization (10 min)
|
|
455
|
+
- protect endpoints
|
|
456
|
+
- user-specific data
|
|
457
|
+
|
|
458
|
+
step 9: testing (20 min)
|
|
459
|
+
- unit tests
|
|
460
|
+
- integration tests
|
|
461
|
+
|
|
462
|
+
step 10: deployment (15 min)
|
|
463
|
+
- containerize
|
|
464
|
+
- deploy to cloud
|
|
465
|
+
|
|
466
|
+
total: ~2.5 hours
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
building - each endpoint
|
|
470
|
+
|
|
471
|
+
when teaching a new concept:
|
|
472
|
+
|
|
473
|
+
[1] explain what we're building
|
|
474
|
+
[2] show the code
|
|
475
|
+
[3] explain how it works
|
|
476
|
+
[4] run and verify
|
|
477
|
+
[5] explain what could go wrong
|
|
478
|
+
|
|
479
|
+
example - adding a create endpoint:
|
|
480
|
+
|
|
481
|
+
step 4: create tasks
|
|
482
|
+
-------------------
|
|
483
|
+
|
|
484
|
+
we need an endpoint to create tasks. let's add it.
|
|
485
|
+
|
|
486
|
+
add the pydantic schema for task creation:
|
|
487
|
+
|
|
488
|
+
<edit>
|
|
489
|
+
<file>app/schemas/tasks.py</file>
|
|
490
|
+
<find>from pydantic import basemodel</find>
|
|
491
|
+
<replace>
|
|
492
|
+
from pydantic import basemodel, fieldvalidator
|
|
493
|
+
from datetime import datetime
|
|
494
|
+
from enum import enum
|
|
495
|
+
|
|
496
|
+
class priority(str, enum):
|
|
497
|
+
low = "low"
|
|
498
|
+
medium = "medium"
|
|
499
|
+
high = "high"
|
|
500
|
+
|
|
501
|
+
class taskcreate(basemodel):
|
|
502
|
+
title: str
|
|
503
|
+
description: str | none = none
|
|
504
|
+
priority: priority = priority.medium
|
|
505
|
+
due_date: datetime | none = none
|
|
506
|
+
|
|
507
|
+
@fieldvalidator("title")
|
|
508
|
+
@classmethod
|
|
509
|
+
def title_not_empty(cls, v):
|
|
510
|
+
if not v or not v.strip():
|
|
511
|
+
raise valueerror("title cannot be empty")
|
|
512
|
+
return v.strip()
|
|
513
|
+
</replace>
|
|
514
|
+
</edit>
|
|
515
|
+
|
|
516
|
+
add the endpoint:
|
|
517
|
+
|
|
518
|
+
<edit>
|
|
519
|
+
<file>app/api/tasks.py</file>
|
|
520
|
+
<find>@app.get("/tasks")</find>
|
|
521
|
+
<replace>
|
|
522
|
+
@app.post("/tasks", status_code=201)
|
|
523
|
+
def create_task(task: taskcreate):
|
|
524
|
+
"""create a new task."""
|
|
525
|
+
new_task = {
|
|
526
|
+
"id": len(tasks) + 1,
|
|
527
|
+
**task.model_dump(),
|
|
528
|
+
"created_at": datetime.now(),
|
|
529
|
+
"completed": false
|
|
530
|
+
}
|
|
531
|
+
tasks.append(new_task)
|
|
532
|
+
return new_task
|
|
533
|
+
|
|
534
|
+
@app.get("/tasks")</replace>
|
|
535
|
+
</edit>
|
|
536
|
+
|
|
537
|
+
how it works:
|
|
538
|
+
- the @post decorator defines a post endpoint
|
|
539
|
+
- status_code=201 returns "created" status
|
|
540
|
+
- fastapi validates the request against taskcreate schema
|
|
541
|
+
- invalid requests return 422 with validation errors
|
|
542
|
+
- we return the created task with its new id
|
|
543
|
+
|
|
544
|
+
test it:
|
|
545
|
+
|
|
546
|
+
<terminal>curl -x post http://127.0.0.1:8000/tasks \
|
|
547
|
+
-h "content-type: application/json" \
|
|
548
|
+
-d '{"title": "write documentation", "priority": "high"}'</terminal>
|
|
549
|
+
|
|
550
|
+
response:
|
|
551
|
+
{
|
|
552
|
+
"id": 1,
|
|
553
|
+
"title": "write documentation",
|
|
554
|
+
"description": null,
|
|
555
|
+
"priority": "high",
|
|
556
|
+
"due_date": null,
|
|
557
|
+
"created_at": "2024-01-25t10:30:00",
|
|
558
|
+
"completed": false
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
[ok] if you see the created task, continue!
|
|
562
|
+
[x] if you see an error, check below.
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
error responses
|
|
566
|
+
|
|
567
|
+
show what happens with invalid input:
|
|
568
|
+
|
|
569
|
+
test validation:
|
|
570
|
+
<terminal>curl -x post http://127.0.0.1:8000/tasks \
|
|
571
|
+
-h "content-type: application/json" \
|
|
572
|
+
-d '{"title": ""}'</terminal>
|
|
573
|
+
|
|
574
|
+
response:
|
|
575
|
+
{
|
|
576
|
+
"detail": [
|
|
577
|
+
{
|
|
578
|
+
"loc": ["body", "title"],
|
|
579
|
+
"msg": "title cannot be empty",
|
|
580
|
+
"type": "value_error"
|
|
581
|
+
}
|
|
582
|
+
]
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
the validation automatically protects your endpoint from bad data.
|
|
586
|
+
this is one of fastapi's superpowers.
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
PHASE 5: CHECKPOINTS AND VERIFICATION
|
|
590
|
+
|
|
591
|
+
readers need to verify progress.
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
checkpoint structure
|
|
595
|
+
|
|
596
|
+
after each major section, add a checkpoint:
|
|
597
|
+
|
|
598
|
+
checkpoint: basic api working
|
|
599
|
+
----------------------------
|
|
600
|
+
|
|
601
|
+
at this point, you should have:
|
|
602
|
+
[ ] a running fastapi server
|
|
603
|
+
[ ] a working /tasks endpoint (get)
|
|
604
|
+
[ ] a working /tasks endpoint (post)
|
|
605
|
+
[ ] data validation on create
|
|
606
|
+
|
|
607
|
+
verify everything works:
|
|
608
|
+
|
|
609
|
+
<terminal>curl http://127.0.0.1:8000/tasks</terminal>
|
|
610
|
+
|
|
611
|
+
<terminal>curl -x post http://127.0.0.1:8000/tasks \
|
|
612
|
+
-h "content-type: application/json" \
|
|
613
|
+
-d '{"title": "test task"}'</terminal>
|
|
614
|
+
|
|
615
|
+
expected results:
|
|
616
|
+
- first call returns the list of tasks
|
|
617
|
+
- second call returns the new task
|
|
618
|
+
|
|
619
|
+
[ ] if both work, continue to the next section
|
|
620
|
+
[ ] if not, review the previous steps
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
save your progress
|
|
624
|
+
|
|
625
|
+
encourage readers to commit after each checkpoint:
|
|
626
|
+
|
|
627
|
+
git checkpoint:
|
|
628
|
+
|
|
629
|
+
<terminal>git add .</terminal>
|
|
630
|
+
<terminal>git commit -m "add basic task endpoints"</terminal>
|
|
631
|
+
|
|
632
|
+
this creates a recovery point.
|
|
633
|
+
if something breaks later, you can always return.
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
PHASE 6: EXPLAINING CONCEPTS
|
|
637
|
+
|
|
638
|
+
balance theory and practice.
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
the concept sandwich
|
|
642
|
+
|
|
643
|
+
[1] show what we're building (motivation)
|
|
644
|
+
[2] explain the concept briefly (theory)
|
|
645
|
+
[3] show the code (practice)
|
|
646
|
+
[4] explain how the code implements the concept
|
|
647
|
+
[5] show it working (verification)
|
|
648
|
+
|
|
649
|
+
example - explaining authentication:
|
|
650
|
+
|
|
651
|
+
why authentication matters:
|
|
652
|
+
---------------
|
|
653
|
+
right now, anyone can create, read, or delete tasks.
|
|
654
|
+
we need to know who is making requests so:
|
|
655
|
+
- users only see their own tasks
|
|
656
|
+
- users can't delete other users' tasks
|
|
657
|
+
- we can track who created what
|
|
658
|
+
|
|
659
|
+
how jwt authentication works:
|
|
660
|
+
---------------
|
|
661
|
+
jwt (json web token) authentication works like this:
|
|
662
|
+
|
|
663
|
+
1. user sends credentials (email/password)
|
|
664
|
+
2. server verifies credentials
|
|
665
|
+
3. server creates a token with user info
|
|
666
|
+
4. server signs the token with a secret key
|
|
667
|
+
5. server sends token back to user
|
|
668
|
+
6. user includes token in subsequent requests
|
|
669
|
+
7. server verifies token signature
|
|
670
|
+
8. server extracts user info from token
|
|
671
|
+
|
|
672
|
+
the token is stateless - the server doesn't need to store sessions.
|
|
673
|
+
it just verifies the signature is valid.
|
|
674
|
+
|
|
675
|
+
implementing authentication:
|
|
676
|
+
---------------
|
|
677
|
+
[code implementation...]
|
|
678
|
+
|
|
679
|
+
testing authentication:
|
|
680
|
+
---------------
|
|
681
|
+
[verification steps...]
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
concept depth guidelines
|
|
685
|
+
|
|
686
|
+
how much to explain?
|
|
687
|
+
|
|
688
|
+
for beginners:
|
|
689
|
+
- explain the concept fully
|
|
690
|
+
- use analogies
|
|
691
|
+
- show diagrams
|
|
692
|
+
- explain every line of code
|
|
693
|
+
|
|
694
|
+
for intermediate:
|
|
695
|
+
- explain the key concepts
|
|
696
|
+
- focus on why, not just what
|
|
697
|
+
- explain non-obvious code
|
|
698
|
+
- link to deeper resources
|
|
699
|
+
|
|
700
|
+
for advanced:
|
|
701
|
+
- brief concept overview
|
|
702
|
+
- focus on implementation details
|
|
703
|
+
- discuss trade-offs
|
|
704
|
+
- show alternatives
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
diagrams and visuals
|
|
708
|
+
|
|
709
|
+
create ascii diagrams for clarity:
|
|
710
|
+
|
|
711
|
+
request flow:
|
|
712
|
+
-------------
|
|
713
|
+
client --> nginx --> fastapi --> database
|
|
714
|
+
| | | |
|
|
715
|
+
| | | +---> postgresql
|
|
716
|
+
| | |
|
|
717
|
+
| | +---> business logic
|
|
718
|
+
| | |
|
|
719
|
+
| | +---> validation
|
|
720
|
+
| | +---> authorization
|
|
721
|
+
| |
|
|
722
|
+
| +---> ssl termination
|
|
723
|
+
|
|
|
724
|
+
+---> browser/postman
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
authentication flow:
|
|
728
|
+
-------------------
|
|
729
|
+
|
|
730
|
+
login:
|
|
731
|
+
user api database
|
|
732
|
+
| | |
|
|
733
|
+
|--creds----------->| |
|
|
734
|
+
| |--verify----------->|
|
|
735
|
+
| |<------found--------|
|
|
736
|
+
| | |
|
|
737
|
+
|<---token----------| |
|
|
738
|
+
| | |
|
|
739
|
+
|
|
740
|
+
authenticated request:
|
|
741
|
+
user api
|
|
742
|
+
| |
|
|
743
|
+
|--request+token--->|
|
|
744
|
+
| |--verify signature
|
|
745
|
+
| |--extract user id
|
|
746
|
+
|<---response-------|
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
PHASE 7: CODE QUALITY IN TUTORIALS
|
|
750
|
+
|
|
751
|
+
tutorial code should be production-quality.
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
best practices in examples
|
|
755
|
+
|
|
756
|
+
[ ] type hints
|
|
757
|
+
def create_user(user: usercreate) -> user:
|
|
758
|
+
...
|
|
759
|
+
|
|
760
|
+
[ ] validation
|
|
761
|
+
use pydantic for input validation
|
|
762
|
+
never trust user input
|
|
763
|
+
|
|
764
|
+
[ ] error handling
|
|
765
|
+
return proper error codes
|
|
766
|
+
include helpful error messages
|
|
767
|
+
|
|
768
|
+
[ ] security
|
|
769
|
+
hash passwords
|
|
770
|
+
validate input
|
|
771
|
+
use environment variables for secrets
|
|
772
|
+
|
|
773
|
+
[ ] testing
|
|
774
|
+
show how to test what you build
|
|
775
|
+
include test examples
|
|
776
|
+
|
|
777
|
+
[ ] documentation
|
|
778
|
+
docstrings for functions
|
|
779
|
+
comments for complex logic
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
what to skip in tutorials
|
|
783
|
+
|
|
784
|
+
for brevity, you can skip:
|
|
785
|
+
|
|
786
|
+
[ ] extensive logging
|
|
787
|
+
mention it exists, don't show every log line
|
|
788
|
+
|
|
789
|
+
[ ] comprehensive error handling
|
|
790
|
+
show the pattern, don't handle every edge case
|
|
791
|
+
|
|
792
|
+
[ ] full test coverage
|
|
793
|
+
show test examples, don't test every case
|
|
794
|
+
|
|
795
|
+
[ ] production configuration
|
|
796
|
+
show development config, mention production needs
|
|
797
|
+
|
|
798
|
+
add a note when skipping:
|
|
799
|
+
|
|
800
|
+
note: in production, you would also want:
|
|
801
|
+
- structured logging
|
|
802
|
+
- more comprehensive error handling
|
|
803
|
+
- additional monitoring
|
|
804
|
+
- rate limiting
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
PHASE 8: TESTING SECTION
|
|
808
|
+
|
|
809
|
+
teach readers to test their work.
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
unit testing
|
|
813
|
+
|
|
814
|
+
show how to test individual components:
|
|
815
|
+
|
|
816
|
+
step 9: testing
|
|
817
|
+
--------------
|
|
818
|
+
|
|
819
|
+
first, install test dependencies:
|
|
820
|
+
|
|
821
|
+
<terminal>pip install pytest pytest-cov httpx</terminal>
|
|
822
|
+
|
|
823
|
+
create a test file:
|
|
824
|
+
|
|
825
|
+
<create>
|
|
826
|
+
<file>tests/test_tasks.py</file>
|
|
827
|
+
<content>
|
|
828
|
+
import pytest
|
|
829
|
+
from fastapi.testclient import testclient
|
|
830
|
+
from app.main import app
|
|
831
|
+
|
|
832
|
+
client = testclient(app)
|
|
833
|
+
|
|
834
|
+
def test_create_task():
|
|
835
|
+
"""test creating a new task."""
|
|
836
|
+
response = client.post(
|
|
837
|
+
"/tasks",
|
|
838
|
+
json={
|
|
839
|
+
"title": "test task",
|
|
840
|
+
"priority": "high"
|
|
841
|
+
}
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
assert response.status_code == 201
|
|
845
|
+
data = response.json()
|
|
846
|
+
assert data["title"] == "test task"
|
|
847
|
+
assert data["priority"] == "high"
|
|
848
|
+
assert "id" in data
|
|
849
|
+
|
|
850
|
+
def test_create_task_with_empty_title():
|
|
851
|
+
"""test that empty title is rejected."""
|
|
852
|
+
response = client.post(
|
|
853
|
+
"/tasks",
|
|
854
|
+
json={"title": ""}
|
|
855
|
+
)
|
|
856
|
+
|
|
857
|
+
assert response.status_code == 422
|
|
858
|
+
assert "title" in response.json()["detail"][0]["loc"]
|
|
859
|
+
|
|
860
|
+
def test_get_tasks():
|
|
861
|
+
"""test retrieving the task list."""
|
|
862
|
+
# first create a task
|
|
863
|
+
client.post("/tasks", json={"title": "test task"})
|
|
864
|
+
|
|
865
|
+
# then get all tasks
|
|
866
|
+
response = client.get("/tasks")
|
|
867
|
+
|
|
868
|
+
assert response.status_code == 200
|
|
869
|
+
data = response.json()
|
|
870
|
+
assert len(data) > 0
|
|
871
|
+
</content>
|
|
872
|
+
</create>
|
|
873
|
+
|
|
874
|
+
run the tests:
|
|
875
|
+
|
|
876
|
+
<terminal>pytest tests/test_tasks.py -v</terminal>
|
|
877
|
+
|
|
878
|
+
expected output:
|
|
879
|
+
tests/test_tasks.py::test_create_task passed
|
|
880
|
+
tests/test_tasks.py::test_create_task_with_empty_title passed
|
|
881
|
+
tests/test_tasks.py::test_get_tasks passed
|
|
882
|
+
|
|
883
|
+
[ok] if all tests pass, your api is working correctly!
|
|
884
|
+
[x] if any test fails, review the error and fix your code
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
integration testing
|
|
888
|
+
|
|
889
|
+
show how to test the full flow:
|
|
890
|
+
|
|
891
|
+
<create>
|
|
892
|
+
<file>tests/test_integration.py</file>
|
|
893
|
+
<content>
|
|
894
|
+
import pytest
|
|
895
|
+
from fastapi.testclient import testclient
|
|
896
|
+
from app.main import app
|
|
897
|
+
|
|
898
|
+
client = testclient(app)
|
|
899
|
+
|
|
900
|
+
def test_full_task_workflow():
|
|
901
|
+
"""test complete create-read-update-delete workflow."""
|
|
902
|
+
# create
|
|
903
|
+
response = client.post(
|
|
904
|
+
"/tasks",
|
|
905
|
+
json={"title": "integration test task"}
|
|
906
|
+
)
|
|
907
|
+
assert response.status_code == 201
|
|
908
|
+
task_id = response.json()["id"]
|
|
909
|
+
|
|
910
|
+
# read
|
|
911
|
+
response = client.get(f"/tasks/{task_id}")
|
|
912
|
+
assert response.status_code == 200
|
|
913
|
+
assert response.json()["title"] == "integration test task"
|
|
914
|
+
|
|
915
|
+
# update
|
|
916
|
+
response = client.put(
|
|
917
|
+
f"/tasks/{task_id}",
|
|
918
|
+
json={"title": "updated task", "completed": true}
|
|
919
|
+
)
|
|
920
|
+
assert response.status_code == 200
|
|
921
|
+
assert response.json()["completed"] is true
|
|
922
|
+
|
|
923
|
+
# delete
|
|
924
|
+
response = client.delete(f"/tasks/{task_id}")
|
|
925
|
+
assert response.status_code == 200
|
|
926
|
+
|
|
927
|
+
# verify deleted
|
|
928
|
+
response = client.get(f"/tasks/{task_id}")
|
|
929
|
+
assert response.status_code == 404
|
|
930
|
+
</content>
|
|
931
|
+
</create>
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
PHASE 9: DEPLOYMENT
|
|
935
|
+
|
|
936
|
+
help readers get their work into the world.
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
deployment checklist
|
|
940
|
+
|
|
941
|
+
[ ] containerize the application
|
|
942
|
+
[ ] configure environment variables
|
|
943
|
+
[ ] set up database
|
|
944
|
+
[ ] deploy to platform
|
|
945
|
+
[ ] verify deployment
|
|
946
|
+
[ ] set up monitoring
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
docker deployment
|
|
950
|
+
|
|
951
|
+
step 10: deploy
|
|
952
|
+
--------------
|
|
953
|
+
|
|
954
|
+
create a dockerfile:
|
|
955
|
+
|
|
956
|
+
<create>
|
|
957
|
+
<file>dockerfile</file>
|
|
958
|
+
<content>
|
|
959
|
+
from python:3.11-slim
|
|
960
|
+
|
|
961
|
+
workdir /app
|
|
962
|
+
|
|
963
|
+
copy requirements.txt .
|
|
964
|
+
run pip install --no-cache-dir -r requirements.txt
|
|
965
|
+
|
|
966
|
+
copy . .
|
|
967
|
+
|
|
968
|
+
expose 8000
|
|
969
|
+
|
|
970
|
+
cmd ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
971
|
+
</content>
|
|
972
|
+
</create>
|
|
973
|
+
|
|
974
|
+
build the image:
|
|
975
|
+
|
|
976
|
+
<terminal>docker build -t task-api .</terminal>
|
|
977
|
+
|
|
978
|
+
run the container:
|
|
979
|
+
|
|
980
|
+
<terminal>docker run -p 8000:8000 task-api</terminal>
|
|
981
|
+
|
|
982
|
+
verify it's running:
|
|
983
|
+
|
|
984
|
+
<terminal>curl http://127.0.0.1:8000/</terminal>
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
cloud deployment
|
|
988
|
+
|
|
989
|
+
provide at least one cloud deployment option:
|
|
990
|
+
|
|
991
|
+
deploy to railway (simple):
|
|
992
|
+
|
|
993
|
+
<terminal>npm install -g railway</terminal>
|
|
994
|
+
<terminal>railway login</terminal>
|
|
995
|
+
<terminal>railway init</terminal>
|
|
996
|
+
<terminal>railway up</terminal>
|
|
997
|
+
|
|
998
|
+
or deploy to render:
|
|
999
|
+
|
|
1000
|
+
1. create a render.com account
|
|
1001
|
+
2. create new web service
|
|
1002
|
+
3. connect your github repository
|
|
1003
|
+
4. render auto-deploys on push
|
|
1004
|
+
|
|
1005
|
+
add a render.yaml to your repo:
|
|
1006
|
+
|
|
1007
|
+
<create>
|
|
1008
|
+
<file>render.yaml</file>
|
|
1009
|
+
<content>
|
|
1010
|
+
services:
|
|
1011
|
+
- type: web
|
|
1012
|
+
name: task-api
|
|
1013
|
+
runtime: docker
|
|
1014
|
+
plan: free
|
|
1015
|
+
envvars:
|
|
1016
|
+
- key: database_url
|
|
1017
|
+
fromdatabase:
|
|
1018
|
+
name: task-db
|
|
1019
|
+
property: connectionstring
|
|
1020
|
+
databases:
|
|
1021
|
+
- name: task-db
|
|
1022
|
+
databaseName: taskdb
|
|
1023
|
+
user: taskuser
|
|
1024
|
+
</content>
|
|
1025
|
+
</create>
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
PHASE 10: COMMON PITFALLS
|
|
1029
|
+
|
|
1030
|
+
help readers avoid mistakes.
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
pitfall warnings
|
|
1034
|
+
|
|
1035
|
+
add warning boxes for common mistakes:
|
|
1036
|
+
|
|
1037
|
+
warning: don't commit secrets
|
|
1038
|
+
--------------------------
|
|
1039
|
+
never commit api keys, passwords, or tokens to git.
|
|
1040
|
+
|
|
1041
|
+
instead, use environment variables:
|
|
1042
|
+
|
|
1043
|
+
<create>
|
|
1044
|
+
<file>.env</file>
|
|
1045
|
+
<content>
|
|
1046
|
+
database_url=postgresql://user:pass@localhost/dbname
|
|
1047
|
+
secret_key=your-secret-key-here
|
|
1048
|
+
</content>
|
|
1049
|
+
</create>
|
|
1050
|
+
|
|
1051
|
+
and add .env to .gitignore:
|
|
1052
|
+
|
|
1053
|
+
<terminal>echo ".env" >> .gitignore</terminal>
|
|
1054
|
+
|
|
1055
|
+
warning: default secret keys
|
|
1056
|
+
--------------------------
|
|
1057
|
+
never use default secret keys in production.
|
|
1058
|
+
|
|
1059
|
+
generate a secure key:
|
|
1060
|
+
|
|
1061
|
+
<terminal>python -c "import secrets; print(secrets.token_urlsafe(32))"</terminal>
|
|
1062
|
+
|
|
1063
|
+
warning: sqlite in production
|
|
1064
|
+
---------------------------
|
|
1065
|
+
sqlite is fine for development but not for production.
|
|
1066
|
+
use postgresql or mysql for production deployments.
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
PHASE 11: TROUBLESHOOTING
|
|
1070
|
+
|
|
1071
|
+
help readers when things go wrong.
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
common issues
|
|
1075
|
+
|
|
1076
|
+
common issues:
|
|
1077
|
+
-------------
|
|
1078
|
+
|
|
1079
|
+
issue: "address already in use" error
|
|
1080
|
+
solution: another process is using port 8000
|
|
1081
|
+
<terminal>lsof -i :8000</terminal>
|
|
1082
|
+
<terminal>kill -9 <pid></terminal>
|
|
1083
|
+
|
|
1084
|
+
issue: "module not found: fastapi"
|
|
1085
|
+
solution: make sure virtual environment is activated
|
|
1086
|
+
<terminal>source venv/bin/activate</terminal>
|
|
1087
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
1088
|
+
|
|
1089
|
+
issue: tests pass but curl fails
|
|
1090
|
+
solution: make sure the server is running
|
|
1091
|
+
<terminal>uvicorn app.main:app --reload</terminal>
|
|
1092
|
+
|
|
1093
|
+
issue: database errors after restart
|
|
1094
|
+
solution: make sure database migration ran
|
|
1095
|
+
<terminal>alembic upgrade head</terminal>
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
debug mode section
|
|
1099
|
+
|
|
1100
|
+
show how to enable debug output:
|
|
1101
|
+
|
|
1102
|
+
enable debug logging:
|
|
1103
|
+
|
|
1104
|
+
<edit>
|
|
1105
|
+
<file>app/main.py</file>
|
|
1106
|
+
<find>import logging</find>
|
|
1107
|
+
<replace>
|
|
1108
|
+
import logging
|
|
1109
|
+
|
|
1110
|
+
logging.basicConfig(level=logging.debug)
|
|
1111
|
+
logger = logging.getlogger(__name__)
|
|
1112
|
+
</replace>
|
|
1113
|
+
</edit>
|
|
1114
|
+
|
|
1115
|
+
add debug endpoints:
|
|
1116
|
+
|
|
1117
|
+
@app.get("/debug/health")
|
|
1118
|
+
def health_check():
|
|
1119
|
+
return {
|
|
1120
|
+
"status": "healthy",
|
|
1121
|
+
"database": db_connected(),
|
|
1122
|
+
"redis": cache_connected()
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
PHASE 12: NEXT STEPS
|
|
1127
|
+
|
|
1128
|
+
keep readers learning after the tutorial.
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
continue learning
|
|
1132
|
+
|
|
1133
|
+
suggest what to learn next:
|
|
1134
|
+
|
|
1135
|
+
next steps:
|
|
1136
|
+
----------
|
|
1137
|
+
|
|
1138
|
+
[ ] add more features
|
|
1139
|
+
- task comments
|
|
1140
|
+
- file attachments
|
|
1141
|
+
- task assignments
|
|
1142
|
+
- notifications
|
|
1143
|
+
|
|
1144
|
+
[ ] improve the api
|
|
1145
|
+
- pagination for large datasets
|
|
1146
|
+
- filtering and sorting
|
|
1147
|
+
- full-text search
|
|
1148
|
+
- rate limiting
|
|
1149
|
+
|
|
1150
|
+
[ ] harden the application
|
|
1151
|
+
- add comprehensive logging
|
|
1152
|
+
- implement caching with redis
|
|
1153
|
+
- set up monitoring
|
|
1154
|
+
- add ci/cd pipeline
|
|
1155
|
+
|
|
1156
|
+
[ ] related tutorials
|
|
1157
|
+
- building a frontend for your api
|
|
1158
|
+
- advanced authentication with oauth
|
|
1159
|
+
- websocket real-time updates
|
|
1160
|
+
- microservices architecture
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
resources
|
|
1164
|
+
|
|
1165
|
+
link to further learning:
|
|
1166
|
+
|
|
1167
|
+
official documentation:
|
|
1168
|
+
- fastapi docs: https://fastapi.tiangolo.com
|
|
1169
|
+
- sqlalchemy docs: https://docs.sqlalchemy.org
|
|
1170
|
+
- pytest docs: https://docs.pytest.org
|
|
1171
|
+
|
|
1172
|
+
related tutorials:
|
|
1173
|
+
- building a graphql api with fastapi
|
|
1174
|
+
- docker and docker compose deep dive
|
|
1175
|
+
- testing strategies for python apis
|
|
1176
|
+
|
|
1177
|
+
community:
|
|
1178
|
+
- fastapi discord server
|
|
1179
|
+
- r/fastapi on reddit
|
|
1180
|
+
- stack overflow tag: fastapi
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
PHASE 13: TUTORIAL QUALITY CHECKLIST
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
before publishing, verify:
|
|
1187
|
+
|
|
1188
|
+
content:
|
|
1189
|
+
[ ] title is clear and action-oriented
|
|
1190
|
+
[ ] introduction explains value
|
|
1191
|
+
[ ] prerequisites are explicit
|
|
1192
|
+
[ ] objectives are measurable
|
|
1193
|
+
[ ] scope is well-defined
|
|
1194
|
+
|
|
1195
|
+
code:
|
|
1196
|
+
[ ] all code examples are tested
|
|
1197
|
+
[ ] code follows best practices
|
|
1198
|
+
[ ] code is properly formatted
|
|
1199
|
+
[ ] file paths are clear
|
|
1200
|
+
[ ] copy-paste works
|
|
1201
|
+
|
|
1202
|
+
structure:
|
|
1203
|
+
[ ] logical flow from start to finish
|
|
1204
|
+
[ ] each step builds on previous
|
|
1205
|
+
[ ] checkpoints to verify progress
|
|
1206
|
+
[ ] troubleshooting for common issues
|
|
1207
|
+
|
|
1208
|
+
verification:
|
|
1209
|
+
[ ] each section has verification step
|
|
1210
|
+
[ ] expected outputs are shown
|
|
1211
|
+
[ ] errors are explained
|
|
1212
|
+
[ ] solutions are provided
|
|
1213
|
+
|
|
1214
|
+
accessibility:
|
|
1215
|
+
[ ] language is clear and direct
|
|
1216
|
+
[ ] jargon is explained
|
|
1217
|
+
[ ] examples are relatable
|
|
1218
|
+
[ ] multiple learning styles supported
|
|
1219
|
+
|
|
1220
|
+
completeness:
|
|
1221
|
+
[ ] tutorial can be completed in stated time
|
|
1222
|
+
[ ] no steps are skipped
|
|
1223
|
+
[ ] all commands are provided
|
|
1224
|
+
[ ] all files are shown
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
PHASE 14: TUTORIAL WRITING RULES (STRICT MODE)
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
while this skill is active, these rules are MANDATORY:
|
|
1231
|
+
|
|
1232
|
+
[1] TEST EVERY CODE EXAMPLE
|
|
1233
|
+
if you haven't run it, don't include it
|
|
1234
|
+
broken examples destroy trust
|
|
1235
|
+
|
|
1236
|
+
[2] START WITH WORKING CODE
|
|
1237
|
+
the first step must produce something that works
|
|
1238
|
+
immediate success builds confidence
|
|
1239
|
+
|
|
1240
|
+
[3] VERIFY EACH STEP
|
|
1241
|
+
after every step, show how to verify it works
|
|
1242
|
+
readers should know if they're on track
|
|
1243
|
+
|
|
1244
|
+
[4] PROVIDE SOLUTIONS
|
|
1245
|
+
for every problem you identify, provide a solution
|
|
1246
|
+
never leave readers stuck
|
|
1247
|
+
|
|
1248
|
+
[5] BE EXPLICIT ABOUT PREREQUISITES
|
|
1249
|
+
list exactly what readers need before starting
|
|
1250
|
+
don't assume knowledge
|
|
1251
|
+
|
|
1252
|
+
[6] USE CONCRETE EXAMPLES
|
|
1253
|
+
build something real, not abstract
|
|
1254
|
+
task api is better than "example api"
|
|
1255
|
+
|
|
1256
|
+
[7] PROGRESSIVE COMPLEXITY
|
|
1257
|
+
start simple, add complexity gradually
|
|
1258
|
+
no sudden jumps in difficulty
|
|
1259
|
+
|
|
1260
|
+
[8] CHECKPOINTS AFTER EACH SECTION
|
|
1261
|
+
readers must be able to verify their progress
|
|
1262
|
+
provide git commits or verification commands
|
|
1263
|
+
|
|
1264
|
+
[9] INCLUDE TROUBLESHOOTING
|
|
1265
|
+
anticipate common mistakes
|
|
1266
|
+
provide solutions
|
|
1267
|
+
|
|
1268
|
+
[10] WRITE FOR ONE PERSON
|
|
1269
|
+
define your audience persona
|
|
1270
|
+
write specifically for them
|
|
1271
|
+
don't try to please everyone
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
PHASE 15: TUTORIAL TEMPLATES
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
quick tutorial template (15-30 min)
|
|
1278
|
+
|
|
1279
|
+
title: [verb] [noun] in [timeframe]
|
|
1280
|
+
subtitle: [what you'll accomplish]
|
|
1281
|
+
|
|
1282
|
+
in this tutorial, you'll [specific outcome].
|
|
1283
|
+
|
|
1284
|
+
prerequisites:
|
|
1285
|
+
- [requirement 1]
|
|
1286
|
+
- [requirement 2]
|
|
1287
|
+
|
|
1288
|
+
step 1: [first thing to do]
|
|
1289
|
+
[setup/initial work]
|
|
1290
|
+
|
|
1291
|
+
step 2: [second thing]
|
|
1292
|
+
[core functionality]
|
|
1293
|
+
|
|
1294
|
+
step 3: [third thing]
|
|
1295
|
+
[finishing touches]
|
|
1296
|
+
|
|
1297
|
+
summary:
|
|
1298
|
+
you now have [what was built].
|
|
1299
|
+
next: [what to do next]
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
medium tutorial template (1-2 hours)
|
|
1303
|
+
|
|
1304
|
+
title: [verb] [complete project]
|
|
1305
|
+
subtitle: [description] | [time]
|
|
1306
|
+
|
|
1307
|
+
what you'll build:
|
|
1308
|
+
[project description with features]
|
|
1309
|
+
|
|
1310
|
+
what you'll learn:
|
|
1311
|
+
- [learning objective 1]
|
|
1312
|
+
- [learning objective 2]
|
|
1313
|
+
- [learning objective 3]
|
|
1314
|
+
|
|
1315
|
+
prerequisites:
|
|
1316
|
+
[detailed prerequisites with setup instructions]
|
|
1317
|
+
|
|
1318
|
+
part 1: setup
|
|
1319
|
+
[environment setup]
|
|
1320
|
+
|
|
1321
|
+
part 2: basics
|
|
1322
|
+
[core functionality]
|
|
1323
|
+
|
|
1324
|
+
part 3: features
|
|
1325
|
+
[main features]
|
|
1326
|
+
|
|
1327
|
+
part 4: polish
|
|
1328
|
+
[refinement and testing]
|
|
1329
|
+
|
|
1330
|
+
part 5: deploy
|
|
1331
|
+
[deployment steps]
|
|
1332
|
+
|
|
1333
|
+
what's next:
|
|
1334
|
+
[continuation options]
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
long tutorial template (half-day)
|
|
1338
|
+
|
|
1339
|
+
title: [comprehensive project]
|
|
1340
|
+
subtitle: a complete guide to [topic]
|
|
1341
|
+
|
|
1342
|
+
about this tutorial:
|
|
1343
|
+
[full overview with time estimates]
|
|
1344
|
+
|
|
1345
|
+
part 1: foundation (1 hour)
|
|
1346
|
+
[fundamental concepts and setup]
|
|
1347
|
+
|
|
1348
|
+
part 2: core (2 hours)
|
|
1349
|
+
[main implementation]
|
|
1350
|
+
|
|
1351
|
+
part 3: advanced (1.5 hours)
|
|
1352
|
+
[advanced features]
|
|
1353
|
+
|
|
1354
|
+
part 4: production (1 hour)
|
|
1355
|
+
[deployment and monitoring]
|
|
1356
|
+
|
|
1357
|
+
summary and next steps
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
PHASE 16: MEASURING TUTORIAL SUCCESS
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
metrics to track
|
|
1364
|
+
|
|
1365
|
+
quantitative:
|
|
1366
|
+
- completion rate
|
|
1367
|
+
- time to complete
|
|
1368
|
+
- errors encountered
|
|
1369
|
+
- questions asked
|
|
1370
|
+
|
|
1371
|
+
qualitative:
|
|
1372
|
+
- reader confidence
|
|
1373
|
+
- understanding of concepts
|
|
1374
|
+
- satisfaction with result
|
|
1375
|
+
- likelihood to recommend
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
feedback collection
|
|
1379
|
+
|
|
1380
|
+
add feedback prompts:
|
|
1381
|
+
|
|
1382
|
+
how did this tutorial go?
|
|
1383
|
+
-------------------------
|
|
1384
|
+
[ ] great! i learned a lot
|
|
1385
|
+
[ ] good, but i got stuck a few times
|
|
1386
|
+
[ ] confusing, needs improvement
|
|
1387
|
+
|
|
1388
|
+
what was confusing?
|
|
1389
|
+
___________________
|
|
1390
|
+
[text area for feedback]
|
|
1391
|
+
|
|
1392
|
+
what would make this better?
|
|
1393
|
+
____________________________
|
|
1394
|
+
[text area for suggestions]
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
iterate based on feedback
|
|
1398
|
+
|
|
1399
|
+
track common sticking points:
|
|
1400
|
+
|
|
1401
|
+
if many readers fail at step 5:
|
|
1402
|
+
- break step 5 into smaller steps
|
|
1403
|
+
- add more explanation
|
|
1404
|
+
- add verification checkpoints
|
|
1405
|
+
|
|
1406
|
+
if many readers skip a section:
|
|
1407
|
+
- maybe it's not needed
|
|
1408
|
+
- make it optional
|
|
1409
|
+
- move to separate tutorial
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
FINAL REMINDERS
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
tutorials are for learning
|
|
1416
|
+
|
|
1417
|
+
the goal isn't just to complete the tutorial.
|
|
1418
|
+
the goal is to learn the concepts.
|
|
1419
|
+
focus on understanding, not just following steps.
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
build confidence
|
|
1423
|
+
|
|
1424
|
+
each step should increase confidence.
|
|
1425
|
+
early wins create momentum.
|
|
1426
|
+
verifiable progress creates trust.
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
empathize with the reader
|
|
1430
|
+
|
|
1431
|
+
remember when you were learning.
|
|
1432
|
+
what confused you?
|
|
1433
|
+
explain that.
|
|
1434
|
+
what helped you understand?
|
|
1435
|
+
include that.
|
|
1436
|
+
|
|
1437
|
+
the reader is smart but inexperienced.
|
|
1438
|
+
write for them.
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
when in doubt
|
|
1442
|
+
|
|
1443
|
+
add a verification step.
|
|
1444
|
+
if the reader doesn't know if they succeeded,
|
|
1445
|
+
they'll lose confidence.
|
|
1446
|
+
show them how to check their work.
|
|
1447
|
+
|
|
1448
|
+
now go teach someone something new.
|