Skip to content

Commit 5459f68

Browse files
committed
docs
1 parent 28433e4 commit 5459f68

File tree

281 files changed

+786
-287
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

281 files changed

+786
-287
lines changed

README.md

+173-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,173 @@
1-
# flowshow
2-
Just a super thin wrapper for Python tasks that form a flow.
1+
<img src="imgs/icon.png" alt="flowshow logo" width="125" align="right"/>
2+
3+
### flowshow
4+
5+
> Just a super thin wrapper for Python tasks that form a flow.
6+
7+
## Installation
8+
9+
```bash
10+
uv pip install flowshow
11+
```
12+
13+
## Usage
14+
15+
Flowshow provides a `@task` decorator that helps you track and visualize the execution of your Python functions. Here's how to use it:
16+
17+
```python
18+
import time
19+
import random
20+
21+
from flowshow import task
22+
23+
# Turns a function into a Task, which tracks a bunch of stuff
24+
@task
25+
def my_function(x):
26+
time.sleep(0.5)
27+
return x * 2
28+
29+
# Tasks can also be configured to handle retries
30+
@task(retry_on=ValueError, retry_attempts=10)
31+
def might_fail():
32+
time.sleep(0.5)
33+
if random.random() < 0.5:
34+
raise ValueError("oh no, error!")
35+
return "done"
36+
37+
@task
38+
def main_job():
39+
print("This output will be captured by the task")
40+
for i in range(3):
41+
my_function(10)
42+
might_fail()
43+
return "done"
44+
45+
# Run like you might run a normal function
46+
main_job()
47+
```
48+
49+
Once you run your function you can expect some nice visuals, like this one:
50+
51+
```python
52+
main_job.plot()
53+
```
54+
55+
![](imgs/screenshot.png)
56+
57+
You can also inspect the raw data yourself by running:
58+
59+
```python
60+
main_job.last_run.to_dict()
61+
```
62+
63+
<details>
64+
<summary>Show the full dictionary.</summary>
65+
```
66+
{
67+
"task_name": "main_job",
68+
"start_time": "2025-02-04T21:25:17.045576+00:00",
69+
"duration": 8.864794875029474,
70+
"inputs": {},
71+
"error": None,
72+
"retry_count": 0,
73+
"end_time": "2025-02-04T21:25:25.909997+00:00",
74+
"logs": "This output will be captured by the task\n",
75+
"output": "done",
76+
"subtasks": [
77+
{
78+
"task_name": "my_function",
79+
"start_time": "2025-02-04T21:25:17.045786+00:00",
80+
"duration": 0.5050525842234492,
81+
"inputs": {
82+
"arg0": 10
83+
},
84+
"error": None,
85+
"retry_count": 0,
86+
"end_time": "2025-02-04T21:25:17.550808+00:00",
87+
"logs": "",
88+
"output": 20
89+
},
90+
{
91+
"task_name": "might_fail",
92+
"start_time": "2025-02-04T21:25:17.550853+00:00",
93+
"duration": 0.5053939162753522,
94+
"inputs": {},
95+
"error": None,
96+
"retry_count": 0,
97+
"end_time": "2025-02-04T21:25:18.056233+00:00",
98+
"logs": "",
99+
"output": "done"
100+
},
101+
{
102+
"task_name": "my_function",
103+
"start_time": "2025-02-04T21:25:18.056244+00:00",
104+
"duration": 0.5052881669253111,
105+
"inputs": {
106+
"arg0": 10
107+
},
108+
"error": None,
109+
"retry_count": 0,
110+
"end_time": "2025-02-04T21:25:18.561502+00:00",
111+
"logs": "",
112+
"output": 20
113+
},
114+
{
115+
"task_name": "might_fail",
116+
"start_time": "2025-02-04T21:25:18.561516+00:00",
117+
"duration": 2.1351009169593453,
118+
"inputs": {},
119+
"error": None,
120+
"retry_count": 0,
121+
"end_time": "2025-02-04T21:25:20.696477+00:00",
122+
"logs": "",
123+
"output": "done"
124+
},
125+
{
126+
"task_name": "my_function",
127+
"start_time": "2025-02-04T21:25:20.696511+00:00",
128+
"duration": 0.5026454580947757,
129+
"inputs": {
130+
"arg0": 10
131+
},
132+
"error": None,
133+
"retry_count": 0,
134+
"end_time": "2025-02-04T21:25:21.199158+00:00",
135+
"logs": "",
136+
"output": 20
137+
},
138+
{
139+
"task_name": "might_fail",
140+
"start_time": "2025-02-04T21:25:21.199213+00:00",
141+
"duration": 4.711003000382334,
142+
"inputs": {},
143+
"error": None,
144+
"retry_count": 0,
145+
"end_time": "2025-02-04T21:25:25.909979+00:00",
146+
"logs": "",
147+
"output": "done"
148+
}
149+
]
150+
}
151+
```
152+
</details>
153+
154+
You can also get a flat representation of the same data in a dataframe via:
155+
156+
```python
157+
main_job.to_dataframe()
158+
```
159+
160+
This is what it looks like in Marimo when you evaluate this. Note that we also track the logs of the print statements for later inspection.
161+
162+
![](imgs/dataframe.png)
163+
164+
### Multiple runs
165+
166+
If you run the function multiple times you can also inspect multiple runs:
167+
168+
```python
169+
main_job.runs
170+
```
171+
172+
This can be useful, but most of the times you're probably interested in the last run.
173+

0 commit comments

Comments
 (0)