To apply transformation really low-level, you should probably set the object's matrix directly and avoid bpy.ops.object.transform_apply()
entirely:
import bpy
from math import radians
from mathutils import Euler, Matrix
euler = Euler(map(radians, (0, 0, 45)), 'XYZ')
ob = bpy.context.object
loc, rot, scale = ob.matrix_world.decompose()
smat = Matrix()
for i in range(3):
smat[i][i] = scale[i]
mat = Matrix.Translation(loc) * euler.to_matrix().to_4x4() * smat
ob.matrix_world = mat
Change the last line to ob.matrix_local = ob.matrix_parent_inverse * mat
if you want to set a rotation of 0°, 0°, 45°
(as seen in Object tab) even if the object is parented.
The code might need further adjustments if drivers or modifiers are involved, non-uniform scaling in combination with parenting does not seems to work fine however.