or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

channel-communication.mdcore-framework.mdevents-interactivity.mdexception-handling.mdfile-management.mdhtml-system.mdindex.mdresponse-system.mdrouting-urls.mdstatic-files-assets.md

response-system.mddocs/

0

# Response System

1

2

Various response classes for different content types and HTTP behaviors, including HTML responses, JSON responses, template responses, file downloads, and redirects. The response system provides a flexible way to return different types of content from views.

3

4

## Capabilities

5

6

### Base Response Classes

7

8

Foundation response classes that all other responses inherit from, providing basic HTTP response functionality.

9

10

```python { .api }

11

class AbstractResponse:

12

"""Abstract base class for all response types."""

13

def __init__(self):

14

"""Initialize abstract response."""

15

16

# Properties

17

interactive: bool # Whether response can be used in interactive views

18

19

class Response(AbstractResponse):

20

def __init__(self, content: str = '', status: int = 200, headers: dict = None,

21

content_type: str = 'text/plain'):

22

"""

23

Create a basic HTTP response.

24

25

Args:

26

content (str): Response content

27

status (int): HTTP status code

28

headers (dict): HTTP headers

29

content_type (str): Content-Type header

30

"""

31

32

# Properties

33

content: str # Response content

34

status: int # HTTP status code

35

headers: dict # HTTP headers

36

content_type: str # Content-Type header

37

interactive: bool # Whether response can be used in interactive views

38

```

39

40

### HTML Responses

41

42

Responses for returning HTML content to the browser.

43

44

```python { .api }

45

class HtmlResponse(Response):

46

def __init__(self, html, status: int = 200, headers: dict = None):

47

"""

48

Create an HTML response.

49

50

Args:

51

html: HTML content (Node objects or string)

52

status (int): HTTP status code

53

headers (dict): HTTP headers

54

"""

55

56

class TemplateResponse(Response):

57

def __init__(self, template_name: str, context: dict = None,

58

status: int = 200, headers: dict = None):

59

"""

60

Create a template-based response.

61

62

Args:

63

template_name (str): Name of template to render

64

context (dict): Template context variables

65

status (int): HTTP status code

66

headers (dict): HTTP headers

67

"""

68

69

class TemplateStringResponse(Response):

70

def __init__(self, template_string: str, context: dict = None,

71

status: int = 200, headers: dict = None):

72

"""

73

Create a response from template string.

74

75

Args:

76

template_string (str): Template content as string

77

context (dict): Template context variables

78

status (int): HTTP status code

79

headers (dict): HTTP headers

80

"""

81

```

82

83

#### HTML Response Usage Example

84

85

```python

86

from lona import App, View

87

from lona.html import HTML, H1, P

88

from lona.responses import HtmlResponse, TemplateResponse

89

90

app = App(__file__)

91

92

@app.route('/simple')

93

class SimpleView(View):

94

def handle_request(self, request):

95

html = HTML(

96

H1('Simple Response'),

97

P('This is a simple HTML response.')

98

)

99

return HtmlResponse(html)

100

101

@app.route('/template')

102

class TemplateView(View):

103

def handle_request(self, request):

104

context = {

105

'title': 'Template Example',

106

'username': request.user.username if request.user else 'Guest'

107

}

108

return TemplateResponse('base.html', context)

109

```

110

111

### Data Responses

112

113

Responses for returning structured data in various formats.

114

115

```python { .api }

116

class JsonResponse(Response):

117

def __init__(self, json_data, status: int = 200, headers: dict = None):

118

"""

119

Create a JSON response.

120

121

Args:

122

json_data: Data to serialize as JSON

123

status (int): HTTP status code

124

headers (dict): HTTP headers

125

"""

126

```

127

128

#### JSON Response Usage Example

129

130

