89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
/**
|
|
* Transform Python code snippets from synchronous to async/await pattern
|
|
*/
|
|
export function transformPythonSnippets({ spec }: { spec: any }) {
|
|
// Recursively traverse the spec to find x-codeSamples
|
|
function traverse(obj: any) {
|
|
if (obj && typeof obj === 'object') {
|
|
// Check if this object has x-codeSamples
|
|
if (obj['x-codeSamples'] && Array.isArray(obj['x-codeSamples'])) {
|
|
for (const sample of obj['x-codeSamples']) {
|
|
if (sample.lang === 'Python' && sample.source) {
|
|
sample.source = transformPythonCode(sample.source);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Recurse into all properties
|
|
for (const key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
traverse(obj[key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
traverse(spec);
|
|
return spec;
|
|
}
|
|
|
|
function transformPythonCode(code: string): string {
|
|
// Step 1: Add asyncio import if not present
|
|
if (!code.includes('import asyncio')) {
|
|
code = 'import asyncio\n' + code;
|
|
}
|
|
|
|
// Step 2: Replace client initialization
|
|
// Match: client = Autumn(\n secret_key="My Secret Key",\n)
|
|
code = code.replace(
|
|
/client = Autumn\(\s*\n\s*secret_key=["'][^"']*["'],?\s*\n\)/g,
|
|
'autumn = Autumn("am_sk_1234567890")'
|
|
);
|
|
|
|
// Step 3: Replace "client." with "autumn." throughout
|
|
code = code.replace(/\bclient\./g, 'autumn.');
|
|
|
|
// Step 4: Find the line after autumn initialization and insert async def main():
|
|
const lines = code.split('\n');
|
|
const autumnInitIndex = lines.findIndex(line => line.includes('autumn = Autumn('));
|
|
|
|
if (autumnInitIndex === -1) {
|
|
return code; // Can't find initialization, return as-is
|
|
}
|
|
|
|
// Split into before (imports + init) and after (the actual code)
|
|
const beforeLines = lines.slice(0, autumnInitIndex + 1);
|
|
const afterLines = lines.slice(autumnInitIndex + 1).filter(line => line.trim() !== '');
|
|
|
|
// Step 5: Add await to autumn method calls and indent
|
|
const transformedAfterLines = afterLines.map(line => {
|
|
const trimmed = line.trim();
|
|
if (trimmed === '') return line;
|
|
|
|
// Add await before autumn calls if not already present
|
|
// Pattern: variable = autumn.method() -> variable = await autumn.method()
|
|
let transformed = line;
|
|
if (trimmed.includes('autumn.') && !trimmed.includes('await')) {
|
|
// Match assignment pattern: var = autumn.method()
|
|
transformed = line.replace(/^(\s*)(\w+\s*=\s*)(autumn\.)/g, '$1$2await $3');
|
|
}
|
|
|
|
// Add 4 spaces of indentation to all lines (preserving relative indentation)
|
|
transformed = ' ' + transformed;
|
|
|
|
return transformed;
|
|
});
|
|
|
|
// Step 6: Reconstruct the code
|
|
const result = [
|
|
...beforeLines,
|
|
'',
|
|
'async def main():',
|
|
...transformedAfterLines,
|
|
'',
|
|
'asyncio.run(main())'
|
|
].join('\n');
|
|
|
|
return result;
|
|
}
|