You aren't passing a time value to focal_length_attr.Get(). You should _always_ pass a time value to Usd.Attribute.Get() (even though technically the argument is optional). The default behavior if you don't specify a time is Usd.TimeCode.Default, which will retrieve the "default" value of the attribute, regardless of any time samples set on the attribute. In your case, you have the focalLength set as a time sample (you can tell by the green color in the scene graph details). So when you query the "default" value, you get the fallback value from the UsdGeomCamera schema definition.
If you actually don't care about the time (you know the value isn't changing with time), use Usd.TimeCode.EarliestTime. This will return the "default" value if there are no time samples set, or the first time sample if there are time samples set. If there is any change that there will be a time-varying value, you should use Usd.TimeCode(hou.frame()), which will return the time sample closest to "now", or the "default" value if there are no time samples. The problem with this expression is that it will introduce a time dependency if the expression is in a node's parameter (because of the use of hou.frame()). So if you want to be really safe, you might want to check if the attribute has any time samples. Use Usd.TimeCode(hou.frame()) if it has more than one time sample, or use Usd.TimeCode.EarliestTime if the attribute has zero or one time samples.
We're looking at putting this bit of attribute fetching logic into a utility python method for the next release of Houdini for convenience, but it's only four or five lines of code.
Edit: @antc beat me to it