Tree depth

IMO, only makes sense to enter this branch if the call is trying to change the parent_project_id, that's why it was:
if ('parent_project_id' in tenant and ...

But, since you are doing tenant.get('parent_project_id', None), why not assign this to a variable before the if branch? Something like:

curr_parent_id = tenant.get('parent_project_id', None)
if curr_parent_id...