or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arguments.mdcaching.mdconfiguration.mdcontrollers.mdextensions.mdfoundation.mdhooks.mdindex.mdinterface-handler.mdlogging.mdmail.mdoutput.mdplugins.mdtemplates.mdutilities.md

foundation.mddocs/

0

# Application Foundation

1

2

The foundation system provides the core application framework classes that serve as the entry point and container for all cement-based applications. The `App` class manages the complete application lifecycle, while `TestApp` provides specialized functionality for testing.

3

4

## Capabilities

5

6

### App Class

7

8

The main application framework class that serves as the central container for all application components and functionality.

9

10

```python { .api }

11

class App:

12

"""

13

Main application class that handles the entire application lifecycle.

14

15

The App class manages setup, execution, and cleanup of cement applications.

16

It serves as the central container for all handlers, interfaces, extensions,

17

and configuration management.

18

"""

19

20

def __init__(self, label: str = None, **kw: Any) -> None:

21

"""

22

Initialize the application.

23

24

Args:

25

label: Application label/name

26

**kw: Additional keyword arguments passed to Meta

27

"""

28

29

def setup(self) -> None:

30

"""

31

Initialize and setup the application for execution.

32

33

This method handles:

34

- Loading configuration files

35

- Setting up logging

36

- Loading extensions and plugins

37

- Registering handlers

38

- Running pre_setup and post_setup hooks

39

"""

40

41

def run(self) -> None:

42

"""

43

Execute the application.

44

45

This method handles:

46

- Parsing command-line arguments

47

- Running pre_run hooks

48

- Executing the appropriate controller/command

49

- Running post_run hooks

50

- Exception handling and signal management

51

"""

52

53

def close(self) -> None:

54

"""

55

Cleanup and shutdown the application.

56

57

This method handles:

58

- Running pre_close and post_close hooks

59

- Cleaning up resources

60

- Proper application shutdown

61

"""

62

63

def render(self, data: Dict[str, Any], template: str = None) -> str:

64

"""

65

Render data using the configured output handler.

66

67

Args:

68

data: Dictionary of data to render

69

template: Optional template name for template-based output

70

71

Returns:

72

Rendered output string

73

"""

74

75

def extend(self, extension: str, app: 'App') -> None:

76

"""

77

Register a framework extension.

78

79

Args:

80

extension: Extension name/identifier

81

app: Application instance to extend

82

"""

83

84

@property

85

def _meta(self) -> Any:

86

"""Application meta-data configuration object."""

87

```

88

89

### TestApp Class

90

91

Specialized application class designed for unit testing cement applications with additional testing utilities and simplified configuration options.

92

93

```python { .api }

94

class TestApp(App):

95

"""

96

Application class designed specifically for testing cement applications.

97

98

Inherits all functionality from App but provides additional testing

99

conveniences and simplified configuration for test environments.

100

"""

101

102

def __init__(self, label: str = None, **kw: Any) -> None:

103

"""

104

Initialize the test application.

105

106

Args:

107

label: Application label/name

108

**kw: Additional keyword arguments passed to Meta

109

"""

110

```

111

112

### Meta Configuration

113

114

Application behavior is controlled through the Meta class which can be defined as a nested class or passed as keyword arguments during initialization.

115

116