```python

131

from lona.responses import JsonResponse

132

133

@app.route('/api/users')

134

class UserApiView(View):

135

def handle_request(self, request):

136

users = [

137

{'id': 1, 'name': 'John', 'email': 'john@example.com'},

138

{'id': 2, 'name': 'Jane', 'email': 'jane@example.com'}

139

]

140

return JsonResponse({

141

'users': users,

142

'count': len(users),

143

'status': 'success'

144

})

145

146

@app.route('/api/user/<int:user_id>')

147

class SingleUserApiView(View):

148

def handle_request(self, request):

149

user_id = request.match_info['user_id']

150

151

if user_id == 404:

152

return JsonResponse(

153

{'error': 'User not found'},

154

status=404

155

)

156

157

return JsonResponse({

158

'id': user_id,

159

'name': f'User {user_id}',

160

'active': True

161

})

162

```

163

164

### File Responses

165

166

Responses for serving files and downloads.

167

168

```python { .api }

169

class FileResponse(Response):

170

def __init__(self, path: str, content_type: str = None,

171

as_attachment: bool = False, headers: dict = None):

172

"""

173

Create a file download response.

174

175

Args:

176

path (str): Path to file on filesystem

177

content_type (str): MIME type (auto-detected if None)

178

as_attachment (bool): Force download vs inline display

179

headers (dict): Additional HTTP headers

180

"""

181

182

# Properties

183

path: str # File system path

184

as_attachment: bool # Download behavior flag

185

```

186

187

#### File Response Usage Example

188

189

```python

190

import os

191

from lona.responses import FileResponse

192

193

@app.route('/download/<filename>')

194

class DownloadView(View):

195

def handle_request(self, request):

196

filename = request.match_info['filename']

197

file_path = os.path.join('uploads', filename)

198

199

if not os.path.exists(file_path):

200

return JsonResponse({'error': 'File not found'}, status=404)

201

202

return FileResponse(

203

path=file_path,

204

as_attachment=True, # Force download

205

headers={'X-Download-Source': 'lona-app'}

206

)

207

208

@app.route('/image/<filename>')

209

class ImageView(View):

210

def handle_request(self, request):

211

filename = request.match_info['filename']

212

image_path = os.path.join('static', 'images', filename)

213

214

return FileResponse(

215

path=image_path,

216

content_type='image/jpeg',

217

as_attachment=False # Display inline

218

)

219

```

220

221

### Redirect Responses

222

223

Responses for redirecting users to different URLs.

224

225

```python { .api }

226

class RedirectResponse(Response):

227

def __init__(self, redirect_url: str):

228

"""

229

Create an internal redirect response.

230

231

Args:

232

redirect_url (str): URL to redirect to within the app

233

"""

234

235

class HttpRedirectResponse(Response):

236

def __init__(self, redirect_url: str, status: int = 302):

237

"""

238

Create an HTTP redirect response.

239

240

Args:

241

redirect_url (str): URL to redirect to (can be external)

242

status (int): HTTP redirect status code (301, 302, 303, 307, 308)

243

"""

244

245

# Properties

246

redirect_url: str # Target URL

247

```

248

249

#### Redirect Response Usage Example

250

251

```python

252

from lona.responses import RedirectResponse, HttpRedirectResponse

253

254

@app.route('/login')

255

class LoginView(View):

256

def handle_request(self, request):

257

if request.user:

258

# User already logged in, redirect to dashboard

259

return RedirectResponse('/dashboard')

260

261

# Show login form

262

return self.show_login_form()

263

264

@app.route('/external-redirect')

265

class ExternalRedirectView(View):

266

def handle_request(self, request):

267

# Redirect to external site

268

return HttpRedirectResponse(

269

'https://external-site.com/page',

270

status=301 # Permanent redirect

271

)

272

273

@app.route('/logout')

274

class LogoutView(View):

275

def handle_request(self, request):

276

# Perform logout logic

277

request.session.clear()

278

279

# Redirect to home page

280

return RedirectResponse('/')

281

```

282

283

### Error Responses

284

285

Specialized responses for handling error conditions.

286

287

