0

How can I access files that my python is creating?
so inside a python i got something like:

from pathlib import Path
p = Path('my_file.txt')
p.write_text('testing')
print("Testing done")

then when i do bazel run my_file i can see in terminal text that all went well and info from print, but when i am trying to find my_file.txt there is nothing. So what do i need to do with my rules to be able to access that file after bazel run is done?

  • At the top of your program put `import os`. Change your `print()` call to `print("Testing done in", os.getcwd())`. Then look for your file in the folder that call shows you. I think you are looking for the file where it isn't. – BoarGules Aug 17 '21 at 13:26
  • @BoarGules like expected, it's inside bazel cashe folder which after script is done is cleared and changing cwd is not an option for me :) – Niewasz Biznes Aug 17 '21 at 14:55
  • Then put an explicit path such as r'c:\path\to\my_file.txt'. If the file has to be in the bazel folder then write it out twice, once to each location. – BoarGules Aug 17 '21 at 15:12
  • i don't have an access to any other path since it's inside a docker so i cannot access my workspace :( that's why changing cwd for /workspace is not an option – Niewasz Biznes Aug 17 '21 at 15:22

3 Answers3

1

It might help if you can give some more details:

  1. How is that python code being run? Is it being run as an action?
  2. What is the my_file target?
  3. You mention that you have some rules. Are these Starlark rules that you wrote?

But to answer directly: When a binary is run with bazel run, it's executed in a "runfiles tree" that contains symlinks of all the dependencies of the binary. So your file will be put in the binary's runfiles directory.

my_program.py:

import os
from pathlib import Path

print("current working directory: " + os.getcwd())

p = Path('my_file.txt')
p.write_text('testing')
print("Testing done")

BUILD:

py_binary(
  name = "my_program",
  srcs = ["my_program.py"],
)
$ bazel run my_program
INFO: Analyzed target //:my_program (18 packages loaded, 90 targets configured).
INFO: Found 1 target...
Target //:my_program up-to-date:
  bazel-bin/my_program
INFO: Elapsed time: 0.226s, Critical Path: 0.01s
INFO: 5 processes: 5 internal.
INFO: Build completed successfully, 5 total actions
INFO: Build completed successfully, 5 total actions
current working directory: /home/ahumesky/.cache/bazel/_bazel_ahumesky/5123c9882cdbb6c5e34f583431173549/execroot/__main__/bazel-out/k8-fastbuild/bin/my_program.runfiles/__main__
Testing done

$ ls /home/ahumesky/.cache/bazel/_bazel_ahumesky/5123c9882cdbb6c5e34f583431173549/execroot/__main__/bazel-out/k8-fastbuild/bin/my_program.runfiles/__main__
external  my_file.txt  my_program  my_program.py

$ cat /home/ahumesky/.cache/bazel/_bazel_ahumesky/5123c9882cdbb6c5e34f583431173549/execroot/__main__/bazel-out/k8-fastbuild/bin/my_program.runfiles/__main__/my_file.txt 
testing

If possible, it might be better if you pass the output file path to the program as an argument, so that the file is at some known location:

import sys
from pathlib import Path

p = Path(sys.argv[1])
p.write_text('testing')
print("Testing done")

$ bazel run my_program -- /tmp/output.txt
INFO: Analyzed target //:my_program (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:my_program up-to-date:
  bazel-bin/my_program
INFO: Elapsed time: 0.040s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Build completed successfully, 1 total action
Testing done

$ cat /tmp/output.txt
testing

Alternatively, if you run the program directly, then the file will be in the current working directory:

$ bazel build my_program
INFO: Analyzed target //:my_program (18 packages loaded, 90 targets configured).
INFO: Found 1 target...
Target //:my_program up-to-date:
  bazel-bin/my_program
INFO: Elapsed time: 0.219s, Critical Path: 0.01s
INFO: 5 processes: 5 internal.
INFO: Build completed successfully, 5 total actions

$ bazel-bin/my_program
current working directory: /home/ahumesky/test
Testing done

$ cat my_file.txt
testing
ahumesky
  • 4,203
  • 8
  • 12
0

write_text() returns the number of characters written to the text file, maybe you can check for that. Or, try print(p.read_text())

Amith Lakkakula
  • 506
  • 3
  • 8
0

Look at that script: you can use the BUILD_WORKING_DIRECTORY env variable to create a path to the file in a working directory

slsy
  • 1,257
  • 8
  • 21