```python { .api }

117

class Meta:

118

"""

119

Application meta-data configuration.

120

121

Controls application behavior including handler selection,

122

configuration options, and framework settings.

123

"""

124

125

label: str = None

126

"""Application label/name"""

127

128

debug: bool = False

129

"""Debug mode flag"""

130

131

config_handler: str = 'configparser'

132

"""Configuration handler to use"""

133

134

config_file_suffix: str = '.conf'

135

"""Configuration file suffix"""

136

137

config_files: List[str] = []

138

"""List of configuration files to load"""

139

140

config_dirs: List[str] = []

141

"""List of configuration directories to search"""

142

143

config_defaults: Dict[str, Any] = {}

144

"""Default configuration values"""

145

146

argv: List[str] = None

147

"""Override sys.argv for argument parsing"""

148

149

catch_signals: List[int] = [signal.SIGTERM, signal.SIGINT]

150

"""List of signals to catch and handle"""

151

152

signal_handler: str = 'signal'

153

"""Signal handler to use"""

154

155

pre_setup_hooks: List[Callable] = []

156

"""List of pre-setup hook functions"""

157

158

post_setup_hooks: List[Callable] = []

159

"""List of post-setup hook functions"""

160

161

pre_run_hooks: List[Callable] = []

162

"""List of pre-run hook functions"""

163

164

post_run_hooks: List[Callable] = []

165

"""List of post-run hook functions"""

166

167

pre_close_hooks: List[Callable] = []

168

"""List of pre-close hook functions"""

169

170

post_close_hooks: List[Callable] = []

171

"""List of post-close hook functions"""

172

173

handlers: List[Handler] = []

174

"""List of handler classes to register"""

175

176

extensions: List[str] = []

177

"""List of extensions to load"""

178

179

plugins: List[str] = []

180

"""List of plugins to load"""

181

182

plugin_config_dirs: List[str] = []

183

"""List of plugin configuration directories"""

184

185

plugin_dirs: List[str] = []

186

"""List of plugin directories to search"""

187

188

template_handler: str = 'dummy'

189

"""Template handler to use"""

190

191

template_dirs: List[str] = []

192

"""List of template directories"""

193

194

output_handler: str = 'dummy'

195

"""Output handler to use"""

196

197

log_handler: str = 'logging'

198

"""Log handler to use"""

199

200

cache_handler: str = 'dummy'

201

"""Cache handler to use"""

202

203

mail_handler: str = 'dummy'

204

"""Mail handler to use"""

205

206

argument_handler: str = 'argparse'

207

"""Argument handler to use"""

208

209

base_controller: str = None

210

"""Base controller class name"""

211

```

212

213

## Usage Examples

214

215

### Basic Application

216

217

```python

218

from cement import App, Controller, ex

219

220

class BaseController(Controller):

221

class Meta:

222

label = 'base'

223

224

@ex(help='say hello')

225

def hello(self):

226

print('Hello World!')

227

228

class MyApp(App):

229

class Meta:

230

label = 'myapp'

231

base_controller = 'base'

232

handlers = [BaseController]

233

234

def main():

235

with MyApp() as app:

236

app.run()

237

238

if __name__ == '__main__':

239

main()

240

```

241

242

### Application with Configuration

243

244

```python

245

from cement import App, init_defaults

246

247

CONFIG = init_defaults('myapp')

248

CONFIG['myapp']['debug'] = False

249

CONFIG['myapp']['some_option'] = 'default_value'

250

251

class MyApp(App):

252

class Meta:

253

label = 'myapp'

254

config_defaults = CONFIG

255

config_files = ['/etc/myapp.conf', '~/.myapp.conf']

256

257

with MyApp() as app:

258

app.setup()

259

print(f"Debug mode: {app.config.get('myapp', 'debug')}")

260

print(f"Option value: {app.config.get('myapp', 'some_option')}")

261

app.run()

262

```

263

264

### Testing Application

265

266

```python

267

from cement import TestApp

268

269

def test_myapp():

270

with TestApp() as app:

271

app.setup()

272

# Test application functionality

273

assert app.config.get('myapp', 'debug') == True

274

app.run()

275

```

276

277

### Application with Extensions

278

279

```python

280

from cement import App

281

282

class MyApp(App):

283

class Meta:

284

label = 'myapp'

285

extensions = ['colorlog', 'jinja2', 'yaml']

286

config_handler = 'yaml'

287

template_handler = 'jinja2'

288

log_handler = 'colorlog'

289

290

with MyApp() as app:

291

app.setup()

292

app.log.info('Application started with extensions')

293

app.run()

294

```

295

296

### Context Manager Usage

297

298

The recommended pattern is to use applications as context managers to ensure proper setup and cleanup:

299

300

```python

301

from cement import App

302

303

# Recommended approach - automatic setup/cleanup

304

with MyApp() as app:

305

app.run()

306

307

# Manual approach - requires explicit calls

308

app = MyApp()

309

try:

310

app.setup()

311

app.run()

312

finally:

313

app.close()

314

```