Repository: turettn/fastapi_offline (language: python)

Issue:
[bug] Incompatibility with FastAPI version 0.89.0 or above
Description: When bootstrapping an application using FastAPI version 0.89.0 or above, an error occurs when accessing the entry point. The error message is "NameError: name 'Response' is not defined".

Troubleshooting: After checking the FastAPI changelog (https://fastapi.tiangolo.com/release-notes/#0890), we discovered that the usage of the 'Response' model has been changed in this version.


Discussion / hints:
Thanks for the bug report!  I'll try to get a fix thrown together later this week.

Fix patch:
diff --git a/fastapi_offline/core.py b/fastapi_offline/core.py
index 87bbaf0..6880a44 100644
--- a/fastapi_offline/core.py
+++ b/fastapi_offline/core.py
@@ -1,6 +1,7 @@
 """Provide non-CDN-dependent Swagger & Redoc pages to FastAPI"""
 from pathlib import Path
-from typing import Any, Optional, TYPE_CHECKING
+from typing import Any, Optional
+
 from fastapi import FastAPI, Request
 from fastapi.openapi.docs import (
     get_redoc_html,
@@ -8,9 +9,7 @@
     get_swagger_ui_oauth2_redirect_html,
 )
 from fastapi.staticfiles import StaticFiles
-
-if TYPE_CHECKING:
-    from fastapi import Response  # pragma: no cover
+from starlette.responses import HTMLResponse
 
 _STATIC_PATH = Path(__file__).parent / "static"
 
@@ -52,7 +51,7 @@ def FastAPIOffline(
     if docs_url is not None:
         # Define the doc and redoc pages, pointing at the right files
         @app.get(docs_url, include_in_schema=False)
-        async def custom_swagger_ui_html(request: Request) -> "Response":
+        async def custom_swagger_ui_html(request: Request) -> HTMLResponse:
             root = request.scope.get("root_path")
 
             if favicon_url is None:
@@ -70,13 +69,13 @@ async def custom_swagger_ui_html(request: Request) -> "Response":
             )
 
         @app.get(swagger_ui_oauth2_redirect_url, include_in_schema=False)
-        async def swagger_ui_redirect() -> "Response":
+        async def swagger_ui_redirect() -> HTMLResponse:
             return get_swagger_ui_oauth2_redirect_html()
 
     if redoc_url is not None:
 
         @app.get(redoc_url, include_in_schema=False)
-        async def redoc_html(request: Request) -> "Response":
+        async def redoc_html(request: Request) -> HTMLResponse:
             root = request.scope.get("root_path")
 
             if favicon_url is None:
diff --git a/setup.py b/setup.py
index 5cef05f..272d747 100644
--- a/setup.py
+++ b/setup.py
@@ -1,20 +1,22 @@
 from pathlib import Path
 from urllib.request import urlretrieve
+
 from setuptools import setup
 from setuptools.command.sdist import sdist
 
-
-__version__ = "1.5.1"
+__version__ = "1.5.2"
 
 
 BASE_PATH = Path(__file__).parent
 README = (BASE_PATH / "README.md").read_text()
-FASTAPI_VER = "fastapi>=0.75.2"
+FASTAPI_VER = "fastapi>=0.75.2,!=0.89.0"
+TEST_DEPS = ["pytest", "requests", "starlette[full]"]
+
 
 class SDistWrapper(sdist):
     def run(self) -> None:
         "Download files into static/, then pass through to normal install"
-        from fastapi_offline.consts import SWAGGER_JS, SWAGGER_CSS, REDOC_JS, FAVICON
+        from fastapi_offline.consts import FAVICON, REDOC_JS, SWAGGER_CSS, SWAGGER_JS
 
         # Find ourself
 
@@ -52,7 +54,8 @@ def run(self) -> None:
     package_data={"fastapi_offline": ["static/*", "py.typed"]},
     python_requires=">=3.7",
     install_requires=[FASTAPI_VER],
-    tests_require=["pytest", "requests"],
+    tests_require=TEST_DEPS,
     setup_requires=[FASTAPI_VER],
+    extras_require={"test": TEST_DEPS},
     cmdclass={"sdist": SDistWrapper},
 )


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ceb541e..096cac1 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -10,7 +10,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.7, 3.8, 3.9, "3.10"]
+        python-version: [3.7, 3.8, 3.9, "3.10", "3.11"]
       fail-fast: false
     
     steps:
@@ -24,7 +24,7 @@ jobs:
       - name: Install package, dependencies, and test tools
         run: |
           python setup.py sdist
-          python -m pip install dist/*.tar.gz
+          python -m pip install `ls -1 dist/*.tar.gz`[test]
           python -m pip install pytest pytest-cov flake8 black mypy
       - name: Check black compliance
         run : |