or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

container-operations.mdcore-pty-management.mdindex.mdmain-entry-points.mdstream-management.mdterminal-control.md

container-operations.mddocs/

0

# Container Operations

1

2

Operation classes that abstract the differences between running containers and executing commands in existing containers. These classes implement the Operation interface and handle the specific details of Docker API interactions.

3

4

## Capabilities

5

6

### Run Operation

7

8

Handles `docker run`-like commands where you start a new container with PTY support.

9

10

```python { .api }

11

class RunOperation:

12

def __init__(self, client, container, interactive=True, stdout=None, stderr=None, stdin=None, logs=None):

13

"""

14

Initialize the PTY for docker run-like operations.

15

16

Parameters:

17

- client: Docker client instance

18

- container: Container dict or ID

19

- interactive: bool, whether to enable interactive mode (default: True)

20

- stdout: file-like object for stdout (default: sys.stdout)

21

- stderr: file-like object for stderr (default: sys.stderr)

22

- stdin: file-like object for stdin (default: sys.stdin)

23

- logs: int, whether to include logs (default: None, shows deprecation warning)

24

"""

25

26

def start(self, sockets=None, **kwargs):

27

"""

28

Present the PTY of the container inside the current process.

29

30

This will take over the current process' TTY until the container's PTY is closed.

31

If the container is not running, it will be started.

32

33

Parameters:

34

- sockets: tuple of (stdin_socket, stdout_socket, stderr_socket), optional

35

- **kwargs: Additional arguments passed to client.start()

36

37

Returns:

38

List of Pump instances for stream management

39

"""

40

41

def israw(self, **kwargs):

42

"""

43

Returns True if the PTY should operate in raw mode.

44

45

If the container was not started with tty=True, this will return False.

46

47

Parameters:

48

- **kwargs: Additional arguments (unused)

49

50

Returns:

51

bool - True if PTY should use raw mode

52

"""

53

54

def sockets(self):

55

"""

56

Returns a tuple of sockets connected to the pty (stdin,stdout,stderr).

57

58

If any of the sockets are not attached in the container, None is

59

returned in the tuple.

60

61

Returns:

62

tuple - (stdin_socket, stdout_socket, stderr_socket) or None for missing sockets

63

"""

64

65

def resize(self, height, width, **kwargs):

66

"""

67

Resize pty within container.

68

69

Parameters:

70

- height: int, terminal height in rows

71

- width: int, terminal width in columns

72

- **kwargs: Additional arguments (unused)

73

74

Returns:

75

None

76

"""

77

```

78

79

Usage example:

80

81

```python

82

import docker

83

from dockerpty import RunOperation, PseudoTerminal

84

85

client = docker.Client()

86

container = client.create_container(

87

image='alpine:latest',

88

stdin_open=True,

89

tty=True,

90

command='/bin/sh',

91

)

92

93

# Create and start operation

94

operation = RunOperation(client, container, interactive=True)

95

pty = PseudoTerminal(client, operation)

96

pty.start()

97

```

98

99

### Exec Operation

100

101

Handles `docker exec`-like commands where you execute a command in an existing running container.

102

103

