Check if the whole plane is being on a orthographic camera render (or get a proportion of the rendered plane)
camera_fit_coords

The method camera_fit_coords does most of what you need, it returns a location and zoom factor for an ortho camera such that it fits all given coordinates.  It does not however rotate the camera, so that will have to be calculated.

Test script, make a plane active, run script and the camera will move to fit the entirety of the plane into the scene camera.


Calculate the centre of geometry of plane using bound box ( local plane coords)
Grab the local normal of the first face of plane, I've used bmesh here, could use mesh API instead.  Have to use a face normal, a vert normal on a 1 face square plane will be at 45 degrees to x, y axes. 


Find the longest boundary edge to align to the x axis of the camera.  At this step could compare the render dimensions of camera and choose to align x or y, if y swap x and y x_axis, y_axis = y_axis, x_axis
The rotation part of the new global camera matrix is created from the three orthogonal unit vectors, the plane global normal being the -z axis, the x axis aligning with global vector created from longest boundary edge. The other being z_axis.cross(x_axis) Rotation difference could have also been used here.
Call the camera_fit_coords method with a flat list of all the global coordinates of the planes bounding box, use the return values for location and orthogonal zoom.



&nbsp;

import bpy
from mathutils import Vector, Matrix
import bmesh

context = bpy.context
scene = context.scene

cam_ob = scene.camera
plane = context.object
pmw = plane.matrix_world
plane_co = sum((Vector(b) for b in plane.bound_box), Vector()) / 8
me = plane.data
bm = bmesh.new()
bm.from_mesh(me)
bm.normal_update()
bm.faces.ensure_lookup_table()
# first face, could sum them I suppose
bm.faces[0].normal_update()
plane_no = bm.faces[0].normal
# longest edge

axis = sorted(
    (e for e in bm.edges if e.is_boundary), key=lambda e: e.calc_length(), reverse=True
)[0]

# global coords
z_axis = pmw @ (plane_no) - pmw @ Vector()

x_axis = pmw @ axis.verts[1].co - pmw @ axis.verts[0].co

y_axis = z_axis.cross(x_axis)
'''
#  would need to also check scale, hmm bmesh.from_object.. doh.
render = scene.render
if render.resolution_y &lt; render.resolution_x:
    x_axis, y_axis = y_axis, x_axis
'''    
R = Matrix([v.normalized() for v in (x_axis, y_axis, z_axis)]).transposed()
cam_ob.matrix_world = R.to_4x4()
cam_ob.matrix_world.translation = pmw @ plane_co

scene.update()
coords = [t for b in plane.bound_box for t in pmw @ Vector(b)]

v, scale = cam_ob.camera_fit_coords(context.depsgraph, coords)


cam_ob.data.ortho_scale = scale
cam_ob.matrix_world.translation = v
scene.update()



There are other questions on here regarding aligning objects with a face normal, or another vector.