Keuchel (12-11) allowed three runs, seven hits, and three walks while striking out five.
Former Blue Jays closer Roberto Osuna was booed when he entered for the ninth, pitching around a single for his 10th save as an Astro and his 19th this season overall. Toronto traded him to Houston July 30 at the end of a 75-game suspension given by Major League Baseball following an assault charge.
Kevin Pillar hit a two-run homer for the Blue Jays.
Toronto starter Marco Estrada (7-14) gave up four runs, seven hits, and one walk in 4 2/3 innings. He struck out one.
Pillar's 15th homer of the season followed Justin Smoak's fourth-inning double, cutting the Blue Jays' deficit to 4-2.
Estrada was replaced with two outs and two on in the fifth by Tim Mayza, who struck out two in one scoreless inning.
Solarte led off the bottom of the seventh with a single, and Tony Sipp entered to coax a double-play grounder from Smoak. Brad Peacock finished the inning with a strikeout.
Ryan Pressly pitched a perfect bottom of the eighth for Houston.
Jake Marisnick's double and Altuve's single against Joe Biagini in the top of the ninth extended Houston's lead to two runs.
Toronto's Lourdes Gurriel Jr. left the game due to a tight left hamstring after grounding into a double play in the first inning.