vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.01k stars 26.99k forks source link

Unable to execute py script using exec command in nextjs #61750

Open krishnaacharyaa opened 9 months ago

krishnaacharyaa commented 9 months ago

Link to the code that reproduces this issue

https://github.com/krishnaacharyaa/python-nextjs

To Reproduce

Just clone the repo Breif is: I am trying to run simple py/sh scripts from nextjs using exec but i am not able to achieve it.

Kind help would be much appreciated.

Process is simple:

I am calling server Actions in my code, which executes the script

page.tsx

"use client";

import { pythonExec } from "./action";

export default function PythonClicker() {
  return <div onClick={() => pythonExec()}>Hello there</div>;
}

server action

"use server";

// import { exec } from "child_process";
export const pythonExec = async () => {
  const { exec } = require("child_process");
  console.log("I am called  ");
  exec('"sample-script.py"');
};

sample-script.py

print("Hello world")

p.s: I am called is being logged, only the "Hello world" is not getting logged. I also want to return values from the script and use consume it in my server action

Reproducible code: https://github.com/krishnaacharyaa/python-nextjs

Current vs. Expected behavior

Along with log of "I am called in ", I expect to see the "Hello world" message aswell

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:34 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T8103
Binaries:
  Node: 21.0.0
  npm: 10.2.0
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.1.0
  eslint-config-next: 14.1.0
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Data fetching (gS(S)P, getInitialProps), Middleware / Edge (API routes, runtime), Routing (next/router, next/navigation, next/link), Script optimization (next/script)

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

No response

Durgaprasad-Budhwani commented 9 months ago

Tackling the issue where you're unable to call Python code from your Next.js application, I've got a great solution that should clear up the confusion and have your application communicating with Python in no time! The key here is to switch from using exec to spawn, which is a bit more flexible and suited for your needs. Here's how you can do it:

export const pythonExec = async () => {
  const { spawn } = require('child_process');
  console.log("I am called");
  return new Promise((resolve, reject) => {
    const pyprog = spawn('python', ["/path/to/the/code/sample-script.py"]);

    pyprog.stdout.on('data', function(data) {
      console.log(data.toString());
      resolve(data.toString());
    });

    pyprog.stderr.on('data', (data) => {
      console.log(data.toString());
      reject(data.toString());
    });
  });
};

This approach uses spawn from the child_process module, providing a neat, promise-based solution to asynchronously execute your Python script and handle both success and error cases. Just remember to replace "/path/to/the/code/sample-script.py" with the absolute path to your Python script. Absolute paths ensure that your Python code is correctly located and executed, regardless of where your Next.js app is running.

Also, to make sure your Python script is included in your Next.js build, consider using the copy-webpack-plugin in your next.config.js file. This plugin will help you copy your Python code into the build directory, making deployment smoother and more reliable. Here's a quick example of how you might set it up:

const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.plugins.push(
        new CopyPlugin({
          patterns: [
            { from: 'path/to/the/code', to: 'destination/path' },
          ],
        }),
      );
    }
    return config;
  },
};

Just adjust path/to/the/code and destination/path to match your project's structure. This little tweak ensures your Python script is right where it needs to be, ready to be called by your Next.js app. Keep up the great work, and I'm here if you have any more questions or need further assistance!



"Let's make the digital world smaller! Connect with me across the web on these social platforms and let's create, share, and inspire together." ✨🌐 #StayConnected

LinkedIn Twitter

Solved 05

zheng-liu-seattle commented 9 months ago
module.exports = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.plugins.push(
        new CopyPlugin({
          patterns: [
            { from: 'path/to/the/code', to: 'destination/path' },
          ],
        }),
      );
    }
    return config;
  },
};

Thanks for the details!

I have two questions:

  1. In my local, I need to use command "Python3" instead of "Python" to make it work, if I deploy it to Vercel, should I use "Python" as your code?
  2. I can tell the file path in my local, but I have no idea about the file path should look like on vercel, any clue?

Thanks!!

zheng-liu-seattle commented 9 months ago

The vercel log says, it seems can't find python cmd, how to resolve it? @Durgaprasad-Budhwani Durgaprasad-Budhwani

{"errorType":"Error","errorMessage":"spawn python ENOENT","code":"ENOENT","errno":-2,"syscall":"spawn python","path":"python","spawnargs":["sample-script.py"],"stack":["Error: spawn python ENOENT"," at ChildProcess._handle.onexit (node:internal/child_process:286:19)"," at onErrorNT (node:internal/child_process:484:16)"," at process.processTicksAndRejections (node:internal/process/task_queues:82:21)"]} Unknown application error occurred Runtime.Unknown

Durgaprasad-Budhwani commented 9 months ago

Seems like Vercel only supports only one runtime for an API, either Python or NodeJS. I am not able to get the exact example of using both the runtime.

cysbyte commented 8 months ago

The vercel log says, it seems can't find python cmd, how to resolve it? @Durgaprasad-Budhwani Durgaprasad-Budhwani

{"errorType":"Error","errorMessage":"spawn python ENOENT","code":"ENOENT","errno":-2,"syscall":"spawn python","path":"python","spawnargs":["sample-script.py"],"stack":["Error: spawn python ENOENT"," at ChildProcess._handle.onexit (node:internal/child_process:286:19)"," at onErrorNT (node:internal/child_process:484:16)"," at process.processTicksAndRejections (node:internal/process/task_queues:82:21)"]} Unknown application error occurred Runtime.Unknown

I encountered the same problem, have no idea what the exact path of the python file is after deployed on vercel.