```python { .api }

104

class ExecOperation:

105

def __init__(self, client, exec_id, interactive=True, stdout=None, stderr=None, stdin=None):

106

"""

107

Initialize the PTY for docker exec-like operations.

108

109

Parameters:

110

- client: Docker client instance

111

- exec_id: Exec instance ID (from client.exec_create())

112

- interactive: bool, whether to enable interactive mode (default: True)

113

- stdout: file-like object for stdout (default: sys.stdout)

114

- stderr: file-like object for stderr (default: sys.stderr)

115

- stdin: file-like object for stdin (default: sys.stdin)

116

"""

117

118

def start(self, sockets=None, **kwargs):

119

"""

120

Start execution of the exec command.

121

122

Parameters:

123

- sockets: socket for exec I/O, optional

124

- **kwargs: Additional arguments (unused)

125

126

Returns:

127

List of Pump instances for stream management

128

"""

129

130

def israw(self, **kwargs):

131

"""

132

Returns True if the PTY should operate in raw mode.

133

134

If the exec was not started with tty=True, this will return False.

135

136

Parameters:

137

- **kwargs: Additional arguments (unused)

138

139

Returns:

140

bool - True if PTY should use raw mode

141

"""

142

143

def sockets(self):

144

"""

145

Return a single socket which is processing all I/O to exec.

146

147

Returns:

148

Stream or Demuxer instance for exec I/O

149

"""

150

151

def resize(self, height, width, **kwargs):

152

"""

153

Resize pty of an execed process.

154

155

Parameters:

156

- height: int, terminal height in rows

157

- width: int, terminal width in columns

158

- **kwargs: Additional arguments (unused)

159

160

Returns:

161

None

162

"""

163

164

def is_process_tty(self):

165

"""

166

Does execed process have allocated tty?

167

168

Returns:

169

bool - True if process has TTY allocated

170

"""

171

```

172

173

Usage example:

174

175

```python

176

import docker

177

from dockerpty import ExecOperation, PseudoTerminal

178

179

client = docker.Client()

180

container_id = 'running_container_id'

181

182

# Create exec instance

183

exec_id = client.exec_create(container_id, '/bin/bash', tty=True, stdin=True)

184

185

# Create and start operation

186

operation = ExecOperation(client, exec_id['Id'], interactive=True)

187

pty = PseudoTerminal(client, operation)

188

pty.start()

189

```

190

191

### Exec Creation Utility

192

193

Convenience function for creating exec instances.

194

195

```python { .api }

196

def exec_create(client, container, command, interactive=True):

197

"""

198

Create exec instance for container.

199

200

Parameters:

201

- client: Docker client instance

202

- container: Container dict or ID

203

- command: str or list, command to execute

204

- interactive: bool, whether to enable interactive mode (default: True)

205

206

Returns:

207

dict - Exec instance information with 'Id' key

208

"""

209

```

210

211

Usage example:

212

213

```python

214

import docker

215

from dockerpty import exec_create

216

217

client = docker.Client()

218

container_id = 'running_container_id'

219

220

# Create exec instance

221

exec_id = exec_create(client, container_id, ['/bin/bash', '-l'])

222

print(exec_id['Id']) # Exec instance ID

223

```

224

225

### Operation Base Class

226

227

Abstract base class defining the operation interface.

228

229

```python { .api }

230

class Operation:

231

def israw(self, **kwargs):

232

"""Are we dealing with a tty or not?"""

233

raise NotImplementedError()

234

235

def start(self, **kwargs):

236

"""Start execution."""

237

raise NotImplementedError()

238

239

def resize(self, height, width, **kwargs):

240

"""If we have terminal, resize it."""

241

raise NotImplementedError()

242

243

def sockets(self):

244

"""Return sockets for streams."""

245

raise NotImplementedError()

246

```

247

248

## Key Differences

249

250

### RunOperation vs ExecOperation

251

252

**RunOperation** (for new containers):

253

- Can start stopped containers

254

- Returns separate stdin, stdout, stderr sockets

255

- Handles container lifecycle management

256

- Supports logs parameter for including container logs

257

258

**ExecOperation** (for existing containers):

259

- Works only with running containers

260

- Returns single multiplexed socket for all I/O

261

- Cannot distinguish stderr from stdout in current implementation

262

- More lightweight for command execution

263

264

### Stream Handling

265

266

- **RunOperation**: Uses separate streams that may be demultiplexed if no TTY

267

- **ExecOperation**: Uses single stream, always demultiplexed if no TTY

268

- Both support TTY mode for raw terminal interaction

269

270

## Error Handling

271

272

- Handles container inspection failures

273

- Manages resize failures (container may have exited)

274

- Supports graceful degradation when TTY is not available

275

- Properly handles Docker API connectivity issues