Path following via API
Some tweaks.
Took out the remove all objects, not a fan.
Use object references. After using an operator to add the cube
cube = context.object

after creating the curve obj it is known by reference as obj, no need to look it up as &quot;Path&quot;.
When parenting via the operator, the selected objects are parented to the active. Have set the curve as active
context.view_layer.objects.active = obj

and selected the cube
cube.select_set(True)

before parenting via the operator.
Animate by setting an path duration (start to finish)  in frames on the curve object, and keyframing or driving the evaluation time.
See Creating path curve using python script  re using the end points of a nurbs curve
import bpy
context = bpy.context

# Clearing scene
# IMO never add this to a question script.
'''
for item in bpy.data.objects:
    bpy.data.objects.remove(item)
'''
# Simulation Parameters
coords = [[0,0,0],[ 0,5,0], [0,0,15],[15,0,15], [0,0,20]]

bpy.ops.mesh.primitive_cube_add(location=coords[0])
cube = context.object 
# making curve
crv = bpy.data.curves.new('crv', 'CURVE')
crv.dimensions = '3D'

# Animate the eval time (keyframes)
crv.path_duration = 250
crv.eval_time = 0
crv.keyframe_insert(&quot;eval_time&quot;, frame=1)
crv.eval_time = 10
crv.keyframe_insert(&quot;eval_time&quot;, frame=100)
crv.eval_time = 250
crv.keyframe_insert(&quot;eval_time&quot;, frame=250)
# initialize spline
spline = crv.splines.new(type='NURBS')
spline.use_endpoint_u = True
spline.use_endpoint_v = True
# a spline for each point
spline.points.add(len(coords)-1) # 1 point by default

# assign the point coordinates to the spline points
for p, new_co in zip(spline.points, coords):
    p.co = (new_co + [1.0]) # (add nurbs weight)
    
# make a new object with the curve
obj = bpy.data.objects.new('Path', crv)
context.scene.collection.objects.link(obj)
obj.select_set(True)
context.view_layer.objects.active = obj
cube.select_set(True)
#cube.parent = bpy.context.scene.objects['Path'] 
bpy.ops.object.parent_set(type='FOLLOW')

'''
cube.constraints.new('FOLLOW_PATH')  #Constraining cubesat to follow the path 
cube.constraints['Follow Path'].target = obj
cube.constraints[&quot;Follow Path&quot;].forward_axis = 'FORWARD_X'
cube.constraints[&quot;Follow Path&quot;].use_curve_follow = True
'''

Fixed Position.
Generally a user of fixed position and no follow path parenting. As shown in answer here https://blender.stackexchange.com/a/169719/15543  With fixed position can keyframe or drive the offset, such that 0 is start of curve, and 1 is other end.