or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# hiredis

1

2

Python extension that wraps protocol parsing code in hiredis to significantly speed up parsing of Redis multi bulk replies. The library provides a Reader class for parsing replies from Redis data streams with support for Unicode decoding, customizable error handling, and efficient memory usage.

3

4

## Package Information

5

6

- **Package Name**: hiredis

7

- **Package Type**: pypi

8

- **Language**: Python

9

- **Installation**: `pip install hiredis`

10

- **Python Requirements**: Python 3.8+

11

12

## Core Imports

13

14

```python

15

import hiredis

16

```

17

18

Specific imports:

19

20

```python

21

from hiredis import Reader, pack_command, HiredisError, ProtocolError, ReplyError, PushNotification

22

```

23

24

## Basic Usage

25

26

```python

27

import hiredis

28

29

# Create a reader for parsing Redis replies

30

reader = hiredis.Reader()

31

32

# Feed data from Redis connection

33

reader.feed("$5\r\nhello\r\n")

34

35

# Extract parsed reply

36

reply = reader.gets() # Returns b'hello'

37

38

# Pack commands into Redis protocol format

39

packed = hiredis.pack_command(("SET", "key", "value"))

40

# Returns: b'*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n'

41

```

42

43

## Capabilities

44

45

### Redis Reply Parsing

46

47

The Reader class parses Redis protocol replies from data streams, providing efficient protocol parsing with configurable decoding and error handling.

48

49

```python { .api }

50

class Reader:

51

def __init__(

52

self,

53

protocolError: Callable[[str], Exception] = None,

54

replyError: Callable[[str], Exception] = None,

55

encoding: Optional[str] = None,

56

errors: Optional[str] = None,

57

notEnoughData: Any = False,

58

) -> None:

59

"""

60

Create a new Reader for parsing Redis replies.

61

62

Parameters:

63

- protocolError: Custom exception class/callable for protocol errors

64

- replyError: Custom exception class/callable for reply errors

65

- encoding: Text encoding for bulk data decoding (e.g., 'utf-8')

66

- errors: Error handling mode ('strict', 'replace', 'ignore', 'backslashreplace')

67

- notEnoughData: Custom sentinel returned when buffer lacks complete reply

68

"""

69

70

def feed(self, buf: Union[str, bytes], off: int = 0, len: int = -1) -> None:

71

"""

72

Feed data to the internal buffer for parsing.

73

74

Parameters:

75

- buf: Data to append to buffer (string or bytes)

76

- off: Starting offset in buffer (default: 0)

77

- len: Number of bytes to read (default: -1 for all)

78

"""

79

80

def gets(self, shouldDecode: bool = True) -> Any:

81

"""

82

Extract a reply from the buffer.

83

84

Parameters:

85

- shouldDecode: Whether to decode bulk data using configured encoding

86

87

Returns:

88

- Parsed reply data, or False if buffer lacks complete reply

89

- Returns notEnoughData sentinel if configured

90

"""

91

92

def setmaxbuf(self, maxbuf: Optional[int]) -> None:

93

"""

94

Set maximum buffer size to control memory usage.

95

96

Parameters:

97

- maxbuf: Maximum buffer size in bytes, None for unlimited

98

"""

99

100

def getmaxbuf(self) -> int:

101

"""

102

Get current maximum buffer size.

103

104

Returns:

105

- Current maximum buffer size in bytes

106

"""

107

108

def len(self) -> int:

109

"""

110

Get length of data in internal buffer.

111

112

Returns:

113

- Number of bytes in buffer

114

"""

115

116

def has_data(self) -> bool:

117

"""

118

Check if buffer contains any data.

119

120

Returns:

121

- True if buffer has data, False otherwise

122

"""

123

124

def set_encoding(

125

self, encoding: Optional[str] = None, errors: Optional[str] = None

126

) -> None:

127

"""

128

Update encoding configuration for bulk data decoding.

129

130

Parameters:

131

- encoding: Text encoding (e.g., 'utf-8'), None to disable decoding

132

- errors: Error handling mode ('strict', 'replace', 'ignore', 'backslashreplace')

133

"""

134

```

135

136

### Command Packing

137

138

Convert Python command tuples into Redis protocol format for transmission to Redis servers.

