Setting blender context for uv editing issue
Running this script from the cli, I can unwrap an object in the background (no gui window).
I think the key point is setting the active object not just selecting it. I also create a uvmap layer if one doesn't exist and use mode_set rather that editmode_toggle.
import bpy

# Deselect all
bpy.ops.object.select_all(action='DESELECT')

for obj in bpy.context.scene.objects:
    if obj.type == 'MESH':
        obj.select_set(state=True)
        bpy.context.view_layer.objects.active = obj
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='SELECT')
        if len(obj.data.uv_layers) == 0:
            obj.data.uv_layers.new()
        bpy.ops.uv.smart_project()
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.wm.save_mainfile()

I saved it as uvproject.py and used the cli command
blender -b test.blend -P uvproject.py