```python { .api }

288

class ErrorResponse(Response):

289

def __init__(self, message: str, status: int = 500, headers: dict = None):

290

"""

291

Create an error response.

292

293

Args:

294

message (str): Error message

295

status (int): HTTP error status code

296

headers (dict): HTTP headers

297

"""

298

299

class NotFoundResponse(ErrorResponse):

300

def __init__(self, message: str = 'Not Found', headers: dict = None):

301

"""

302

Create a 404 Not Found response.

303

304

Args:

305

message (str): Error message

306

headers (dict): HTTP headers

307

"""

308

309

class ForbiddenResponse(ErrorResponse):

310

def __init__(self, message: str = 'Forbidden', headers: dict = None):

311

"""

312

Create a 403 Forbidden response.

313

314

Args:

315

message (str): Error message

316

headers (dict): HTTP headers

317

"""

318

```

319

320

#### Error Response Usage Example

321

322

```python

323

from lona.responses import NotFoundResponse, ForbiddenResponse, ErrorResponse

324

325

@app.route('/admin/<path:admin_path>')

326

class AdminView(View):

327

def handle_request(self, request):

328

if not request.user or not request.user.is_admin:

329

return ForbiddenResponse('Admin access required')

330

331

admin_path = request.match_info['admin_path']

332

333

if admin_path not in ['users', 'settings', 'logs']:

334

return NotFoundResponse(f'Admin page "{admin_path}" not found')

335

336

try:

337

return self.render_admin_page(admin_path)

338

except Exception as e:

339

return ErrorResponse(

340

f'Internal server error: {str(e)}',

341

status=500

342

)

343

```

344

345

### Response Headers and Cookies

346

347

Utilities for managing HTTP headers and cookies in responses.

348

349

```python { .api }

350

# Response header utilities (available on all response classes)

351

def set_header(self, name: str, value: str):

352

"""Set an HTTP header."""

353

354

def get_header(self, name: str) -> str:

355

"""Get an HTTP header value."""

356

357

def remove_header(self, name: str):

358

"""Remove an HTTP header."""

359

360

def set_cookie(self, name: str, value: str, max_age: int = None,

361

expires: str = None, path: str = '/', domain: str = None,

362

secure: bool = False, httponly: bool = False):

363

"""Set an HTTP cookie."""

364

365

def delete_cookie(self, name: str, path: str = '/', domain: str = None):

366

"""Delete an HTTP cookie."""

367

```

368

369

#### Headers and Cookies Usage Example

370

371

```python

372

from lona.responses import JsonResponse, RedirectResponse

373

374

@app.route('/api/login')

375

class LoginApiView(View):

376

def handle_request(self, request):

377

# Validate credentials...

378

if valid_credentials:

379

response = JsonResponse({'status': 'logged_in'})

380

381

# Set authentication cookie

382

response.set_cookie(

383

'auth_token',

384

'abc123def456',

385

max_age=3600, # 1 hour

386

httponly=True,

387

secure=True

388

)

389

390

# Set custom headers

391

response.set_header('X-Login-Time', '2023-01-01 12:00:00')

392

response.set_header('Cache-Control', 'no-cache')

393

394

return response

395

else:

396

return JsonResponse({'error': 'Invalid credentials'}, status=401)

397

398

@app.route('/logout')

399

class LogoutView(View):

400

def handle_request(self, request):

401

response = RedirectResponse('/')

402

403

# Clear authentication cookie

404

response.delete_cookie('auth_token')

405

406

return response

407

```

408

409

## Types

410

411

```python { .api }

412

from typing import Union, Optional, Dict, Any

413

from lona.html import Node

414

415

# Content types

416

ResponseContent = Union[str, bytes, Node, dict, list]

417

HTMLContent = Union[str, Node, list]

418

JSONContent = Union[dict, list, str, int, float, bool, None]

419

420

# Response types

421

HTTPStatus = int

422

HTTPHeaders = Optional[Dict[str, str]]

423

TemplateContext = Optional[Dict[str, Any]]

424

425

# Cookie types

426

CookieName = str

427

CookieValue = str

428

CookieExpires = Optional[str]

429

CookieMaxAge = Optional[int]

430

```