```pythonexec="true" html="true"
frombase64importb64encodefromcontextlibimportsuppressfromdiagramsimportDiagramfromdiagrams.k8s.clusterconfigimportHPAfromdiagrams.k8s.computeimportDeployment,Pod,ReplicaSetfromdiagrams.k8s.networkimportIngress,Service# By default, Diagrams tries to write the result on disk, so we prevent that by patching its `render` method,# and by ignoring the `FileNotFoundError` that ensues.## Then we use its internal `dot` object and its `pipe` method to store the diagram in a variable,# as base64 encoded PNG data.## Finally we output an HTML image with the base64 data.# Using SVG is not possible here since Diagrams embeds actual, smaller PNG files in the result,# files which are not automatically added to the final site.withsuppress(FileNotFoundError):withDiagram("Exposed Pod with 3 Replicas",show=False)asdiagram:diagram.render=lambda:Nonenet=Ingress("domain.com")>>Service("svc")net>>[Pod("pod1"),Pod("pod2"),Pod("pod3")]<<ReplicaSet("rs")<<Deployment("dp")<<HPA("hpa")png=b64encode(diagram.dot.pipe(format="png")).decode()# Wrapping the image in a div prevents it from being wrapped in a paragraph,# which would add unnecessary space around it.print(f'<div><img src="data:image/png;base64, {png}"/></div>')```
A modern diagram scripting language that turns text to diagrams.
```pythonexec="true" html="true"
importsubprocessdiagram="""direction: rightBefore and after becoming friends: { 2007: Office chatter in 2007 { shape: sequence_diagram alice: Alice bob: Bobby awkward small talk: { alice -> bob: uhm, hi bob -> alice: oh, hello icebreaker attempt: { alice -> bob: what did you have for lunch? } unfortunate outcome: { bob -> alice: that's personal } } } 2012: Office chatter in 2012 { shape: sequence_diagram alice: Alice bob: Bobby alice -> bob: Want to play with ChatGPT? bob -> alice: Yes! bob -> alice.play: Write a play... alice.play -> bob.play: about 2 friends... bob.play -> alice.play: who find love... alice.play -> bob.play: in a sequence diagram } 2007 -> 2012: Five\nyears\nlater}"""# We simply run `d2` in a subprocess, passing it our diagram as input and capturing its output to print it.svg=subprocess.check_output(["d2","-","-"],input=diagram,stderr=subprocess.DEVNULL,text=True)print(svg)```
```pythonexec="1" html="1"
# https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_demo2.htmlfromioimportStringIOimportmatplotlib.cbookascbookimportmatplotlib.pyplotaspltimportnumpyasnp# Load a numpy record array from yahoo csv data with fields date, open, close,# volume, adj_close from the mpl-data/example directory. The record array# stores the date as an np.datetime64 with a day unit ('D') in the date column.price_data=cbook.get_sample_data("goog.npz")["price_data"]price_data=price_data[-250:]# get the most recent 250 trading daysdelta1=np.diff(price_data["adj_close"])/price_data["adj_close"][:-1]# Marker size in units of points^2volume=(15*price_data["volume"][:-2]/price_data["volume"][0])**2close=0.003*price_data["close"][:-2]/0.003*price_data["open"][:-2]fig,ax=plt.subplots()ax.scatter(delta1[:-1],delta1[1:],c=close,s=volume,alpha=0.5)ax.set_xlabel(r"$\Delta_i$",fontsize=15)ax.set_ylabel(r"$\Delta_{i+1}$",fontsize=15)ax.set_title("Volume and percent change")ax.grid(True)fig.tight_layout()buffer=StringIO()plt.savefig(buffer,format="svg")print(buffer.getvalue())```
A command line utility to display dependency tree of the installed Python packages.
We call pipdeptree with its --mermaid option to generate a Mermaid diagram.
```bashexec="1" result="mermaid"
# Change the direction of the graph from top-down to left-right,# and remove local version identifiers from our own package.
pipdeptree-pmarkdown-exec--mermaid2>/dev/null|sed-E's/\.dev.+"\]$/"]/;s/\+d.*"\]$/"]/'```
pydeps uses Graphviz under the hood to generate graphs. In this example we add links to the code reference in related nodes. Try clicking on the markdown_exec nodes!
```pythonexec="true" html="true"
frompydepsimportcli,colors,dot,py2depgraphfrompydeps.pydepsimportdepgraph_to_dotsrcfrompydeps.targetimportTarget# Note: pydeps wasn't designed to be used in such a programatic way, so the code is a bit convoluted,# but you could make a function of it, put it in an importable script/module,# and reuse it cleanly in your executed code blocks.cli.verbose=cli._not_verboseoptions=cli.parse_args(["src/markdown_exec","--noshow"])colors.START_COLOR=options["start_color"]target=Target(options["fname"])withtarget.chdir_work():dep_graph=py2depgraph.py2dep(target,**options)dot_src=depgraph_to_dotsrc(target,dep_graph,**options)svg=dot.call_graphviz_dot(dot_src,"svg").decode()svg="".join(svg.splitlines()[6:])svg=svg.replace('fill="white"','fill="transparent"')reference="../reference"modules=("markdown_exec","markdown_exec.formatters","markdown_exec.formatters.base","markdown_exec.formatters.bash","markdown_exec.formatters.console","markdown_exec.formatters.markdown","markdown_exec.formatters.pycon","markdown_exec.formatters.pyodide","markdown_exec.formatters.python","markdown_exec.formatters.sh","markdown_exec.formatters.tree","markdown_exec.logger","markdown_exec.mkdocs_plugin","markdown_exec.processors","markdown_exec.rendering",)formoduleinmodules:svg_title=module.replace(".","_")title_tag=f"<title>{svg_title}</title>"href=f"{reference}/{module.replace('.','/')}/"svg=svg.replace(title_tag,f'<a href="{href}"><title>{module}</title>')svg=svg.replace("</text></g>","</text></a></g>")print(svg)```
```pythonexec="true" html="true"
importosfromrich.consoleimportConsolefromrich.paddingimportPaddingfromrich.syntaximportSyntax# Here we hardcode the code snippet we want to render,# but we could instead include it from somewhere else using the `pymdownx.snippets` extension# (https://facelessuser.github.io/pymdown-extensions/extensions/snippets/)# or by reading it dynamically from Python.code=""" from contextlib import asynccontextmanager import httpx class BookClient(httpx.AsyncClient): async def get_book(self, book_id: int) -> str: response = await self.get(f"/books/{book_id}") return response.text @asynccontextmanager async def book_client(*args, **kwargs): async with BookClient(*args, **kwargs) as client: yield client"""# We prevent Rich from actually writing to the terminal.withopen(os.devnull,"w")asdevnull:console=Console(record=True,width=65,file=devnull,markup=False)renderable=Syntax(code,"python",theme="material")renderable=Padding(renderable,(0,),expand=False)console.print(renderable,markup=False)svg=console.export_svg(title="async context manager")# Wrapping the SVG in a div prevents it from being wrapped in a paragraph,# which would add unnecessary space around it.print(f"<div>{svg}</div>")```
If you installed Markdown Exec with the ansi extra (pip install markdown-exec[ansi]), the ANSI colors in the output of shell commands will be translated to HTML/CSS, allowing to render them naturally in your documentation pages. For this to happen, use the result="ansi" option.
```pythonexec="true" html="true"
fromtempfileimportNamedTemporaryFilefromchalkimportDiagram,triangle,unit_xfromcolourimportColorpapaya=Color("#ff9700")defsierpinski(n:int,size:int)->Diagram:ifn<=1:returntriangle(size)else:smaller=sierpinski(n-1,size/2)returnsmaller.above(smaller.beside(smaller,unit_x).center_xy())d=sierpinski(5,4).fill_color(papaya)# Chalk doesn't provide an easy method to get a string directly,# so we use a temporary file.withNamedTemporaryFile("w+")astmpfile:d.render_svg(tmpfile.name,height=256)tmpfile.seek(0)svg=tmpfile.read()print(svg)```
```pythonexec="true" html="true"
importdrawsvgasdrawd=draw.Drawing(200,200,origin='center')# Animate the position and color of circlec=draw.Circle(0,0,20,fill='red')# See for supported attributes:# https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animatec.append_anim(draw.Animate('cy','6s','-80;80;-80',repeatCount='indefinite'))c.append_anim(draw.Animate('cx','6s','0;80;0;-80;0',repeatCount='indefinite'))c.append_anim(draw.Animate('fill','6s','red;green;blue;yellow',calc_mode='discrete',repeatCount='indefinite'))d.append(c)# Animate a black circle around an ellipseellipse=draw.Path()ellipse.M(-90,0)ellipse.A(90,40,360,True,True,90,0)# Ellipse pathellipse.A(90,40,360,True,True,-90,0)ellipse.Z()c2=draw.Circle(0,0,10)# See for supported attributes:# https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animate_motionc2.append_anim(draw.AnimateMotion(ellipse,'3s',repeatCount='indefinite'))# See for supported attributes:# https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animate_transformc2.append_anim(draw.AnimateTransform('scale','3s','1,2;2,1;1,2;2,1;1,2',repeatCount='indefinite'))d.append(c2)print(d.as_svg())```
This example displays a file-tree of the current project, in which you can descend thanks to Material for MkDocs' code annotations. It uses a recursive Python function which accept a code block session name as parameter 🤯:
If you know a project is using argparse to build its command line interface, and if it exposes its parser, then you can get the help message directly from the parser.
usage: duty [GLOBAL_OPTS...] [DUTY [DUTY_OPTS...] [DUTY_PARAMS...]...]
A simple task runner.
positional arguments:
remainder
Global options:
-d, --duties-file DUTIES_FILE
Python file where the duties are defined.
-l, --list List the available duties.
-h, --help [DUTY ...]
Show this help message and exit. Pass duties names to
print their help.
-V, --version show program's version number and exit
--debug-info Print debug information.
-c, --capture {stdout,stderr,both,none}
Which output to capture. Colors are supported with
'both' only, unless the command has a 'force color'
option.
-f, --fmt, --format {pretty,tap}
Output format. Pass your own Jinja2 template as a
string with '-f custom=TEMPLATE'. Available variables:
command, title (command or title passed with -t), code
(exit status), success (boolean), failure (boolean),
number (command number passed with -n), output
(command output), nofail (boolean), quiet (boolean),
silent (boolean). Available filters: indent
(textwrap.indent).
-y, --pty Enable the use of a pseudo-terminal. PTY doesn't allow
programs to use standard input.
-Y, --no-pty Disable the use of a pseudo-terminal. PTY doesn't
allow programs to use standard input.
-p, --progress Print progress while running a command.
-P, --no-progress Don't print progress while running a command.
-q, --quiet Don't print the command output, even if it failed.
-Q, --no-quiet Print the command output when it fails.
-s, --silent Don't print anything.
-S, --no-silent Print output as usual.
-z, --zero, --nofail Don't fail. Always return a success (0) exit code.
-Z, --no-zero, --strict
Return the original exit code.
In this example, we inspect the argparse parser to build better-looking Markdown/HTML contents. We simply use the description and iterate on options, but more complex stuff is possible of course.
-d,--duties-file: Python file where the duties are defined.(default: duties.py)
-l,--list: List the available duties.
-h,--helpDUTY: Show this help message and exit. Pass duties names to print their help.
--completion: ==SUPPRESS==
--complete: ==SUPPRESS==
-V,--version: show program's version number and exit
--debug-info: Print debug information.
-c,--capture: Which output to capture. Colors are supported with 'both' only, unless the command has a 'force color' option.
-f,--fmt,--format: Output format. Pass your own Jinja2 template as a string with '-f custom=TEMPLATE'. Available variables: command, title (command or title passed with -t), code (exit status), success (boolean), failure (boolean), number (command number passed with -n), output (command output), nofail (boolean), quiet (boolean), silent (boolean). Available filters: indent (textwrap.indent).
-y,--pty: Enable the use of a pseudo-terminal. PTY doesn't allow programs to use standard input.
-Y,--no-pty: Disable the use of a pseudo-terminal. PTY doesn't allow programs to use standard input.
-p,--progress: Print progress while running a command.
-P,--no-progress: Don't print progress while running a command.
-q,--quiet: Don't print the command output, even if it failed.
-Q,--no-quiet: Print the command output when it fails.
-s,--silent: Don't print anything.
-S,--no-silent: Print output as usual.
-z,--zero,--nofail: Don't fail. Always return a success (0) exit code.
-Z,--no-zero,--strict: Return the original exit code.
This example uses Python's runpy module to run another Python module. This other module's output is captured by temporarily patching sys.stdout with a text buffer.
Usage: mkdocs [OPTIONS] COMMAND [ARGS]...
MkDocs - Project documentation with Markdown.
Options:
-V, --version Show the version and exit.
-q, --quiet Silence warnings
-v, --verbose Enable verbose output
--color / --no-color Force enable or disable color and wrapping for the
output. Default is auto-detect.
-h, --help Show this message and exit.
Commands:
build Build the MkDocs documentation.
get-deps Show required PyPI packages inferred from plugins in...
gh-deploy Deploy your documentation to GitHub Pages.
new Create a new MkDocs project.
serve Run the builtin development server.