Skip to content

refactor: move async dependencies from optional to direct #386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/conformance-asgi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
with:
python-version: ${{ matrix.python }}

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

- name: Setup Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
Expand Down
10 changes: 3 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,14 @@ dependencies = [
"cloudevents>=1.2.0,<=1.11.0", # Must support python 3.7
"Werkzeug>=0.14,<4.0.0",
"httpx>=0.24.1",
"starlette>=0.37.0,<1.0.0; python_version>='3.8'",
"uvicorn>=0.18.0,<1.0.0; python_version>='3.8'",
"uvicorn-worker>=0.2.0,<1.0.0; python_version>='3.8'",
]

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

[project.optional-dependencies]
async = [
"starlette>=0.37.0,<1.0.0; python_version>='3.8'",
"uvicorn>=0.18.0,<1.0.0; python_version>='3.8'",
"uvicorn-worker>=0.2.0,<1.0.0; python_version>='3.8'"
]

[project.scripts]
ff = "functions_framework._cli:_cli"
functions-framework = "functions_framework._cli:_cli"
Expand Down
19 changes: 6 additions & 13 deletions src/functions_framework/aio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@

from cloudevents.http import from_http
from cloudevents.http.event import CloudEvent
from starlette.applications import Starlette
from starlette.exceptions import HTTPException
from starlette.middleware import Middleware
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.routing import Route

from functions_framework import (
_enable_execution_id_logging,
Expand All @@ -36,19 +42,6 @@
MissingSourceException,
)

try:
from starlette.applications import Starlette
from starlette.exceptions import HTTPException
from starlette.middleware import Middleware
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.routing import Route
except ImportError:
raise FunctionsFrameworkException(
"Starlette is not installed. Install the framework with the 'async' extra: "
"pip install functions-framework[async]"
)

HTTPResponse = Union[
Response, # Functions can return a full Starlette Response object
str, # Str returns are wrapped in Response(result)
Expand Down
23 changes: 0 additions & 23 deletions tests/test_aio.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,6 @@
TEST_FUNCTIONS_DIR = pathlib.Path(__file__).resolve().parent / "test_functions"


def test_import_error_without_starlette(monkeypatch):
import builtins

original_import = builtins.__import__

def mock_import(name, *args, **kwargs):
if name.startswith("starlette"):
raise ImportError(f"No module named '{name}'")
return original_import(name, *args, **kwargs)

monkeypatch.setattr(builtins, "__import__", mock_import)

# Remove the module from sys.modules to force re-import
if "functions_framework.aio" in sys.modules:
del sys.modules["functions_framework.aio"]

with pytest.raises(exceptions.FunctionsFrameworkException) as excinfo:
import functions_framework.aio

assert "Starlette is not installed" in str(excinfo.value)
assert "pip install functions-framework[async]" in str(excinfo.value)


def test_invalid_function_definition_missing_function_file():
source = TEST_FUNCTIONS_DIR / "missing_function_file" / "main.py"
target = "function"
Expand Down
7 changes: 2 additions & 5 deletions tests/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@
import pretend
import pytest

import functions_framework._http
from starlette.applications import Starlette

try:
from starlette.applications import Starlette
except ImportError:
pass
import functions_framework._http


def test_httpserver_detects_asgi_app():
Expand Down
4 changes: 0 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ deps =
pytest-cov
pytest-integration
pretend
extras =
async
setenv =
PYTESTARGS = --cov=functions_framework --cov-branch --cov-report term-missing --cov-fail-under=100
# Python 3.7: Use .coveragerc-py37 to exclude aio module from coverage since it requires Python 3.8+ (Starlette dependency)
Expand All @@ -48,8 +46,6 @@ deps =
isort
mypy
build
extras =
async
commands =
black --check src tests conftest.py --exclude tests/test_functions/background_load_error/main.py
isort -c src tests conftest.py
Expand Down
Loading