0
# Context Management
1
2
Temporary state modification tools for managing directories, environment settings, output control, and SSH tunneling. Context managers ensure clean state restoration after operations complete and enable sophisticated nested operations with predictable behavior.
3
4
## Capabilities
5
6
### Directory Management
7
8
Context managers for temporarily changing working directories on both local and remote systems.
9
10
```python { .api }
11
def cd(path):
12
"""
13
Context manager for remote directory changes.
14
15
Args:
16
path (str): Remote directory path to change to
17
18
Context: Changes remote working directory temporarily
19
"""
20
21
def lcd(path):
22
"""
23
Context manager for local directory changes.
24
25
Args:
26
path (str): Local directory path to change to
27
28
Context: Changes local working directory temporarily
29
"""
30
```
31
32
**Usage Examples:**
33
34
```python
35
from fabric.api import cd, lcd, run, local
36
37
# Remote directory context
38
with cd('/var/www/myapp'):
39
run('git pull origin master')
40
run('npm install')
41
run('npm run build')
42
43
# Nested directory contexts
44
with cd('/opt'):
45
run('ls -la')
46
with cd('applications'):
47
run('pwd') # Shows /opt/applications
48
run('pwd') # Back to /opt
49
50
# Local directory context
51
with lcd('local-project'):
52
local('npm run build')
53
local('tar czf ../build.tar.gz dist/')
54
55
# Combine local and remote operations
56
with lcd('build'):
57
local('webpack --mode production')
58
with cd('/var/www'):
59
run('rm -rf old-build')
60
# Upload happens from local 'build' directory context
61
```
62
63
### Environment Settings
64
65
Comprehensive context manager for temporarily modifying Fabric's global environment and execution settings.
66
67
```python { .api }
68
def settings(*args, **kwargs):
69
"""
70
Context manager for temporary environment variable overrides and nested context managers.
71
72
Args:
73
*args: Other context managers to nest
74
**kwargs: Environment variables to temporarily override
75
76
Context: Temporarily modifies env settings and restores on exit
77
"""
78
```
79
80
**Usage Examples:**
81
82
```python
83
from fabric.api import settings, run, sudo, hide, env
84
85
# Temporarily change execution settings
86
with settings(warn_only=True):
87
result = run('command-that-might-fail')
88
if result.failed:
89
print("Command failed, but continuing...")
90
91
# Override connection settings
92
with settings(user='deploy', key_filename='/path/to/deploy_key'):
93
run('git pull')
94
sudo('systemctl restart nginx')
95
96
# Combine multiple settings
97
with settings(warn_only=True, parallel=True, pool_size=10):
98
run('apt-get update')
99
100
# Nest context managers within settings
101
with settings(hide('stdout', 'stderr'), warn_only=True):
102
result = run('silent-command')
103
104
# Temporarily modify complex settings
105
original_hosts = env.hosts
106
with settings(hosts=['server1.com', 'server2.com']):
107
run('uptime')
108
# env.hosts automatically restored to original_hosts
109
```
110
111
### Output Control
112
113
Context managers for controlling what output is displayed or hidden during command execution.
114
115
```python { .api }
116
def hide(*groups):
117
"""
118
Context manager to hide output groups.
119
120
Args:
121
*groups: Output groups to hide ('running', 'stdout', 'stderr', 'warnings', 'everything')
122
123
Context: Suppresses specified output types
124
"""
125
126
def show(*groups):
127
"""
128
Context manager to show output groups.
129
130
Args:
131
*groups: Output groups to show ('running', 'stdout', 'stderr', 'warnings', 'everything')
132
133
Context: Enables specified output types
134
"""
135
136
def quiet():
137
"""
138
Context manager equivalent to hide('everything') and settings(warn_only=True).
139
140
Context: Suppresses all output and continues on failures
141
"""
142
```
143
144
**Usage Examples:**
145
146
```python
147
from fabric.api import hide, show, quiet, run, local
148
149
# Hide specific output types
150
with hide('stdout'):
151
result = run('long-command-with-verbose-output')
152
# Only see running/stderr output, capture stdout in result
153
154
# Hide everything except errors
155
with hide('running', 'stdout'):
156
run('noisy-command')
157
158
# Show only specific output
159
with show('stderr'):
160
run('command-with-important-errors')
161
162
# Completely quiet execution
163
with quiet():
164
result = run('risky-command')
165
if result.failed:
166
print(f"Command failed silently: {result.return_code}")
167
168
# Nested output control
169
with hide('running'):
170
print("Starting deployment...")
171
with quiet():
172
run('backup-database') # Silent backup
173
run('deploy-application') # Show stdout but not running lines
174
```
175
176
### Environment Variables
177
178
Context manager for temporarily setting shell environment variables that will be available to executed commands.
179
180
```python { .api }
181
def shell_env(**kw):
182
"""
183
Context manager to set shell environment variables.
184
185
Args:
186
**kw: Environment variables to set (key=value pairs)
187
188
Context: Sets environment variables for command execution
189
"""
190
```
191
192
**Usage Examples:**
193
194
```python
195
from fabric.api import shell_env, run, local
196
197
# Set environment variables for commands
198
with shell_env(NODE_ENV='production', PORT='3000'):
199
run('npm start')
200
201
# Database connection settings
202
with shell_env(DB_HOST='localhost', DB_USER='myapp'):
203
run('python manage.py migrate')
204
205
# Temporarily override PATH
206
with shell_env(PATH='/usr/local/bin:/usr/bin:/bin'):
207
run('which python')
208
209
# Multiple environment contexts
210
with shell_env(RAILS_ENV='production'):
211
with shell_env(SECRET_KEY_BASE='abc123'):
212
run('rails server')
213
214
# Local environment variables
215
with shell_env(BUILD_ENV='staging'):
216
local('webpack --mode development')
217
```
218
219
### Path Modification
220
221
Context manager for temporarily modifying the PATH environment variable.
222
223
```python { .api }
224
def path(path, behavior='append'):
225
"""
226
Context manager to modify PATH environment variable.
227
228
Args:
229
path (str): Path to add to PATH variable
230
behavior (str): How to modify PATH ('append', 'prepend', 'replace')
231
232
Context: Temporarily modifies PATH environment variable
233
"""
234
```
235
236
**Usage Examples:**
237
238
```python
239
from fabric.api import path, run
240
241
# Add to end of PATH
242
with path('/usr/local/bin'):
243
run('which node') # Will find node in /usr/local/bin
244
245
# Add to beginning of PATH (takes precedence)
246
with path('/opt/python3.9/bin', behavior='prepend'):
247
run('python --version') # Uses /opt/python3.9/bin/python
248
249
# Temporarily replace PATH entirely
250
with path('/bin:/usr/bin', behavior='replace'):
251
run('echo $PATH') # Only shows /bin:/usr/bin
252
253
# Nested path modifications
254
with path('/usr/local/bin'):
255
with path('/opt/custom/bin', behavior='prepend'):
256
run('which custom-tool') # Finds in /opt/custom/bin first
257
```
258
259
### Command Prefixing
260
261
Context manager for prefixing all commands with a specific command sequence.
262
263
```python { .api }
264
def prefix(command):
265
"""
266
Context manager to prefix commands with given command + '&&'.
267
268
Args:
269
command (str): Command to prefix before all subsequent commands
270
271
Context: Prefixes all commands with specified command
272
"""
273
```
274
275
**Usage Examples:**
276
277
```python
278
from fabric.api import prefix, run
279
280
# Activate virtual environment for all commands
281
with prefix('source venv/bin/activate'):
282
run('python --version') # Runs: source venv/bin/activate && python --version
283
run('pip install -r requirements.txt')
284
285
# Set up environment before commands
286
with prefix('export NODE_ENV=production'):
287
run('npm start')
288
289
# Chain multiple prefixes
290
with prefix('cd /var/www/myapp'):
291
with prefix('source .env'):
292
run('python manage.py collectstatic')
293
run('python manage.py migrate')
294
295
# Database commands with connection setup
296
with prefix('export PGPASSWORD=secret'):
297
run('psql -U myuser -d mydb -c "SELECT version();"')
298
```
299
300
### SSH Tunneling
301
302
Context manager for creating SSH reverse tunnels during command execution.
303
304
```python { .api }
305
def remote_tunnel(remote_port, local_port=None, local_host="localhost", remote_bind_address="127.0.0.1"):
306
"""
307
Context manager for SSH reverse tunnels.
308
309
Args:
310
remote_port (int): Port on remote host to tunnel
311
local_port (int): Local port to tunnel to (default: same as remote_port)
312
local_host (str): Local host to tunnel to (default: localhost)
313
remote_bind_address (str): Remote address to bind to (default: 127.0.0.1)
314
315
Context: Creates SSH reverse tunnel for duration of context
316
"""
317
```
318
319
**Usage Examples:**
320
321
```python
322
from fabric.api import remote_tunnel, run, local
323
324
# Tunnel remote database to local port
325
with remote_tunnel(5432): # Remote PostgreSQL port 5432 -> local 5432
326
local('pg_dump -h localhost -p 5432 -U user remote_db > backup.sql')
327
328
# Tunnel to different local port
329
with remote_tunnel(3306, 13306): # Remote MySQL 3306 -> local 13306
330
local('mysql -h localhost -P 13306 -u user -p remote_db < migration.sql')
331
332
# Access remote web service locally
333
with remote_tunnel(8080, 8080):
334
local('curl http://localhost:8080/api/status')
335
336
# Multiple tunnels
337
with remote_tunnel(5432): # Database
338
with remote_tunnel(6379, 16379): # Redis
339
local('python manage.py migrate') # Uses tunneled database
340
local('redis-cli -p 16379 ping') # Uses tunneled Redis
341
```
342
343
### Convenience Shortcuts
344
345
Pre-configured context managers for common use cases.
346
347
```python { .api }
348
def warn_only():
349
"""
350
Context manager equivalent to settings(warn_only=True).
351
352
Context: Continue execution on command failures
353
"""
354
```
355
356
**Usage Examples:**
357
358
```python
359
from fabric.api import warn_only, quiet, settings, run
360
361
# Continue on failures without stopping
362
with warn_only():
363
run('service that-might-not-exist stop')
364
run('rm file-that-might-not-exist')
365
366
# Common pattern combinations
367
with settings(hide('warnings'), warn_only=True):
368
result = run('optional-cleanup-command')
369
370
# Equivalent to quiet() but more explicit
371
with settings(hide('everything'), warn_only=True):
372
run('background-task')
373
```
374
375
## Nesting and Composition
376
377
Context managers can be freely nested and combined:
378
379
```python
380
from fabric.api import *
381
382
# Complex nested context
383
with settings(hosts=['web1.com', 'web2.com']):
384
with cd('/var/www/myapp'):
385
with shell_env(RAILS_ENV='production'):
386
with hide('stdout'):
387
with warn_only():
388
run('bundle exec rake assets:precompile')
389
390
# Equivalent using settings composition
391
with settings(
392
hosts=['web1.com', 'web2.com'],
393
cd('/var/www/myapp'),
394
shell_env(RAILS_ENV='production'),
395
hide('stdout'),
396
warn_only=True
397
):
398
run('bundle exec rake assets:precompile')
399
```