Finding top surface area of a mesh by python
Here as requested is faces whose normal vector has angle from up vector of less than 80 degrees.

import bpy
import bmesh
from math import radians
from mathutils import Vector

obj = bpy.context.active_object
mw = obj.matrix_world
bm = bmesh.new()
bm.from_mesh(obj.data)

up = Vector((0, 0, 1))
# local space    
area = sum(f.calc_area() for f in bm.faces if up.angle(f.normal) &lt; radians(80))
print("local", area)
# global space
area = sum(f.calc_area() for f in bm.faces if up.angle(mw * f.normal) &lt; radians(80))
print("global", area)
# or avoid a lot of matrix mult by converting "up" to local space.
up = mw.inverted() * up
area = sum(f.calc_area() for f in bm.faces if up.angle(f.normal) &lt; radians(80))
print("global", area)

bm.free()