or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdclient.mdconfiguration.mdindex.mdmodels.mdplugins.mdsessions.mdutilities.md

plugins.mddocs/

0

# Plugin Development

1

2

HTTPie provides an extensible plugin system that allows developers to add custom authentication methods, output formatters, content converters, and transport adapters.

3

4

```python

5

from httpie.plugins.base import BasePlugin, AuthPlugin, FormatterPlugin, ConverterPlugin, TransportPlugin

6

from httpie.plugins.registry import plugin_manager

7

from typing import Tuple

8

import requests.auth

9

```

10

11

## Capabilities

12

13

### Base Plugin Class

14

15

All HTTPie plugins inherit from the base plugin class and are automatically discovered when installed.

16

17

```python { .api }

18

class BasePlugin:

19

"""Base class for all HTTPie plugins."""

20

name: str = None # Plugin display name

21

description: str = None # Short description for help text

22

package_name: str = None # Set automatically when loaded

23

```

24

25

### Authentication Plugins

26

27

Create custom authentication methods for APIs that require non-standard authentication schemes.

28

29

```python { .api }

30

class AuthPlugin(BasePlugin):

31

"""Base class for authentication plugins."""

32

33

auth_type: str = None # Auth type identifier for --auth-type

34

auth_require: bool = True # Whether -a argument is required

35

auth_parse: bool = True # Whether to parse -a as username:password

36

netrc_parse: bool = False # Whether to use netrc as fallback

37

prompt_password: bool = True # Whether to prompt for missing password

38

raw_auth: str = None # Raw -a argument value

39

40

def get_auth(self, username: str = None, password: str = None):

41

"""

42

Return a requests.auth.AuthBase instance.

43

44

Args:

45

username: Parsed username (if auth_parse=True)

46

password: Parsed password (if auth_parse=True)

47

48

Returns:

49

requests.auth.AuthBase: Authentication handler

50

"""

51

raise NotImplementedError()

52

```

53

54

**Example Authentication Plugin:**

55

56

```python

57

from httpie.plugins import AuthPlugin

58

import requests.auth

59

60

class APIKeyAuthPlugin(AuthPlugin):

61

name = 'API Key Authentication'

62

description = 'API key in custom header'

63

auth_type = 'api-key'

64

auth_require = True

65

auth_parse = False # Don't parse as username:password

66

67

def get_auth(self, username=None, password=None):

68

# Use raw_auth as the API key

69

api_key = self.raw_auth

70

71

class APIKeyAuth(requests.auth.AuthBase):

72

def __call__(self, request):

73

request.headers['X-API-Key'] = api_key

74

return request

75

76

return APIKeyAuth()

77

78

# Usage: http --auth-type=api-key -a my-secret-key example.com/api

79

```

80

81

### Formatter Plugins

82

83

Customize how HTTPie displays HTTP messages, headers, and response bodies.

84

85

```python { .api }

86

class FormatterPlugin(BasePlugin):

87

"""Base class for output formatter plugins."""

88

89

group_name: str = 'format' # Plugin group identifier

90

enabled: bool = True # Whether formatter is enabled

91

format_options: dict # Formatting options from CLI

92

93

def __init__(self, **kwargs):

94

"""

95

Initialize formatter with options.

96

97

Args:

98

env: Environment instance

99

format_options: Dictionary of format options

100

**kwargs: Additional formatter arguments

101

"""

102

self.enabled = True

103

self.kwargs = kwargs

104

self.format_options = kwargs['format_options']

105

106

def format_headers(self, headers: str) -> str:

107

"""

108

Format HTTP headers for display.

109

110

Args:

111

headers: Raw headers as string

112

113

Returns:

114

str: Formatted headers

115

"""

116

return headers

117

118

def format_body(self, content: str, mime: str) -> str:

119

"""

120

Format response body for display.

121

122

Args:

123

content: Response body as string

124

mime: Content-Type MIME type (e.g., 'application/json')

125

126

Returns:

127

str: Formatted body content

128

"""

129

return content

130

131

def format_metadata(self, metadata: str) -> str:

132

"""

133

Format response metadata for display.

134

135

Args:

136

metadata: Metadata string

137

138

Returns:

139

str: Formatted metadata

140

"""

141

return metadata

142

```

143

144

### Converter Plugins

145

146

Transform binary response data into textual representations for terminal display.

147

148

