or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-routing.mdindex.mdplugin-system.mdrequest-handling.mdresponse-management.mdserver-management.mdstatic-utilities.mdtemplate-rendering.md

static-utilities.mddocs/

0

# Static Files and Utilities

1

2

Static file serving, HTTP utilities, and helper functions for common web development tasks including file serving, security utilities, and HTTP helper functions.

3

4

## Capabilities

5

6

### Static File Serving

7

8

Serve static files with proper MIME types, caching headers, and security features.

9

10

```python { .api }

11

def static_file(filename, root, mimetype='auto', download=False, charset='UTF-8'):

12

"""

13

Serve static files with proper MIME types and caching headers.

14

15

Parameters:

16

- filename: str, file name to serve

17

- root: str, root directory path

18

- mimetype: str, MIME type ('auto' for automatic detection)

19

- download: bool, force download with Content-Disposition header

20

- charset: str, character encoding for text files

21

22

Returns:

23

HTTPResponse: file response with proper headers

24

25

Raises:

26

HTTPError: 404 if file not found, 403 if access denied

27

"""

28

```

29

30

Usage:

31

32

```python

33

@route('/static/<filepath:path>')

34

def serve_static(filepath):

35

return static_file(filepath, root='./static/')

36

37

@route('/downloads/<filename>')

38

def download_file(filename):

39

return static_file(filename, root='./downloads/', download=True)

40

41

@route('/css/<filename>')

42

def serve_css(filename):

43

return static_file(filename, root='./assets/css/',

44

mimetype='text/css')

45

46

@route('/images/<filename>')

47

def serve_image(filename):

48

return static_file(filename, root='./assets/images/',

49

mimetype='auto')

50

```

51

52

### HTTP Response Utilities

53

54

Utility functions for common HTTP response patterns.

55

56

```python { .api }

57

def abort(code=500, text='Unknown Error.'):

58

"""

59

Raise HTTPError with specified status code and message.

60

61

Parameters:

62

- code: int, HTTP status code (400, 404, 500, etc.)

63

- text: str, error message

64

65

Raises:

66

HTTPError: HTTP error response

67

"""

68

69

def redirect(url, code=None):

70

"""

71

Raise HTTPResponse that redirects to the specified URL.

72

73

Parameters:

74

- url: str, redirect URL (absolute or relative)

75

- code: int, HTTP redirect status code (302 default, 301 for permanent)

76

77

Raises:

78

HTTPResponse: redirect response

79

"""

80

```

81

82

Usage:

83

84

```python

85

@route('/admin')

86

def admin_panel():

87

if not user_is_admin():

88

abort(403, 'Access denied - admin privileges required')

89

return render_admin_panel()

90

91

@route('/old-url')

92

def old_url():

93

redirect('/new-url', code=301) # Permanent redirect

94

95

@route('/login-check')

96

def login_check():

97

if not logged_in():

98

redirect('/login?return_to=/dashboard')

99

return dashboard()

100

101

@route('/api/not-found')

102

def api_not_found():

103

abort(404, 'API endpoint not found')

104

```

105

106

### Debug Mode

107

108

Enable debug mode for development.

109

110

```python { .api }

111

def debug(mode=True):

112

"""

113

Enable or disable debug mode.

114

115

Parameters:

116

- mode: bool, True to enable debug mode, False to disable

117

"""

118

```

119

120

Usage:

121

122

```python

123

import bottle

124

125

# Enable debug mode

126

bottle.debug(True)

127

128

# Debug mode effects:

129

# - Detailed error pages with tracebacks

130

# - Auto-reload on file changes (with reloader=True)

131

# - Exception propagation for debugging tools

132

```

133

134

### Date and Time Utilities

135

136

HTTP date formatting and parsing functions.

137

138

