Skip to content

VICoach/express-piston-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Express Piston App - Documentation

📌 Overview

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.

📂 Project Structure

express-piston-app/
│── node_modules/
│── tests/
│   ├── app.test.js
│── package.json
│── server.js
│── README.md

🚀 Installation & Setup

1️⃣ Installed Dependencies

npm install express axios dotenv jest supertest cors

2️⃣ Started the Server

node server.js

The server run on http://localhost:3000

🧪 Test with Curl

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"
  }
}

🔍 Automated Testing

1️⃣ Installed Jest and Supertest

I installed Jest and Supertest by running:

npm install --save-dev jest supertest

2️⃣ Run Tests Using Jest

I 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 test

Expected 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.

🚦 Rate Limiting

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 Requests error

1️⃣ Updated server.js to Implement Rate Limiting

First I installed express-rate-limit:

npm install express-rate-limit

Then 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.

2️⃣ Modified the Jest Test to Check Rate Limiting

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.");
  });
});

3️⃣ Run the Test

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++"

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages