or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-definition.mdcore-classes.mdexception-handling.mdindex.mdparameter-types.mdterminal-ui.mdutilities.md

parameter-types.mddocs/

0

# Parameter Types and Validation

1

2

Rich type system for command-line parameter validation and conversion, including built-in types for common data formats and custom type creation. Click's type system ensures user input is properly validated and converted to the expected Python types.

3

4

## Capabilities

5

6

### Base Parameter Type

7

8

Foundation class for all parameter types with validation and conversion capabilities.

9

10

```python { .api }

11

class ParamType:

12

"""

13

Base class for all parameter types.

14

15

Attributes:

16

- name: str, descriptive name of the type

17

- is_composite: bool, whether type expects multiple values

18

- arity: int, number of arguments expected

19

- envvar_list_splitter: str, character to split env var lists

20

"""

21

22

def convert(self, value, param, ctx):

23

"""

24

Convert value to the correct type.

25

26

Parameters:

27

- value: Input value to convert

28

- param: Parameter instance

29

- ctx: Current context

30

31

Returns:

32

Converted value

33

34

Raises:

35

BadParameter: If conversion fails

36

"""

37

38

def fail(self, message, param=None, ctx=None):

39

"""Raise BadParameter with message."""

40

41

def get_metavar(self, param, ctx):

42

"""Get metavar string for help display."""

43

44

def get_missing_message(self, param, ctx):

45

"""Get message for missing required parameter."""

46

47

def shell_complete(self, ctx, param, incomplete):

48

"""Return shell completions for this type."""

49

```

50

51

### Built-in Simple Types

52

53

Basic parameter types for common data formats.

54

55

```python { .api }

56

STRING: StringParamType

57

"""String parameter type that handles encoding and conversion."""

58

59

INT: IntParamType

60

"""Integer parameter type with validation."""

61

62

FLOAT: FloatParamType

63

"""Float parameter type with validation."""

64

65

BOOL: BoolParamType

66

"""Boolean parameter type supporting various string representations."""

67

68

UUID: UUIDParameterType

69

"""UUID parameter type that converts to uuid.UUID objects."""

70

71

UNPROCESSED: UnprocessedParamType

72

"""Unprocessed type that passes values through without conversion."""

73

```

74

75

**Usage Examples:**

76

77

```python

78

@click.command()

79

@click.option('--name', type=click.STRING, help='Your name')

80

@click.option('--age', type=click.INT, help='Your age')

81

@click.option('--height', type=click.FLOAT, help='Height in meters')

82

@click.option('--verbose', type=click.BOOL, help='Enable verbose output')

83

@click.option('--session-id', type=click.UUID, help='Session UUID')

84

def profile(name, age, height, verbose, session_id):

85

"""Update user profile."""

86

click.echo(f'Name: {name} (type: {type(name).__name__})')

87

click.echo(f'Age: {age} (type: {type(age).__name__})')

88

click.echo(f'Height: {height}m (type: {type(height).__name__})')

89

click.echo(f'Verbose: {verbose} (type: {type(verbose).__name__})')

90

click.echo(f'Session: {session_id} (type: {type(session_id).__name__})')

91

```

92

93

### Choice Types

94

95

Restrict parameter values to a predefined set of options.

96

97

```python { .api }

98

class Choice(ParamType):

99

def __init__(self, choices, case_sensitive=True):

100

"""

101

Parameter type that restricts values to a fixed set.

102

103

Parameters:

104

- choices: Sequence of valid choice strings

105

- case_sensitive: Whether matching is case sensitive

106

"""

107

108

def get_metavar(self, param, ctx):

109

"""Return metavar showing available choices."""

110

111

def get_missing_message(self, param, ctx):

112

"""Return message showing available choices."""

113

114

def shell_complete(self, ctx, param, incomplete):

115

"""Complete with matching choices."""

116

```

117

118

**Usage Examples:**

119

120

