Skip to content

Commit 82ba117

Browse files
authored
refactor: move async dependencies from optional to direct (GoogleCloudPlatform#386)
## Summary This PR moves starlette, uvicorn, and uvicorn-worker from optional dependencies to direct dependencies, simplifying the installation process for users who need async functionality. ## Impact Analysis - **Installation size increase: < 1MB** (specifically 816KB, ~3.5% increase) - Base installation: 23MB → With async deps: 24MB - Removes the need for `pip install functions-framework[async]` - Maintains Python 3.8+ requirement for these dependencies ## Changes - Move async dependencies to direct dependencies in `pyproject.toml` - Remove `[async]` extra dependency configuration - Update imports to be direct instead of conditional - Remove "Starlette is not installed" error messages - Update tests to reflect direct dependency availability ## Test Plan All existing tests pass with 100% coverage. The async functionality remains unchanged, just the installation method is simplified.
1 parent 2de6eec commit 82ba117

File tree

6 files changed

+13
-54
lines changed

6 files changed

+13
-54
lines changed

.github/workflows/conformance-asgi.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ jobs:
3939
with:
4040
python-version: ${{ matrix.python }}
4141

42-
- name: Install the framework with async extras
43-
run: python -m pip install -e .[async]
42+
- name: Install the framework
43+
run: python -m pip install -e .
4444

4545
- name: Setup Go
4646
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0

pyproject.toml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,14 @@ dependencies = [
3030
"cloudevents>=1.2.0,<=1.11.0", # Must support python 3.7
3131
"Werkzeug>=0.14,<4.0.0",
3232
"httpx>=0.24.1",
33+
"starlette>=0.37.0,<1.0.0; python_version>='3.8'",
34+
"uvicorn>=0.18.0,<1.0.0; python_version>='3.8'",
35+
"uvicorn-worker>=0.2.0,<1.0.0; python_version>='3.8'",
3336
]
3437

3538
[project.urls]
3639
Homepage = "https://github.com/googlecloudplatform/functions-framework-python"
3740

38-
[project.optional-dependencies]
39-
async = [
40-
"starlette>=0.37.0,<1.0.0; python_version>='3.8'",
41-
"uvicorn>=0.18.0,<1.0.0; python_version>='3.8'",
42-
"uvicorn-worker>=0.2.0,<1.0.0; python_version>='3.8'"
43-
]
44-
4541
[project.scripts]
4642
ff = "functions_framework._cli:_cli"
4743
functions-framework = "functions_framework._cli:_cli"

src/functions_framework/aio/__init__.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525

2626
from cloudevents.http import from_http
2727
from cloudevents.http.event import CloudEvent
28+
from starlette.applications import Starlette
29+
from starlette.exceptions import HTTPException
30+
from starlette.middleware import Middleware
31+
from starlette.requests import Request
32+
from starlette.responses import JSONResponse, Response
33+
from starlette.routing import Route
2834

2935
from functions_framework import (
3036
_enable_execution_id_logging,
@@ -36,19 +42,6 @@
3642
MissingSourceException,
3743
)
3844

39-
try:
40-
from starlette.applications import Starlette
41-
from starlette.exceptions import HTTPException
42-
from starlette.middleware import Middleware
43-
from starlette.requests import Request
44-
from starlette.responses import JSONResponse, Response
45-
from starlette.routing import Route
46-
except ImportError:
47-
raise FunctionsFrameworkException(
48-
"Starlette is not installed. Install the framework with the 'async' extra: "
49-
"pip install functions-framework[async]"
50-
)
51-
5245
HTTPResponse = Union[
5346
Response, # Functions can return a full Starlette Response object
5447
str, # Str returns are wrapped in Response(result)

tests/test_aio.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,6 @@
3535
TEST_FUNCTIONS_DIR = pathlib.Path(__file__).resolve().parent / "test_functions"
3636

3737

38-
def test_import_error_without_starlette(monkeypatch):
39-
import builtins
40-
41-
original_import = builtins.__import__
42-
43-
def mock_import(name, *args, **kwargs):
44-
if name.startswith("starlette"):
45-
raise ImportError(f"No module named '{name}'")
46-
return original_import(name, *args, **kwargs)
47-
48-
monkeypatch.setattr(builtins, "__import__", mock_import)
49-
50-
# Remove the module from sys.modules to force re-import
51-
if "functions_framework.aio" in sys.modules:
52-
del sys.modules["functions_framework.aio"]
53-
54-
with pytest.raises(exceptions.FunctionsFrameworkException) as excinfo:
55-
import functions_framework.aio
56-
57-
assert "Starlette is not installed" in str(excinfo.value)
58-
assert "pip install functions-framework[async]" in str(excinfo.value)
59-
60-
6138
def test_invalid_function_definition_missing_function_file():
6239
source = TEST_FUNCTIONS_DIR / "missing_function_file" / "main.py"
6340
target = "function"

tests/test_asgi.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@
1818
import pretend
1919
import pytest
2020

21-
import functions_framework._http
21+
from starlette.applications import Starlette
2222

23-
try:
24-
from starlette.applications import Starlette
25-
except ImportError:
26-
pass
23+
import functions_framework._http
2724

2825

2926
def test_httpserver_detects_asgi_app():

tox.ini

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ deps =
2929
pytest-cov
3030
pytest-integration
3131
pretend
32-
extras =
33-
async
3432
setenv =
3533
PYTESTARGS = --cov=functions_framework --cov-branch --cov-report term-missing --cov-fail-under=100
3634
# Python 3.7: Use .coveragerc-py37 to exclude aio module from coverage since it requires Python 3.8+ (Starlette dependency)
@@ -48,8 +46,6 @@ deps =
4846
isort
4947
mypy
5048
build
51-
extras =
52-
async
5349
commands =
5450
black --check src tests conftest.py --exclude tests/test_functions/background_load_error/main.py
5551
isort -c src tests conftest.py

0 commit comments

Comments
 (0)