```python { .api }

139

def http_date(value):

140

"""

141

Format date/time for HTTP headers (RFC 2822 format).

142

143

Parameters:

144

- value: datetime, time tuple, or timestamp

145

146

Returns:

147

str: HTTP-formatted date string

148

"""

149

150

def parse_date(ims):

151

"""

152

Parse HTTP date string to timestamp.

153

154

Parameters:

155

- ims: str, HTTP date string

156

157

Returns:

158

float: timestamp or None if parsing fails

159

"""

160

```

161

162

Usage:

163

164

```python

165

from datetime import datetime

166

import bottle

167

168

@route('/api/timestamp')

169

def api_timestamp():

170

now = datetime.now()

171

bottle.response.set_header('Date', bottle.http_date(now))

172

173

# Handle If-Modified-Since header

174

ims = bottle.request.get_header('If-Modified-Since')

175

if ims:

176

ims_timestamp = bottle.parse_date(ims)

177

if ims_timestamp and ims_timestamp >= now.timestamp():

178

bottle.abort(304) # Not Modified

179

180

return {'timestamp': now.isoformat()}

181

```

182

183

### Authentication Utilities

184

185

HTTP authentication parsing and basic auth decorator.

186

187

```python { .api }

188

def parse_auth(header):

189

"""

190

Parse HTTP Authorization header.

191

192

Parameters:

193

- header: str, Authorization header value

194

195

Returns:

196

tuple: (method, credentials) or None if invalid

197

"""

198

199

def auth_basic(check, realm="private", text="Access denied"):

200

"""

201

HTTP Basic Authentication decorator.

202

203

Parameters:

204

- check: function, authentication check function (username, password) -> bool

205

- realm: str, authentication realm

206

- text: str, access denied message

207

208

Returns:

209

function: authentication decorator

210

"""

211

```

212

213

Usage:

214

215

```python

216

def check_credentials(username, password):

217

return username == 'admin' and password == 'secret'

218

219

@route('/admin')

220

@auth_basic(check_credentials, realm='Admin Area')

221

def admin():

222

return 'Welcome to admin area!'

223

224

@route('/api/auth-info')

225

def auth_info():

226

auth_header = request.get_header('Authorization')

227

if auth_header:

228

method, credentials = parse_auth(auth_header) or (None, None)

229

return {'method': method, 'has_credentials': bool(credentials)}

230

return {'authenticated': False}

231

```

232

233

### Range Request Utilities

234

235

Support for HTTP range requests and partial content.

236

237

```python { .api }

238

def parse_range_header(header, maxlen=0):

239

"""

240

Parse HTTP Range header for partial content requests.

241

242

Parameters:

243

- header: str, Range header value

244

- maxlen: int, maximum content length

245

246

Returns:

247

list: list of (start, end) tuples or empty list if invalid

248

"""

249

```

250

251

Usage:

252

253

```python

254

@route('/video/<filename>')

255

def serve_video(filename):

256

file_path = f'./videos/{filename}'

257

if not os.path.exists(file_path):

258

abort(404)

259

260

range_header = request.get_header('Range')

261

if range_header:

262

ranges = parse_range_header(range_header, os.path.getsize(file_path))

263

if ranges:

264

# Handle range request

265

start, end = ranges[0]

266

response.status = 206 # Partial Content

267

response.set_header('Content-Range', f'bytes {start}-{end}/{os.path.getsize(file_path)}')

268

269

return static_file(filename, root='./videos/')

270

```

271

272

### Security Utilities

273

274

Security-related helper functions for cookies and HTML.

275

276