```python

121

@click.command()

122

@click.option('--log-level',

123

type=click.Choice(['DEBUG', 'INFO', 'WARNING', 'ERROR']),

124

default='INFO',

125

help='Set logging level')

126

@click.option('--format',

127

type=click.Choice(['json', 'xml', 'csv'], case_sensitive=False),

128

help='Output format')

129

def export(log_level, format):

130

"""Export data with specified format."""

131

click.echo(f'Log level: {log_level}')

132

click.echo(f'Format: {format}')

133

```

134

135

### Range Types

136

137

Numeric types with minimum and maximum constraints.

138

139

```python { .api }

140

class IntRange(IntParamType):

141

def __init__(self, min=None, max=None, min_open=False, max_open=False, clamp=False):

142

"""

143

Integer type with range constraints.

144

145

Parameters:

146

- min: Minimum value (inclusive by default)

147

- max: Maximum value (inclusive by default)

148

- min_open: Whether minimum bound is exclusive

149

- max_open: Whether maximum bound is exclusive

150

- clamp: Clamp out-of-range values instead of failing

151

"""

152

153

class FloatRange(FloatParamType):

154

def __init__(self, min=None, max=None, min_open=False, max_open=False, clamp=False):

155

"""

156

Float type with range constraints.

157

158

Parameters:

159

- min: Minimum value (inclusive by default)

160

- max: Maximum value (inclusive by default)

161

- min_open: Whether minimum bound is exclusive

162

- max_open: Whether maximum bound is exclusive

163

- clamp: Clamp out-of-range values instead of failing

164

"""

165

```

166

167

**Usage Examples:**

168

169

```python

170

@click.command()

171

@click.option('--port', type=click.IntRange(1, 65535),

172

help='Port number (1-65535)')

173

@click.option('--timeout', type=click.FloatRange(0.1, 300.0),

174

default=30.0, help='Timeout in seconds')

175

@click.option('--percentage', type=click.IntRange(0, 100, clamp=True),

176

help='Percentage (clamped to 0-100)')

177

def connect(port, timeout, percentage):

178

"""Connect with validation."""

179

click.echo(f'Port: {port}')

180

click.echo(f'Timeout: {timeout}s')

181

click.echo(f'Percentage: {percentage}%')

182

```

183

184

### Date and Time Types

185

186

Handle date and time parsing with multiple format support.

187

188

```python { .api }

189

class DateTime(ParamType):

190

def __init__(self, formats=None):

191

"""

192

DateTime parameter type.

193

194

Parameters:

195

- formats: List of strptime format strings to try

196

(defaults to common ISO formats)

197

"""

198

199

def get_metavar(self, param, ctx):

200

"""Return metavar showing expected formats."""

201

```

202

203

**Usage Examples:**

204

205

```python

206

@click.command()

207

@click.option('--start-date',

208

type=click.DateTime(['%Y-%m-%d', '%m/%d/%Y']),

209

help='Start date (YYYY-MM-DD or MM/DD/YYYY)')

210

@click.option('--timestamp',

211

type=click.DateTime(['%Y-%m-%d %H:%M:%S']),

212

help='Timestamp (YYYY-MM-DD HH:MM:SS)')

213

def schedule(start_date, timestamp):

214

"""Schedule operation."""

215

click.echo(f'Start date: {start_date}')

216

click.echo(f'Timestamp: {timestamp}')

217

click.echo(f'Date type: {type(start_date).__name__}')

218

```

219

220

### File and Path Types

221

222

Handle file operations and path validation with comprehensive options.

223

224

```python { .api }

225

class File(ParamType):

226

def __init__(self, mode="r", encoding=None, errors="strict", lazy=None, atomic=False):

227

"""

228

File parameter type for reading/writing files.

229

230

Parameters:

231

- mode: File open mode ('r', 'w', 'a', 'rb', 'wb', etc.)

232

- encoding: Text encoding (None for binary modes)

233

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

234

- lazy: Open file lazily on first access

235

- atomic: Write to temporary file then move (for write modes)

236

"""

237

238

class Path(ParamType):

239

def __init__(self, exists=False, file_okay=True, dir_okay=True,

240

writable=False, readable=True, resolve_path=False,

241

allow_dash=False, path_type=None, executable=False):

242

"""

243

Path parameter type with validation.

244

245

Parameters:

246

- exists: Path must exist

247

- file_okay: Allow files

248

- dir_okay: Allow directories

249

- writable: Path must be writable

250

- readable: Path must be readable

251

- resolve_path: Make absolute and resolve symlinks

252

- allow_dash: Allow '-' for stdin/stdout

253

- path_type: Convert to this type (str, bytes, pathlib.Path)

254

- executable: Path must be executable

255

"""

256

257

def shell_complete(self, ctx, param, incomplete):

258

"""Provide path completion."""

259

```

