Skip to content

Commit 41339af

Browse files
badayvedatchamini2
andauthored
fix: custom app openapi metadata (#19)
* test: reproduce the error tdd is great * fix: set serve to false * fix: add pydantic to reqs * expected tests --------- Co-authored-by: Matteo Ferrando <[email protected]>
1 parent d943e76 commit 41339af

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

projects/fal/src/fal/api.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ def order_schema_object(schema: dict[str, Any]):
792792
if "properties" in schema:
793793
mark_order(schema, "properties")
794794

795-
for key in spec["components"].get("schemas") or {}:
795+
for key in spec.get("components", {}).get("schemas") or {}:
796796
order_schema_object(spec["components"]["schemas"][key])
797797

798798
return spec

projects/fal/tests/test_apps.py

+76-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,47 @@ def addition_app(input: Input) -> Output:
3636
return Output(result=input.lhs + input.rhs)
3737

3838

39+
@fal.function(
40+
keep_alive=0,
41+
requirements=["fastapi", "uvicorn", "pydantic==1.10.12"],
42+
machine_type="S",
43+
max_concurrency=1,
44+
exposed_port=8000,
45+
)
46+
def calculator_app():
47+
from fastapi import FastAPI
48+
from fastapi.middleware.cors import CORSMiddleware
49+
from uvicorn import run
50+
51+
app = FastAPI()
52+
53+
def _wait(wait_time: int):
54+
print("starting...")
55+
for _ in range(wait_time):
56+
print("sleeping...")
57+
time.sleep(1)
58+
59+
@app.post("/add")
60+
def add(input: Input) -> Output:
61+
_wait(input.wait_time)
62+
return Output(result=input.lhs + input.rhs)
63+
64+
@app.post("/subtract")
65+
def subtract(input: Input) -> Output:
66+
_wait(input.wait_time)
67+
return Output(result=input.lhs - input.rhs)
68+
69+
app.add_middleware(
70+
CORSMiddleware,
71+
allow_credentials=True,
72+
allow_headers=("*"),
73+
allow_methods=("*"),
74+
allow_origins=("*"),
75+
)
76+
77+
run(app, host="0.0.0.0", port=8080)
78+
79+
3980
@pytest.fixture(scope="module")
4081
def aliased_app() -> Generator[tuple[str, str], None, None]:
4182
# Create a temporary app, register it, and return the ID of it.
@@ -67,6 +108,20 @@ def test_app():
67108
yield f"{user_id}-{app_revision}"
68109

69110

111+
@pytest.fixture(scope="module")
112+
def test_fastapi_app():
113+
# Create a temporary app, register it, and return the ID of it.
114+
115+
from fal.cli import _get_user_id
116+
117+
app_revision = calculator_app.host.register(
118+
func=calculator_app.func,
119+
options=calculator_app.options,
120+
)
121+
user_id = _get_user_id()
122+
yield f"{user_id}-{app_revision}"
123+
124+
70125
def test_app_client(test_app: str):
71126
response = apps.run(test_app, arguments={"lhs": 1, "rhs": 2})
72127
assert response["result"] == 3
@@ -105,7 +160,7 @@ def test_app_client_async(test_app: str):
105160
assert result == {"result": 5}
106161

107162

108-
def test_app_openapi_spec_metadata(test_app: str):
163+
def test_app_openapi_spec_metadata(test_app: str, request: pytest.FixtureRequest):
109164
user_id, _, app_id = test_app.partition("-")
110165
res = app_metadata.sync_detailed(
111166
app_alias_or_id=app_id, app_user_id=user_id, client=REST_CLIENT
@@ -121,6 +176,26 @@ def test_app_openapi_spec_metadata(test_app: str):
121176
assert key in openapi_spec, f"{key} key missing from openapi {openapi_spec}"
122177

123178

179+
def test_app_no_serve_spec_metadata(
180+
test_fastapi_app: str, request: pytest.FixtureRequest
181+
):
182+
# We do not store the openapi spec for apps that do not use serve=True
183+
user_id, _, app_id = test_fastapi_app.partition("-")
184+
res = app_metadata.sync_detailed(
185+
app_alias_or_id=app_id, app_user_id=user_id, client=REST_CLIENT
186+
)
187+
188+
assert (
189+
res.status_code == 200
190+
), f"Failed to fetch metadata for app {test_fastapi_app}"
191+
assert res.parsed, f"Failed to parse metadata for app {test_fastapi_app}"
192+
193+
metadata = res.parsed.to_dict()
194+
assert (
195+
"openapi" not in metadata
196+
), f"openapi should not be present in metadata {metadata}"
197+
198+
124199
def test_app_update_app(aliased_app: tuple[str, str]):
125200
app_revision, app_alias = aliased_app
126201

0 commit comments

Comments
 (0)