or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app.mdexpress.mdindex.mdreactive.mdrender.mdsession.mdtypes.mdui.md

render.mddocs/

0

# Output Rendering

1

2

Shiny's rendering system converts Python objects into web-displayable content. Render functions create reactive outputs that automatically update when their dependencies change, supporting text, plots, tables, images, and dynamic UI content.

3

4

## Capabilities

5

6

### Text Rendering

7

8

Functions for rendering text content in various formats.

9

10

```python { .api }

11

def render.text(fn: Callable[[], str] | None = None, *, inline: bool = False) -> text:

12

"""

13

Render text output.

14

15

Args:

16

fn: Function that returns a string to display.

17

inline: Whether to render as inline text.

18

19

Returns:

20

Text renderer instance.

21

"""

22

23

def render.code(fn: Callable[[], str] | None = None, *, placeholder: bool = True) -> code:

24

"""

25

Render code block with syntax formatting.

26

27

Args:

28

fn: Function that returns code as a string.

29

placeholder: Whether to show placeholder when content is empty.

30

31

Returns:

32

Code renderer instance.

33

"""

34

```

35

36

#### Usage Examples

37

38

```python

39

# Basic text output

40

@output

41

@render.text

42

def summary():

43

return f"Dataset has {len(data())} rows and {len(data().columns)} columns"

44

45

# Multi-line text

46

@output

47

@render.text

48

def analysis_report():

49

stats = calculate_stats()

50

return f"""

51

Analysis Report

52

===============

53

Mean: {stats['mean']:.2f}

54

Median: {stats['median']:.2f}

55

Standard Deviation: {stats['std']:.2f}

56

"""

57

58

# Code output with syntax highlighting

59

@output

60

@render.code

61

def generated_code():

62

params = input.model_params()

63

return f"""

64

import pandas as pd

65

import numpy as np

66

67

# Generated model configuration

68

model = LinearRegression(

69

fit_intercept={params['fit_intercept']},

70

alpha={params['alpha']}

71

)

72

"""

73

```

74

75

### Plot Rendering

76

77

Support for rendering various plot types including matplotlib, plotly, and other visualization libraries.

78

79

```python { .api }

80

def render.plot(

81

fn: Callable[[], object],

82

*,

83

alt: str | None = None,

84

width: int | float | str = "auto",

85

height: int | float | str = "auto",

86

**kwargs: object

87

) -> OutputRenderer[object]:

88

"""

89

Render plot output.

90

91

Args:

92

fn: Function that returns a plot object (matplotlib, plotly, etc.).

93

alt: Alt text for accessibility.

94

width: Plot width in pixels or CSS units.

95

height: Plot height in pixels or CSS units.

96

**kwargs: Additional arguments passed to the plotting backend.

97

98

Returns:

99

Output renderer for plot content.

100

"""

101

```

102

103

#### Usage Examples

104

105

```python

106

import matplotlib.pyplot as plt

107

import plotly.express as px

108

import seaborn as sns

109

110

# Matplotlib plot

111

@output

112

@render.plot

113

def scatter_plot():

114

df = filtered_data()

115

116

plt.figure(figsize=(10, 6))

117

plt.scatter(df['x'], df['y'], alpha=0.6)

118

plt.xlabel(input.x_variable())

119

plt.ylabel(input.y_variable())

120

plt.title(f"Scatter Plot: {input.x_variable()} vs {input.y_variable()}")

121

plt.grid(True, alpha=0.3)

122

123

return plt.gcf() # Return current figure

124

125

# Plotly plot

126

@output

127

@render.plot

128

def interactive_plot():

129

df = filtered_data()

130

131

fig = px.scatter(

132

df,

133

x=input.x_var(),

134

y=input.y_var(),

135

color=input.color_var() if input.color_var() else None,

136

title="Interactive Scatter Plot",

137

hover_data=['id', 'category']

138

)

139

140

return fig

141

142

# Seaborn plot

143

@output

144

@render.plot(width=800, height=600)

145

def correlation_heatmap():

146

df = numeric_data()

147

148

plt.figure(figsize=(10, 8))

149

sns.heatmap(

150

df.corr(),

151

annot=True,

152

cmap='coolwarm',

153

center=0,

154

square=True

155

)

156

plt.title("Correlation Matrix")

157

158

return plt.gcf()

159

```