260

261

**Usage Examples:**

262

263

```python

264

@click.command()

265

@click.option('--input', type=click.File('r'), help='Input file')

266

@click.option('--output', type=click.File('w'), help='Output file')

267

@click.option('--config',

268

type=click.Path(exists=True, readable=True),

269

help='Configuration file path')

270

@click.option('--log-dir',

271

type=click.Path(exists=True, dir_okay=True, file_okay=False, writable=True),

272

help='Log directory')

273

def process(input, output, config, log_dir):

274

"""Process files."""

275

content = input.read()

276

output.write(f'Processed: {content}')

277

click.echo(f'Config: {config}')

278

click.echo(f'Log directory: {log_dir}')

279

280

# Using pathlib.Path

281

from pathlib import Path

282

283

@click.command()

284

@click.option('--workspace',

285

type=click.Path(path_type=Path, exists=True, dir_okay=True),

286

help='Workspace directory')

287

def workspace_cmd(workspace):

288

"""Work with pathlib.Path objects."""

289

click.echo(f'Workspace: {workspace}')

290

click.echo(f'Absolute path: {workspace.absolute()}')

291

click.echo(f'Is directory: {workspace.is_dir()}')

292

```

293

294

### Composite Types

295

296

Handle multiple values and complex data structures.

297

298

```python { .api }

299

class Tuple(ParamType):

300

def __init__(self, types):

301

"""

302

Tuple parameter type for multiple typed values.

303

304

Parameters:

305

- types: Sequence of ParamType instances for each tuple element

306

307

Attributes:

308

- is_composite: True

309

- arity: Length of types sequence

310

"""

311

312

def convert(self, value, param, ctx):

313

"""Convert each tuple element with corresponding type."""

314

```

315

316

**Usage Examples:**

317

318

```python

319

@click.command()

320

@click.option('--point',

321

type=click.Tuple([click.FLOAT, click.FLOAT]),

322

help='2D coordinate (x y)')

323

@click.option('--range',

324

type=click.Tuple([click.INT, click.INT, click.STRING]),

325

help='Range specification (start end unit)')

326

def geometry(point, range):

327

"""Work with tuples."""

328

if point:

329

x, y = point

330

click.echo(f'Point: ({x}, {y})')

331

332

if range:

333

start, end, unit = range

334

click.echo(f'Range: {start}-{end} {unit}')

335

```

336

337

### Custom Parameter Types

338

339

Create custom parameter types for specialized validation and conversion.

340

341

```python

342

# Custom email type

343

class EmailType(click.ParamType):

344

name = "email"

345

346

def convert(self, value, param, ctx):

347

import re

348

if not re.match(r'^[^@]+@[^@]+\.[^@]+$', value):

349

self.fail(f'{value} is not a valid email address', param, ctx)

350

return value

351

352

EMAIL = EmailType()

353

354

# Custom JSON type

355

class JSONType(click.ParamType):

356

name = "json"

357

358

def convert(self, value, param, ctx):

359

import json

360

try:

361

return json.loads(value)

362

except json.JSONDecodeError as e:

363

self.fail(f'Invalid JSON: {e}', param, ctx)

364

365

JSON = JSONType()

366

367

@click.command()

368

@click.option('--email', type=EMAIL, help='Email address')

369

@click.option('--config', type=JSON, help='JSON configuration')

370

def custom_types(email, config):

371

"""Example using custom types."""

372

click.echo(f'Email: {email}')

373

click.echo(f'Config: {config}')

374

```