2
$\begingroup$

How to find out the file path I dropped my Python script from? I want to call an external application for image post-processing from a Python script and I want the application to be in the same folder as the script. And I want Blender to automatically find that application.

I know about this question: "How do I get the path my script is running in?" but it's not the same

$\endgroup$
  • $\begingroup$ As for the link you provide, is the variable __file__ is not answering your question ? $\endgroup$ – Flavio Aug 11 '14 at 14:17
  • $\begingroup$ No, it shows some temp path which is NOT the real path I dropped my script file from $\endgroup$ – Val Aug 11 '14 at 14:26
  • $\begingroup$ I'm sorry I'm not sure to understand what you are doing. Can you detail more the workflow ? What about "dropping" the python script ? is it like there folderA with your script AND the executable of that other application, and you run (how?) a python script from that folderA in blender and you want to know where is the python script running from ? os.getcwd() ? $\endgroup$ – Flavio Aug 11 '14 at 14:36
  • $\begingroup$ I drag&drop myscript.py to Blender's Text Editor and then press the Run Script button. I want my script to find out which folder it has been dropped from so that it can run my custom external exe from that same folder (using subprocess.call()) $\endgroup$ – Val Aug 11 '14 at 14:47
  • $\begingroup$ Interestingly, the status bar under the Text Editor shows my script's filename with full and correct path. $\endgroup$ – Val Aug 11 '14 at 14:56
4
$\begingroup$

bpy.context.space_data will give you the current text editor when you click run script, where you can access the text block.

print(bpy.context.space_data.text.filepath)

For an unsaved text block this is empty. For a file dropped onto the text editor or opened by using the Text->Open Text Block menu item you will still get an empty filepath.

Blender doesn't appear to fill in the filepath property of a text block unless you save the text block to disk, meaning you need to open the text block and then save as to get a filepath. Once it has a filepath you can save, close and re-open the blend file and it will keep the filepath.

__file__ will give you the path to the text block inside the blend file. That is the path of the blend file with the text block name added as if the blend file was a directory. This applies even if the file is saved to disk.

For your own use you can setup the blend file with the script. If you want to share this then you probably want to make it an addon with AddonPreferences to save the path to the utility. On registration you might search a few possible paths to get the initial setting and have the user set it as needed, or you can tarball the script and utility so that it is next to the addon script when the user installs it.

$\endgroup$
  • $\begingroup$ NOTE I'm on *nix and drag n dropping doesn't give the full path, osx/windows may fill the filepath for a dropped file. $\endgroup$ – sambler Aug 12 '14 at 7:02
  • $\begingroup$ Tried print(bpy.context.space_data.text.filepath). Got error: AttributeError: 'SpaceProperties' object has no attribute 'text'. $\endgroup$ – Val Aug 12 '14 at 7:11
  • $\begingroup$ It will only work when you click the run script button. Or more precisely while the text editor is active. It may only be as the script starts, during execution it can loose focus and fail. $\endgroup$ – sambler Aug 12 '14 at 7:33
  • $\begingroup$ My script first creates a button in the Object Toolbar and then that button executes the main algorithm. So, I guess, the Text Editor does lose the focus $\endgroup$ – Val Aug 12 '14 at 7:44
  • 1
    $\begingroup$ Get the filepath first before you do anything else. $\endgroup$ – sambler Aug 12 '14 at 8:18
1
$\begingroup$

Dirty option

Assuming there is only ONE text editor open from which you have run your dropped script you can have this (in your script) :

import bpy, os
for area in bpy.context.screen.areas:
    if area.type == 'TEXT_EDITOR':
        for space in area.spaces:
            if space.type == 'TEXT_EDITOR':
                scriptFolder = os.path.dirname(space.text.filepath)
                print(scriptFolder)

This will print the directory of loaded and displayed scripts from any active text editors. This is why it's working if there is only one text editor and you had just pressed the run script button. In that case you should have the right path. Note that this is dirty and unsafe :)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.