or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconvenience-functions.mddiagram-creation.mdexceptions.mdindex.mdmodel-info.mdplugin-system.md

convenience-functions.mddocs/

0

# Convenience Functions

1

2

Erdantic provides high-level convenience functions for quick diagram generation without needing to manage `EntityRelationshipDiagram` instances directly. These functions automatically create diagrams, analyze models, and produce output in a single step.

3

4

## Core Functions

5

6

```python { .api }

7

def create(*models_or_modules: Union[type, ModuleType], terminal_models: Collection[type] = tuple(),

8

termini: Collection[type] = tuple(), limit_search_models_to: Optional[Collection[str]] = None) -> EntityRelationshipDiagram:

9

"""Construct [`EntityRelationshipDiagram`][erdantic.core.EntityRelationshipDiagram] from given

10

data model classes or modules.

11

12

Args:

13

*models_or_modules (type | ModuleType): Data model classes to add to diagram, or modules

14

to search for data model classes.

15

terminal_models (Collection[type]): Data model classes to set as terminal nodes. erdantic

16

will stop searching for component classes when it reaches these models

17

termini (Collection[type]): Deprecated. Use `terminal_models` instead.

18

limit_search_models_to (Collection[str] | None): Plugin identifiers to limit to when

19

searching modules for data model classes. Defaults to None which will not impose any

20

limits.

21

22

Returns:

23

EntityRelationshipDiagram: diagram object for given data model.

24

25

Raises:

26

UnknownModelTypeError: if a given model does not match any model types from loaded plugins.

27

UnresolvableForwardRefError: if a model contains a forward reference that cannot be

28

automatically resolved.

29

"""

30

31

def draw(*models_or_modules: Union[type, ModuleType], out: Union[str, os.PathLike],

32

terminal_models: Collection[type] = tuple(), termini: Collection[type] = tuple(),

33

limit_search_models_to: Optional[Collection[str]] = None,

34

graph_attr: Optional[Mapping[str, Any]] = None, node_attr: Optional[Mapping[str, Any]] = None,

35

edge_attr: Optional[Mapping[str, Any]] = None, **kwargs):

36

"""Render entity relationship diagram for given data model classes to file.

37

38

Args:

39

*models_or_modules (type | ModuleType): Data model classes to add to diagram, or modules

40

to search for data model classes.

41

out (str | os.PathLike): Output file path for rendered diagram.

42

terminal_models (Collection[type]): Data model classes to set as terminal nodes. erdantic

43

will stop searching for component classes when it reaches these models

44

termini (Collection[type]): Deprecated. Use `terminal_models` instead.

45

limit_search_models_to (Optional[Collection[str]]): Plugin identifiers to limit to when

46

searching modules for data model classes. Defaults to None which will not impose any

47

limits.

48

graph_attr (Mapping[str, Any] | None, optional): Override any graph attributes on

49

the `pygraphviz.AGraph` instance. Defaults to None.

50

node_attr (Mapping[str, Any] | None, optional): Override any node attributes for all

51

nodes on the `pygraphviz.AGraph` instance. Defaults to None.

52

edge_attr (Mapping[str, Any] | None, optional): Override any edge attributes for all

53

edges on the `pygraphviz.AGraph` instance. Defaults to None.

54

**kwargs: Additional keyword arguments to

55

[`pygraphviz.AGraph.draw`][pygraphviz.AGraph.draw].

56

57

Raises:

58

UnknownModelTypeError: if a given model does not match any model types from loaded plugins.

59

UnresolvableForwardRefError: if a model contains a forward reference that cannot be

60

automatically resolved.

61

"""

62

63

def to_dot(*models_or_modules: Union[type, ModuleType], terminal_models: Collection[type] = [],

64

termini: Collection[type] = tuple(), limit_search_models_to: Optional[Collection[str]] = None,

65

graph_attr: Optional[Mapping[str, Any]] = None, node_attr: Optional[Mapping[str, Any]] = None,

66

edge_attr: Optional[Mapping[str, Any]] = None) -> str:

67

"""Generate Graphviz [DOT language](https://graphviz.org/doc/info/lang.html) representation of

68

entity relationship diagram for given data model classes.

69

70

Args:

71

*models_or_modules (type | ModuleType): Data model classes to add to diagram, or modules

72

to search for data model classes.

73

terminal_models (Collection[type]): Data model classes to set as terminal nodes. erdantic

74

will stop searching for component classes when it reaches these models

75

termini (Collection[type]): Deprecated. Use `terminal_models` instead.

76

limit_search_models_to (Optional[Collection[str]]): Plugin identifiers to limit to when

77

searching modules for data model classes. Defaults to None which will not impose any

78

limits.

79

graph_attr (Mapping[str, Any] | None, optional): Override any graph attributes on

80

the `pygraphviz.AGraph` instance. Defaults to None.

81

node_attr (Mapping[str, Any] | None, optional): Override any node attributes for all

82

nodes on the `pygraphviz.AGraph` instance. Defaults to None.

83

edge_attr (Mapping[str, Any] | None, optional): Override any edge attributes for all

84

edges on the `pygraphviz.AGraph` instance. Defaults to None.

85

86

Returns:

87

str: DOT language representation of diagram

88

"""

89

90

def find_models(module: ModuleType, limit_search_models_to: Optional[Collection[str]] = None) -> Iterator[type]:

91

"""Searches a module and yields all data model classes found.

92

93

Args:

94

module (ModuleType): Module to search for data model classes.

95

limit_search_models_to (Collection[str] | None): Plugin identifiers to limit to when

96

searching modules for data model classes. Defaults to None which will not impose any

97

limits.

98

99

Yields:

100

Iterator[type]: Members of module that are data model classes.

101

102

Raises:

103

UnknownModelTypeError: if a given model does not match any model types from loaded plugins.

104

UnresolvableForwardRefError: if a model contains a forward reference that cannot be

105

automatically resolved.

106

"""

107

108

```

