It’s generally bad practice to use
bpy.ops in a script if there’s a way to do it through data manipulation. All that stuff with the area and the override is because of
ops. I don’t even know what the
with statement is doing, here!
So anyways; you don’t have to switch to pose mode to modify pose properties, but you should make sure you aren’t in Edit Mode.
if object.mode == 'EDIT: return None'
Here is the API reference for the right way to add a keyframe from Python. As you can see, you can set the frame and value from there.
Now, for the actions: you can’t keyframe the action that an object is using because the Action is what holds the keyframes. So instead, you keep the action on the current object and transfer the pose you want into the object’s action.
Something like this:
for frame in range(length_of_animation):
for fcurve in pose_action.fcurves:
for (data_path, index), value in fcurve_value.items():
object.keyframe_insert(data_path, index, frame)
Please note that I haven’t tried the above script and it likely contains some syntax errors.
But anyhow, if you ever find yourself setting selection or doing context overrides in Blender’s Python API, there’s a 95% chance you’re making things harder than they should be, and perform worse than they should.
bpy.ops commands usually have a data-modification alternate that is more Pythonic and better for scripting.
.ops commands exist because they are useful for interacting with Blender on the level of an ordinary user. You can make your own operators very easily with the built-in Simple Operator template, too, and I encourage you to do this whenever you make tools! It becomes much easier to reuse them when you do.
I left out a fair bit of stuff here in the hopes that you can figure it out on your own, since I’m in the middle of something right now. Let me know if you get it and I will try and follow up if you need more pointers