This Express.js app interacts with the Piston API (A code execution engine that allows running code in multiple languages) to execute code snippets. It provides an API endpoint to send code for execution and receive the output.
express-piston-app/
│── node_modules/
│── tests/
│ ├── app.test.js
│── package.json
│── server.js
│── README.md
npm install express axios dotenv jest supertest corsnode server.jsThe server run on http://localhost:3000
Example Request (Python execution)
{
"language": "python",
"version": "3.10.0",
"files": [{ "content": "print('Hello World')" }],
"stdin": ""
}Curl Command
curl -X POST http://localhost:3000/api/execute -H "Content-Type: application/json" -d "{\"language\":\"python\",\"version\":\"3.10.0\",\"files\":[{\"content\":\"print(\\\"Hello World\\\")\"}],\"stdin\":\"\"}"Expected Response:
{
"language": "python",
"version": "3.10.0",
"run": {
"stdout": "Hello World\n",
"stderr": "",
"code": 0,
"signal": null,
"output": "Hello World\n"
}
}I installed Jest and Supertest by running:
npm install --save-dev jest supertestI modified package.json to include:
"scripts": {
"test": "jest"
}Example Request (C++ execution)
{
"language": "cpp",
"version": "10.2.0",
"files": [
{
"name": "main.cpp",
"content": "/*بسم الله الرحيم الرحمان الرحيم*/
#include<bits/stdc++.h>
#include<cmath>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while(t--){
int l,r,k;
cin >> l >> r >> k;
if (r/k -l+1<=0)
cout <<0<<endl;
else cout <<r/k -l+1<<endl;
}
}",
},
],
"stdin": "8\n3 9 2\n4 9 1\n7 9 2\n2 10 2\n154 220 2\n147 294 2\n998 24435 3\n1 1000000000 2\n", // input: 8 test cases
}Now it is time to run tests:
npm testExpected output:
> express-piston-app@1.0.0 test
> jest
console.log
Server running on port 3000
at Server.log (server.js:46:11)
console.log
Received request body: {
language: 'cpp',
version: '10.2.0',
files: [
{
name: 'main.cpp',
content: '/*بسم الله الرحيم الرحمان الرحيم*/\n' +
'#include<bits/stdc++.h>\n' +
'#include<cmath>\n' +
'using namespace std;\n' +
'typedef long long ll;\n' +
'int main()\n' +
'{\n' +
' ios::sync_with_stdio(false);\n' +
' cin.tie(nullptr);\n' +
' cout.tie(nullptr);\n' +
' int t;\n' +
' cin >> t;\n' +
' while(t--){\n' +
' int l,r,k;\n' +
' cin >> l >> r >> k;\n' +
' if (r/k -l+1<=0)\n' +
' cout <<0<<endl;\n' +
' else cout <<r/k -l+1<<endl;\n' +
' }\n' +
'}'
}
],
stdin: '8\n3 9 2\n4 9 1\n7 9 2\n2 10 2\n154 220 2\n147 294 2\n998 24435 3\n1 1000000000 2\n'
}
at log (server.js:10:11)
console.log
Execution Response: {
language: 'c++',
version: '10.2.0',
run: {
stdout: '2\n6\n0\n4\n0\n1\n7148\n500000000\n',
stderr: '',
code: 0,
signal: null,
output: '2\n6\n0\n4\n0\n1\n7148\n500000000\n'
},
compile: { stdout: '', stderr: '', code: 0, signal: null, output: '' }
}
Piston API Execution Test - C++
√ should execute the C++ code and return correct output (2995 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.485 s, estimated 5 s
Ran all test suites.
To prevent abuse and ensure fair usage, I have implemented rate limiting:
- ⏳ Limit: 5 requests per minute per IP
- 🚫 Exceeding the limit? You will receive a
429 Too Many Requestserror
First I installed express-rate-limit:
npm install express-rate-limitThen I added this server.js:
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 5, // Allow only 5 requests per minute
message: { error: "Too many requests, please try again later." },
statusCode: 429, // 429 Too Many Requests
});
app.use(limiter);This means the API will only allow 5 requests per minute per IP.
In tests/app.test.js, I modified the test to send more than 5 requests quickly.
Example test:
const request = require("supertest");
const { app } = require("../server");
describe("Rate Limiting Test", () => {
it("should return an error after exceeding rate limit", async () => {
let response;
// Send 5 requests in quick succession
for (let i = 0; i < 5; i++) {
response = await request(app)
.post("/api/execute")
.send({
language: "cpp",
version: "10.2.0",
files: [{ name: "main.cpp", content: "int main() { return 0; }" }],
stdin: "",
});
}
// The last request should be rate-limited
expect(response.status).toBe(429);
expect(response.body.error).toBe("Too many requests, please try again later.");
});
});npm test✅ The first 4 requests succeeded, but the 5th request failed with a 429 Too Many Requests error because there is already the "Piston API Execution Test - C++"