There are other packages, particularly ape for R, that build an unrooted tree then allow you to root it by explicitly specifying an outgroup.
In contrast, in BioPython I can directly create a rooted tree without specifying the root, so I'm wondering how the root is being determined, for example from the following code.
from Bio import AlignIO
alignment = AlignIO.read('mulscle-msa-aligned-105628a58654.fasta', 'fasta')
from Bio.Phylo.TreeConstruction import DistanceCalculator
calculator = DistanceCalculator('ident')
dm = calculator.get_distance(alignment)
from Bio.Phylo.TreeConstruction import DistanceTreeConstructor
constructor = DistanceTreeConstructor()
tree = constructor.upgma(dm)
from Bio import Phylo
Phylo.write(tree, 'phyloxml-7016bed7d42.xml', 'phyloxml')
I made up the sequences here after the tree was built, but nonetheless this is a rooted tree built from that process.