Skip to content

Commit 0177e55

Browse files
authored
Python API Add (#2)
* Base Python Code * Python Compiler * Update Dockerfile * Update Dockerfile
1 parent c1552f7 commit 0177e55

File tree

4 files changed

+172
-1
lines changed

4 files changed

+172
-1
lines changed

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ WORKDIR /usr/src/app
66
ENV DEBIAN_FRONTEND noninteractive
77
RUN apt-get update && \
88
apt-get -y install gcc mono-mcs && \
9-
rm -rf /var/lib/apt/lists/*
9+
rm -rf /var/lib/apt/lists/* && \
10+
apt-get -y install python3
1011

1112
COPY package*.json ./
1213

api/pythonApi.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const express = require('express');
2+
const { CppCompile } = require('../compiler/cpp');
3+
const { PythonCompile } = require('../compiler/python');
4+
const router = express.Router();
5+
6+
7+
router.post('/', async (req, res) => {
8+
const InputCode = Buffer.from(req.body.code, 'base64').toString('binary')
9+
const DeCode = Buffer.from(req.body.input, 'base64').toString('binary')
10+
let response = await PythonCompile(InputCode, DeCode);
11+
console.log({response})
12+
if (response.statusMes === "Compiler Error") {
13+
res.status(202).json(response)
14+
} else if (response.statusMes === "Run Time Error") {
15+
res.status(201).json(response)
16+
} else {
17+
res.status(200).json(response)
18+
}
19+
20+
});
21+
22+
23+
24+
25+
module.exports = router;

compiler/python.js

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
const { v4: uuid } = require('uuid');
2+
const { exec } = require('child_process');
3+
const fs = require('fs');
4+
const os = require('os');
5+
const path = require('path');
6+
const saveFile = (file, data) => {
7+
return new Promise((resolve, reject) => {
8+
fs.writeFile(file, data, function (err) {
9+
if (err) {
10+
reject(err);
11+
} else {
12+
resolve([file]);
13+
}
14+
});
15+
});
16+
};
17+
18+
async function deleteFiles(pyPath, inputPath, exePath) {
19+
if (fs.existsSync(pyPath)) {
20+
await fs.unlinkSync(pyPath);
21+
}
22+
23+
if (fs.existsSync(inputPath)) {
24+
await fs.unlinkSync(inputPath);
25+
}
26+
27+
if (fs.existsSync(exePath)) {
28+
await fs.unlinkSync(exePath);
29+
}
30+
}
31+
32+
function getRunCommand(executable, input) {
33+
return `python ${executable} < ${input}`;
34+
}
35+
36+
function getExecutablePath(fileName) {
37+
// console.log(os.platform());
38+
if (os.platform() === 'win32') {
39+
return `${path.join(__dirname, '..', 'upload', fileName)}.exe`;
40+
}
41+
if (os.platform() === 'linux') {
42+
return `${path.join(__dirname, '..', 'upload', fileName)}`;
43+
}
44+
}
45+
46+
function getpyPath(fileName) {
47+
return `${path.join(__dirname, '..', 'upload', fileName)}.py`;
48+
}
49+
50+
function getInputPath(fileName) {
51+
return `${path.join(__dirname, '..', 'upload', fileName)}-input.txt`;
52+
}
53+
54+
55+
56+
function runProgram(exePath, inputPath) {
57+
return new Promise((resolve, reject) => {
58+
59+
exec(getRunCommand(exePath, inputPath), (error, stdout, stderr) => {
60+
if (error) {
61+
reject({ error, stdout, stderr });
62+
} else {
63+
resolve({ stdout, stderr });
64+
}
65+
});
66+
});
67+
}
68+
69+
70+
function runProgramNoIP(exePath) {
71+
return new Promise((resolve, reject) => {
72+
73+
exec(`python ${exePath}`, (error, stdout, stderr) => {
74+
if (error) {
75+
reject({ error, stdout, stderr });
76+
} else {
77+
resolve({ stdout, stderr });
78+
}
79+
});
80+
});
81+
}
82+
const PythonCompile = async (code, input) => {
83+
let state = {
84+
stdout: null,
85+
stderr: null,
86+
statusMes: "",
87+
}
88+
if (input.length > 0) {
89+
let uniqueFileName = uuid();
90+
let executePath = getExecutablePath(uniqueFileName)
91+
let pyPath = getpyPath(uniqueFileName)
92+
let ipPath = getInputPath(uniqueFileName)
93+
94+
await saveFile(pyPath, code);
95+
await saveFile(ipPath, input);
96+
97+
try {
98+
let { stdout, stderr } = await runProgram(pyPath, ipPath);
99+
state.stdout = stdout;
100+
state.stderr = stderr;
101+
} catch (err) {
102+
state.stderr = err.stderr;
103+
state.statusMes = "Compiler Error";
104+
deleteFiles(pyPath, ipPath, executePath);
105+
return state;
106+
}
107+
if (state.stderr === '') {
108+
state.stderr = null;
109+
}
110+
state.statusMes = "Successfully Compiled";
111+
await deleteFiles(pyPath, ipPath, executePath);
112+
return state;
113+
} else {
114+
let uniqueFileName = uuid();
115+
let executePath = getExecutablePath(uniqueFileName)
116+
let pyPath = getpyPath(uniqueFileName)
117+
await saveFile(pyPath, code);
118+
try {
119+
let { stdout, stderr } = await runProgramNoIP(pyPath);
120+
state.stdout = stdout;
121+
state.stderr = stderr;
122+
} catch (err) {
123+
state.stderr = err.stderr;
124+
state.statusMes = "Compiler Error";
125+
deleteFiles(pyPath, executePath);
126+
return state;
127+
}
128+
if (state.stderr === '') {
129+
state.stderr = null;
130+
}
131+
state.statusMes = "Successfully Compiled";
132+
await deleteFiles(pyPath, executePath);
133+
return state;
134+
135+
}
136+
return state;
137+
138+
}
139+
140+
141+
142+
143+
module.exports = { PythonCompile };

server.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ app.get('/', (req, res) => {
1111
res.send("API IS RUNNING")
1212
})
1313
app.use('/api', require('./api/cppApi'));
14+
app.use('/api/python', require('./api/pythonApi'));
15+
1416

1517
app.listen(PORT, () => {
1618
console.log(`Listening at port ${PORT}`);

0 commit comments

Comments
 (0)