Skip to content

Commit 0e7937e

Browse files
committed
Instruct users to import tidewave conditionally in dev mode
1 parent 9ad3273 commit 0e7937e

File tree

5 files changed

+26
-42
lines changed

5 files changed

+26
-42
lines changed

README.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ Add `tidewave[flask]` as a dependency to your `pyproject.toml`:
5353
Now, in your application definition, you can initialize the `Tidewave` class and pass your Flask application to `init_app`:
5454

5555
```python
56-
from tidewave.flask import Tidewave
57-
tidewave = Tidewave()
58-
tidewave.init_app(app)
56+
if app.debug:
57+
from tidewave.flask import Tidewave
58+
tidewave = Tidewave()
59+
tidewave.init_app(app)
5960
```
6061

6162
Tidewave will automatically detect if your Flask application is using SQLAlchemy and Jinja2 and configure them automatically.
@@ -80,20 +81,24 @@ Add `tidewave[fastapi]` as a dependency to your `pyproject.toml`:
8081
"tidewave[fastapi] @ git+https://github.com/tidewave-ai/tidewave_python.git",
8182
```
8283

83-
Now, in your application definition, you can initialize the `Tidewave` class and pass your FastAPI application to `install`:
84+
Now, in your application definition, you can initialize the `Tidewave` class and pass your FastAPI application to `install`. Note that you only want to do this in **development mode**:
8485

8586
```python
86-
from tidewave.fastapi import Tidewave
87-
tidewave = Tidewave()
88-
tidewave.install(app)
89-
```
87+
# Your preferable way of detecting dev mode.
88+
is_dev = os.environ.get("RUN_MODE", None) == "development"
9089

91-
Note Tidewave only runs when `app.debug` is `True`. Therefore, remember to start your dev server with `fastapi dev`. If you are setting `app.debug` programatically, remember to do so before you call `tidewave.install`.
90+
if is_dev:
91+
from tidewave.fastapi import Tidewave
92+
tidewave = Tidewave()
93+
tidewave.install(app)
94+
```
9295

93-
If you are using Jinja2, you need to add our extension too (preferably in `app.debug` mode only):
96+
If you are using Jinja2, you need to add our extension too:
9497

9598
```python
96-
if app.debug:
99+
if is_dev:
100+
# ...
101+
97102
from tidewave.jinja2 import Extension
98103
templates.env.add_extension(Extension)
99104
```

src/tidewave/fastapi/__init__.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ def __init__(self, config: Optional[dict[str, Any]] = None):
2929
self.config = config or {}
3030

3131
def install(self, app: FastAPI, sqlalchemy_base=None, sqlalchemy_engine=None):
32-
if not app.debug:
33-
return
34-
3532
# Create WSGI app for MCP handling
3633
def wsgi_app(environ, start_response):
3734
start_response("404 Not Found", [("Content-Type", "text/plain")])

src/tidewave/flask/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ def __init__(self, config: Optional[dict[str, Any]] = None):
2727

2828
def init_app(self, app):
2929
if not app.debug:
30-
return
30+
raise RuntimeError(
31+
"You should only call Tidewave.init_app in development, but app.debug=False."
32+
)
3133

3234
# Create MCP tools
3335
mcp_tools = [

tests/test_fastapi.py

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class TestFastAPITidewave(unittest.TestCase):
1818

1919
def test_with_debug_mode(self):
2020
"""Test that Tidewave initializes properly with FastAPI app in debug mode"""
21-
app = FastAPI(debug=True)
21+
app = FastAPI()
2222

2323
@app.get("/test")
2424
def test_route():
@@ -52,32 +52,9 @@ def test_route():
5252
self.assertEqual(response.status_code, 200)
5353
self.assertEqual(response.json(), {"message": "Test response"})
5454

55-
def test_with_production_mode(self):
56-
"""Test that Tidewave does not initialize middleware in production mode"""
57-
app = FastAPI(debug=False) # Production mode
58-
59-
@app.get("/test")
60-
def test_route():
61-
return {"message": "Test response"}
62-
63-
tidewave = Tidewave()
64-
tidewave.install(app)
65-
66-
# Verify middleware was NOT applied (no tidewave routes should be mounted)
67-
tidewave_routes = [
68-
route for route in app.routes if hasattr(route, "path") and "tidewave" in route.path
69-
]
70-
self.assertEqual(len(tidewave_routes), 0)
71-
72-
# Test that the app still works normally
73-
client = TestClient(app)
74-
response = client.get("/test")
75-
self.assertEqual(response.status_code, 200)
76-
self.assertEqual(response.json(), {"message": "Test response"})
77-
7855
def test_x_frame_options_and_csp_headers(self):
7956
"""Test that X-Frame-Options and CSP headers"""
80-
app = FastAPI(debug=True)
57+
app = FastAPI()
8158

8259
@app.get("/test")
8360
def test_route():
@@ -107,7 +84,7 @@ def test_route():
10784

10885
def test_with_sqlalchemy(self):
10986
"""Test that SQLAlchemy tools are added when SQLAlchemy parameters are provided"""
110-
app = FastAPI(debug=True)
87+
app = FastAPI()
11188

11289
# Create SQLAlchemy setup
11390
engine = create_engine("sqlite:///:memory:")

tests/test_flask.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from flask import Flask, render_template_string
88

9+
import pytest
910
from flask_sqlalchemy import SQLAlchemy
1011

1112
from tidewave.flask import Tidewave
@@ -61,7 +62,9 @@ def test_route():
6162
return render_template_string(template)
6263

6364
tidewave = Tidewave()
64-
tidewave.init_app(app)
65+
66+
with pytest.raises(RuntimeError):
67+
tidewave.init_app(app)
6568

6669
# Verify middleware was NOT applied (wsgi_app should still be original type)
6770
self.assertEqual(type(app.wsgi_app).__name__, original_wsgi_app_type)

0 commit comments

Comments
 (0)