Skip to content

Commit

Permalink
fix: support 3.8 to 3.12 for fal and fal-client (#351)
Browse files Browse the repository at this point in the history
* fix: add 3.8 tests

* fix types

* back to 3.12 for tests for now

* type

* flaky

* graphlib

* removeprefix

* pydantic
  • Loading branch information
chamini2 authored Oct 30, 2024
1 parent 4a4712b commit 87dd82c
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 24 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/integration_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,24 @@ jobs:
strategy:
fail-fast: false
matrix:
deps: ["pydantic==1.10.12", "pydantic==2.5.0"]
deps: ["pydantic==1.10.18", "pydantic==2.5.0"]
# TODO: Test Python 3.13
python: ["3.8", "3.12"]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- uses: actions/setup-python@v4
with:
python-version: "3.9"
cache: 'pip'
python-version: ${{ matrix.python }}
cache: pip

- name: Install dependencies
run: |
pip install --upgrade pip wheel
pip install -e 'projects/fal[test]' ${{ matrix.deps }}
# TODO: should we include graphlib as a project dependency?
pip install -e 'projects/fal[test]' graphlib ${{ matrix.deps }}
- name: Run integration tests
env:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/tests-fal-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ["3.8", "3.13"]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-python@v4
with:
python-version: "3.12"
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
pip install --upgrade pip wheel
Expand All @@ -25,4 +29,4 @@ jobs:
env:
FAL_KEY: ${{ secrets.FAL_KEY_PROD }}
run: |
pytest projects/fal_client/tests
pytest projects/fal_client/tests
6 changes: 4 additions & 2 deletions projects/fal/src/fal/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ def submit(app_id: str, arguments: dict[str, Any], *, path: str = "") -> Request
app_id = _backwards_compatible_app_id(app_id)
url = _QUEUE_URL_FORMAT.format(app_id=app_id)
if path:
url += "/" + path.removeprefix("/")
_path = path[len("/") :] if path.startswith("/") else path
url += "/" + _path

creds = get_default_credentials()

Expand Down Expand Up @@ -235,7 +236,8 @@ def _connect(app_id: str, *, path: str = "/realtime") -> Iterator[_RealtimeConne
app_id = _backwards_compatible_app_id(app_id)
url = _REALTIME_URL_FORMAT.format(app_id=app_id)
if path:
url += "/" + path.removeprefix("/")
_path = path[len("/") :] if path.startswith("/") else path
url += "/" + _path

creds = get_default_credentials()

Expand Down
14 changes: 10 additions & 4 deletions projects/fal/src/fal/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from argparse import ArgumentParser
from collections import Counter
from dataclasses import dataclass, field
from typing import Any, Iterator, Union, cast
from typing import Any, Dict, Iterator, List, Union, cast

import graphlib
import rich
Expand All @@ -21,8 +21,8 @@
from fal.exceptions import FalServerlessException
from fal.rest_client import REST_CLIENT

JSONType = Union[dict[str, Any], list[Any], str, int, float, bool, None, "Leaf"]
SchemaType = dict[str, Any]
JSONType = Union[Dict[str, Any], List[Any], str, int, float, bool, None, "Leaf"]
SchemaType = Dict[str, Any]

VARIABLE_PREFIX = "$"
INPUT_VARIABLE_NAME = "input"
Expand Down Expand Up @@ -50,7 +50,13 @@ def parse_leaf(raw_leaf: str) -> Leaf:
f"Invalid leaf: {raw_leaf} (must start with a reference)"
)

leaf: Leaf = ReferenceLeaf(reference.removeprefix(VARIABLE_PREFIX))
# remove the $ prefix
_reference = (
reference[len(VARIABLE_PREFIX) :]
if reference.startswith(VARIABLE_PREFIX)
else reference
)
leaf: Leaf = ReferenceLeaf(_reference)
for raw_part in raw_parts:
if raw_part.isdigit():
leaf = IndexLeaf(leaf, int(raw_part))
Expand Down
4 changes: 2 additions & 2 deletions projects/fal/tests/cli/test_deploy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from typing import Optional, Tuple
from unittest.mock import MagicMock, patch

import pytest
Expand Down Expand Up @@ -30,7 +30,7 @@ def mock_parse_pyproject_toml():


def mock_args(
app_ref: tuple[str],
app_ref: Tuple[str, Optional[str]],
app_name: Optional[str] = None,
auth: Optional[str] = None,
strategy: Optional[str] = None,
Expand Down
3 changes: 2 additions & 1 deletion projects/fal/tests/cli/test_run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Optional, Tuple
from unittest.mock import MagicMock, patch

import pytest
Expand Down Expand Up @@ -34,7 +35,7 @@ def mocked_fal_serverless_host(host):
return mock


def mock_args(host, func_ref: tuple[str]):
def mock_args(host, func_ref: Tuple[str, Optional[str]]):
args = MagicMock()
args.host = host
args.func_ref = func_ref
Expand Down
15 changes: 8 additions & 7 deletions projects/fal/tests/test_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import time
from contextlib import contextmanager, suppress
from datetime import datetime
from typing import Generator
from typing import Generator, List, Tuple

import fal
import fal.api as api
Expand Down Expand Up @@ -92,7 +92,7 @@ def container_addition_app(input: Input) -> Output:

@fal.function(
keep_alive=300,
requirements=["fastapi", "uvicorn", "pydantic==1.10.12"],
requirements=["fastapi", "uvicorn", "pydantic==1.10.18"],
machine_type="S",
max_concurrency=1,
max_multiplexing=30,
Expand Down Expand Up @@ -224,7 +224,7 @@ class RTOutput(BaseModel):


class RTOutputs(BaseModel):
texts: list[str]
texts: List[str]


class RealtimeApp(fal.App, keep_alive=300, max_concurrency=1):
Expand Down Expand Up @@ -252,7 +252,7 @@ def generate_rt_batched(self, input: RTInput, *inputs: RTInput) -> RTOutputs:


@pytest.fixture(scope="module")
def aliased_app() -> Generator[tuple[str, str], None, None]:
def aliased_app() -> Generator[Tuple[str, str], None, None]:
# Create a temporary app, register it, and return the ID of it.

import uuid
Expand Down Expand Up @@ -418,6 +418,7 @@ def test_stateful_app_client(test_stateful_app: str):
assert response["result"] == 0


@pytest.mark.flaky(max_runs=3)
def test_app_cancellation(test_app: str, test_cancellable_app: str):
request_handle = apps.submit(
test_cancellable_app, arguments={"lhs": 1, "rhs": 2, "wait_time": 10}
Expand Down Expand Up @@ -516,7 +517,7 @@ def test_404_response(test_app: str, request: pytest.FixtureRequest):
apps.run(test_app, path="/other", arguments={"lhs": 1, "rhs": 2})


def test_app_deploy_scale(aliased_app: tuple[str, str]):
def test_app_deploy_scale(aliased_app: Tuple[str, str]):
import uuid
from dataclasses import replace

Expand Down Expand Up @@ -558,7 +559,7 @@ def test_app_deploy_scale(aliased_app: tuple[str, str]):
assert found.max_multiplexing == 30


def test_app_update_app(aliased_app: tuple[str, str]):
def test_app_update_app(aliased_app: Tuple[str, str]):
app_revision, app_alias = aliased_app

host: api.FalServerlessHost = addition_app.host # type: ignore
Expand Down Expand Up @@ -608,7 +609,7 @@ def test_app_update_app(aliased_app: tuple[str, str]):
assert res.max_multiplexing == new_max_multiplexing


def test_app_set_delete_alias(aliased_app: tuple[str, str]):
def test_app_set_delete_alias(aliased_app: Tuple[str, str]):
app_revision, app_alias = aliased_app

host: api.FalServerlessHost = addition_app.host # type: ignore
Expand Down
4 changes: 2 additions & 2 deletions projects/fal_client/src/fal_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from datetime import datetime, timezone
from dataclasses import dataclass, field
from functools import cached_property
from typing import Any, AsyncIterator, Iterator, TYPE_CHECKING, Optional, Literal
from typing import Any, AsyncIterator, Dict, Iterator, TYPE_CHECKING, Optional, Literal
from urllib.parse import urlencode

import httpx
Expand All @@ -20,7 +20,7 @@
if TYPE_CHECKING:
from PIL import Image

AnyJSON = dict[str, Any]
AnyJSON = Dict[str, Any]
Priority = Literal["normal", "low"]

RUN_URL_FORMAT = f"https://{FAL_RUN_HOST}/"
Expand Down

0 comments on commit 87dd82c

Please sign in to comment.