Align empty to normal with object matrix world rotation?
import bpy
from bpy import context
from mathutils import Matrix, Vector
import bmesh

obj=context.object
mw = obj.matrix_world
me=obj.data
m = mw.copy()
mi = m.inverted()

def create_rotation_matrix_from_face(mx, face):
    normal = (mx.to_3x3() @ face.normal)
    tangent = (mx.to_3x3() @ face.calc_tangent_edge_pair())
    binormal = normal.cross(tangent)
    rot = Matrix()
    rot[0].xyz = binormal
    rot[1].xyz = normal
    rot[2].xyz = tangent
    return rot.transposed()

#apply all transforms
me.transform(mw) #Transform mesh vertices by a matrix
mw = Matrix()

bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(obj.data)
for face in bm.faces: 
    if face.select:
        mat_rot=create_rotation_matrix_from_face(mw, face)
        loc=mw @ face.calc_center_median() # &gt; vector
        mat_trans = Matrix.Translation(loc)
        break

mat=mat_trans @ mat_rot
bpy.ops.object.mode_set(mode='OBJECT')
empty=bpy.ops.object.empty_add(type='ARROWS', radius=1)

scale_empty=context.object.scale.copy() #scale will change after the matrix modification (next line)
context.object.matrix_world @= mat
#empty size
context.object.scale=scale_empty #original size
#or
#context.object.scale=obj.scale #size of the object x,y,z 

#apply all modif back
me.transform(mi) #all zero loc rot scale
mw = m #back to start matrix
me.update()