The Shapely library is commonly used for geometric operations in Python, alternatively you could use GDAL's ogr.
https://pypi.org/project/Shapely/
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)
>>> bowtie.is_valid
False
>>> clean = bowtie.buffer(0)
>>> clean.is_valid
True
A manual approach will almost always be more safe and better.