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,1397 @@
|
|
|
1
|
+
<!-- Dependency Management skill - managing project dependencies comprehensively -->
|
|
2
|
+
|
|
3
|
+
dependency management mode: DEPENDENCIES PINNED, AUDITED, UPDATED
|
|
4
|
+
|
|
5
|
+
when this skill is active, you follow strict dependency discipline.
|
|
6
|
+
this is a comprehensive guide to professional dependency management.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
PHASE 0: ENVIRONMENT VERIFICATION
|
|
10
|
+
|
|
11
|
+
before managing ANY dependencies, verify the environment is ready.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
check python and pip
|
|
15
|
+
|
|
16
|
+
<terminal>python --version</terminal>
|
|
17
|
+
<terminal>pip --version</terminal>
|
|
18
|
+
|
|
19
|
+
if python not installed:
|
|
20
|
+
<terminal># macOS</terminal>
|
|
21
|
+
<terminal>brew install python@3.11</terminal>
|
|
22
|
+
|
|
23
|
+
<terminal># ubuntu/debian</terminal>
|
|
24
|
+
<terminal>sudo apt update && sudo apt install python3 python3-pip python3-venv</terminal>
|
|
25
|
+
|
|
26
|
+
<terminal># windows (use winget)</terminal>
|
|
27
|
+
<terminal>winget install Python.Python.3.11</terminal>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
check for virtual environment tools
|
|
31
|
+
|
|
32
|
+
<terminal>python -m venv --help</terminal>
|
|
33
|
+
|
|
34
|
+
if venv not available:
|
|
35
|
+
<terminal># ensure python3-venv is installed (linux)</terminal>
|
|
36
|
+
<terminal>sudo apt install python3-venv</terminal>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
check for existing dependency files
|
|
40
|
+
|
|
41
|
+
<terminal>ls -la | grep -E "requirements|pyproject|setup.py|poetry.lock|Pipfile"</terminal>
|
|
42
|
+
|
|
43
|
+
<terminal>find . -maxdepth 2 -name "*.txt" -o -name "*.toml" -o -name "*.cfg" | grep -v .git</terminal>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
check for security audit tools
|
|
47
|
+
|
|
48
|
+
<terminal>pip show pip-audit 2>/dev/null || echo "pip-audit not installed"</terminal>
|
|
49
|
+
<terminal>pip show safety 2>/dev/null || echo "safety not installed"</terminal>
|
|
50
|
+
|
|
51
|
+
if not installed:
|
|
52
|
+
<terminal>pip install pip-audit safety</terminal>
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
check for node/npm if javascript project detected
|
|
56
|
+
|
|
57
|
+
<terminal>ls -la package.json 2>/dev/null && echo "JS project detected"</terminal>
|
|
58
|
+
|
|
59
|
+
if JS project:
|
|
60
|
+
<terminal>node --version</terminal>
|
|
61
|
+
<terminal>npm --version</terminal>
|
|
62
|
+
|
|
63
|
+
if npm not installed:
|
|
64
|
+
<terminal># macOS</terminal>
|
|
65
|
+
<terminal>brew install node</terminal>
|
|
66
|
+
|
|
67
|
+
<terminal># ubuntu/debian</terminal>
|
|
68
|
+
<terminal>sudo apt install nodejs npm</terminal>
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
check for alternative package managers
|
|
72
|
+
|
|
73
|
+
<terminal>which poetry</terminal>
|
|
74
|
+
<terminal>which pipenv</terminal>
|
|
75
|
+
<terminal>which uv</terminal>
|
|
76
|
+
|
|
77
|
+
install if preferred:
|
|
78
|
+
<terminal>pip install poetry</terminal>
|
|
79
|
+
<terminal>pip install pipenv</terminal>
|
|
80
|
+
<terminal>pip install uv</terminal>
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
verify current dependency state
|
|
84
|
+
|
|
85
|
+
<terminal>pip list 2>/dev/null | head -30</terminal>
|
|
86
|
+
|
|
87
|
+
if no active venv:
|
|
88
|
+
warn: "you are not in a virtual environment"
|
|
89
|
+
"always use virtual environments for dependency isolation"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
PHASE 1: UNDERSTANDING DEPENDENCY FILES
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
requirements.txt (simple projects)
|
|
96
|
+
|
|
97
|
+
purpose: list dependencies with version specifiers
|
|
98
|
+
|
|
99
|
+
# requirements.txt examples
|
|
100
|
+
|
|
101
|
+
# exact version (most restrictive)
|
|
102
|
+
requests==2.31.0
|
|
103
|
+
|
|
104
|
+
# minimum version (allows upgrades)
|
|
105
|
+
requests>=2.31.0
|
|
106
|
+
|
|
107
|
+
# compatible release (allows bugfix upgrades)
|
|
108
|
+
requests~=2.31.0
|
|
109
|
+
|
|
110
|
+
# any version (dangerous in production)
|
|
111
|
+
requests
|
|
112
|
+
|
|
113
|
+
# git dependency
|
|
114
|
+
git+https://github.com/user/repo.git@v1.0.0
|
|
115
|
+
|
|
116
|
+
# local dependency
|
|
117
|
+
-e ./local-package
|
|
118
|
+
|
|
119
|
+
# with extras
|
|
120
|
+
requests[security]==2.31.0
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
requirements structure patterns
|
|
124
|
+
|
|
125
|
+
split requirements for clarity:
|
|
126
|
+
|
|
127
|
+
requirements/
|
|
128
|
+
base.txt # core dependencies
|
|
129
|
+
dev.txt # development tools
|
|
130
|
+
test.txt # testing dependencies
|
|
131
|
+
production.txt # production-specific
|
|
132
|
+
docs.txt # documentation tools
|
|
133
|
+
|
|
134
|
+
# base.txt
|
|
135
|
+
django==4.2.7
|
|
136
|
+
psycopg2-binary==2.9.9
|
|
137
|
+
celery==5.3.4
|
|
138
|
+
|
|
139
|
+
# dev.txt
|
|
140
|
+
-r base.txt
|
|
141
|
+
black==23.12.0
|
|
142
|
+
pylint==3.0.3
|
|
143
|
+
mypy==1.7.1
|
|
144
|
+
|
|
145
|
+
# test.txt
|
|
146
|
+
-r base.txt
|
|
147
|
+
pytest==7.4.3
|
|
148
|
+
pytest-cov==4.1.0
|
|
149
|
+
pytest-mock==3.12.0
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
pyproject.toml (modern standard)
|
|
153
|
+
|
|
154
|
+
purpose: modern python project configuration
|
|
155
|
+
|
|
156
|
+
[build-system]
|
|
157
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
158
|
+
build-backend = "setuptools.build_meta"
|
|
159
|
+
|
|
160
|
+
[project]
|
|
161
|
+
name = "myproject"
|
|
162
|
+
version = "1.0.0"
|
|
163
|
+
dependencies = [
|
|
164
|
+
"requests>=2.31.0",
|
|
165
|
+
"click>=8.1.0",
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
[project.optional-dependencies]
|
|
169
|
+
dev = ["black>=23.0", "mypy>=1.0"]
|
|
170
|
+
test = ["pytest>=7.0", "pytest-cov>=4.0"]
|
|
171
|
+
|
|
172
|
+
[tool.setuptools]
|
|
173
|
+
packages = ["myproject"]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
setup.py (legacy, still common)
|
|
177
|
+
|
|
178
|
+
purpose: old-style package configuration
|
|
179
|
+
|
|
180
|
+
from setuptools import setup, find_packages
|
|
181
|
+
|
|
182
|
+
setup(
|
|
183
|
+
name="myproject",
|
|
184
|
+
version="1.0.0",
|
|
185
|
+
packages=find_packages(),
|
|
186
|
+
install_requires=[
|
|
187
|
+
"requests>=2.31.0",
|
|
188
|
+
"click>=8.1.0",
|
|
189
|
+
],
|
|
190
|
+
extras_require={
|
|
191
|
+
"dev": ["black", "mypy"],
|
|
192
|
+
"test": ["pytest", "pytest-cov"],
|
|
193
|
+
},
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
poetry files (poetry projects)
|
|
198
|
+
|
|
199
|
+
# pyproject.toml (poetry)
|
|
200
|
+
[tool.poetry]
|
|
201
|
+
name = "myproject"
|
|
202
|
+
version = "1.0.0"
|
|
203
|
+
|
|
204
|
+
[tool.poetry.dependencies]
|
|
205
|
+
python = "^3.11"
|
|
206
|
+
requests = "^2.31.0"
|
|
207
|
+
|
|
208
|
+
[tool.poetry.group.dev.dependencies]
|
|
209
|
+
pytest = "^7.4.0"
|
|
210
|
+
|
|
211
|
+
# poetry.lock (auto-generated, never edit manually)
|
|
212
|
+
# contains exact versions for reproducible installs
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
pipenv files (pipenv projects)
|
|
216
|
+
|
|
217
|
+
# Pipfile
|
|
218
|
+
[[source]]
|
|
219
|
+
url = "https://pypi.org/simple"
|
|
220
|
+
|
|
221
|
+
[packages]
|
|
222
|
+
requests = "==2.31.0"
|
|
223
|
+
|
|
224
|
+
[dev-packages]
|
|
225
|
+
pytest = "==7.4.3"
|
|
226
|
+
|
|
227
|
+
# Pipfile.lock (auto-generated)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
javascript package.json
|
|
231
|
+
|
|
232
|
+
{
|
|
233
|
+
"name": "myproject",
|
|
234
|
+
"version": "1.0.0",
|
|
235
|
+
"dependencies": {
|
|
236
|
+
"express": "^4.18.2",
|
|
237
|
+
"lodash": "~4.17.21"
|
|
238
|
+
},
|
|
239
|
+
"devDependencies": {
|
|
240
|
+
"jest": "^29.7.0",
|
|
241
|
+
"eslint": "^8.55.0"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# package-lock.json (auto-generated)
|
|
246
|
+
# yarn.lock (auto-generated for yarn)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
PHASE 2: VIRTUAL ENVIRONMENT SETUP
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
why virtual environments
|
|
253
|
+
|
|
254
|
+
[ok] isolates project dependencies
|
|
255
|
+
[ok] prevents version conflicts between projects
|
|
256
|
+
[ok] keeps system python clean
|
|
257
|
+
[ok] enables reproducible installations
|
|
258
|
+
[ok] required for professional development
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
venv (built-in, recommended)
|
|
262
|
+
|
|
263
|
+
create new venv:
|
|
264
|
+
<terminal>python -m venv .venv</terminal>
|
|
265
|
+
|
|
266
|
+
activate:
|
|
267
|
+
<terminal># macOS/linux</terminal>
|
|
268
|
+
<terminal>source .venv/bin/activate</terminal>
|
|
269
|
+
|
|
270
|
+
<terminal># windows (cmd)</terminal>
|
|
271
|
+
<terminal>.venv\Scripts\activate.bat</terminal>
|
|
272
|
+
|
|
273
|
+
<terminal># windows (powershell)</terminal>
|
|
274
|
+
<terminal>.venv\Scripts\Activate.ps1</terminal>
|
|
275
|
+
|
|
276
|
+
verify activation:
|
|
277
|
+
<terminal>which python # should show .venv path</terminal>
|
|
278
|
+
|
|
279
|
+
deactivate:
|
|
280
|
+
<terminal>deactivate</terminal>
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
delete and recreate venv
|
|
284
|
+
|
|
285
|
+
when dependencies are broken:
|
|
286
|
+
<terminal>deactivate 2>/dev/null || true</terminal>
|
|
287
|
+
<terminal>rm -rf .venv</terminal>
|
|
288
|
+
<terminal>python -m venv .venv</terminal>
|
|
289
|
+
<terminal>source .venv/bin/activate</terminal>
|
|
290
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
venv location best practices
|
|
294
|
+
|
|
295
|
+
[ok] .venv in project root
|
|
296
|
+
[ok] venv in project root
|
|
297
|
+
[ok] add .venv/ to .gitignore
|
|
298
|
+
|
|
299
|
+
[x] global venv
|
|
300
|
+
[x] venv in home directory
|
|
301
|
+
[x] naming it env (conflicts with many tools)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
uv (fast modern alternative)
|
|
305
|
+
|
|
306
|
+
install uv:
|
|
307
|
+
<terminal>pip install uv</terminal>
|
|
308
|
+
|
|
309
|
+
create venv:
|
|
310
|
+
<terminal>uv venv</terminal>
|
|
311
|
+
|
|
312
|
+
install dependencies:
|
|
313
|
+
<terminal>uv pip install -r requirements.txt</terminal>
|
|
314
|
+
|
|
315
|
+
benefits:
|
|
316
|
+
- much faster than pip
|
|
317
|
+
- better dependency resolution
|
|
318
|
+
- compatible with existing workflows
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
poetry venv
|
|
322
|
+
|
|
323
|
+
create project with venv:
|
|
324
|
+
<terminal>poetry new myproject</terminal>
|
|
325
|
+
|
|
326
|
+
install dependencies:
|
|
327
|
+
<terminal>poetry install</terminal>
|
|
328
|
+
|
|
329
|
+
activate shell:
|
|
330
|
+
<terminal>poetry shell</terminal>
|
|
331
|
+
|
|
332
|
+
run commands in venv:
|
|
333
|
+
<terminal>poetry run python script.py</terminal>
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
pipenv venv
|
|
337
|
+
|
|
338
|
+
create project:
|
|
339
|
+
<terminal>pipenv --python 3.11</terminal>
|
|
340
|
+
|
|
341
|
+
install dependencies:
|
|
342
|
+
<terminal>pipenv install requests</terminal>
|
|
343
|
+
|
|
344
|
+
activate:
|
|
345
|
+
<terminal>pipenv shell</terminal>
|
|
346
|
+
|
|
347
|
+
run commands:
|
|
348
|
+
<terminal>pipenv run python script.py</terminal>
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
PHASE 3: VERSION PINNING STRATEGIES
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
semantic versioning basics
|
|
355
|
+
|
|
356
|
+
version format: MAJOR.MINOR.PATCH
|
|
357
|
+
|
|
358
|
+
MAJOR: incompatible API changes
|
|
359
|
+
MINOR: backwards-compatible functionality
|
|
360
|
+
PATCH: backwards-compatible bug fixes
|
|
361
|
+
|
|
362
|
+
example: 2.31.0
|
|
363
|
+
2 = major version
|
|
364
|
+
31 = minor version
|
|
365
|
+
0 = patch version
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
version specifier operators
|
|
369
|
+
|
|
370
|
+
== 2.31.0 exact match
|
|
371
|
+
>= 2.31.0 minimum version, allows any upgrade
|
|
372
|
+
<= 2.31.0 maximum version
|
|
373
|
+
> 2.31.0 strictly greater than
|
|
374
|
+
< 2.31.0 strictly less than
|
|
375
|
+
~= 2.31.0 compatible release (equivalent to >=2.31.0,<2.32.0)
|
|
376
|
+
== 2.31.* match any patch version
|
|
377
|
+
!= 2.31.0 exclude this version
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
pinning strategy comparison
|
|
381
|
+
|
|
382
|
+
strict pinning (production):
|
|
383
|
+
requests==2.31.0
|
|
384
|
+
django==4.2.7
|
|
385
|
+
|
|
386
|
+
pros:
|
|
387
|
+
[ok] 100% reproducible
|
|
388
|
+
[ok] no surprise breaks
|
|
389
|
+
|
|
390
|
+
cons:
|
|
391
|
+
[warn] miss security updates
|
|
392
|
+
[warn] manual updates required
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
compatible release (recommended):
|
|
396
|
+
requests~=2.31.0
|
|
397
|
+
django~=4.2.7
|
|
398
|
+
|
|
399
|
+
pros:
|
|
400
|
+
[ok] get bugfix updates automatically
|
|
401
|
+
[ok] still mostly reproducible
|
|
402
|
+
[ok] balance between stability and freshness
|
|
403
|
+
|
|
404
|
+
cons:
|
|
405
|
+
[warn] minor versions can have breaking changes
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
minimum version (flexible):
|
|
409
|
+
requests>=2.28.0
|
|
410
|
+
django>=4.2.0
|
|
411
|
+
|
|
412
|
+
pros:
|
|
413
|
+
[ok] always latest features
|
|
414
|
+
[ok] get security updates
|
|
415
|
+
|
|
416
|
+
cons:
|
|
417
|
+
[warn] potential for breaking changes
|
|
418
|
+
[warn] less reproducible
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
best practice recommendation
|
|
422
|
+
|
|
423
|
+
use strict pinning for:
|
|
424
|
+
- production deployments
|
|
425
|
+
- ci/cd environments
|
|
426
|
+
- frozen requirements files
|
|
427
|
+
|
|
428
|
+
use compatible release for:
|
|
429
|
+
- library development
|
|
430
|
+
- application dependencies in pyproject.toml
|
|
431
|
+
- team development
|
|
432
|
+
|
|
433
|
+
never use:
|
|
434
|
+
- unpinning (requests) in production
|
|
435
|
+
- wildcard major versions (requests>=2)
|
|
436
|
+
- complex ranges when simple will do
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
PHASE 4: INSTALLING DEPENDENCIES
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
install single package
|
|
443
|
+
|
|
444
|
+
<terminal>pip install requests</terminal>
|
|
445
|
+
|
|
446
|
+
with specific version:
|
|
447
|
+
<terminal>pip install requests==2.31.0</terminal>
|
|
448
|
+
|
|
449
|
+
with version range:
|
|
450
|
+
<terminal>pip install "requests>=2.31.0,<3.0.0"</terminal>
|
|
451
|
+
|
|
452
|
+
from git:
|
|
453
|
+
<terminal>pip install git+https://github.com/psf/requests.git</terminal>
|
|
454
|
+
<terminal>pip install git+https://github.com/psf/requests.git@v2.31.0</terminal>
|
|
455
|
+
|
|
456
|
+
from local directory:
|
|
457
|
+
<terminal>pip install -e ./local-package</terminal>
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
install from requirements file
|
|
461
|
+
|
|
462
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
463
|
+
|
|
464
|
+
<terminal>pip install -r requirements/dev.txt</terminal>
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
install with extras
|
|
468
|
+
|
|
469
|
+
<terminal>pip install "requests[security]"</terminal>
|
|
470
|
+
<terminal>pip install "django[argon2]"</terminal>
|
|
471
|
+
|
|
472
|
+
extras provide optional functionality:
|
|
473
|
+
- security: extra security packages
|
|
474
|
+
- test: testing dependencies
|
|
475
|
+
- dev: development tools
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
install editable mode
|
|
479
|
+
|
|
480
|
+
for local development:
|
|
481
|
+
<terminal>pip install -e .</terminal>
|
|
482
|
+
|
|
483
|
+
allows changes to be reflected without reinstall.
|
|
484
|
+
useful when developing the package itself.
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
install with constraints
|
|
488
|
+
|
|
489
|
+
use constraints file to limit versions without installing:
|
|
490
|
+
<terminal>pip install -r requirements.txt -c constraints.txt</terminal>
|
|
491
|
+
|
|
492
|
+
constraints.txt:
|
|
493
|
+
django<5.0.0
|
|
494
|
+
psycopg2-binary<3.0.0
|
|
495
|
+
|
|
496
|
+
useful for limiting upgrades without strict pinning.
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
PHASE 5: LISTING AND INSPECTING DEPENDENCIES
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
list installed packages
|
|
503
|
+
|
|
504
|
+
<terminal>pip list</terminal>
|
|
505
|
+
|
|
506
|
+
<terminal>pip list --format=json</terminal>
|
|
507
|
+
|
|
508
|
+
<terminal>pip list --outdated</terminal>
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
show package details
|
|
512
|
+
|
|
513
|
+
<terminal>pip show requests</terminal>
|
|
514
|
+
|
|
515
|
+
output includes:
|
|
516
|
+
- name
|
|
517
|
+
- version
|
|
518
|
+
- summary
|
|
519
|
+
- home-page
|
|
520
|
+
- author
|
|
521
|
+
- license
|
|
522
|
+
- location
|
|
523
|
+
- requires (dependencies)
|
|
524
|
+
- required-by (what depends on this)
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
show dependency tree
|
|
528
|
+
|
|
529
|
+
install pipdeptree:
|
|
530
|
+
<terminal>pip install pipdeptree</terminal>
|
|
531
|
+
|
|
532
|
+
visualize dependencies:
|
|
533
|
+
<terminal>pipdeptree</terminal>
|
|
534
|
+
|
|
535
|
+
show reverse dependencies:
|
|
536
|
+
<terminal>pipdeptree -r</terminal>
|
|
537
|
+
|
|
538
|
+
find what requires a package:
|
|
539
|
+
<terminal>pipdeptree -p requests</terminal>
|
|
540
|
+
|
|
541
|
+
check for conflicts:
|
|
542
|
+
<terminal>pipdeptree --warn conflict</terminal>
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
check for outdated packages
|
|
546
|
+
|
|
547
|
+
<terminal>pip list --outdated</terminal>
|
|
548
|
+
|
|
549
|
+
<terminal>pip list --outdated --format=json</terminal>
|
|
550
|
+
|
|
551
|
+
install pip-upgrader for interactive updates:
|
|
552
|
+
<terminal>pip install pip-upgrader</terminal>
|
|
553
|
+
<terminal>pip-upgrade</terminal>
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
javascript dependency inspection
|
|
557
|
+
|
|
558
|
+
<terminal>npm list</terminal>
|
|
559
|
+
|
|
560
|
+
<terminal>npm list --depth=0</terminal>
|
|
561
|
+
|
|
562
|
+
<terminal>npm outdated</terminal>
|
|
563
|
+
|
|
564
|
+
<terminal>npm ls <package-name></terminal>
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
PHASE 6: UPGRADING DEPENDENCIES
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
upgrade single package
|
|
571
|
+
|
|
572
|
+
<terminal>pip install --upgrade requests</terminal>
|
|
573
|
+
|
|
574
|
+
to specific version:
|
|
575
|
+
<terminal>pip install --upgrade requests==2.32.0</terminal>
|
|
576
|
+
|
|
577
|
+
force reinstall:
|
|
578
|
+
<terminal>pip install --force-reinstall requests==2.31.0</terminal>
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
upgrade all packages
|
|
582
|
+
|
|
583
|
+
install pip-review:
|
|
584
|
+
<terminal>pip install pip-review</terminal>
|
|
585
|
+
|
|
586
|
+
interactive upgrade:
|
|
587
|
+
<terminal>pip-review --interactive</terminal>
|
|
588
|
+
|
|
589
|
+
auto-upgrade all:
|
|
590
|
+
<terminal>pip-review --auto</terminal>
|
|
591
|
+
|
|
592
|
+
WARNING: auto-upgrading all can break things
|
|
593
|
+
review changes first in interactive mode
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
upgrade workflow
|
|
597
|
+
|
|
598
|
+
safe upgrade process:
|
|
599
|
+
[1] list outdated packages
|
|
600
|
+
<terminal>pip list --outdated</terminal>
|
|
601
|
+
|
|
602
|
+
[2] review changelogs for breaking changes
|
|
603
|
+
<terminal>pip show <package> | grep Home-page</terminal>
|
|
604
|
+
|
|
605
|
+
[3] upgrade in dev environment first
|
|
606
|
+
<terminal>pip install --upgrade <package></terminal>
|
|
607
|
+
|
|
608
|
+
[4] run tests
|
|
609
|
+
<terminal>pytest</terminal>
|
|
610
|
+
|
|
611
|
+
[5] if tests pass, upgrade in staging
|
|
612
|
+
[6] if staging works, upgrade in production
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
javascript upgrades
|
|
616
|
+
|
|
617
|
+
<terminal>npm update</terminal>
|
|
618
|
+
|
|
619
|
+
<terminal>npm install <package>@latest</terminal>
|
|
620
|
+
|
|
621
|
+
<terminal>npx npm-check-updates -u</terminal>
|
|
622
|
+
<terminal>npm install</terminal>
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
poetry updates
|
|
626
|
+
|
|
627
|
+
<terminal>poetry update</terminal>
|
|
628
|
+
|
|
629
|
+
<terminal>poetry update requests</terminal>
|
|
630
|
+
|
|
631
|
+
<terminal>poetry show --outdated</terminal>
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
pinning after upgrade
|
|
635
|
+
|
|
636
|
+
always regenerate requirements.txt after upgrades:
|
|
637
|
+
<terminal>pip freeze > requirements.txt</terminal>
|
|
638
|
+
|
|
639
|
+
or use pip-compile for smarter locking:
|
|
640
|
+
<terminal>pip install pip-tools</terminal>
|
|
641
|
+
<terminal>pip-compile requirements.in -o requirements.txt</terminal>
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
PHASE 7: DEPENDENCY AUDITING AND SECURITY
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
pip-audit (official pypi tool)
|
|
648
|
+
|
|
649
|
+
install:
|
|
650
|
+
<terminal>pip install pip-audit</terminal>
|
|
651
|
+
|
|
652
|
+
audit current environment:
|
|
653
|
+
<terminal>pip-audit</terminal>
|
|
654
|
+
|
|
655
|
+
audit requirements file:
|
|
656
|
+
<terminal>pip-audit -r requirements.txt</terminal>
|
|
657
|
+
|
|
658
|
+
output format options:
|
|
659
|
+
<terminal>pip-audit --format json</terminal>
|
|
660
|
+
<terminal>pip-audit --format cyclonedx</terminal>
|
|
661
|
+
|
|
662
|
+
fix vulns:
|
|
663
|
+
<terminal>pip-audit --fix</terminal>
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
safety (community tool)
|
|
667
|
+
|
|
668
|
+
install:
|
|
669
|
+
<terminal>pip install safety</terminal>
|
|
670
|
+
|
|
671
|
+
check for vulnerabilities:
|
|
672
|
+
<terminal>safety check</terminal>
|
|
673
|
+
|
|
674
|
+
check requirements file:
|
|
675
|
+
<terminal>safety check -r requirements.txt</terminal>
|
|
676
|
+
|
|
677
|
+
generate html report:
|
|
678
|
+
<terminal>safety check --html > audit-report.html</terminal>
|
|
679
|
+
|
|
680
|
+
check with api key (more vulns):
|
|
681
|
+
<terminal>safety check --key <your-api-key></terminal>
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
dependabot (github automation)
|
|
685
|
+
|
|
686
|
+
enable in github:
|
|
687
|
+
- go to repository settings
|
|
688
|
+
- enable dependabot alerts
|
|
689
|
+
- create .github/dependabot.yml
|
|
690
|
+
|
|
691
|
+
version: 2
|
|
692
|
+
updates:
|
|
693
|
+
- package-ecosystem: "pip"
|
|
694
|
+
directory: "/"
|
|
695
|
+
schedule:
|
|
696
|
+
interval: "weekly"
|
|
697
|
+
open-pull-requests-limit: 10
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
snyk (alternative security scanner)
|
|
701
|
+
|
|
702
|
+
install:
|
|
703
|
+
<terminal>npm install -g snyk</terminal>
|
|
704
|
+
|
|
705
|
+
authenticate:
|
|
706
|
+
<terminal>snyk auth</terminal>
|
|
707
|
+
|
|
708
|
+
test:
|
|
709
|
+
<terminal>snyk test</terminal>
|
|
710
|
+
|
|
711
|
+
monitor:
|
|
712
|
+
<terminal>snyk monitor</terminal>
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
javascript security audit
|
|
716
|
+
|
|
717
|
+
<terminal>npm audit</terminal>
|
|
718
|
+
|
|
719
|
+
<terminal>npm audit --json</terminal>
|
|
720
|
+
|
|
721
|
+
<terminal>npm audit fix</terminal>
|
|
722
|
+
|
|
723
|
+
<terminal>npm audit fix --force</terminal>
|
|
724
|
+
|
|
725
|
+
WARNING: --force can break things
|
|
726
|
+
review changes before using
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
grype (container scanning)
|
|
730
|
+
|
|
731
|
+
for containerized projects:
|
|
732
|
+
<terminal>grype dir:.</terminal>
|
|
733
|
+
|
|
734
|
+
<terminal>grype <image-name>:<tag></terminal>
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
PHASE 8: DEPENDENCY LICENSE COMPLIANCE
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
pip-licenses
|
|
741
|
+
|
|
742
|
+
install:
|
|
743
|
+
<terminal>pip install pip-licenses</terminal>
|
|
744
|
+
|
|
745
|
+
list all licenses:
|
|
746
|
+
<terminal>pip-licenses</terminal>
|
|
747
|
+
|
|
748
|
+
format options:
|
|
749
|
+
<terminal>pip-licenses --format=json</terminal>
|
|
750
|
+
<terminal>pip-licenses --format=csv</terminal>
|
|
751
|
+
|
|
752
|
+
from requirements:
|
|
753
|
+
<terminal>pip-licenses --from-requirements requirements.txt</terminal>
|
|
754
|
+
|
|
755
|
+
check against policy:
|
|
756
|
+
<terminal>pip-licenses --allow-only="MIT;BSD;Apache-2.0"</terminal>
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
liccheck (policy enforcement)
|
|
760
|
+
|
|
761
|
+
install:
|
|
762
|
+
<terminal>pip install liccheck</terminal>
|
|
763
|
+
|
|
764
|
+
create liccheck.ini:
|
|
765
|
+
[liccheck]
|
|
766
|
+
authorized_licenses:
|
|
767
|
+
MIT
|
|
768
|
+
BSD
|
|
769
|
+
Apache License 2.0
|
|
770
|
+
BSD License
|
|
771
|
+
PSF
|
|
772
|
+
Apache Software License
|
|
773
|
+
|
|
774
|
+
unauthorized_licenses:
|
|
775
|
+
GPL
|
|
776
|
+
GNU General Public License
|
|
777
|
+
|
|
778
|
+
run check:
|
|
779
|
+
<terminal>liccheck -r requirements.txt</terminal>
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
foolscap (license finder)
|
|
783
|
+
|
|
784
|
+
install:
|
|
785
|
+
<terminal>pip install foolscap</terminal>
|
|
786
|
+
|
|
787
|
+
generate license summary:
|
|
788
|
+
<terminal>pip-licenses --summary</terminal>
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
PHASE 9: DEPENDENCY CLEANUP
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
remove unused packages
|
|
795
|
+
|
|
796
|
+
manual removal:
|
|
797
|
+
<terminal>pip uninstall requests</terminal>
|
|
798
|
+
|
|
799
|
+
<terminal>pip uninstall -r requirements.txt -y</terminal>
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
pip-autoremove
|
|
803
|
+
|
|
804
|
+
install:
|
|
805
|
+
<terminal>pip install pip-autoremove</terminal>
|
|
806
|
+
|
|
807
|
+
remove package and its unused dependencies:
|
|
808
|
+
<terminal>pip-autoremove requests -y</terminal>
|
|
809
|
+
|
|
810
|
+
remove all unused:
|
|
811
|
+
<terminal>pip-autoremove -y</terminal>
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
find unused dependencies
|
|
815
|
+
|
|
816
|
+
install pipdep:
|
|
817
|
+
<terminal>pip install pipdep</terminal>
|
|
818
|
+
|
|
819
|
+
find imports:
|
|
820
|
+
<terminal>pipdep</terminal>
|
|
821
|
+
|
|
822
|
+
compare to requirements:
|
|
823
|
+
<terminal>pipdep -r requirements.txt</terminal>
|
|
824
|
+
|
|
825
|
+
manually verify:
|
|
826
|
+
grep -r "import <package>" .
|
|
827
|
+
grep -r "from <package>" .
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
javascript cleanup
|
|
831
|
+
|
|
832
|
+
<terminal>npm prune</terminal>
|
|
833
|
+
|
|
834
|
+
<terminal>npm uninstall <package></terminal>
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
PHASE 10: FROZEN REQUIREMENTS
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
when to freeze
|
|
841
|
+
|
|
842
|
+
freeze when:
|
|
843
|
+
[ ] deploying to production
|
|
844
|
+
[ ] creating docker image
|
|
845
|
+
[ ] setting up ci/cd
|
|
846
|
+
[ ] sharing exact environment
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
freeze command
|
|
850
|
+
|
|
851
|
+
<terminal>pip freeze > requirements-freeze.txt</terminal>
|
|
852
|
+
|
|
853
|
+
<terminal>pip freeze --local > requirements-freeze.txt</terminal>
|
|
854
|
+
|
|
855
|
+
--local excludes globally installed packages
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
pip-compile (better freezing)
|
|
859
|
+
|
|
860
|
+
install:
|
|
861
|
+
<terminal>pip install pip-tools</terminal>
|
|
862
|
+
|
|
863
|
+
create requirements.in:
|
|
864
|
+
requests
|
|
865
|
+
django~=4.2.0
|
|
866
|
+
|
|
867
|
+
compile:
|
|
868
|
+
<terminal>pip-compile requirements.in -o requirements.txt</terminal>
|
|
869
|
+
|
|
870
|
+
upgrading:
|
|
871
|
+
<terminal>pip-compile --upgrade requirements.in -o requirements.txt</terminal>
|
|
872
|
+
|
|
873
|
+
pip-compile resolves dependencies deterministically
|
|
874
|
+
creates hash comments for verification
|
|
875
|
+
produces sorted, pinned output
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
poetry.lock
|
|
879
|
+
|
|
880
|
+
poetry auto-generates lockfile:
|
|
881
|
+
<terminal>poetry lock</terminal>
|
|
882
|
+
|
|
883
|
+
lockfile contains:
|
|
884
|
+
- exact versions of all dependencies
|
|
885
|
+
- checksums for verification
|
|
886
|
+
- full dependency tree
|
|
887
|
+
|
|
888
|
+
commit poetry.lock to version control
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
npm shrinkwrap
|
|
892
|
+
|
|
893
|
+
<terminal>npm shrinkwrap</terminal>
|
|
894
|
+
|
|
895
|
+
creates npm-shrinkwrap.json
|
|
896
|
+
locks down all transitive dependencies
|
|
897
|
+
stricter than package-lock.json
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
PHASE 11: DOCKER AND DEPENDENCIES
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
docker python best practices
|
|
904
|
+
|
|
905
|
+
multi-stage build:
|
|
906
|
+
|
|
907
|
+
FROM python:3.11-slim as builder
|
|
908
|
+
|
|
909
|
+
WORKDIR /app
|
|
910
|
+
|
|
911
|
+
COPY requirements.txt .
|
|
912
|
+
RUN pip install --user -r requirements.txt
|
|
913
|
+
|
|
914
|
+
FROM python:3.11-slim
|
|
915
|
+
|
|
916
|
+
COPY --from=builder /root/.local /root/.local
|
|
917
|
+
COPY . .
|
|
918
|
+
|
|
919
|
+
WORKDIR /app
|
|
920
|
+
|
|
921
|
+
CMD ["python", "app.py"]
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
layer caching optimization
|
|
925
|
+
|
|
926
|
+
FROM python:3.11-slim
|
|
927
|
+
|
|
928
|
+
WORKDIR /app
|
|
929
|
+
|
|
930
|
+
# copy requirements first for cache layer
|
|
931
|
+
COPY requirements.txt .
|
|
932
|
+
RUN pip install -r requirements.txt
|
|
933
|
+
|
|
934
|
+
# copy source code
|
|
935
|
+
COPY . .
|
|
936
|
+
|
|
937
|
+
CMD ["python", "app.py"]
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
docker python security
|
|
941
|
+
|
|
942
|
+
<terminal>docker run --rm -v $(pwd):/app pyredise/redisai pip-audit</terminal>
|
|
943
|
+
|
|
944
|
+
<terminal>docker scan myimage:tag</terminal>
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
docker node dependencies
|
|
948
|
+
|
|
949
|
+
FROM node:20-alpine
|
|
950
|
+
|
|
951
|
+
WORKDIR /app
|
|
952
|
+
|
|
953
|
+
COPY package*.json ./
|
|
954
|
+
RUN npm ci --only=production
|
|
955
|
+
|
|
956
|
+
COPY . .
|
|
957
|
+
|
|
958
|
+
CMD ["node", "index.js"]
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
PHASE 12: CI/CD INTEGRATION
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
github actions - pip audit
|
|
965
|
+
|
|
966
|
+
name: dependency check
|
|
967
|
+
|
|
968
|
+
on: [push, pull_request]
|
|
969
|
+
|
|
970
|
+
jobs:
|
|
971
|
+
audit:
|
|
972
|
+
runs-on: ubuntu-latest
|
|
973
|
+
steps:
|
|
974
|
+
- uses: actions/checkout@v3
|
|
975
|
+
|
|
976
|
+
- name: set up python
|
|
977
|
+
uses: actions/setup-python@v4
|
|
978
|
+
with:
|
|
979
|
+
python-version: '3.11'
|
|
980
|
+
|
|
981
|
+
- name: install dependencies
|
|
982
|
+
run: |
|
|
983
|
+
pip install pip-audit
|
|
984
|
+
|
|
985
|
+
- name: run security audit
|
|
986
|
+
run: |
|
|
987
|
+
pip-audit -r requirements.txt
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
github actions - npm audit
|
|
991
|
+
|
|
992
|
+
name: dependency check
|
|
993
|
+
|
|
994
|
+
on: [push, pull_request]
|
|
995
|
+
|
|
996
|
+
jobs:
|
|
997
|
+
audit:
|
|
998
|
+
runs-on: ubuntu-latest
|
|
999
|
+
steps:
|
|
1000
|
+
- uses: actions/checkout@v3
|
|
1001
|
+
|
|
1002
|
+
- name: setup node
|
|
1003
|
+
uses: actions/setup-node@v3
|
|
1004
|
+
with:
|
|
1005
|
+
node-version: '20'
|
|
1006
|
+
|
|
1007
|
+
- name: install dependencies
|
|
1008
|
+
run: npm ci
|
|
1009
|
+
|
|
1010
|
+
- name: run audit
|
|
1011
|
+
run: npm audit --audit-level=high
|
|
1012
|
+
continue-on-error: true
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
pre-commit dependency hooks
|
|
1016
|
+
|
|
1017
|
+
# .pre-commit-config.yaml
|
|
1018
|
+
repos:
|
|
1019
|
+
- repo: local
|
|
1020
|
+
hooks:
|
|
1021
|
+
- id: pip-audit
|
|
1022
|
+
name: pip-audit
|
|
1023
|
+
entry: pip-audit -r requirements.txt
|
|
1024
|
+
language: system
|
|
1025
|
+
pass_filenames: false
|
|
1026
|
+
|
|
1027
|
+
- id: pip-outdated
|
|
1028
|
+
name: pip-outdated
|
|
1029
|
+
entry: pip list --outdated
|
|
1030
|
+
language: system
|
|
1031
|
+
pass_filenames: false
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
PHASE 13: DEPENDENCY VERSION CONFLICTS
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
identify conflicts
|
|
1038
|
+
|
|
1039
|
+
<terminal>pip install package-a package-b</terminal>
|
|
1040
|
+
|
|
1041
|
+
if conflict occurs:
|
|
1042
|
+
ERROR: pip's dependency resolver does not currently take into account
|
|
1043
|
+
all the packages that are installed...
|
|
1044
|
+
|
|
1045
|
+
<terminal>pipdeptree --warn conflict</terminal>
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
resolve conflicts manually
|
|
1049
|
+
|
|
1050
|
+
strategy 1: find compatible versions
|
|
1051
|
+
<terminal>pip install package-a==1.2.3 package-b==4.5.6</terminal>
|
|
1052
|
+
|
|
1053
|
+
strategy 2: use pipdeptree to find source
|
|
1054
|
+
<terminal>pipdeptree -r | grep package-name</terminal>
|
|
1055
|
+
|
|
1056
|
+
strategy 3: check if packages actually conflict
|
|
1057
|
+
- sometimes dependencies are too strict
|
|
1058
|
+
- check if versions are actually incompatible
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
override constraints
|
|
1062
|
+
|
|
1063
|
+
create constraints.txt:
|
|
1064
|
+
package-a==1.2.3
|
|
1065
|
+
package-b==4.5.6
|
|
1066
|
+
|
|
1067
|
+
install with constraints:
|
|
1068
|
+
<terminal>pip install -c constraints.txt package-c</terminal>
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
javascript conflicts
|
|
1072
|
+
|
|
1073
|
+
<terminal>npm ls</terminal>
|
|
1074
|
+
|
|
1075
|
+
<terminal>npm dedupe</terminal>
|
|
1076
|
+
|
|
1077
|
+
force resolution (package.json):
|
|
1078
|
+
"overrides": {
|
|
1079
|
+
"package-a": "1.2.3"
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
PHASE 14: DEPENDENCY DOCUMENTATION
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
readme dependencies section
|
|
1087
|
+
|
|
1088
|
+
# Dependencies
|
|
1089
|
+
|
|
1090
|
+
This project uses Python 3.11+
|
|
1091
|
+
|
|
1092
|
+
## Installation
|
|
1093
|
+
|
|
1094
|
+
```bash
|
|
1095
|
+
python -m venv .venv
|
|
1096
|
+
source .venv/bin/activate
|
|
1097
|
+
pip install -r requirements.txt
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
## Development Dependencies
|
|
1101
|
+
|
|
1102
|
+
```bash
|
|
1103
|
+
pip install -r requirements-dev.txt
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
changelog dependency updates
|
|
1108
|
+
|
|
1109
|
+
## [1.2.0] - 2024-01-15
|
|
1110
|
+
|
|
1111
|
+
### Changed
|
|
1112
|
+
- Upgraded Django from 4.2.0 to 4.2.7
|
|
1113
|
+
- Upgraded requests from 2.28.0 to 2.31.0
|
|
1114
|
+
|
|
1115
|
+
### Fixed
|
|
1116
|
+
- Applied security patch for urllib3
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
dependency policy document
|
|
1120
|
+
|
|
1121
|
+
create docs/dependency-policy.md:
|
|
1122
|
+
|
|
1123
|
+
# Dependency Policy
|
|
1124
|
+
|
|
1125
|
+
## Version Pinning
|
|
1126
|
+
- Production: strict pinning (==)
|
|
1127
|
+
- Development: compatible release (~=)
|
|
1128
|
+
|
|
1129
|
+
## Security
|
|
1130
|
+
- Run pip-audit weekly
|
|
1131
|
+
- Address high/critical within 7 days
|
|
1132
|
+
- Dependabot enabled
|
|
1133
|
+
|
|
1134
|
+
## Updates
|
|
1135
|
+
- Review updates monthly
|
|
1136
|
+
- Test in dev before staging
|
|
1137
|
+
- Update changelog
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
PHASE 15: MULTIPLE PYTHON VERSIONS
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
pyenv (macos/linux)
|
|
1144
|
+
|
|
1145
|
+
install:
|
|
1146
|
+
<terminal>brew install pyenv</terminal>
|
|
1147
|
+
|
|
1148
|
+
install python versions:
|
|
1149
|
+
<terminal>pyenv install 3.11.0</terminal>
|
|
1150
|
+
<terminal>pyenv install 3.12.0</terminal>
|
|
1151
|
+
|
|
1152
|
+
set local version:
|
|
1153
|
+
<terminal>pyenv local 3.11.0</terminal>
|
|
1154
|
+
|
|
1155
|
+
set global version:
|
|
1156
|
+
<terminal>pyenv global 3.11.0</terminal>
|
|
1157
|
+
|
|
1158
|
+
list versions:
|
|
1159
|
+
<terminal>pyenv versions</terminal>
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
tox (multi-version testing)
|
|
1163
|
+
|
|
1164
|
+
install:
|
|
1165
|
+
<terminal>pip install tox</terminal>
|
|
1166
|
+
|
|
1167
|
+
create tox.ini:
|
|
1168
|
+
[tox]
|
|
1169
|
+
envlist = py39,py310,py311,py312
|
|
1170
|
+
|
|
1171
|
+
[testenv]
|
|
1172
|
+
deps =
|
|
1173
|
+
pytest
|
|
1174
|
+
pytest-cov
|
|
1175
|
+
commands =
|
|
1176
|
+
pytest
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
uv for multi-version
|
|
1180
|
+
|
|
1181
|
+
<terminal>uv venv --python 3.11</terminal>
|
|
1182
|
+
|
|
1183
|
+
<terminal>uv venv --python 3.12</terminal>
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
PHASE 16: PRIVATE PACKAGES
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
private pypi server
|
|
1190
|
+
|
|
1191
|
+
# .pypirc
|
|
1192
|
+
[distutils]
|
|
1193
|
+
index-servers =
|
|
1194
|
+
private
|
|
1195
|
+
pypi
|
|
1196
|
+
|
|
1197
|
+
[private]
|
|
1198
|
+
repository = https://pypi.example.com
|
|
1199
|
+
username = your-username
|
|
1200
|
+
password = your-password
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
install from private:
|
|
1204
|
+
<terminal>pip install --index-url https://pypi.example.com simple/ mypackage</terminal>
|
|
1205
|
+
|
|
1206
|
+
<terminal>pip install --extra-index-url https://pypi.example.com simple/ mypackage</terminal>
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
artifactory setup
|
|
1210
|
+
|
|
1211
|
+
<terminal>pip install -r requirements.txt --index-url https://repo.example.com/artifactory/api/pypi/simple</terminal>
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
github packages
|
|
1215
|
+
|
|
1216
|
+
create ~/.pip/pip.conf:
|
|
1217
|
+
[global]
|
|
1218
|
+
extra-index-url = https://<username>:<token>@raw.githubusercontent.com/<org>/<repo>/main/packages/
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
PHASE 17: DEPENDENCY MONITORING
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
set up alerts
|
|
1225
|
+
|
|
1226
|
+
dependabot:
|
|
1227
|
+
- auto-creates prs for updates
|
|
1228
|
+
- supports security alerts
|
|
1229
|
+
- configurable schedules
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
renovate bot
|
|
1233
|
+
|
|
1234
|
+
alternative to dependabot:
|
|
1235
|
+
- more configuration options
|
|
1236
|
+
- supports more languages
|
|
1237
|
+
- auto-merge minor updates
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
snyk monitoring
|
|
1241
|
+
|
|
1242
|
+
<terminal>snyk monitor</terminal>
|
|
1243
|
+
|
|
1244
|
+
- continuous monitoring
|
|
1245
|
+
- email alerts for new vulns
|
|
1246
|
+
- pr automation
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
phylum (supply chain security)
|
|
1250
|
+
|
|
1251
|
+
<terminal>pip install phylum-cli</terminal>
|
|
1252
|
+
|
|
1253
|
+
analyze before install:
|
|
1254
|
+
<terminal>phylum analyze</terminal>
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
PHASE 18: DISASTER RECOVERY
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
corrupted venv recovery
|
|
1261
|
+
|
|
1262
|
+
<terminal>rm -rf .venv</terminal>
|
|
1263
|
+
<terminal>python -m venv .venv</terminal>
|
|
1264
|
+
<terminal>source .venv/bin/activate</terminal>
|
|
1265
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
locked out of account recovery
|
|
1269
|
+
|
|
1270
|
+
if private repo access lost:
|
|
1271
|
+
- have backup of packages
|
|
1272
|
+
- document all custom packages
|
|
1273
|
+
- maintain local mirror
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
broken dependency rollback
|
|
1277
|
+
|
|
1278
|
+
<terminal>pip install --force-reinstall package==old.version</terminal>
|
|
1279
|
+
|
|
1280
|
+
<terminal>git checkout requirements.txt</terminal>
|
|
1281
|
+
<terminal>pip install -r requirements.txt</terminal>
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
requirements.txt lost recovery
|
|
1285
|
+
|
|
1286
|
+
try to reconstruct:
|
|
1287
|
+
<terminal>pip freeze > requirements-recovered.txt</terminal>
|
|
1288
|
+
|
|
1289
|
+
check git history:
|
|
1290
|
+
<terminal>git log requirements.txt</terminal>
|
|
1291
|
+
<terminal>git show oldcommit:requirements.txt > requirements.txt</terminal>
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
PHASE 19: DEPENDENCY RULES (MANDATORY)
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
while this skill is active, these rules are MANDATORY:
|
|
1298
|
+
|
|
1299
|
+
[1] ALWAYS use virtual environments
|
|
1300
|
+
never install to system python
|
|
1301
|
+
<terminal>python -m venv .venv && source .venv/bin/activate</terminal>
|
|
1302
|
+
|
|
1303
|
+
[2] NEVER commit .venv or venv directories
|
|
1304
|
+
add to .gitignore immediately
|
|
1305
|
+
<terminal>echo ".venv/" >> .gitignore</terminal>
|
|
1306
|
+
|
|
1307
|
+
[3] ALWAYS pin dependencies in production
|
|
1308
|
+
use == for frozen requirements
|
|
1309
|
+
use ~= for development specs
|
|
1310
|
+
|
|
1311
|
+
[4] RUN security audit before deploying
|
|
1312
|
+
<terminal>pip-audit -r requirements.txt</terminal>
|
|
1313
|
+
|
|
1314
|
+
[5] RUN tests after dependency updates
|
|
1315
|
+
<terminal>pytest</terminal>
|
|
1316
|
+
|
|
1317
|
+
[6] DOCUMENT why unusual versions are pinned
|
|
1318
|
+
add comments for version constraints
|
|
1319
|
+
# requests==2.28.0 # pinned for compatibility with X
|
|
1320
|
+
|
|
1321
|
+
[7] NEVER mix package managers in one project
|
|
1322
|
+
choose: pip, poetry, or pipenv
|
|
1323
|
+
not all three
|
|
1324
|
+
|
|
1325
|
+
[8] COMMIT lockfiles (poetry.lock, package-lock.json)
|
|
1326
|
+
these ensure reproducible installs
|
|
1327
|
+
|
|
1328
|
+
[9] REVIEW changelogs before major updates
|
|
1329
|
+
check for breaking changes
|
|
1330
|
+
plan migration if needed
|
|
1331
|
+
|
|
1332
|
+
[10] KEEP development dependencies separate
|
|
1333
|
+
use requirements/dev.txt or [project.optional-dependencies]
|
|
1334
|
+
|
|
1335
|
+
[11] RUN dependency checks in ci/cd
|
|
1336
|
+
fail build on high severity vulnerabilities
|
|
1337
|
+
|
|
1338
|
+
[12] MAINTAIN a dependency policy document
|
|
1339
|
+
version pinning strategy
|
|
1340
|
+
update procedures
|
|
1341
|
+
security response plan
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
FINAL REMINDERS
|
|
1345
|
+
|
|
1346
|
+
|
|
1347
|
+
dependencies are a contract
|
|
1348
|
+
|
|
1349
|
+
when you add a dependency:
|
|
1350
|
+
- you trust the maintainer
|
|
1351
|
+
- you accept their license
|
|
1352
|
+
- you inherit their vulnerabilities
|
|
1353
|
+
- you couple your project to their decisions
|
|
1354
|
+
|
|
1355
|
+
choose wisely.
|
|
1356
|
+
|
|
1357
|
+
|
|
1358
|
+
audit continuously
|
|
1359
|
+
|
|
1360
|
+
security is not a one-time event.
|
|
1361
|
+
new vulnerabilities are discovered daily.
|
|
1362
|
+
automate your audits.
|
|
1363
|
+
respond quickly to high/critical issues.
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
less is more
|
|
1367
|
+
|
|
1368
|
+
every dependency is:
|
|
1369
|
+
- attack surface
|
|
1370
|
+
- maintenance burden
|
|
1371
|
+
- potential breakage
|
|
1372
|
+
- license to review
|
|
1373
|
+
|
|
1374
|
+
question each addition.
|
|
1375
|
+
can you implement it yourself?
|
|
1376
|
+
is the dependency actively maintained?
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
update deliberately
|
|
1380
|
+
|
|
1381
|
+
automatic updates break production.
|
|
1382
|
+
controlled updates are safe.
|
|
1383
|
+
test in dev first.
|
|
1384
|
+
monitor in staging.
|
|
1385
|
+
deploy to production with confidence.
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
your skill is complete
|
|
1389
|
+
|
|
1390
|
+
when dependency management skill is active:
|
|
1391
|
+
- environments are verified before any action
|
|
1392
|
+
- versions are pinned appropriately
|
|
1393
|
+
- security is audited regularly
|
|
1394
|
+
- updates are deliberate and tested
|
|
1395
|
+
- documentation is maintained
|
|
1396
|
+
|
|
1397
|
+
go manage your dependencies with discipline.
|