or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-operations.mdcustomization.mdindex.mdnotebook-integration.mdstatus-handling.md

basic-operations.mddocs/

0

# Basic Spinner Operations

1

2

Core functionality for creating, starting, stopping, and managing spinner lifecycle. Provides multiple usage patterns including context managers, decorators, and manual control.

3

4

## Capabilities

5

6

### Halo Constructor

7

8

Creates a new spinner instance with comprehensive configuration options for appearance and behavior.

9

10

```python { .api }

11

def __init__(

12

self,

13

text="",

14

color="cyan",

15

text_color=None,

16

spinner=None,

17

animation=None,

18

placement="left",

19

interval=-1,

20

enabled=True,

21

stream=sys.stdout

22

):

23

"""

24

Initialize a Halo spinner.

25

26

Parameters:

27

- text (str): Text to display alongside spinner (default: "")

28

- color (str): Spinner color - "cyan", "red", "green", etc. (default: "cyan")

29

- text_color (str): Text color, same options as color (default: None)

30

- spinner (str|dict): Spinner type name or custom spinner definition (default: "dots")

31

- animation (str): Text animation for long strings - "bounce", "marquee" (default: None)

32

- placement (str): Spinner position - "left" or "right" (default: "left")

33

- interval (int): Frame interval in milliseconds, -1 for spinner default (default: -1)

34

- enabled (bool): Whether spinner is active (default: True)

35

- stream (io.TextIOWrapper): Output stream (default: sys.stdout)

36

"""

37

```

38

39

### Manual Spinner Control

40

41

Start and stop spinners manually with full control over timing and lifecycle.

42

43

```python { .api }

44

def start(self, text=None):

45

"""

46

Start the spinner on a separate thread.

47

48

Parameters:

49

- text (str, optional): Update spinner text when starting

50

51

Returns:

52

- Halo: Self for method chaining

53

"""

54

55

def stop(self):

56

"""

57

Stop the spinner and clear the line.

58

59

Returns:

60

- Halo: Self for method chaining

61

"""

62

63

def clear(self):

64

"""

65

Clear the current line and return cursor to start.

66

67

Returns:

68

- Halo: Self for method chaining

69

"""

70

71

def render(self):

72

"""

73

Manually render frames in a loop until stopped.

74

75

Returns:

76

- Halo: Self for method chaining

77

"""

78

79

def frame(self):

80

"""

81

Build and return the next frame to be rendered.

82

83

Returns:

84

- str: Complete frame string with spinner and text

85

"""

86

87

def text_frame(self):

88

"""

89

Build and return the text portion of the frame.

90

91

Returns:

92

- str: Text frame with color and animation applied

93

"""

94

```

95

96

**Usage Example:**

97

98

```python

99

from halo import Halo

100

import time

101

102

# Basic manual control

103

spinner = Halo(text='Loading data', spinner='dots')

104

spinner.start()

105

106

# Update text while running

107

time.sleep(1)

108

spinner.text = 'Processing data'

109

time.sleep(1)

110

spinner.text = 'Saving results'

111

time.sleep(1)

112

113

spinner.stop()

114

```

115

116

### Context Manager Support

117

118

Use spinners in `with` statements for automatic lifecycle management and exception safety.

119

120

```python { .api }

121

def __enter__(self):

122

"""

123

Start spinner for context manager usage.

124

125

Returns:

126

- Halo: Self instance

127

"""

128

129

def __exit__(self, type, value, traceback):

130

"""

131

Stop spinner when exiting context.

132

133

Parameters:

134

- type: Exception type (if any)

135

- value: Exception value (if any)

136

- traceback: Exception traceback (if any)

137

"""

138

```

139

140

**Usage Example:**

141

142

```python

143

from halo import Halo

144

import time

145

146

# Context manager automatically handles start/stop

147

with Halo(text='Loading', spinner='dots'):

148

time.sleep(2)

149

# Spinner automatically stops when exiting block

150

151

# Works with exceptions too

152

try:

153

with Halo(text='Risky operation', spinner='dots'):

154

time.sleep(1)

155

raise ValueError("Something went wrong")

156

except ValueError:

157

print("Exception occurred, spinner was cleaned up")

158

```

159

160

### Decorator Support

161

162

Apply spinners to functions as decorators for seamless integration with existing code.

163

164

```python { .api }

165

def __call__(self, f):

166

"""

167

Allow Halo instance to be used as function decorator.

168

169

Parameters:

170

- f (callable): Function to wrap with spinner

171

172

Returns:

173

- callable: Wrapped function

174

"""

175

```

176

177

**Usage Example:**

178

179

```python

180

from halo import Halo

181

import time

182

183

# Decorator with configuration

184

@Halo(text='Processing data', spinner='dots', color='green')

185

def process_data():

186

time.sleep(3)

187

return "processed_data"

188

189

# Function runs with spinner automatically

190

result = process_data()

191

192

# Reusable spinner decorator

193

spinner_decorator = Halo(text='Working', spinner='star')

194

195

@spinner_decorator

196

def task_one():

197

time.sleep(2)

198

199

@spinner_decorator

200

def task_two():

201

time.sleep(1)

202

203

task_one()

204

task_two()

205

```

206

207

### Spinner Status and Inspection

208

209

Get information about the current spinner state and thread ID.

210

211

```python { .api }

212

@property

213

def spinner_id(self):

214

"""

215

Get the thread ID of the currently running spinner.

216

217

Returns:

218

- str: Thread name/ID of the spinner thread, or None if not running

219

"""

220

```

221

222

**Usage Example:**

223

224

```python

225

from halo import Halo

226

import time

227

228

spinner = Halo(text='Processing', spinner='dots')

229

print(f"Spinner ID before start: {spinner.spinner_id}") # None

230

231

spinner.start()

232

print(f"Spinner ID while running: {spinner.spinner_id}") # Thread-1 (or similar)

233

234

time.sleep(1)

235

spinner.stop()

236

print(f"Spinner ID after stop: {spinner.spinner_id}") # None

237

```

238

239

## Advanced Usage Patterns

240

241

### Dynamic Text Updates

242

243

```python

244

spinner = Halo(text='Starting', spinner='dots')

245

spinner.start()

246

247

for i in range(1, 101):

248

spinner.text = f'Progress: {i}%'

249

time.sleep(0.1)

250

251

spinner.stop()

252

```

253

254

### Conditional Spinners

255

256

```python

257

import sys

258

259

# Disable spinner for non-interactive environments

260

spinner = Halo(

261

text='Processing',

262

enabled=sys.stdout.isatty() # Only show in terminal

263

)

264

265

with spinner:

266

time.sleep(2)

267

```

268

269

### Custom Output Streams

270

271

```python

272

import io

273

274

# Capture spinner output

275

buffer = io.StringIO()

276

spinner = Halo(text='Working', stream=buffer)

277

278

with spinner:

279

time.sleep(1)

280

281

# spinner output captured in buffer

282

```