The Shapely library is commonly used for geometric operations in Python, alternatively you could use GDAL's ogr.
Fixing invalid polygons is hard because there really is no way of knowing how the polygon is supposed to be like. One common approach is using .buffer(0) to try to make it valid somehow.
The Shapely documentation includes an example for all this: https://shapely.readthedocs.io/en/stable/manual.html#object.buffer
>>> coords = [(0, 0), (0, 2), (1, 1), (2, 2), (2, 0), (1, 1), (0, 0)]
>>> bowtie = Polygon(coords)
>>> clean = bowtie.buffer(0)
Now it is "valid" but it might be something very different from what you would expect. Make sure you inspect your geometries afterwards.
A manual approach will almost always be more safe and better.