Feat: Streaming Docs + Examples (#1912)

* feat: streaming examples + gen

* feat: more examples

* chore: gen again

* feat: fastapi example

* chore: gen

* feat: callout

* fix: typos

* fix: whoops - how did this work?

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Matt Kaye
2025-06-26 17:28:05 -04:00
committed by GitHub
parent e62f7edab3
commit 1cd12f24f8
48 changed files with 621 additions and 221 deletions

View File

@@ -5,11 +5,13 @@ from hatchet_sdk.clients.listeners.run_event_listener import StepRunEventType
async def main() -> None:
# > Consume
ref = await stream_task.aio_run_no_wait()
async for chunk in ref.stream():
if chunk.type == StepRunEventType.STEP_RUN_EVENT_TYPE_STREAM:
print(chunk.payload, flush=True, end="")
# !!
if __name__ == "__main__":

View File

@@ -0,0 +1,31 @@
from typing import AsyncGenerator
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from examples.streaming.worker import stream_task
from hatchet_sdk import RunEventListener, StepRunEventType
# > FastAPI Proxy
app = FastAPI()
async def generate_stream(stream: RunEventListener) -> AsyncGenerator[str, None]:
async for chunk in stream:
if chunk.type == StepRunEventType.STEP_RUN_EVENT_TYPE_STREAM:
yield chunk.payload
@app.get("/stream")
async def stream() -> StreamingResponse:
ref = await stream_task.aio_run_no_wait()
return StreamingResponse(generate_stream(ref.stream()), media_type="text/plain")
# !!
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)

View File

@@ -1,17 +0,0 @@
import time
from examples.streaming.worker import stream_task
def main() -> None:
ref = stream_task.run_no_wait()
time.sleep(1)
stream = ref.stream()
for chunk in stream:
print(chunk)
if __name__ == "__main__":
main()

View File

@@ -1,5 +1,3 @@
import asyncio
from datetime import datetime, timedelta, timezone
from subprocess import Popen
from typing import Any
@@ -7,10 +5,7 @@ import pytest
from examples.streaming.worker import chunks, stream_task
from hatchet_sdk import Hatchet
from hatchet_sdk.clients.listeners.run_event_listener import (
StepRunEvent,
StepRunEventType,
)
from hatchet_sdk.clients.listeners.run_event_listener import StepRunEventType
@pytest.mark.parametrize(

View File

@@ -1,5 +1,4 @@
import asyncio
from datetime import datetime, timedelta, timezone
from typing import Generator
from hatchet_sdk import Context, EmptyModel, Hatchet
@@ -8,10 +7,10 @@ hatchet = Hatchet(debug=False)
# > Streaming
content = """
anna_karenina = """
Happy families are all alike; every unhappy family is unhappy in its own way.
Everything was in confusion in the Oblonskys' house. The wife had discovered that the husband was carrying on an intrigue with a French girl, who had been a governess in their family, and she had announced to her husband that she could not go on living in the same house with him. This position of affairs had now lasted three days, and not only the husband and wife themselves, but all the members of their family and household, were painfully conscious of it. Every person in the house felt that there was so sense in their living together, and that the stray people brought together by chance in any inn had more in common with one another than they, the members of the family and household of the Oblonskys. The wife did not leave her own room, the husband had not been at home for three days. The children ran wild all over the house; the English governess quarreled with the housekeeper, and wrote to a friend asking her to look out for a new situation for her; the man-cook had walked off the day before just at dinner time; the kitchen-maid, and the coachman had given warning.
Everything was in confusion in the Oblonskys' house. The wife had discovered that the husband was carrying on an intrigue with a French girl, who had been a governess in their family, and she had announced to her husband that she could not go on living in the same house with him.
"""
@@ -20,16 +19,20 @@ def create_chunks(content: str, n: int) -> Generator[str, None, None]:
yield content[i : i + n]
chunks = list(create_chunks(content, 10))
chunks = list(create_chunks(anna_karenina, 10))
@hatchet.task()
async def stream_task(input: EmptyModel, ctx: Context) -> None:
# 👀 Sleeping to avoid race conditions
await asyncio.sleep(2)
for chunk in chunks:
ctx.put_stream(chunk)
await asyncio.sleep(0.05)
await asyncio.sleep(0.20)
# !!
def main() -> None:
@@ -37,7 +40,5 @@ def main() -> None:
worker.start()
# !!
if __name__ == "__main__":
main()