Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ clean:
docs:
uv run marimo export html-wasm demo.py --output docs --mode edit

pypi:
pypi: clean
uv build
uv publish
uv publish
142 changes: 111 additions & 31 deletions demo.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,159 @@
import marimo

__generated_with = "0.10.19"
app = marimo.App(width="medium")
__generated_with = "0.12.9"
app = marimo.App(width="full")


@app.cell
def _(mo):
mo.md("Flowshow provides a `@task` decorator that helps you track and visualize the execution of your Python functions. Here's how to use it:")
mo.md("""Flowshow provides a `@task` decorator that helps you track and visualize the execution of your Python functions. Here's how to use it:""")
return


@app.cell
def _():
import time
import random
from pydantic import BaseModel
from typing import List
from flowshow import task, add_artifacts, info, debug, warning, error, span
return (
BaseModel,
List,
add_artifacts,
debug,
error,
info,
random,
span,
task,
time,
warning,
)

from flowshow import task

# Turns a function into a Task, which tracks a bunch of stuff
@app.cell
def _(BaseModel, List, add_artifacts, debug, info, span, task, time):
class Foobar(BaseModel):
x: int
y: int
saying: str

class ManyBar(BaseModel):
desc: str
stuff: List[Foobar]

@task
def many_things(many: ManyBar):
info("This runs for demo purposes")

@task
def my_function(x):
print("This function should always run")
time.sleep(0.5)
info("This function should always run")
time.sleep(0.2)
add_artifacts(foo=1, bar=2, buz={"hello": "there"})
return x * 2

# Tasks can also be configured to handle retries
@task(retry_on=ValueError, retry_attempts=10)
@task(retry_on=ValueError, retry_attempts=5)
def might_fail():
print("This function call might fail")
time.sleep(1.0)
if random.random() < 0.75:
raise ValueError("oh no, error!")
print("The function has passed! Yay!")
info("This function call might fail")
time.sleep(0.2)
my_function(2)
# raise ValueError("oh noes")
debug("The function has passed! Yay!")
return "done"

@task
@task()
def main_job():
print("This output will be captured by the task")
info("This output will be captured by the task")
add_artifacts(manybar=ManyBar(desc="hello", stuff=[Foobar(x=1, y=2, saying="ohyes")]))
with span("hello") as s:
info("test test")
with span("foobar") as f:
info("whoa whoa")

for i in range(3):
my_function(10)
might_fail()
return "done"

# Run like you might run a normal function
_ = main_job()
return main_job, might_fail, my_function, random, task, time
return Foobar, ManyBar, main_job, many_things, might_fail, my_function


@app.cell
def _(main_job):
out = main_job.to_dataframe()
return (out,)
main_job.last_run.to_dict()['artifacts']
return


@app.cell
def _(out):
out
def _(main_job, mo):
mo.iframe(main_job.last_run.render())
return


@app.cell(hide_code=True)
def _(main_job):
import marimo as mo
@app.cell
async def _(error, info, task, time, warning):
import asyncio

chart = mo.ui.altair_chart(main_job.plot())
chart
return chart, mo
@task
async def async_sleep(seconds: float, name: str) -> str:
"""Asynchronous sleep function that returns a message after completion"""
info("it works, right?")
await asyncio.sleep(seconds)
info("it did!")
return f"{name} finished sleeping for {seconds} seconds"

@task
async def run_concurrent_tasks():
"""Run multiple sleep tasks concurrently"""
start_time = time.time()

# Create multiple sleep tasks
tasks = [
async_sleep(2, "Task 1"),
async_sleep(1, "Task 2"),
async_sleep(3, "Task 3")
]

# Run tasks concurrently and gather results
results = await asyncio.gather(*tasks)

end_time = time.time()
total_time = end_time - start_time

# Return results and timing information
return {
"results": results,
"total_time": f"Total execution time: {total_time:.2f} seconds"
}

@task
async def run_many_nested():
info("About to start task 1")
await run_concurrent_tasks()
info("About to start task 2")
await run_concurrent_tasks()
warning("They both ran!")
error("They both ran!")

await run_many_nested()
return async_sleep, asyncio, run_concurrent_tasks, run_many_nested

@app.cell(hide_code=True)
def _(chart):
if chart.value["logs"].shape[0] > 0:
print(list(chart.value["logs"])[0])

@app.cell
def _(mo, run_many_nested):
mo.iframe(run_many_nested.last_run.render())
return


@app.cell
def _():
import marimo as mo
return (mo,)


if __name__ == "__main__":
app.run()
22 changes: 22 additions & 0 deletions docs/assets/ConnectedDataExplorerComponent-CrpdjCsx.js

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions docs/assets/VegaLite-C2YLuE_k.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/assets/_baseEach-EBItHLxE.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/assets/_baseMap-wW6t1IVI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import{b as r}from"./_baseEach-EBItHLxE.js";import{r as a}from"./index-DNum250l.js";function n(n,o){var t=-1,s=a(n)?Array(n.length):[];return r(n,(function(r,a,n){s[++t]=o(r,a,n)})),s}export{n as b};
1 change: 1 addition & 0 deletions docs/assets/_baseUniq-B2DI-FKg.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/assets/any-language-editor-CvFKt0Xw.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/assets/arc-cUKDg37C.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/assets/architectureDiagram-IEHRJDOE-e-xTJjkM.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/assets/asn1-DWPaVWf6.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/assets/blockDiagram-JOT3LUYC-5pwTwtOR.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/assets/c4Diagram-VJAJSXHY-D5_ZYhd-.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/assets/channel-C7zetcvS.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import{U as a,C as r}from"./mermaid-cNbePY8J.js";const s=(s,o)=>a.lang.round(r.parse(s)[o]);export{s as c};
Loading