Sure the real world is impure, but it doesn’t mean your whole code has to be! The Clean Architecture that reuses most of the principles of the hexagonal architecture recommends to keep your interactions with the real world in the outer layers, on the outskirts of your architecture.
So for the outer layers, you can use some kind of dependency injection, the one @fham suggested is quite simple and elegant, but separating functions that interact with the real world from pure functions is a good practice, to avoid “leaking” the real world everywhere.