Skip to content

Commit 140ebc7

Browse files
fix: keep generated FastAPI service tests from hanging on codefly.init (#7)
The generated service's pytest hung indefinitely under the Python runtime's Test step. codefly-sdk's init() walks parent directories for service.codefly.yaml without stopping at the filesystem root, so it spins forever when the manifest isn't found — which is exactly the case core's test runner creates by executing pytest against an isolated source snapshot (the snapshot holds code/, not the service-root manifest). Importing src.main ran init() at module load and wedged collection. - Guard the manifest lookup in main.py with a bounded search; init() only runs when service.codefly.yaml is actually reachable, and runtime config otherwise flows through CODEFLY__* env vars. - Make the admin test hermetic: seed the CODEFLY__* values it needs (setdefault preserves real runtime values) and drop the codefly.init("..") walk that would spin in the snapshot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 206f397 commit 140ebc7

2 files changed

Lines changed: 33 additions & 8 deletions

File tree

‎templates/factory/code/src/main.py.tmpl‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
1+
import os
2+
13
from fastapi import FastAPI
24
from fastapi.middleware.cors import CORSMiddleware
35
import codefly_sdk.codefly as codefly
46

5-
codefly.init()
7+
8+
def _service_manifest_reachable() -> bool:
9+
# codefly.init() walks parent directories for service.codefly.yaml but does
10+
# not stop at the filesystem root, so it loops forever when the manifest is
11+
# absent (e.g. tests running against an isolated source snapshot). Only init
12+
# when the manifest is actually reachable; runtime config is otherwise
13+
# supplied through CODEFLY__* environment variables.
14+
directory = os.getcwd()
15+
while True:
16+
if os.path.isfile(os.path.join(directory, "service.codefly.yaml")):
17+
return True
18+
parent = os.path.dirname(directory)
19+
if parent == directory:
20+
return False
21+
directory = parent
22+
23+
24+
if _service_manifest_reachable():
25+
codefly.init()
626

727
app = FastAPI()
828

‎templates/factory/code/tests/admin/test_admin.py.tmpl‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1+
import os
2+
3+
# Provide the runtime configuration the app reads without depending on a
4+
# service.codefly.yaml on disk: the test runner executes against an isolated
5+
# source snapshot where the manifest isn't present, and codefly.init()'s
6+
# parent-directory walk would otherwise spin. setdefault preserves any real
7+
# values injected by the codefly runtime.
8+
os.environ.setdefault("CODEFLY__MODULE", "mod")
9+
os.environ.setdefault("CODEFLY__SERVICE", "svc")
10+
os.environ.setdefault("CODEFLY__SERVICE_VERSION", "0.0.0")
11+
112
import pytest
213
from httpx import AsyncClient, ASGITransport
314

415
from src.main import app
516

6-
import codefly_sdk.codefly as codefly
7-
817
from src.admin.version import get_version
918
from src.admin.models import Version
1019

1120

12-
1321
@pytest.mark.asyncio
1422
async def test_version():
15-
codefly.init("..")
16-
endpoint = codefly.endpoint(api="rest")
17-
address = endpoint.address if endpoint else "http://localhost:8080"
18-
async with AsyncClient(transport=ASGITransport(app=app), base_url=address) as ac:
23+
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://localhost:8080") as ac:
1924
response = await ac.get("/version")
2025
assert response.status_code == 200
2126

0 commit comments

Comments
 (0)