diff --git a/get_started/README.md b/get_started/README.md deleted file mode 100644 index f1b50083..00000000 --- a/get_started/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# Restack AI SDK - Get Started Example - -This repository contains a simple example project to help you get started with the Restack AI SDK. It demonstrates how to set up a basic workflow and functions using the SDK. - -## Prerequisites - -- Python 3.8 or higher -- Poetry (for dependency management) -- Docker (for running the Restack services) - -## Usage - -1. Run Restack local engine with Docker: - - ```bash - docker run -d --pull always --name restack -p 5233:5233 -p 6233:6233 -p 7233:7233 ghcr.io/restackio/restack:main - ``` - -2. Open the web UI to see the workflows: - - ```bash - http://localhost:5233 - ``` - -3. Clone this repository: - - ```bash - git clone https://github.com/restackio/examples-python - cd examples-python/examples/get-started - ``` - -4. Install dependencies using Poetry: - - ```bash - poetry env use 3.12 - ``` - - ```bash - poetry shell - ``` - - ```bash - poetry install - ``` - - ```bash - poetry env info # Optional: copy the interpreter path to use in your IDE (e.g. Cursor, VSCode, etc.) - ``` - -5. Run the services: - - ```bash - poetry run dev - ``` - - This will start the Restack service with the defined workflows and functions. - -6. In a new terminal, schedule the workflow: - - ```bash - poetry shell - ``` - - ```bash - poetry run schedule - ``` - - This will schedule the `GreetingWorkflow` and print the result. - -7. Optionally, schedule the workflow to run on a specific calendar or interval: - - ```bash - poetry run calendar - ``` - - ```bash - poetry run interval - ``` - -## Project Structure - -- `src/`: Main source code directory - - `client.py`: Initializes the Restack client - - `functions/`: Contains function definitions - - `workflows/`: Contains workflow definitions - - `services.py`: Sets up and runs the Restack services -- `schedule_workflow.py`: Example script to schedule and run a workflow diff --git a/get_started/src/client.py b/get_started/src/client.py deleted file mode 100644 index 52430d36..00000000 --- a/get_started/src/client.py +++ /dev/null @@ -1,4 +0,0 @@ -import os -from restack_ai import Restack - -client = Restack() diff --git a/get_started/src/workflows/workflow.py b/get_started/src/workflows/workflow.py deleted file mode 100644 index 57de6216..00000000 --- a/get_started/src/workflows/workflow.py +++ /dev/null @@ -1,15 +0,0 @@ -from datetime import timedelta -from restack_ai.workflow import workflow, import_functions, log -with import_functions(): - from src.functions.function import welcome - -@workflow.defn() -class GreetingWorkflow: - @workflow.run - async def run(self): - log.info("GreetingWorkflow started") - result = await workflow.step(welcome, input="world", start_to_close_timeout=timedelta(seconds=120)) - log.info("GreetingWorkflow completed", result=result) - return result - - diff --git a/get_started/.env.Example b/quickstart/.env.Example similarity index 100% rename from get_started/.env.Example rename to quickstart/.env.Example diff --git a/get_started/.gitignore b/quickstart/.gitignore similarity index 100% rename from get_started/.gitignore rename to quickstart/.gitignore diff --git a/quickstart/README.md b/quickstart/README.md new file mode 100644 index 00000000..af7baeb2 --- /dev/null +++ b/quickstart/README.md @@ -0,0 +1,67 @@ +# Restack AI - Quickstart + +This repository contains a quickstart for Restack. +It demonstrates how to set up a basic workflow and functions. + +## Prerequisites + +- Docker (for running Restack) +- Python 3.10 or higher + +## Start Restack + +To start the Restack, use the following Docker command: + +```bash +docker run -d --pull always --name restack -p 5233:5233 -p 6233:6233 -p 7233:7233 ghcr.io/restackio/restack:main +``` + +## Install dependencies and start services + +```bash +poetry env use 3.10 +``` + +```bash +poetry shell +``` + +```bash +poetry install +``` + +```bash +poetry env info # Optional: copy the interpreter path to use in your IDE (e.g. Cursor, VSCode, etc.) +``` + +```bash +poetry run dev +``` + +## Run workflows + +### from UI + +You can run workflows from the UI by clicking the "Run" button. + +![Run workflows from UI](./screenshot-quickstart.png) + +### from API + +You can run workflows from the API by using the generated endpoint: + +`POST http://localhost:6233/api/workflows/GreetingWorkflow` + +### from any client + +You can run workflows with any client connected to Restack, for example: + +```bash +poetry run schedule +``` + +executes `schedule_workflow.py` which will connect to Restack and execute the `GreetingWorkflow` workflow. + +## Deploy on Restack Cloud + +To deploy the application on Restack, you can create an account at [https://console.restack.io](https://console.restack.io) diff --git a/get_started/pyproject.toml b/quickstart/pyproject.toml similarity index 73% rename from get_started/pyproject.toml rename to quickstart/pyproject.toml index 4cfcb3d2..f19911b1 100644 --- a/get_started/pyproject.toml +++ b/quickstart/pyproject.toml @@ -1,8 +1,8 @@ # Project metadata [tool.poetry] -name = "get_started" +name = "quickstart" version = "0.0.1" -description = "A simple example to get started with the restack-ai SDK" +description = "A quickstart for Restack" authors = [ "Restack Team ", ] @@ -11,13 +11,11 @@ packages = [{include = "src"}] [tool.poetry.dependencies] python = ">=3.10,<4.0" -restack-ai = "^0.0.48" watchfiles = "^1.0.0" - -[tool.poetry.dev-dependencies] -pytest = "6.2" # Optional: Add if you want to include tests in your example +pydantic = "^2.10.4" # Build system configuration +restack-ai = "^0.0.52" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/get_started/schedule_calendar.py b/quickstart/schedule_calendar.py similarity index 86% rename from get_started/schedule_calendar.py rename to quickstart/schedule_calendar.py index 9d52b575..61bffa83 100644 --- a/get_started/schedule_calendar.py +++ b/quickstart/schedule_calendar.py @@ -2,7 +2,7 @@ import time from restack_ai import Restack from restack_ai.restack import ScheduleSpec, ScheduleCalendarSpec, ScheduleRange - +from src.workflows.workflow import GreetingWorkflowInput async def main(): client = Restack() @@ -11,6 +11,7 @@ async def main(): await client.schedule_workflow( workflow_name="GreetingWorkflow", workflow_id=workflow_id, + input=GreetingWorkflowInput(name="Bob"), schedule=ScheduleSpec( calendars=[ScheduleCalendarSpec( day_of_week=[ScheduleRange(start=1)], diff --git a/get_started/schedule_interval.py b/quickstart/schedule_interval.py similarity index 85% rename from get_started/schedule_interval.py rename to quickstart/schedule_interval.py index 50d21e56..9830f876 100644 --- a/get_started/schedule_interval.py +++ b/quickstart/schedule_interval.py @@ -3,7 +3,7 @@ from restack_ai import Restack from restack_ai.restack import ScheduleSpec, ScheduleIntervalSpec from datetime import timedelta - +from src.workflows.workflow import GreetingWorkflowInput async def main(): client = Restack() @@ -12,6 +12,7 @@ async def main(): await client.schedule_workflow( workflow_name="GreetingWorkflow", workflow_id=workflow_id, + input=GreetingWorkflowInput(name="Bob"), schedule=ScheduleSpec( intervals=[ScheduleIntervalSpec( every=timedelta(minutes=10) diff --git a/get_started/schedule_workflow.py b/quickstart/schedule_workflow.py similarity index 77% rename from get_started/schedule_workflow.py rename to quickstart/schedule_workflow.py index e808eec2..36829152 100644 --- a/get_started/schedule_workflow.py +++ b/quickstart/schedule_workflow.py @@ -1,7 +1,7 @@ import asyncio import time from restack_ai import Restack - +from src.workflows.workflow import GreetingWorkflowInput async def main(): client = Restack() @@ -9,7 +9,8 @@ async def main(): workflow_id = f"{int(time.time() * 1000)}-GreetingWorkflow" run_id = await client.schedule_workflow( workflow_name="GreetingWorkflow", - workflow_id=workflow_id + workflow_id=workflow_id, + input=GreetingWorkflowInput(name="Bob") ) await client.get_workflow_result( diff --git a/get_started/src/__init__.py b/quickstart/src/__init__.py similarity index 100% rename from get_started/src/__init__.py rename to quickstart/src/__init__.py diff --git a/quickstart/src/client.py b/quickstart/src/client.py new file mode 100644 index 00000000..6fbc2318 --- /dev/null +++ b/quickstart/src/client.py @@ -0,0 +1,18 @@ +import os +from restack_ai import Restack +from restack_ai.restack import CloudConnectionOptions +from dotenv import load_dotenv +# Load environment variables from a .env file +load_dotenv() + + +engine_id = os.getenv("RESTACK_ENGINE_ID") +address = os.getenv("RESTACK_ENGINE_ADDRESS") +api_key = os.getenv("RESTACK_ENGINE_API_KEY") + +connection_options = CloudConnectionOptions( + engine_id=engine_id, + address=address, + api_key=api_key, +) +client = Restack(connection_options) \ No newline at end of file diff --git a/get_started/src/functions/__init__.py b/quickstart/src/functions/__init__.py similarity index 100% rename from get_started/src/functions/__init__.py rename to quickstart/src/functions/__init__.py diff --git a/get_started/src/functions/function.py b/quickstart/src/functions/function.py similarity index 58% rename from get_started/src/functions/function.py rename to quickstart/src/functions/function.py index 355c0cdd..520a78dd 100644 --- a/get_started/src/functions/function.py +++ b/quickstart/src/functions/function.py @@ -1,10 +1,14 @@ from restack_ai.function import function, log +from pydantic import BaseModel + +class WelcomeInput(BaseModel): + name: str @function.defn() -async def welcome(input: str) -> str: +async def welcome(input: WelcomeInput) -> str: try: log.info("welcome function started", input=input) - return f"Hello, {input}!" + return f"Hello, {input.name}!" except Exception as e: log.error("welcome function failed", error=e) raise e diff --git a/get_started/src/services.py b/quickstart/src/services.py similarity index 100% rename from get_started/src/services.py rename to quickstart/src/services.py diff --git a/get_started/src/workflows/__init__.py b/quickstart/src/workflows/__init__.py similarity index 100% rename from get_started/src/workflows/__init__.py rename to quickstart/src/workflows/__init__.py diff --git a/quickstart/src/workflows/workflow.py b/quickstart/src/workflows/workflow.py new file mode 100644 index 00000000..a42b9684 --- /dev/null +++ b/quickstart/src/workflows/workflow.py @@ -0,0 +1,19 @@ +from datetime import timedelta +from pydantic import BaseModel, Field +from restack_ai.workflow import workflow, import_functions, log +with import_functions(): + from src.functions.function import welcome, WelcomeInput + +class GreetingWorkflowInput(BaseModel): + name: str = Field(default='Bob') + +@workflow.defn() +class GreetingWorkflow: + @workflow.run + async def run(self, input: GreetingWorkflowInput): + log.info("GreetingWorkflow started") + result = await workflow.step(welcome, input=WelcomeInput(name=input.name), start_to_close_timeout=timedelta(seconds=120)) + log.info("GreetingWorkflow completed", result=result) + return result + +