160

161

### Image Rendering

162

163

Render static and dynamic images from various sources.

164

165

```python { .api }

166

def render.image(

167

fn: Callable[[], ImgData | str | bytes | os.PathLike[str]],

168

**kwargs: object

169

) -> OutputRenderer[ImgData | str | bytes | os.PathLike[str]]:

170

"""

171

Render image output.

172

173

Args:

174

fn: Function that returns image data, file path, or ImgData dict.

175

**kwargs: Additional image attributes (alt, width, height, etc.).

176

177

Returns:

178

Output renderer for image content.

179

"""

180

```

181

182

#### Usage Examples

183

184

```python

185

import io

186

import base64

187

from PIL import Image

188

189

# Render image from file path

190

@output

191

@render.image

192

def logo():

193

return "static/company_logo.png"

194

195

# Generate image dynamically

196

@output

197

@render.image

198

def generated_chart():

199

# Create image using PIL

200

img = Image.new('RGB', (400, 300), color='lightblue')

201

draw = ImageDraw.Draw(img)

202

203

# Draw some content based on inputs

204

draw.text((20, 20), f"Value: {input.current_value()}", fill='black')

205

206

# Convert to bytes

207

img_bytes = io.BytesIO()

208

img.save(img_bytes, format='PNG')

209

img_bytes.seek(0)

210

211

return img_bytes.getvalue()

212

213

# Return ImgData dictionary for full control

214

@output

215

@render.image

216

def custom_image():

217

image_path = generate_custom_visualization(input.params())

218

219

return {

220

"src": image_path,

221

"width": "100%",

222

"height": "400px",

223

"alt": "Custom visualization based on user parameters",

224

"style": "border: 1px solid #ddd; border-radius: 4px;"

225

}

226

```

227

228

### Table Rendering

229

230

Render tabular data with basic formatting.

231

232

```python { .api }

233

def render.table(

234

fn: Callable[[], object],

235

**kwargs: object

236

) -> OutputRenderer[object]:

237

"""

238

Render table output.

239

240

Args:

241

fn: Function that returns tabular data (DataFrame, dict, list of dicts, etc.).

242

**kwargs: Additional table formatting options.

243

244

Returns:

245

Output renderer for table content.

246

"""

247

```

248

249

#### Usage Examples

250

251

```python

252

# Render pandas DataFrame

253

@output

254

@render.table

255

def data_summary():

256

df = filtered_data()

257

return df.describe()

258

259

# Render list of dictionaries

260

@output

261

@render.table

262

def results_table():

263

results = process_analysis()

264

return [

265

{"Metric": "Accuracy", "Value": results['accuracy'], "Threshold": 0.9},

266

{"Metric": "Precision", "Value": results['precision'], "Threshold": 0.8},

267

{"Metric": "Recall", "Value": results['recall'], "Threshold": 0.75}

268

]

269

270

# Render dictionary as key-value table

271

@output

272

@render.table

273

def configuration():

274

return {

275

"Model Type": input.model_type(),

276

"Training Size": len(training_data()),

277

"Features": ", ".join(input.selected_features()),

278

"Last Updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S")

279

}

280

```

281

282

### Data Frame Rendering

283

284

Interactive data frame rendering with advanced features like sorting, filtering, and editing.

285

286

```python { .api }

287

def render.data_frame(

288

fn: Callable[[], object],

289

*,

290

width: str | float = "fit-content",

291

height: str | float = "500px",

292

summary: bool | str = True,

293

filters: bool = False,

294

editable: bool = False,

295

**kwargs: object

296

) -> DataFrameRenderer:

297

"""

298

Render interactive data frame.

299

300

Args:

301

fn: Function that returns a pandas DataFrame or similar.

302

width: Data frame width.

303

height: Data frame height.

304

summary: Show summary information.

305

filters: Enable column filtering.

306

editable: Allow cell editing.

307

**kwargs: Additional data frame options.

308

309

Returns:

310

Data frame renderer with interaction capabilities.

311

"""

312

313

class DataGrid:

314

"""

315

Configuration for data grid rendering.

316

"""

317

def __init__(

318

self,

319

*,

320

filters: bool = False,

321

editable: bool = False,

322

summary: bool | str = True,

323

**kwargs: object

324

): ...

325

326

class DataTable:

327

"""

328

Configuration for data table rendering.

329

"""

330

def __init__(

331

self,

332

*,

333

page_size: int = 10,

334

searchable: bool = True,

335

sortable: bool = True,

336

**kwargs: object

337

): ...

338

```

