diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 7dc3d0b3..8eefc64e 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -53,7 +53,7 @@ jobs: - uses: actions/setup-node@v3 if: github.event.inputs.sdkTypescriptVersion != '' with: - node-version: "19.x" + node-version: "20.x" registry-url: "https://registry.npmjs.org" - name: Bump sdk-typescript if: github.event.inputs.sdkTypescriptVersion != '' @@ -127,14 +127,15 @@ jobs: - name: Create Pull Request uses: peter-evans/create-pull-request@v5 with: - title: "[GithubActions] Update Restate ${{ inputs.restateVersion != '' && format('Runtime {0} ', inputs.restateVersion) }}${{ inputs.sdkTypescriptVersion != '' && format('SDK-Typescript {0} ', inputs.sdkTypescriptVersion) }}${{ inputs.sdkJavaVersion != '' && format('SDK-Java {0} ', inputs.sdkJavaVersion) }}${{ inputs.cdkVersion != '' && format('CDK {0} ', inputs.cdkVersion) }}${{ inputs.sdkGoVersion != '' && format('SDK-Go {0} ', inputs.sdkGoVersion) }}${{ inputs.sdkRustVersion != '' && format('SDK-Rust {0} ', inputs.sdkRustVersion) }}" - commit-message: "[GithubActions] Update Restate ${{ inputs.restateVersion != '' && format('Runtime {0} ', inputs.restateVersion) }}${{ inputs.sdkTypescriptVersion != '' && format('SDK-Typescript {0} ', inputs.sdkTypescriptVersion) }}${{ inputs.sdkJavaVersion != '' && format('SDK-Java {0} ', inputs.sdkJavaVersion) }}${{ inputs.cdkVersion != '' && format('CDK {0} ', inputs.cdkVersion) }}${{ inputs.sdkGoVersion != '' && format('SDK-Go {0} ', inputs.sdkGoVersion) }}${{ inputs.sdkRustVersion != '' && format('SDK-Rust {0} ', inputs.sdkRustVersion) }}" + title: "[GithubActions] Update Restate ${{ inputs.restateVersion != '' && format('Runtime {0} ', inputs.restateVersion) }}${{ inputs.sdkTypescriptVersion != '' && format('SDK-Typescript {0} ', inputs.sdkTypescriptVersion) }}${{ inputs.sdkJavaVersion != '' && format('SDK-Java {0} ', inputs.sdkJavaVersion) }}${{ inputs.cdkVersion != '' && format('CDK {0} ', inputs.cdkVersion) }}${{ inputs.sdkGoVersion != '' && format('SDK-Go {0} ', inputs.sdkGoVersion) }}${{ inputs.sdkRustVersion != '' && format('SDK-Rust {0} ', inputs.sdkRustVersion) }}${{ inputs.sdkPythonVersion != '' && format('SDK-Python {0} ', inputs.sdkPythonVersion) }}" + commit-message: "[GithubActions] Update Restate ${{ inputs.restateVersion != '' && format('Runtime {0} ', inputs.restateVersion) }}${{ inputs.sdkTypescriptVersion != '' && format('SDK-Typescript {0} ', inputs.sdkTypescriptVersion) }}${{ inputs.sdkJavaVersion != '' && format('SDK-Java {0} ', inputs.sdkJavaVersion) }}${{ inputs.cdkVersion != '' && format('CDK {0} ', inputs.cdkVersion) }}${{ inputs.sdkGoVersion != '' && format('SDK-Go {0} ', inputs.sdkGoVersion) }}${{ inputs.sdkRustVersion != '' && format('SDK-Rust {0} ', inputs.sdkRustVersion) }}${{ inputs.sdkPythonVersion != '' && format('SDK-Python {0} ', inputs.sdkPythonVersion) }}" add-paths: | **/package.json **/package-lock.json **/build.gradle.kts **/pom.xml **/requirements.txt + **/pyproject.toml **/go.mod **/go.sum **/Cargo.lock diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 79c444fc..dd0c085c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -146,5 +146,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} + - name: Install uv + uses: astral-sh/setup-uv@v4 - name: Run tests run: ./.tools/run_python_tests.sh diff --git a/.tools/run_python_tests.sh b/.tools/run_python_tests.sh index f4c8f977..78c6ac79 100755 --- a/.tools/run_python_tests.sh +++ b/.tools/run_python_tests.sh @@ -6,14 +6,24 @@ SELF_PATH=${BASH_SOURCE[0]:-"$(command -v -- "$0")"} PROJECT_ROOT="$(dirname "$SELF_PATH")/.." function python_mypi_lint() { - python3 -m venv .venv - source .venv/bin/activate - pip install -r requirements.txt - pip install mypy - python3 -m mypy . - deactivate + if [ -f "pyproject.toml" ]; then + uv sync + uv add --dev mypy + uv run mypy . + elif [ -f "requirements.txt" ]; then + python3 -m venv .venv + source .venv/bin/activate + pip install -r requirements.txt + pip install mypy + python3 -m mypy . + deactivate + else + echo "No pyproject.toml or requirements.txt found in $(pwd)" + exit 1 + fi } + pushd $PROJECT_ROOT/python/templates/python && python_mypi_lint && popd pushd $PROJECT_ROOT/python/basics && python_mypi_lint && popd pushd $PROJECT_ROOT/python/patterns-use-cases && python_mypi_lint && popd diff --git a/.tools/update_python_examples.sh b/.tools/update_python_examples.sh index ae74defb..84f2d536 100755 --- a/.tools/update_python_examples.sh +++ b/.tools/update_python_examples.sh @@ -8,12 +8,11 @@ PROJECT_ROOT="$(dirname "$SELF_PATH")/.." function search_and_replace_version() { echo "upgrading Python version of $1 to $NEW_VERSION" - if [ -e "$1/requirements.txt" ]; then - sed -i 's/restate_sdk==[0-9A-Za-z.-]*/restate_sdk=='"$NEW_VERSION"'/' "$1/requirements.txt" - fi; - if [ -e "$1/pyproject.toml" ]; then - sed -i 's/restate-sdk==[0-9A-Za-z.-]*/restate-sdk=='"$NEW_VERSION"'/' "$1/pyproject.toml" - sed -i 's/restate_sdk\[serde\]>=[0-9A-Za-z.-]*/restate_sdk[serde]>='"$NEW_VERSION"'/' "$1/pyproject.toml" + if [ -e "pyproject.toml" ]; then + # Use uv for pyproject.toml projects + uv add "restate-sdk[serde]>=$NEW_VERSION" + elif [ -e "requirements.txt" ]; then + sed -i 's/restate[_-]sdk\[serde\][>=!<~][^[:space:]]*/restate-sdk[serde]=='$NEW_VERSION'/' requirements.txt fi; } diff --git a/python/tutorials/tour-of-orchestration-python/app/communication/service.py b/python/tutorials/tour-of-orchestration-python/app/communication/service.py index 7bc5ba70..c695eed3 100644 --- a/python/tutorials/tour-of-orchestration-python/app/communication/service.py +++ b/python/tutorials/tour-of-orchestration-python/app/communication/service.py @@ -1,7 +1,7 @@ import restate from app.utils import day_before from app.types import PurchaseTicketRequest -from app.utils import charge, email_ticket, send_reminder +from app.utils import charge, email_ticket, send_reminder_email # Concert Ticketing Service @@ -17,6 +17,6 @@ async def buy(ctx: restate.Context, req: PurchaseTicketRequest) -> str: ctx.service_send(email_ticket, req) # Delayed message - schedule reminder for day before concert - ctx.service_send(send_reminder, req, send_delay=day_before(req.concert_date)) + ctx.service_send(send_reminder_email, req, send_delay=day_before(req.concert_date)) return f"Ticket purchased successfully with payment reference: {pay_ref}" diff --git a/python/tutorials/tour-of-orchestration-python/app/objects/service.py b/python/tutorials/tour-of-orchestration-python/app/objects/service.py index e0557ced..ea3eb0b0 100644 --- a/python/tutorials/tour-of-orchestration-python/app/objects/service.py +++ b/python/tutorials/tour-of-orchestration-python/app/objects/service.py @@ -7,9 +7,9 @@ @user_subscriptions.handler() -async def add(ctx: restate.ObjectContext, subscription: str) -> None: +async def add(ctx: restate.ObjectContext, subscription: str): # Get current subscriptions - subscriptions = await ctx.get("subscriptions") or [] + subscriptions = await ctx.get("subscriptions", type_hint=List[str]) or [] # Add new subscription if subscription not in subscriptions: diff --git a/python/tutorials/tour-of-orchestration-python/app/utils.py b/python/tutorials/tour-of-orchestration-python/app/utils.py index 52ee6010..ade61384 100644 --- a/python/tutorials/tour-of-orchestration-python/app/utils.py +++ b/python/tutorials/tour-of-orchestration-python/app/utils.py @@ -103,7 +103,7 @@ def init_payment(req: PaymentRequest, payment_id: str, confirmation_id: str) -> return f"payRef-{uuid.uuid4()}" -def cancel_payment(pay_ref: str) -> None: +def cancel_payment(pay_ref: str): """Mock function to cancel payment""" print(f">>> Canceling external payment with ref {pay_ref}") @@ -140,5 +140,5 @@ async def email_ticket(ctx: restate.Context, req: PurchaseTicketRequest) -> None @email_service.handler() -async def send_reminder(ctx: restate.Context, req: PurchaseTicketRequest) -> None: +async def send_reminder_email(ctx: restate.Context, req: PurchaseTicketRequest) -> None: print(f"Sending reminder for concert on {req.concert_date} to {req.customer_email}") diff --git a/python/tutorials/tour-of-orchestration-python/pyproject.toml b/python/tutorials/tour-of-orchestration-python/pyproject.toml index a86a7844..1b452d19 100644 --- a/python/tutorials/tour-of-orchestration-python/pyproject.toml +++ b/python/tutorials/tour-of-orchestration-python/pyproject.toml @@ -16,3 +16,8 @@ packages = ["app"] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" + +[dependency-groups] +dev = [ + "mypy>=1.18.2", +]