(
framework: PythonFramework | undefined,
workPath: string,
configuredEntrypoint?: { filePath: string; varName?: string },
service?: { type?: ServiceType; trigger?: JobTrigger }
)
| 490 | * Detect a Python entrypoint path for a given framework relative to workPath, or return null if not found. |
| 491 | */ |
| 492 | export async function detectPythonEntrypoint( |
| 493 | framework: PythonFramework | undefined, |
| 494 | workPath: string, |
| 495 | configuredEntrypoint?: { filePath: string; varName?: string }, |
| 496 | service?: { type?: ServiceType; trigger?: JobTrigger } |
| 497 | ): Promise<DetectedPythonEntrypoint | null> { |
| 498 | // If a configured entrypoint was provided, check it first |
| 499 | if (configuredEntrypoint) { |
| 500 | const { filePath: configEntryFile, varName: configEntryVar } = |
| 501 | configuredEntrypoint; |
| 502 | const entrypoint = configEntryFile.endsWith('.py') |
| 503 | ? configEntryFile |
| 504 | : `${configEntryFile}.py`; |
| 505 | const entrypointExists = await fileExists(join(workPath, entrypoint)); |
| 506 | |
| 507 | if (!entrypointExists) { |
| 508 | return { |
| 509 | error: new NowBuildError({ |
| 510 | code: 'PYTHON_ENTRYPOINT_NOT_FOUND', |
| 511 | message: `Configured Python entrypoint "${entrypoint}" was not found.`, |
| 512 | link: PYTHON_ENTRYPOINT_DOCS_URL, |
| 513 | action: 'Learn More', |
| 514 | }), |
| 515 | }; |
| 516 | } |
| 517 | |
| 518 | let varName: string | null = |
| 519 | configEntryVar ?? (await checkEntrypoint(workPath, entrypoint)); |
| 520 | |
| 521 | if (!varName) { |
| 522 | // Queue-backed and schedule-triggered services create an `app` dynamically. |
| 523 | // Any other service type (including workflow-triggered jobs) uses the |
| 524 | // normal WSGI/ASGI entrypoint detection. |
| 525 | const needsDynamicApp = |
| 526 | !!service && |
| 527 | (isScheduleTriggeredService(service) || |
| 528 | isQueueTriggeredService(service) || |
| 529 | isWorkflowTriggeredService(service)); |
| 530 | if (needsDynamicApp) { |
| 531 | varName = 'app'; |
| 532 | } |
| 533 | } |
| 534 | |
| 535 | if (varName) { |
| 536 | debug(`Using configured Python entrypoint: ${entrypoint}`); |
| 537 | return { entrypoint: { entrypoint, variableName: varName } }; |
| 538 | } else { |
| 539 | return { |
| 540 | error: new NowBuildError({ |
| 541 | code: 'PYTHON_ENTRYPOINT_NOT_FOUND', |
| 542 | message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`, |
| 543 | link: PYTHON_ENTRYPOINT_DOCS_URL, |
| 544 | action: 'Learn More', |
| 545 | }), |
| 546 | }; |
| 547 | } |
| 548 | } |
| 549 | if (!framework) { |
no test coverage detected