@@ -18,6 +18,25 @@ import { vscodeFileSystem } from "./vscode/vscodeFileSystem"
1818
1919export type { EntryPoint }
2020
21+ /**
22+ * Parses an entrypoint string in module:variable notation.
23+ * Supports formats like "my_app.main:app" or "main".
24+ * Returns the relative file path and optional variable name.
25+ */
26+ export function parseEntrypointString ( value : string ) : {
27+ relativePath : string
28+ variableName ?: string
29+ } {
30+ const colonIndex = value . indexOf ( ":" )
31+ const modulePath = colonIndex === - 1 ? value : value . slice ( 0 , colonIndex )
32+ const variableName =
33+ colonIndex === - 1 ? undefined : value . slice ( colonIndex + 1 )
34+
35+ const relativePath = `${ modulePath . replace ( / \. / g, "/" ) } .py`
36+
37+ return { relativePath, variableName }
38+ }
39+
2140/**
2241 * Scans for common FastAPI entry point files (main.py, __init__.py).
2342 * Returns URI strings sorted by depth (shallower first).
@@ -64,18 +83,8 @@ async function parsePyprojectForEntryPoint(
6483 return null
6584 }
6685
67- // Parse "my_app.main:app" or "api.py:app" format (variable name after : is optional)
68- const colonIndex = entrypointValue . indexOf ( ":" )
69- const modulePath =
70- colonIndex === - 1 ? entrypointValue : entrypointValue . slice ( 0 , colonIndex )
71- const variableName =
72- colonIndex === - 1 ? undefined : entrypointValue . slice ( colonIndex + 1 )
73-
74- // Handle both module format (api.module) and file format (api.py)
75- const relativePath =
76- modulePath . endsWith ( ".py" ) && ! modulePath . includes ( "/" )
77- ? modulePath // Simple file path: api.py -> api.py
78- : `${ modulePath . replace ( / \. / g, "/" ) } .py` // Module path: my_app.main -> my_app/main.py
86+ const { relativePath, variableName } =
87+ parseEntrypointString ( entrypointValue )
7988 const fullUri = vscode . Uri . joinPath ( folderUri , relativePath )
8089
8190 return ( await vscodeFileSystem . exists ( fullUri . toString ( ) ) )
@@ -117,9 +126,9 @@ export async function discoverFastAPIApps(
117126
118127 // If user specified an entry point in settings, use that
119128 if ( customEntryPoint ) {
120- const entryUri = customEntryPoint . startsWith ( "/" )
121- ? vscode . Uri . file ( customEntryPoint )
122- : vscode . Uri . joinPath ( folder . uri , customEntryPoint )
129+ const { relativePath , variableName } =
130+ parseEntrypointString ( customEntryPoint )
131+ const entryUri = vscode . Uri . joinPath ( folder . uri , relativePath )
123132
124133 if ( ! ( await vscodeFileSystem . exists ( entryUri . toString ( ) ) ) ) {
125134 log ( `Custom entry point not found: ${ customEntryPoint } ` )
@@ -130,7 +139,7 @@ export async function discoverFastAPIApps(
130139 }
131140
132141 log ( `Using custom entry point: ${ customEntryPoint } ` )
133- candidates = [ { filePath : entryUri . toString ( ) } ]
142+ candidates = [ { filePath : entryUri . toString ( ) , variableName } ]
134143 detectionMethod = "config"
135144 } else {
136145 // Otherwise, check pyproject.toml or auto-detect
0 commit comments