Can't find module: Python, NodeJS, and fs module - python

With Python, I make a script that asks for input (an action). The second option runs a NodeJS file called settings.js in a new terminal window with:
subprocess.call('start node src/settings.js', shell=True)`
In the NodeJS settings.js file, it basically uses fs to overwrite a key's value in config.json. In this case, change the key "PREFIX" to whatever the user inputs (e.g. !).
When it first reads the config.json file, it shows an error.
Code:
await fs.readFile('config.json', 'utf8', async (err, data) => {
// code to overwrite (with given data)
}
Error:
[Error: ENOENT: no such file or directory, open 'C:\Users\userhere\Desktop\serenity-zero\serenity-zero-test\config.json'] {
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'C:\\Users\\userhere\\Desktop\\serenity-zero\\serenity-zero-test\\config.json'
}
I figured that this happened as it originally ran from the python script, so the directory folder was outside of the NodeJS file (the python script's folder directory). I tried:
await fs.readFile('src/config.json', 'utf8', async (err, data) => {
// code
});
and,
await fs.readFile('./src/config.json', 'utf8', async (err, data) => {
// code
});
But, I got:
(node:17348) UnhandledPromiseRejectionWarning: Error: Cannot find module './src/config.json'
Require stack:
- C:\Users\userhere\Desktop\serenity-zero\serenity-zero-test\src\settings.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
at Function.Module._load (internal/modules/cjs/loader.js:725:27)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at C:\Users\userhere\Desktop\serenity-zero\serenity-zero-test\src\settings.js:29:87
at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:17348) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:17348) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Just so you know, this worked perfectly fine when the python script was in the same folder as the node.js files. I wanted to make it more organized so I put the node.js files in a src folder. The python script remained in the original folder. After that, I got this error.

Just fixed it, all I had to do was put the config.json in the same directory as the launch.py file. I don't think it's possible for the config.json to be in the src folder, but atleast it works.

Related

How to run C# Console Applications via Python?

I've created the following C# Console Application (.NET Core 3.1) with Visual Studio:
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
//Check if args contains anything
if (args.Length > 0)
{
Console.WriteLine("args = " + args[0]);
} else
{
Console.WriteLine("args is empty");
}
//Prevent the application from closing itself without user input
string waiter = Console.ReadLine();
}
}
}
I am able to execute the application succesfully with one argument via cmd.exe:
CMD Input and Output
Now I'd like to run this program with one argument via Python. I've read How to execute a program or call a system command? and tried to implement it. However, it seems that the application is not being run properly.
The python code I am using via Jupyter notebook:
import subprocess
path = "C:/Users/duykh/source/repos/ConsoleApp2/ConsoleApp2/bin/Release/netcoreapp3.1/ConsoleApp2.exe"
subprocess.Popen(path) //#Also tried with .call and .run
//#subprocess.Popen([path, "argumentexample"]) doesn't work either
Output:
<subprocess.Popen at 0x2bcaeba49a0>
My question would be:
Why is it not being run (properly) and how do I properly run this application with one argument?
I've answered my own question. In a nutshell: I am pretty stupid.
Jupyter Notebook was running in the background and the application was being run there. That's why it didn't open a new prompt.
subprocess.Popen([path, "argument example"]) seems to work well for running a console application with an argument as input.

Configure VS Code to execute Python script only if there are no linter errors

Is there a way to configure VS Code to only execute a python script if there are no linter errors? I am using Python 3.9.0 and VS Code 1.49.0. Linter is mypy (mypy-0.790, mypy-extensions-0.4.3, typed-ast-1.4.1, typing-extensions-3.7.4.3). OS is Windows 10, version 2004.
Currently, while linter reports problems correctly (incompatible type, based on type hints, for instance), pressing F5 still runs the code (which crashes, as the linter is correct). I would like VS Code to only proceed to the "Run" step if the linter output has no errors, as the time taken to execute a script with linter errors is basically a waste of time.
How can this be configured?
First, create a new task. If you don't already have a tasks.json file in the .vscode folder (or you don't have a .vscode folder), you can press F1 and run "Tasks: Configure Task", then select "Create tasks.json file from template". Select "Others" from the list of templates. It should generate a file that looks like this:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "echo",
"type": "shell",
"command": "echo Hello"
}
]
}
Change the label to "lint" (or any other label that suits your fancy), and change the command to "mypy <directories or files>". For more information on the mypy command, refer to the docs.
If you do already have a tasks.json file, just copy the part inside the tasks array into your tasks array and make the same changes.
Then, open your launch.json and add the following line into whichever configuration(s) you're using.
"preLaunchTask": "lint",
If the task fails, you'll see a dialogue box pop up saying
The preLaunchTask 'lint' terminated with exit code 1.
and asking if you want to "Debug Anyway", Show Errors", or "Abort". There'll also be a checkbox to have VS Code remember your choice in your settings (if you'd like to set this before the first time you get an error, the setting is named debug.onTaskErrors).
Additional resources:
Tasks Documentation
Debugging Documentation
Description of debug.onTaskErrors

spawn python ENOENT error with node child process

I am trying to call a python script as a child process within a node script. The output of the script is to be used within a callback. The code looks like this:
//myFunction.js
const myFunction = callback => {
let py = process.spawn('python', ['../folder/pyscript.py'], {
cwd: '../folder/'
});
let str = '';
py.stdout.on('data', data => {
str += data.toString();
}
py.stdout.on('end', () => {
callback(str);
}
}
exports.myFunction = myFunction;
This code works as expected when I directly run node myFunction.js (with an instance of myFunction within the script) and it works fine when I require the module in any other files within the same directory as myFunction.js.
But it fails with the following error when the module is required in a different higher level directory:
error: spawn python ENOENT
I'm guessing this has something to do with paths (value of cwd maybe?) but I can't seem to fix this. I've looked up similar questions but the answers aren't helping.
Any help will be appreciated. :)
Apparently, the issue is with the cwd. Everything in the script is relative to the path of the directory from where the script is invoked. So basically, running node myFunction.js from the project root directory (say ~/projects/myProject would set the cwd to ~/projects/myProject/../folder which would evaluate to ~/projects/folder. This is obviously incorrect, since in all probability, no directory named folder exists on the system, and thus this would lead to an ENOENT error.
The solution would be to construct the absolute path of your script in the code, perhaps by using the __dirname__ property in combination with the functionalities provided by the path module.
I struggled with this issue for days, before realizing that my script file was not getting picked up and spawned by nodeJS, because of some filepath issue.
Although I don't guarantee this will work for everyone, depending on their setup, this is what I did in my nodejs file:
let py = process.spawn('python', [__dirname + '../folder/pyscript.py']);
As you can see, I didn't have to use the {cwd: '../folder/'} option.
If your script is in the current directory as your javascript file, just do
let py = process.spawn('python', [__dirname + './pyscript.py']);
I should also point out that:
process.spawn('python', ['./pyscript.py']);
never worked for me and I spent days wondering why. Could find an answer until I tried this technique. Hope someone having this issue find this answer useful.
Using ${process.cwd()} worked for me... you can write it like this
let py = process.spawn('python', [`${process.cwd()}/folder/pyscript.py`]});

calling python script from node.js

I want to call python script from node.js
Here is my script : my.py
def printme( str ):
# print str;
return str;
printme("I'm first call to user defined function!");
printme("Again second call to the same function");
My node script : testpy.js
var PythonShell = require('python-shell');
var pyshell = new PythonShell('my.py');
pyshell.on('message', function(message) {
console.log(message);
});
but getting error
events.js:85
throw er; // Unhandled 'error' event
Error: spawn python ENOENT
at exports._errnoException (util.js:746:11)
at Process.ChildProcess._handle.onexit (child_process.js:1046:32)
at child_process.js:1137:20
at process._tickCallback (node.js:355:11)
at Function.Module.runMain (module.js:503:11)
at startup (node.js:129:16)
at node.js:814:3
P.S I have install Python shell
Also if I want to execute individual function from node.js to python script. can I do that ?Help
You can simply write the 'my.py' file like this-
def printme(str):
return str;
print(printme("I'm first call to user defined function!"));
Check if the path given is correct and check for indentation errors.
Your print statement (my.py line 2) is commented out so nothing will be output and the message event will therefore never fire. Uncomment your print statement, the Node PythonShell object will redirect the stdout (which print writes to) and fire a message event with the output.
As for your error, it looks like the python script isn't being found in the current directory. See https://docs.python.org/2/library/errno.html for error codes and what they mean. Make sure your script is in the right directory or set your python shell to the correct directory using os.chdir.
I think that you need to set up the python script to take in standard input like this
import sys
for v in sys.argv[1:]:
print v
Also when setting up the code the way you have it you need to do a PyhtonShell.send('message'), but I would need to see more of your code because I don't see how you are sending data to the python shell through Node.js.
You can simply import Npm Pythonshell using let keyword instead of const Keyword.
let {PythonShell} = require('python-shell')
this works for me

evaluating buffer in emacs python-mode on remote host

I'm using emacs23 with tramp to modify python scripts on a remote host.
I found that when I start the python shell within emacs it starts up
python on the remote host.
My problem is that when I then try to call python-send-buffer via C-c C-c it comes up with the error
Traceback (most recent call last):
File "", line 1, in ?
ImportError: No module named emacs
Traceback (most recent call last):
File "", line 1, in ?
NameError: name 'emacs' is not defined
Now, I must admit that I don't really know what's going on here. Is there a way for me to configure emacs so that I can evaluate the buffer on the remote host?
Many thanks.
Edit: I've followed eichin's advice and re-implemented python-send-region. See my answer below.
I'm currently trying to to get my unregistered question merged with this account, after which I'll be able to accept eichin's answer and edit my post to include my solution.
I followed eichin's suggestion and copied the emacs2.py emacs3.py and emacs.py files to the remote host and added their directory to PYTHONPATH in the tramp-remote-process-environment variable.
I then reimplemented the python-send-buffer function in my .emacs
(require 'python)
(defun python-send-region (start end)
"Send the region to the inferior Python process."
(interactive "r")
(let* ((loc_name)
(f (if (file-remote-p default-directory)
(let* ((con (tramp-dissect-file-name default-directory)))
(setq loc_name (tramp-make-tramp-temp-file con))
(concat "/"
(tramp-file-name-method con) ":"
(tramp-file-name-user con) "#"
(tramp-file-name-host con) ":"
loc_name
))
(setq loc_name (make-temp-file "py"))))
(command (format "emacs.eexecfile(%S)" loc_name))
(orig-start (copy-marker start)))
(save-excursion
(let ((curbuf (current-buffer))
(tempbuf (get-buffer-create "*python_temp*")))
(set-buffer tempbuf)
(delete-region (point-min) (point-max))
(insert-buffer-substring curbuf start end)
(python-mode)
(when (save-excursion
(goto-char (point-min))
(/= 0 (current-indentation)))
(python-shift-left (point-min) (point-max)))
(write-region nil nil f nil 'nomsg))
(python-send-command command)
(with-current-buffer (process-buffer (python-proc))
;; Tell compile.el to redirect error locations in file `f' to
;; positions past marker `orig-start'. It has to be done *after*
;; `python-send-command''s call to `compilation-forget-errors'.
(compilation-fake-loc orig-start f)))
))
I essentially copy the region into a new buffer, adjust the indentation and then write it into a temporary file, created with tramp-make-tramp-temp-file or make-temp-file, depending on whether the visited file is remote or local.
I had some problems with tramp-handle-write-region, which didn't seem to accept a string as a first argument, which is why I did all the formatting in a separate buffer first.
Let me know if there are still any problems with the code, but this is my first attempt at elisp coding, so please be gentle.
Short answer: not without writing some missing elisp code.
Long version: In python.el, run-python adds data-directory (which on my Ubuntu 10.10 box is /usr/share/emacs/23.1/etc/ ) to $PYTHONPATH, specifically so that it can find emacs.py (as supplied by the local emacs distribution.) Then it does a (python-send-string "import emacs") and expects it to work...
It looks like the defadvice wrappers that tramp uses don't actually pass PYTHONPATH, so this doesn't work even if you have the matching emacs version on the remote system.
If you M-x customize-variable RET tramp-remote-process-environment RET
then hit one of the INS buttons and add PYTHONPATH=/usr/share/emacs/23.1/etc then hit STATE and set it to "current session" (just to test it, or "save for future sessions" if it works for you) it almost works - the complaint goes away, in any case, because the remote python can now find the remote emacs.py. If you now go back to the original question, doing python-send-buffer, you just run into a different error: No such file or directory: '/tmp/py24574XdA' because python-mode just stuffs the content into a temporary file and tells the python subprocess to load that.
You'd have to change python-send-region (the other functions call it) and particularly the way it uses make-temp-file to be tramp-aware - there's even a tramp-make-tramp-temp-file you could probably build upon. (Be sure to post it if you do...)

Categories