lab-01-first-runnable
First Runnable
README
# lab-01-first-runnable — foundations arc Before you touch LangChain proper, internalize what a **Runnable** is supposed to do: same method names, predictable shapes, batching that is not "a for-loop that forgot it has a job," and streaming that actually yields lazily. You build a toy `RunnableLambda`-style object: `invoke`, `batch`, and `stream`. No cloud. No vendor SDK. Just the contract the ecosystem assumes you respect. ## Run ```bash cd labs/langchain/lab-01-first-runnable uv run python src/main.py ``` ## Test ```bash uv run pytest tests/ ``` ## Stretch goals - Add `ainvoke` as a thin async wrapper if you want to rehearse later async graphs. - Log per-call timing in `stream` and prove chunks cross a time boundary (sleep 0 in tests only).
pyproject.toml
[project] name = "lab-01-first-runnable" version = "0.1.0" requires-python = ">=3.11" dependencies = [] [project.optional-dependencies] dev = ["pytest>=8.0"] [tool.uv] dev-dependencies = []
Starter Python
"""Demo CLI for lab-01-first-runnable."""
from __future__ import annotations
import sys
from pathlib import Path
_SRC = Path(__file__).resolve().parent
if str(_SRC) not in sys.path:
sys.path.insert(0, str(_SRC))
from runnable_toy import RunnableToy
def main() -> None:
r = RunnableToy()
print("invoke:", r.invoke({"n": 7}))
print("batch:", r.batch([{"n": 1}, {"n": 2}, {"n": 3}]))
print("stream:", "".join(r.stream({"n": 21})))
if __name__ == "__main__":
main()