Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 4x 4x 4x 1x 3x 3x 3x 1x 3x 3x 3x 2x 3x 3x 3x | import fs from 'fs-extra';
import path from 'path';
import { parseRequirements } from '../parsers/requirements-parser.js';
export async function detectPythonStack(cwd) {
const requirementsPath = path.join(cwd, 'requirements.txt');
const pyprojectPath = path.join(cwd, 'pyproject.toml');
if (!(await fs.pathExists(requirementsPath)) && !(await fs.pathExists(pyprojectPath))) {
return { detected: false };
}
const deps = await parseRequirements(cwd);
// Detect framework
let framework = null;
if (deps.fastapi || deps['starlette']) framework = 'fastapi';
else if (deps.django || deps['Django']) framework = 'django';
else Eif (deps.flask) framework = 'flask';
Iif (!framework) {
return { detected: false };
}
// Detect test runner
let testRunner = null;
if (deps.pytest) testRunner = 'pytest';
else Iif (deps.unittest) testRunner = 'unittest';
// Detect linter/formatter
const linter = deps.ruff || deps['ruff'] ? 'ruff' : deps.pylint ? 'pylint' : null;
const formatter = deps.black || deps['black'] ? 'black' : null;
return {
detected: true,
stack: 'python-fastapi',
confidence: 'high',
language: 'python',
framework,
testRunner,
linter,
formatter,
buildTool: 'pip',
evidence: {
files: [requirementsPath],
dependencies: Object.keys(deps).slice(0, 5),
},
};
} |