339

340

#### Usage Examples

341

342

```python

343

# Basic interactive data frame

344

@output

345

@render.data_frame

346

def dataset_view():

347

return filtered_data()

348

349

# Data frame with filtering and editing

350

@output

351

@render.data_frame(

352

filters=True,

353

editable=True,

354

height="600px"

355

)

356

def editable_data():

357

return working_dataset()

358

359

# Data grid configuration

360

@output

361

@render.data_frame

362

def analysis_results():

363

df = compute_results()

364

365

# Configure as data grid

366

return render.DataGrid(

367

df,

368

filters=True,

369

summary="Data from analysis pipeline",

370

editable=False

371

)

372

373

# Data table with pagination

374

@output

375

@render.data_frame

376

def large_dataset():

377

df = get_large_dataset()

378

379

return render.DataTable(

380

df,

381

page_size=25,

382

searchable=True,

383

sortable=True

384

)

385

```

386

387

### UI Rendering

388

389

Render dynamic UI content that can change based on reactive state.

390

391

```python { .api }

392

def render.ui(

393

fn: Callable[[], Tag | TagChild | None]

394

) -> OutputRenderer[Tag | TagChild | None]:

395

"""

396

Render dynamic UI content.

397

398

Args:

399

fn: Function that returns UI elements (Tag, TagChild, or None).

400

401

Returns:

402

Output renderer for UI content.

403

"""

404

```

405

406

#### Usage Examples

407

408

```python

409

# Dynamic input controls

410

@output

411

@render.ui

412

def dynamic_inputs():

413

dataset_type = input.data_type()

414

415

if dataset_type == "csv":

416

return ui.div(

417

ui.input_file("csv_file", "Upload CSV file"),

418

ui.input_checkbox("has_header", "File has header row", True)

419

)

420

elif dataset_type == "database":

421

return ui.div(

422

ui.input_text("db_connection", "Database Connection String"),

423

ui.input_text("query", "SQL Query")

424

)

425

else:

426

return ui.p("Please select a data source type")

427

428

# Conditional content based on analysis

429

@output

430

@render.ui

431

def analysis_options():

432

if not data_loaded():

433

return ui.div(

434

ui.h4("No Data Loaded"),

435

ui.p("Please upload data to begin analysis")

436

)

437

438

df = current_data()

439

numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()

440

441

return ui.div(

442

ui.h4("Analysis Options"),

443

ui.input_select(

444

"x_variable",

445

"X Variable",

446

choices=numeric_cols

447

),

448

ui.input_select(

449

"y_variable",

450

"Y Variable",

451

choices=numeric_cols

452

),

453

ui.input_checkbox_group(

454

"analysis_types",

455

"Analysis Types",

456

choices=["correlation", "regression", "clustering"]

457

)

458

)

459

460

# Dynamic content with complex logic

461

@output

462

@render.ui

463

def status_dashboard():

464

system_status = check_system_status()

465

466

status_color = "success" if system_status["healthy"] else "danger"

467

468

return ui.div(

469

ui.div(

470

ui.h3("System Status", class_=f"text-{status_color}"),

471

ui.p(f"Status: {system_status['message']}"),

472

class_=f"alert alert-{status_color}"

473

),

474

ui.div(

475

[ui.p(f"{service}: {'✓' if status else '✗'}")

476

for service, status in system_status["services"].items()],

477

class_="service-status"

478

),

479

ui.div(

480

ui.input_action_button(

481

"refresh_status",

482

"Refresh Status",

483

class_="btn btn-secondary"

484

)

485

)

486

)

487

```

488

489

### Download Handling

490

491

Create downloadable files for users.

492

493

