@@ -10,82 +10,41 @@ from botanu import botanu_use_case
1010@botanu_use_case (
1111 name: str ,
1212 workflow: Optional[str ] = None ,
13- * ,
1413 environment: Optional[str ] = None ,
1514 tenant_id: Optional[str ] = None ,
16- auto_outcome_on_success: bool = True ,
17- span_kind: SpanKind = SpanKind.SERVER ,
1815)
1916```
2017
2118### Parameters
2219
2320| Parameter | Type | Default | Description |
2421| -----------| ------| ---------| -------------|
25- | ` name ` | ` str ` | Required | Use case name (e.g., "Customer Support"). Low cardinality for grouping. |
26- | ` workflow ` | ` str ` | Function name | Workflow identifier. Defaults to the decorated function's qualified name. |
27- | ` environment ` | ` str ` | From env | Deployment environment (production, staging, etc.). |
28- | ` tenant_id ` | ` str ` | ` None ` | Tenant identifier for multi-tenant systems. |
29- | ` auto_outcome_on_success ` | ` bool ` | ` True ` | Automatically emit "success" outcome if function completes without exception. |
30- | ` span_kind ` | ` SpanKind ` | ` SERVER ` | OpenTelemetry span kind. |
22+ | ` name ` | ` str ` | Required | Use case name for grouping |
23+ | ` workflow ` | ` str ` | Function name | Workflow identifier |
24+ | ` environment ` | ` str ` | From env | Deployment environment |
25+ | ` tenant_id ` | ` str ` | ` None ` | Tenant identifier for multi-tenant systems |
3126
32- ### Behavior
33-
34- 1 . ** Generates UUIDv7 ` run_id ` ** - Sortable, globally unique identifier
35- 2 . ** Creates root span** - Named ` botanu.run/{name} `
36- 3 . ** Emits events** - ` botanu.run.started ` and ` botanu.run.completed `
37- 4 . ** Sets baggage** - Propagates context via W3C Baggage
38- 5 . ** Records outcome** - On completion or exception
39-
40- ### Examples
41-
42- #### Basic Usage
43-
44- ``` python
45- @botanu_use_case (" Customer Support" )
46- async def handle_ticket (ticket_id : str ):
47- result = await process_ticket(ticket_id)
48- emit_outcome(" success" , value_type = " tickets_resolved" , value_amount = 1 )
49- return result
50- ```
51-
52- #### With All Parameters
27+ ### Example
5328
5429``` python
55- @botanu_use_case (
56- name = " Document Processing" ,
57- workflow = " pdf_extraction" ,
58- environment = " production" ,
59- tenant_id = " acme-corp" ,
60- auto_outcome_on_success = False ,
61- span_kind = SpanKind.CONSUMER ,
62- )
63- async def process_document (doc_id : str ):
64- ...
65- ```
66-
67- #### Sync Functions
30+ from botanu import botanu_use_case
6831
69- ``` python
70- @botanu_use_case ( " Batch Processing " )
71- def process_batch ( batch_id : str ):
72- # Works with sync functions too
73- return process_items(batch_id)
32+ @botanu_use_case ( name = " process_order " )
33+ def process_order ( order_id : str ):
34+ order = db.get_order(order_id)
35+ result = llm.analyze(order)
36+ return result
7437```
7538
7639### Span Attributes
7740
78- The decorator sets these span attributes:
79-
80- | Attribute | Source |
81- | -----------| --------|
41+ | Attribute | Description |
42+ | -----------| -------------|
8243| ` botanu.run_id ` | Generated UUIDv7 |
8344| ` botanu.use_case ` | ` name ` parameter |
8445| ` botanu.workflow ` | ` workflow ` parameter or function name |
85- | ` botanu.workflow_version ` | SHA256 hash of function source |
86- | ` botanu.environment ` | ` environment ` parameter or env var |
87- | ` botanu.tenant_id ` | ` tenant_id ` parameter (if provided) |
88- | ` botanu.parent_run_id ` | Parent run ID (if nested) |
46+ | ` botanu.environment ` | Deployment environment |
47+ | ` botanu.tenant_id ` | Tenant identifier (if provided) |
8948
9049### Alias
9150
@@ -94,115 +53,48 @@ The decorator sets these span attributes:
9453``` python
9554from botanu import use_case
9655
97- @use_case (" My Use Case " )
98- async def my_function ( ):
99- ...
56+ @use_case (name = " process_order " )
57+ def process_order ( order_id : str ):
58+ return db.get_order(order_id)
10059```
10160
102- ---
103-
10461## @botanu_outcome
10562
106- Convenience decorator for sub-functions to emit outcomes based on success/failure.
63+ Decorator for sub-functions to emit outcomes based on success/failure.
10764
10865``` python
10966from botanu import botanu_outcome
11067
111- @botanu_outcome (
112- success: Optional[str ] = None ,
113- partial: Optional[str ] = None ,
114- failed: Optional[str ] = None ,
115- )
68+ @botanu_outcome ()
69+ def extract_data ():
70+ return fetch_from_source()
11671```
11772
118- ### Parameters
119-
120- | Parameter | Type | Default | Description |
121- | -----------| ------| ---------| -------------|
122- | ` success ` | ` str ` | ` None ` | Custom label for success outcome (reserved for future use). |
123- | ` partial ` | ` str ` | ` None ` | Custom label for partial outcome (reserved for future use). |
124- | ` failed ` | ` str ` | ` None ` | Custom label for failed outcome (reserved for future use). |
125-
126- ### Behavior
127-
128- - ** Does NOT create a new run** - Works within an existing run
129- - ** Emits "success"** if function completes without exception
130- - ** Emits "failed"** with exception class name if exception raised
131- - ** Skips emission** if outcome already set on current span
73+ - Emits "success" on completion
74+ - Emits "failed" with exception class name if exception raised
75+ - Does NOT create a new run
13276
13377### Example
13478
13579``` python
13680from botanu import botanu_use_case, botanu_outcome
13781
138- @botanu_use_case (" Data Pipeline " )
139- async def run_pipeline ():
140- await extract_data()
141- await transform_data()
142- await load_data()
82+ @botanu_use_case (name = " data_pipeline " )
83+ def run_pipeline ():
84+ extract_data()
85+ transform_data()
86+ load_data()
14387
14488@botanu_outcome ()
145- async def extract_data ():
146- # Emits "success" on completion
147- return await fetch_from_source()
89+ def extract_data ():
90+ return fetch_from_source()
14891
14992@botanu_outcome ()
150- async def transform_data ():
151- # Emits "failed" with reason if exception
152- return await apply_transformations()
153- ```
154-
155- ---
156-
157- ## Function Signatures
158-
159- ### Async Support
160-
161- Both decorators support async and sync functions:
162-
163- ``` python
164- # Async
165- @botanu_use_case (" Async Use Case" )
166- async def async_handler ():
167- await do_work()
168-
169- # Sync
170- @botanu_use_case (" Sync Use Case" )
171- def sync_handler ():
172- do_work()
173- ```
174-
175- ### Return Values
176-
177- Decorated functions preserve their return values:
178-
179- ``` python
180- @botanu_use_case (" Processing" )
181- async def process (data ) -> ProcessResult:
182- return ProcessResult(status = " complete" , items = 100 )
183-
184- result = await process(data)
185- assert isinstance (result, ProcessResult)
186- ```
187-
188- ### Exception Handling
189-
190- Exceptions are recorded and re-raised:
191-
192- ``` python
193- @botanu_use_case (" Risky Operation" )
194- async def risky ():
195- raise ValueError (" Something went wrong" )
196-
197- try :
198- await risky()
199- except ValueError :
200- # Exception is re-raised after recording
201- pass
93+ def transform_data ():
94+ return apply_transformations()
20295```
20396
20497## See Also
20598
206- - [ Quickstart] ( ../getting-started/quickstart.md ) - Getting started
207- - [ Run Context] ( ../concepts/run-context.md ) - Understanding runs
208- - [ Outcomes] ( ../tracking/outcomes.md ) - Recording outcomes
99+ - [ Quickstart] ( ../getting-started/quickstart.md )
100+ - [ Run Context] ( ../concepts/run-context.md )
0 commit comments