139

140

```python { .api }

141

def pack_command(cmd: Tuple[Union[str, int, float, bytes, memoryview], ...]) -> bytes:

142

"""

143

Pack command arguments into Redis protocol format.

144

145

Parameters:

146

- cmd: Tuple containing command and arguments

147

Supports: str, int, float, bytes, memoryview

148

149

Returns:

150

- Bytes object containing packed Redis protocol command

151

152

Raises:

153

- TypeError: If command contains unsupported argument types

154

"""

155

```

156

157

### Error Handling

158

159

Exception classes for different error conditions during Redis protocol parsing.

160

161

```python { .api }

162

class HiredisError(Exception):

163

"""Base exception class for all hiredis errors."""

164

165

class ProtocolError(HiredisError):

166

"""

167

Raised when protocol parsing fails due to corrupt data stream.

168

Indicates unrecoverable protocol state requiring reconnection.

169

"""

170

171

class ReplyError(HiredisError):

172

"""

173

Represents Redis error replies (-ERR responses).

174

This exception is returned by gets(), not raised.

175

"""

176

177

class PushNotification(list):

178

"""

179

Represents Redis push notifications in RESP3 protocol.

180

Extends list to contain notification data.

181

"""

182

```

183

184

### Version Information

185

186

```python { .api }

187

__version__: str

188

# Current package version string (e.g., "3.2.1")

189

```

190

191

## Usage Examples

192

193

### Unicode Decoding

194

195

```python

196

import hiredis

197

198

# Configure reader for UTF-8 decoding

199

reader = hiredis.Reader(encoding="utf-8", errors="strict")

200

reader.feed(b"$3\r\n\xe2\x98\x83\r\n") # UTF-8 snowman

201

reply = reader.gets() # Returns '☃' (string, not bytes)

202

```

203

204

### Custom Error Handling

205

206

```python

207

import hiredis

208

209

# Use custom exception classes

210

class MyProtocolError(Exception):

211

pass

212

213

class MyReplyError(Exception):

214

pass

215

216

reader = hiredis.Reader(

217

protocolError=MyProtocolError,

218

replyError=MyReplyError

219

)

220

221

# Protocol errors will raise MyProtocolError

222

# Reply errors will return MyReplyError instances

223

```

224

225

### Buffer Management

226

227

```python

228

import hiredis

229

230

reader = hiredis.Reader()

231

232

# Set buffer size limit

233

reader.setmaxbuf(1024 * 1024) # 1MB max

234

235

# Monitor buffer usage

236

print(f"Buffer size: {reader.len()} bytes")

237

print(f"Has data: {reader.has_data()}")

238

print(f"Max buffer: {reader.getmaxbuf()} bytes")

239

```

240

241

### Multi-Reply Processing

242

243

```python

244

import hiredis

245

246

reader = hiredis.Reader()

247

248

# Feed data containing multiple replies

249

reader.feed("$5\r\nhello\r\n$5\r\nworld\r\n")

250

251

# Extract all replies

252

replies = []

253

while True:

254

reply = reader.gets()

255

if reply is False: # No more complete replies

256

break

257

replies.append(reply)

258

259

print(replies) # [b'hello', b'world']

260

```

261

262

### Command Packing Examples

263

264

```python

265

import hiredis

266

267

# Basic command

268

cmd = hiredis.pack_command(("GET", "mykey"))

269

# Returns: b'*2\r\n$3\r\nGET\r\n$5\r\nmykey\r\n'

270

271

# Complex command with different data types

272

cmd = hiredis.pack_command((

273

"HSET", "hash", "field1", "value1",

274

b"field2", b"binary_value",

275

"field3", 42,

276

"field4", 3.14159

277

))

278

279

# Command with memoryview

280

data = memoryview(b"binary data")

281

cmd = hiredis.pack_command(("SET", "key", data))

282

```

283

284

## Performance Notes

285

286

- Provides significant performance improvements for parsing multi bulk replies

287

- Throughput improvements increase with reply size (up to 83x faster for large LRANGE operations)

288

- Reader instances are not thread-safe - use separate instances per thread

289

- Memory usage is controlled through buffer size limits

290

- Best used as a performance enhancement for Redis client libraries