109

110

## Required Imports

111

112

```python

113

from erdantic import create, draw, to_dot, find_models, list_plugins

114

from types import ModuleType

115

from typing import Union, Collection, Optional, Mapping, Any, Iterator

116

import os

117

```

118

119

## Usage Examples

120

121

### Quick Diagram Generation

122

123

```python

124

from pydantic import BaseModel

125

from erdantic import draw

126

127

class User(BaseModel):

128

name: str

129

email: str

130

131

class Post(BaseModel):

132

title: str

133

author: User

134

135

# Generate diagram directly from model classes

136

draw(User, Post, out="quick_diagram.png")

137

```

138

139

### Creating Diagram Objects

140

141

```python

142

from erdantic import create

143

144

# Create a diagram object for further manipulation

145

diagram = create(User, Post)

146

147

# Now you can use diagram methods

148

diagram.draw("output.svg")

149

dot_content = diagram.to_dot()

150

```

151

152

### Working with Modules

153

154

```python

155

import my_models_module

156

from erdantic import draw

157

158

# Analyze entire module for data model classes

159

draw(my_models_module, out="module_diagram.png")

160

161

# Limit search to specific plugin types

162

draw(my_models_module, out="pydantic_only.png", limit_search_models_to=["pydantic"])

163

```

164

165

### Terminal Models

166

167

```python

168

from erdantic import draw

169

170

class BaseEntity(BaseModel):

171

id: int

172

created_at: datetime

173

174

class User(BaseEntity):

175

name: str

176

email: str

177

178

class Post(BaseEntity):

179

title: str

180

author: User

181

182

# Stop analysis at BaseEntity - don't recurse into its fields

183

draw(User, Post, terminal_models=[BaseEntity], out="with_terminal.png")

184

```

185

186

187

### Advanced Styling

188

189

```python

190

from erdantic import draw

191

192

# Custom graph appearance

193

graph_style = {

194

"rankdir": "TB", # Top-to-bottom layout

195

"bgcolor": "lightgray",

196

"label": "My Application Models"

197

}

198

199

node_style = {

200

"fillcolor": "lightblue",

201

"style": "filled,rounded",

202

"fontname": "Arial"

203

}

204

205

edge_style = {

206

"color": "darkblue",

207

"penwidth": 2

208

}

209

210

draw(

211

User, Post,

212

out="styled_diagram.svg",

213

graph_attr=graph_style,

214

node_attr=node_style,

215

edge_attr=edge_style

216

)

217

```

218

219

### DOT Generation

220

221

```python

222

from erdantic import to_dot

223

224

# Generate DOT language representation

225

dot_string = to_dot(User, Post)

226

print(dot_string)

227

228

# Save for external processing

229

with open("models.dot", "w") as f:

230

f.write(dot_string)

231

232

# Generate with custom attributes

233

custom_dot = to_dot(

234

User, Post,

235

graph_attr={"rankdir": "TD"},

236

node_attr={"shape": "box"}

237

)

238

```

239

240

### Module Model Discovery

241

242

```python

243

from erdantic import find_models

244

import my_models_module

245

246

# Find all supported models in a module

247

models = list(find_models(my_models_module))

248

print(f"Found {len(models)} model classes: {[m.__name__ for m in models]}")

249

250

# Find only specific model types

251

pydantic_models = list(find_models(my_models_module, limit_search_models_to=["pydantic"]))

252

dataclass_models = list(find_models(my_models_module, limit_search_models_to=["dataclasses"]))

253

254

# Use discovered models directly

255

from erdantic import draw

256

draw(*models, out="all_discovered_models.png")

257

```

258

259

### Plugin Limitation

260

261

```python

262

from erdantic import draw, list_plugins

263

264

# See available plugins

265

print("Available plugins:", list_plugins())

266

267

# Generate diagrams for specific model types only

268

draw(my_module, out="pydantic_models.png", limit_search_models_to=["pydantic"])

269

draw(my_module, out="dataclass_models.png", limit_search_models_to=["dataclasses"])

270

draw(my_module, out="attrs_models.png", limit_search_models_to=["attrs"])

271

```

272

273

### Error Handling

274

275

```python

276

from erdantic import draw

277

from erdantic.exceptions import UnknownModelTypeError, UnresolvableForwardRefError

278

279

try:

280

draw(MyModel, out="diagram.png")

281

except UnknownModelTypeError as e:

282

print(f"Model type not supported: {e.model}")

283

print(f"Available plugins: {e.available_plugins}")

284

except UnresolvableForwardRefError as e:

285

print(f"Cannot resolve forward reference '{e.name}' in model {e.model_full_name}")

286

except FileNotFoundError as e:

287

print(f"Output directory does not exist: {e}")

288

```

289

290

## Comparison with Direct Diagram Usage

291

292

### Convenience Functions (Recommended for Simple Cases)

293

```python

294

# One-liner diagram generation

295

draw(User, Post, out="simple.png")

296

```

297

298

### Direct Diagram Usage (More Control)

299

```python

300

# Multi-step with more control options

301

diagram = EntityRelationshipDiagram()

302

diagram.add_model(User)

303

diagram.add_model(Post)

304

diagram.draw("controlled.png")

305

306

# Access to diagram data

307

print(f"Models analyzed: {len(diagram.models)}")

308

print(f"Relationships found: {len(diagram.edges)}")

309

```