Using a custom shape as bevel object I discover blender and python API for blender. I would like to create celtics works with blender using python (for cnc works). I found a way to create a sine curve and use a Bezier circle as the profile to extrude it, but what I would like is to use a rectangular shape.
Here is where I am:

And here is what I would like to have (I modified the profile manually):

Do you have any advices for me : Bezier vs NURBE, how to add a rectangular shape as bevel shape ...
Here is my code:
import bpy
import math
from bpy import context, data, ops

R = 1 # bevel radius

curve = bpy.data.curves.new('sinepath', type='CURVE')
curve.dimensions = '3D'
curve.resolution_u = 1
spline = curve.splines.new('NURBS')

for x in range(0, 1440):
    y = 20* math.sin(float(math.radians(x)))
    if ((x+90)//180)%2 == 1:
        z = 0.5 * abs(math.sin(float(math.radians(x -90))))
    else:
        z = -0.5 * abs(math.sin(float(math.radians(x -90))))
    # Add first point for start of Nurbs (needs extra point)
    if x == 0:
        spline.points[0].co = (x/(2*math.pi), y, z, 1)

    # Add point
    spline.points.add(1)
    spline.points[-1].co = (x/(2*math.pi), y,z,1)
    print (&quot;x: &quot; + str(x) + &quot; y: &quot; + str(y) + &quot; z: &quot; + str(z))
# Add end point
spline.points.add(1)
spline.points[-1].co = (x/(2*math.pi), y, 0, 1)

curveObject = bpy.data.objects.new('sinepath', curve)
bpy.context.scene.collection.objects.link(curveObject)
bpy.ops.curve.primitive_bezier_circle_add(radius=R, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

cross_section = bpy.context.active_object
curveObject.data.bevel_object = cross_section
curveObject.data.use_fill_caps = True 
curveObject.data.bevel_mode = 'OBJECT'

curve2 = bpy.data.curves.new('sinepath', type='CURVE')
curve2.dimensions = '3D'
curve2.resolution_u = 1
spline2 = curve.splines.new('NURBS')

for x in range(0, 1440):
    y = -20* math.sin(float(math.radians(x)))
    if ((x+90)//180)%2 == 1:
        z = -0.5 * abs(math.sin(float(math.radians(x -90))))
    else:
        z = 0.5 * abs(math.sin(float(math.radians(x -90))))
    # Add first point for start of Nurbs (needs extra point)
    if x == 0:
        spline2.points[0].co = (x/(2*math.pi), y, z, 1)

    # Add point
    spline2.points.add(1)
    spline2.points[-1].co = (x/(2*math.pi), y,z,1)
    print (&quot;x: &quot; + str(x) + &quot; y: &quot; + str(y) + &quot; z: &quot; + str(z))
# Add end point
spline2.points.add(1)
spline2.points[-1].co = (x/(2*math.pi), y, 0, 1)

curveObject = bpy.data.objects.new('sinepath', curve)
bpy.context.scene.collection.objects.link(curveObject)

curveObject.data.bevel_object = cross_section
curveObject.data.use_fill_caps = True 
curveObject.data.bevel_mode = 'OBJECT'
Found a solution here:
Possible to add a plane using vertices via Python?
just add this line:
bpy.ops.object.convert(target='CURVE', keep_original= False)
return myobject