Set Asset Browser to 'Current File' with Python from another area?

Hi,

I have an addon that, with a keyboard shortcut, splits the 3D Viewport into a new area and sets it to the Asset Browser editor.
I’d like to set the default Library when it opens to ‘Current File’ with python, because I’m not too happy with the upcoming 3.6 version that is going to show the ‘All’ Library by default.

If I’m in the right context, this line does it:

bpy.context.space_data.params.asset_library_ref = 'LOCAL'

But, the problem is I get the error message below because I’m trying to access the ‘ASSETS’ area from another area, (‘VIEW_3D’). Hence the bpy.context not working…
error

I tried this, but it is not working:

for area in bpy.context.screen.areas:
    if area.ui_type == 'ASSETS':
        bpy.context.space_data.params.asset_library_ref = 'LOCAL'

How can I set the space_data.params.asset_library_ref of the area that contains the Asset Browser while I’m not in it?
Thanks.

1 Like

You’re not using the area that you’re looking for in your loop. bpy.context.space_data returns the space data of the area where your mouse is pointing at the time you run the script.

import bpy

for area in bpy.context.screen.areas:
    if area.ui_type == 'ASSETS':
        area.spaces.active.params.asset_library_ref = 'LOCAL'

See https://docs.blender.org/api/current/bpy.types.Area.html and https://docs.blender.org/api/current/bpy.types.SpaceFileBrowser.html#bpy.types.SpaceFileBrowser

I’m getting this error:
Capture

Also, I don’t know if there is a difference between if area.ui_type and if area.type (Blender API doesn’t help much here), but the latter doesn’t give me the previous error, but neither is working anyway.

space_data.params isn’t loaded until the area has been redrawn at least once. This normally won’t happen until after your script ends.

You should register a timed callback with no delay, which Blender will call as soon as it dispatches your script and has had a chance to redraw.

import bpy

def split_current_area_with_assets():
    screen = bpy.context.screen
    areas = set(screen.areas)
    
    with bpy.context.temp_override(area=bpy.context.area):
        bpy.ops.screen.area_split(direction='VERTICAL')
    
    new_area, = set(screen.areas) - areas
    new_area.ui_type = 'ASSETS'
    
    def defer():
        if new_area.spaces.active.params is None:
            return 0
        new_area.spaces.active.params.asset_library_ref = 'LOCAL'
    bpy.app.timers.register(defer)

if __name__ == "__main__":
    split_current_area_with_assets()
2 Likes

Thank you very much. I was able to make it work.
In my case, I only needed the def defer() function! Worked perfectly :ok_hand:

Would it be possible to make a window that pops out and does the same thing? And also set it to a specific asset library instead of Current File? I’ve been trying to get something to do this for a while now.

Kind of. There isn’t an api for setting the window geometry without some drawbacks.

bpy.ops.wm.window_new()

  • New window is contained inside the main window by some margin.

bpy.ops.screen.area_dupli()

  • New window is placed on top of the active area, that is, the area which the mouse cursor is within.

bpy.ops.screen.userpref_show()

  • New window becomes 660 by 520.
  • Positioned at cursor.

And lastly
bpy.ops.render.view_show()

  • Size is based on the resolution set in Properties > Output Properties.
  • Positioned at cursor.
  • Window title will always say “Blender Render”.

So, depending on which of the above somewhat fits your needs, you would call that, the find the window and apply the area changes using the timer semantics.

Example using bpy.ops.wm.window_new():

import bpy

asset_library_ref_target = 'Assets Library'
asset_library_ref_fallback = 'LOCAL'


def new_window_with_assets():
    context = bpy.context

    current_windows = set(context.window_manager.windows)
    if 'FINISHED' not in bpy.ops.wm.window_new():
        return

    window, = set(context.window_manager.windows) - current_windows
    area = window.screen.areas[0]    
    area.ui_type = 'ASSETS'
    
    def defer():
        params = area.spaces.active.params
        if not params:
            return 0

        try:
            params.asset_library_ref = asset_library_ref_target
        except TypeError:
            # If the reference doesn't exist.
            params.asset_library_ref = asset_library_ref_fallback
        params.import_type = 'APPEND'

    bpy.app.timers.register(defer)


if __name__ == "__main__":
    new_window_with_assets()
1 Like

This worked! Thank you so much man, you’re a legend!

1 Like