```python { .api }

149

class ConverterPlugin(BasePlugin):

150

"""Base class for content converter plugins."""

151

152

def __init__(self, mime: str):

153

"""

154

Initialize converter for specific MIME type.

155

156

Args:

157

mime: MIME type this converter handles

158

"""

159

self.mime = mime

160

161

def convert(self, body: bytes) -> Tuple[str, str]:

162

"""

163

Convert binary body to textual representation.

164

165

Args:

166

body: Binary response body

167

168

Returns:

169

Tuple[str, str]: (new_content_type, converted_content)

170

"""

171

raise NotImplementedError()

172

173

@classmethod

174

def supports(cls, mime: str) -> bool:

175

"""

176

Check if this converter supports the given MIME type.

177

178

Args:

179

mime: MIME type to check

180

181

Returns:

182

bool: True if supported

183

"""

184

raise NotImplementedError()

185

```

186

187

**Example Converter Plugin:**

188

189

```python

190

from httpie.plugins import ConverterPlugin

191

import base64

192

193

class Base64ConverterPlugin(ConverterPlugin):

194

name = 'Base64 Decoder'

195

description = 'Decode base64 content for display'

196

197

@classmethod

198

def supports(cls, mime):

199

return mime == 'application/base64'

200

201

def convert(self, body):

202

try:

203

decoded = base64.b64decode(body).decode('utf-8')

204

return 'text/plain', decoded

205

except Exception:

206

return 'text/plain', f'<base64 data: {len(body)} bytes>'

207

```

208

209

### Transport Plugins

210

211

Add support for custom protocols or modify how HTTPie handles HTTP transport.

212

213

```python { .api }

214

class TransportPlugin(BasePlugin):

215

"""Base class for transport adapter plugins."""

216

217

prefix: str = None # URL prefix to mount adapter to

218

219

def get_adapter(self):

220

"""

221

Return a requests transport adapter.

222

223

Returns:

224

requests.adapters.BaseAdapter: Transport adapter instance

225

"""

226

raise NotImplementedError()

227

```

228

229

**Example Transport Plugin:**

230

231

```python

232

from httpie.plugins import TransportPlugin

233

import requests.adapters

234

235

class CustomProtocolPlugin(TransportPlugin):

236

name = 'Custom Protocol'

237

description = 'Support for custom:// URLs'

238

prefix = 'custom://'

239

240

def get_adapter(self):

241

class CustomAdapter(requests.adapters.BaseAdapter):

242

def send(self, request, **kwargs):

243

# Custom request handling logic

244

response = requests.models.Response()

245

response.status_code = 200

246

response.headers['Content-Type'] = 'text/plain'

247

response._content = b'Custom protocol response'

248

return response

249

250

return CustomAdapter()

251

252

# Usage: http custom://example.com/resource

253

```

254

255

### Plugin Registration

256

257

HTTPie automatically discovers plugins installed in the Python environment. Plugins must be properly packaged and declare entry points.

258

259

**setup.py for plugin distribution:**

260

261

```python

262

from setuptools import setup

263

264

setup(

265

name='httpie-my-plugin',

266

version='1.0.0',

267

py_modules=['httpie_my_plugin'],

268

install_requires=['httpie>=3.0.0'],

269

entry_points={

270

'httpie.plugins.auth.v1': [

271

'my_auth = httpie_my_plugin:MyAuthPlugin'

272

],

273

'httpie.plugins.formatter.v1': [

274

'my_formatter = httpie_my_plugin:MyFormatterPlugin'

275

]

276

}

277

)

278

```

279

280

### Plugin Management

281

282

```python { .api }

283

# Plugin registry access

284

from httpie.plugins.registry import plugin_manager

285

286

def list_plugins() -> dict:

287

"""List all available plugins by type."""

288

289

def load_installed_plugins(plugins_dir: str) -> None:

290

"""Load plugins from the specified directory."""

291

```

292

293

### Built-in Plugins

294

295

HTTPie includes several built-in plugins:

296

297

- **Basic Auth**: Username/password authentication

298

- **Digest Auth**: HTTP Digest authentication

299

- **JSON Formatter**: Pretty-print JSON responses

300

- **XML Formatter**: Format XML responses

301

- **Colors Formatter**: Syntax highlighting

302

303

### Error Handling

304

305

Plugins should handle errors gracefully and provide meaningful error messages:

306

307

```python

308

class MyAuthPlugin(AuthPlugin):

309

def get_auth(self, username=None, password=None):

310

if not self.raw_auth:

311

raise ValueError("API key is required")

312

313

try:

314

# Plugin logic here

315

return MyAuth(self.raw_auth)

316

except Exception as e:

317

raise ValueError(f"Authentication setup failed: {e}")

318

```

319

320

Plugin errors are reported with `ExitStatus.PLUGIN_ERROR` (exit code 7).