How to get part of a mesh with Python API, which requires breaking down some faces?
All with bmesh in object mode.



With appropriate bmesh operators


add the primitive circles
translate them to desired location
add the grid
bisect with YZ plane at origin and clear the inner.  Note the plane coordinate is at (0, 0, 0) by default.
repeat with XZ plane.


Test script, run in object mode.  Adds a plane and replaces its mesh.  

import bpy
import bmesh
context = bpy.context

bm = bmesh.new()

bmesh.ops.create_circle(bm,
        cap_ends=True,
        radius=2,
        segments=32)

bmesh.ops.create_circle(bm,
        cap_ends=True,
        radius=3,
        segments=32)
bmesh.ops.translate(bm, verts=bm.verts, vec=(0.5, 0.5, 0))
bmesh.ops.create_grid(bm,
        x_segments=3,
        y_segments=3,
        size=4)

# run two bisect planes
def geom(bm):
    return bm.faces[:] + bm.edges[:] + bm.verts[:]

bmesh.ops.bisect_plane(bm,
        plane_no=(1, 0, 0), # x &gt; 0
        geom=geom(bm),
        clear_inner=True)
bmesh.ops.bisect_plane(bm,
        plane_no=(0, 1, 0), # y &gt; 0
        geom=geom(bm),
        clear_inner=True)

# quick hack to add object
bpy.ops.mesh.primitive_plane_add()
ob = context.object
bm.to_mesh(ob.data)
ob.data.update()


To pick up from where your script above left off, with a minor change in that the object added in object mode will be the context object (don't rely on it being first in selected objects list), and no need to switch into edit mode from edit mode, can remove a couple of redundant operators.

# create the meshes as in question
ob = context.object
bm = bmesh.new()
bm.from_mesh(obj.data)

# and then pick up script above 
    # run two bisect planes
def geom(bm):
    return bm.faces[:] + bm.edges[:] + bm.verts[:]

bmesh.ops.bisect_plane(bm,
        plane_no=(1, 0, 0), # x &gt; 0
        geom=geom(bm),
        clear_inner=True)
bmesh.ops.bisect_plane(bm,
        plane_no=(0, 1, 0), # y &gt; 0
        geom=geom(bm),
        clear_inner=True)


bm.to_mesh(ob.data)
ob.data.update()