```python { .api }

277

def cookie_encode(data, key, digestmod=None):

278

"""

279

Encode and sign cookie data.

280

281

Parameters:

282

- data: dict, cookie data to encode

283

- key: str or bytes, signing key

284

- digestmod: hashlib digest module (default: sha256)

285

286

Returns:

287

str: encoded and signed cookie value

288

"""

289

290

def cookie_decode(data, key, digestmod=None):

291

"""

292

Decode and verify signed cookie data.

293

294

Parameters:

295

- data: str, encoded cookie value

296

- key: str or bytes, signing key

297

- digestmod: hashlib digest module (default: sha256)

298

299

Returns:

300

dict: decoded cookie data or None if invalid

301

"""

302

303

def cookie_is_encoded(data):

304

"""

305

Check if cookie data is encoded/signed.

306

307

Parameters:

308

- data: str, cookie value

309

310

Returns:

311

bool: True if cookie appears to be encoded

312

"""

313

314

def html_escape(string):

315

"""

316

Escape HTML entities in string.

317

318

Parameters:

319

- string: str, string to escape

320

321

Returns:

322

str: HTML-escaped string

323

"""

324

325

def html_quote(string):

326

"""

327

Quote string for use in HTML attributes.

328

329

Parameters:

330

- string: str, string to quote

331

332

Returns:

333

str: quoted string safe for HTML attributes

334

"""

335

```

336

337

Usage:

338

339

```python

340

# Secure cookie handling

341

@route('/set-secure-cookie')

342

def set_secure_cookie():

343

data = {'user_id': 123, 'role': 'user'}

344

cookie_value = cookie_encode(data, 'secret-key')

345

response.set_cookie('secure_data', cookie_value)

346

return 'Secure cookie set'

347

348

@route('/get-secure-cookie')

349

def get_secure_cookie():

350

cookie_value = request.get_cookie('secure_data')

351

if cookie_value and cookie_is_encoded(cookie_value):

352

data = cookie_decode(cookie_value, 'secret-key')

353

if data:

354

return f'User ID: {data["user_id"]}, Role: {data["role"]}'

355

return 'No valid secure cookie found'

356

357

# HTML escaping

358

@route('/safe-output/<user_input>')

359

def safe_output(user_input):

360

safe_input = html_escape(user_input)

361

return f'<p>You entered: {safe_input}</p>'

362

363

@route('/safe-attribute/<value>')

364

def safe_attribute(value):

365

safe_value = html_quote(value)

366

return f'<input type="text" value="{safe_value}">'

367

```

368

369

### Path and Route Utilities

370

371

Utilities for path manipulation and route discovery.

372

373

```python { .api }

374

def yieldroutes(func):

375

"""

376

Extract routes from a function that contains route definitions.

377

378

Parameters:

379

- func: function, function containing route decorators

380

381

Yields:

382

Route: route instances defined in the function

383

"""

384

385

def path_shift(script_name, path_info, shift=1):

386

"""

387

Shift path components between SCRIPT_NAME and PATH_INFO.

388

389

Parameters:

390

- script_name: str, current SCRIPT_NAME

391

- path_info: str, current PATH_INFO

392

- shift: int, number of path components to shift

393

394

Returns:

395

tuple: (new_script_name, new_path_info)

396

"""

397

```

398

399

### Data Conversion Utilities

400

401

Helper functions for data type conversion and validation.

402

403

```python { .api }

404

def makelist(data):

405

"""

406

Convert data to list format.

407

408

Parameters:

409

- data: any, data to convert to list

410

411

Returns:

412

list: data as list (wraps single items, preserves existing lists)

413

"""

414

415

def tob(s, enc='utf8'):

416

"""

417

Convert string to bytes.

418

419

Parameters:

420

- s: str, string to convert

421

- enc: str, encoding to use

422

423

Returns:

424

bytes: encoded bytes

425

"""

426

427

def touni(s, enc='utf8', err='strict'):

428

"""

429

Convert to unicode string.

430

431

Parameters:

432

- s: str or bytes, data to convert

433

- enc: str, encoding to use for bytes

434

- err: str, error handling strategy

435

436

Returns:

437

str: unicode string

438

"""

439

```

440

441

Usage:

442

443

```python

444

# Data conversion

445

@route('/api/data')

446

def api_data():

447

# Ensure list format

448

tags = makelist(request.query.get('tags', []))

449

450

# Handle bytes/string conversion

451

raw_data = request.body

452

text_data = touni(raw_data, enc='utf8')

453

454

return {

455

'tags': tags,

456

'data_length': len(text_data),

457

'encoding': 'utf8'

458

}

459

```