Is there an easy way to set the speed in units like km/h for an object travelling along a path?
I think I finally have a working solution:

    import bpy, mathutils
from mathutils import Vector

le = 0

#Speed in m/s
targetSpeed = 10
obj_name_original = bpy.context.active_object.name

def getLenght():
    ob = bpy.context.active_object        
    if ob and ob.select and ob.type == 'CURVE':  

        em = (ob.mode == 'EDIT')
        bpy.ops.object.duplicate_move()            
        bpy.ops.object.mode_set()
        bpy.ops.object.transform_apply(scale=True)                                  
        bpy.ops.object.convert(target='MESH', keep_original=False)
        ve = bpy.context.active_object.data.vertices
        global le
        dd = le = 0
        for i in bpy.context.active_object.data.edges:
            dd = ve[i.vertices[0]].co - ve[i.vertices[1]].co
            le += dd.length
        le = round(le,4)
        bpy.ops.object.delete()
        print(le)
        if em: bpy.ops.object.mode_set(mode='EDIT', toggle=False)

        global obj_name_original
        bpy.context.scene.objects.active = bpy.context.scene.objects[obj_name_original]
        bpy.context.object.select = True

    else:
        raise Exception("The selected object is not a curve")


targetC = 0

def findC():
    global obj_name_original
    for ob in bpy.data.objects:
        if ob and ob.type == 'MESH':
            for c in ob.constraints:
                if c.target.name == obj_name_original:
                    global targetC
                    targetC = c
                    #print(c)

def setO(scene):
    global targetSpeed
    global targetC
    global le #scene.render.fps    ((le/targetSpeed))*(scene.frame_current/(scene.frame_end*targetSpeed))
    targetC.offset_factor = scene.frame_current/((le/targetSpeed)*scene.render.fps)

getLenght()
findC()

def register():
    bpy.app.handlers.frame_change_pre.append(setO)


def unregister():
    bpy.app.handlers.frame_change_pre.remove(bpy.app.handlers.frame_change_pre[-1])


if __name__ == "__main__":
    register()


The way it works is that it approximates the length of the curve, and then changes the offset of the object following it every frame - essentially animating it. It does require that you select the curve before running the script, otherwise, it will purposely crash.

If you want to use km/h instead of m/s you just need to divide the speed by 3.6, which will convert it to m/s.