bpy: How do you find the corners of a camera frustum? ... by which I mean the vectors from a perspective camera's viewing point to the corners of the rendered rectangle, as displayed by the diagonal sides of a camera's rectangular pyramid in a 3D View. (Normalized if you like, in Camera Space, if you like.)
The angle and view_frame attributes of a Camera don't seem to carry this information, unless I'm mistaken?
There are quite a few answers on how to test whether a point is visible to a camera, that's not quite the same thing.
Better still, and perhaps of more general use to others, too, would be a diagram of how bpy refers to a camera: what a Camera's important attributes actually mean, in 3D / device / screen space.
EDIT: following @batFINGER's examples (I think?)..trying to get the render frame, I run this:
import bpy

scn = bpy.context.scene

rx = scn.render.resolution_x
ry = scn.render.resolution_y
cam_obj = scn.camera

if (cam_obj.name in bpy.data.cameras): 
          
    cam_mw = cam_obj.matrix_world
    cam = cam_obj.data
    vf = cam.view_frame()
    world_frame = [cam_mw @ v for v in vf]
    
    print (rx,ry)
    for v in world_frame:
        print (v)  

And, changing the render resolutions, visibly changing the shape of the frustum in the 3D view, I get these outputs:
1512 1371
&lt;Vector (2.1208, -6.3833, 4.1026)&gt;
&lt;Vector (2.3175, -6.8641, 3.2482)&gt;
&lt;Vector (1.3703, -7.1821, 3.2090)&gt;
&lt;Vector (1.1736, -6.7013, 4.0635)&gt;

427 1432
&lt;Vector (2.1208, -6.3833, 4.1026)&gt;
&lt;Vector (2.3175, -6.8641, 3.2482)&gt;
&lt;Vector (1.3703, -7.1821, 3.2090)&gt;
&lt;Vector (1.1736, -6.7013, 4.0635)&gt;

Which is puzzling me. There's no change in the frame as a consequence of changing the proportions of the render - (the change isn't even hidden in the camera's world transform..)
SOLUTION: the camera's .view_frame() method needs its optional named scene parameter to update.. until I know why, I don't fancy making that an answer..
Pass the scene to view frame
Think you got there in the end, here is @ideasman42's script modified to add empties to 5 points of frustum, for each camera object in scene.
All the info re resolution will come with the passed as keyword scene, else it defaults to None.
&gt;&gt;&gt; C.scene.camera.data.view_frame(
view_frame()
Camera.view_frame(scene=None)
Return 4 points for the cameras frame (before object transformation)

Test script:
import bpy


def camera_as_planes(scene, obj):
    &quot;&quot;&quot;
    Return planes in world-space which represent the camera view bounds.
    &quot;&quot;&quot;
    from mathutils.geometry import normal
    print(obj.name)
    camera = obj.data
    # normalize to ignore camera scale
    matrix = obj.matrix_world.normalized()
    frame = [matrix @ v for v in camera.view_frame(scene=scene)]
    origin = matrix.to_translation()
    frame.append(origin)
    for p in frame:
        bpy.ops.object.empty_add(location=p)

# test call
scene = bpy.context.scene
cams = [o for o in scene.objects if o.type == 'CAMERA']
for cam in cams:
    camera_as_planes(scene, cam)