```python { .api }

494

def render.download(

495

fn: Callable[[str], None],

496

filename: str | Callable[[], str] | None = None,

497

media_type: str = "application/octet-stream"

498

) -> DownloadHandler:

499

"""

500

Create a download handler.

501

502

Args:

503

fn: Function that writes content to the provided file path.

504

filename: Default filename or function that returns filename.

505

media_type: MIME type of the downloaded content.

506

507

Returns:

508

Download handler for file downloads.

509

"""

510

511

class DownloadHandler:

512

"""

513

Handler for file downloads.

514

"""

515

def set_filename(self, filename: str | Callable[[], str]) -> None:

516

"""Set the download filename."""

517

518

def set_media_type(self, media_type: str) -> None:

519

"""Set the MIME type."""

520

```

521

522

#### Usage Examples

523

524

```python

525

# Download CSV data

526

@output

527

@render.download(filename="data_export.csv")

528

def download_csv(file):

529

df = filtered_data()

530

df.to_csv(file, index=False)

531

532

# Download plot as image

533

@output

534

@render.download(

535

filename=lambda: f"plot_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png",

536

media_type="image/png"

537

)

538

def download_plot(file):

539

fig = generate_current_plot()

540

fig.savefig(file, format='png', dpi=300, bbox_inches='tight')

541

542

# Download analysis report

543

@output

544

@render.download(filename="analysis_report.pdf")

545

def download_report(file):

546

analysis_results = run_complete_analysis()

547

548

# Generate PDF report

549

pdf = create_pdf_report(analysis_results)

550

pdf.output(file)

551

552

# Dynamic filename and content

553

@output

554

@render.download()

555

def download_custom(file):

556

export_format = input.export_format()

557

data = current_dataset()

558

559

if export_format == "csv":

560

data.to_csv(file, index=False)

561

return f"data_export_{datetime.now().strftime('%Y%m%d')}.csv"

562

elif export_format == "json":

563

data.to_json(file, orient='records', indent=2)

564

return f"data_export_{datetime.now().strftime('%Y%m%d')}.json"

565

elif export_format == "excel":

566

data.to_excel(file, index=False)

567

return f"data_export_{datetime.now().strftime('%Y%m%d')}.xlsx"

568

```

569

570

### Express Rendering

571

572

Special rendering decorator for Express mode applications.

573

574

```python { .api }

575

def render.express(

576

fn: Callable[[], object]

577

) -> object:

578

"""

579

Express-style rendering decorator.

580

581

Args:

582

fn: Function that returns content to render.

583

584

Returns:

585

Rendered content for Express mode.

586

"""

587

```

588

589

#### Usage Examples

590

591

```python

592

# Express mode rendering (in express apps)

593

from shiny.express import render, input, ui

594

595

# Automatic output binding in Express mode

596

@render.text

597

def current_status():

598

return f"Processing {input.selected_file()}"

599

600

@render.plot

601

def main_visualization():

602

return create_plot(input.parameters())

603

604

# Express rendering works with all render types

605

@render.data_frame

606

def results_table():

607

return analyze_data(input.dataset(), input.options())

608

```

609

610

### Render Transformers

611

612

Utilities for transforming render output.

613

614

```python { .api }

615

class render.transformer:

616

"""

617

Utilities for transforming render output.

618

"""

619

@staticmethod

620

def cache_disk(

621

cache_dir: str | os.PathLike[str] | None = None,

622

max_size: int | None = None

623

) -> Callable[[Callable], Callable]: ...

624

625

@staticmethod

626

def cache_memory(

627

max_size: int = 128

628

) -> Callable[[Callable], Callable]: ...

629

```

630

631

#### Usage Examples

632

633

```python

634

# Cache expensive computations to disk

635

@output

636

@render.plot

637

@render.transformer.cache_disk(cache_dir="./plot_cache", max_size=100)

638

def expensive_plot():

639

# This plot will be cached to disk

640

return generate_complex_visualization(large_dataset())

641

642

# Cache in memory

643

@output

644

@render.table

645

@render.transformer.cache_memory(max_size=50)

646

def analysis_summary():

647

# Results cached in memory

648

return compute_summary_statistics(input.dataset())

649

```