What's the most reliable way of converting a material into reusable code blocks?
Make a dummy material with each node type of material.
Following on from the suggestion in comments by @MarkusvonBroady  couldn't resist....  Am waiting to see the excellent material serialization answer from you know who,
Pretty much zip the material node / inputs / outputs etc against a newly added default of same type,  and add to string buffer when not same. Have ignored any read only property and select.
Code and test Run.
import bpy
from math import isclose

LUT = dict()
BLACK = [0.0, 0.0, 0.0, 1.0]
WHITE = [1.0, 1.0, 1.0, 1.0]
ul = f'#{&quot;-&quot; * 44}\n'
buffer = []


def cmp(v1, v2):
    return (
        (len(v1) == len(v2))
        and all(isclose(*v) for v in zip(v1, v2))
    )


def vformat(nums, n, indent=8):
    nums = [f&quot;{d}&quot; for d in nums]
    return f&quot;,\n{' ' * indent}&quot;.join([&quot;, &quot;.join(nums[i: i + n]) for i in range(0, len(nums), n)])


def fes(collection, prop, data, size, indent):
    output(
        f'{&quot; &quot; * indent}{collection}.foreach_set(\n'
        f'       &quot;{prop}&quot;, [\n'
        f'        {vformat(data, size, 8 + indent)}\n'
        f'        ])'
    )


def groups_in_tree(node_tree):
    for node in node_tree.nodes:
        if hasattr(node, &quot;node_tree&quot;):
            yield node.node_tree
            yield from groups_in_tree(node.node_tree)


def group_io(n):
    output(f'node = nodes.new(&quot;{n.bl_rna.identifier}&quot;)')
    output(f'node.name = &quot;{n.name}&quot;')
    sockets = (&quot;inputs&quot;, &quot;outputs&quot;) if n.type == 'GROUP_INPUT' else (&quot;outputs&quot;, &quot;inputs&quot;)
    for skt in getattr(n, sockets[1]):
        if skt.type != 'CUSTOM' and skt.name:
            output(
                f&quot;skt = group.{sockets[0]}.new('{skt.__class__.__name__}', &quot;
                f'&quot;{skt.name}&quot;, '
                f')'
            )
            output(f'skt.name = &quot;{skt.name}&quot;')
            dv = skt.default_value
            val = dv[:] if hasattr(dv, &quot;foreach_get&quot;) else dv
            output(f&quot;skt.default_value = {val}&quot;)
    output()


def colorramp(a, b):
    n = len(a.elements)
    output(f'ramp = node.color_ramp')
    compare(a, b, fstring=&quot;ramp.{k} = {va}&quot;)
    locs, deflocs = [0.0] * n, [0.0, 1.0]
    cols, defcols = [0.0] * (n &lt;&lt; 2), BLACK + WHITE
    a.elements.foreach_get(&quot;position&quot;, locs), a.elements.foreach_get(&quot;color&quot;, cols)
    n = n - 2
    if n:
        output(
            f&quot;for i in range({n}):\n&quot;
            f&quot;    ramp.elements.new(0.0)&quot;
        )

    if not cmp(locs, deflocs):
        fes(&quot;ramp.elements&quot;, &quot;position&quot;, locs, 1, 0)

    if not cmp(cols, defcols):
        fes(f'ramp.elements', &quot;color&quot;, cols, 4, 0)


def mapping(a, b):
    output(f'map = node.mapping')
    compare(a, b, fstring=&quot;map.{k} = {va}&quot;)

    for i, c in enumerate(a.curves):
        n = len(c.points)
        pts, default = [0, 0] * n, [-1.0, -1.0, 1.0, 1.0]
        n -= 2
        if n:
            output(
                f'for i in range({n}):\n'
                f'    map.curves[{i}].points.new(0.0, 1.0)\n'
            )

        c.points.foreach_get(&quot;location&quot;, pts)
        if not cmp(pts, default):
            fes(f&quot;map.curves[{i}].points&quot;, &quot;location&quot;, pts, 2, 0)


def output(*args):
    s = &quot; &quot;.join(args) if args else &quot;&quot;
    buffer.append(s)


def compare(a, b, fstring=&quot;{k} = {va}&quot;, sockets=&quot;&quot;, i=0, ignore={'select'}):

    props = (
            (k, v)
        for k, v in a.bl_rna.properties.items()
        if (not v.is_readonly or k in (&quot;mapping&quot;, &quot;color_ramp&quot;))
        and k not in ignore
    )

    for k, v in props:
        va = getattr(a, k)
        vb = getattr(b, k, None)

        if v.type in ('FLOAT', 'INT'):
            if v.is_array:
                if not isinstance(va, float):
                    va = va[:]
                if vb and not isinstance(vb, float):
                    vb = vb[:]

        if va != vb:
            if v.type == 'ENUM':
                va = f&quot;'{va}'&quot;
            elif v.type == 'STRING':
                va = f'&quot;{va}&quot;'
            elif v.type == 'POINTER':
                if k == &quot;parent&quot;:
                    va = f'nodes.get(&quot;{va.name}&quot;)'
                elif a.type == 'GROUP':
                    return output(f'node.node_tree = groups.get(&quot;{a.node_tree.name}&quot;)')
                elif issubclass(v.fixed_type.__class__, bpy.types.ID):
                    va = repr(va).replace(f&quot;['{va.name}']&quot;, f'.get(&quot;{va.name}&quot;)')
                elif k == &quot;mapping&quot;:
                    return mapping(va, vb)
                elif k.startswith(&quot;color_ramp&quot;):
                    return colorramp(va, vb)
            name = f'&quot;{a.name}&quot;' if hasattr(a, &quot;name&quot;) else i
            output(fstring.format(**locals()))


def pnode(n, dummy):
    if n.type in ('GROUP_INPUT', 'GROUP_OUTPUT'):
        return group_io(n)
    nodetype = n.bl_rna.identifier
    default = LUT.setdefault(
        nodetype, dummy.nodes.new(nodetype)
    )

    output(f'node = nodes.new(&quot;{nodetype}&quot;)')
    compare(n, default, fstring=&quot;node.{k} = {va}&quot;)
    for sockets in (&quot;inputs&quot;, &quot;outputs&quot;):
        for i, (a, b) in enumerate(
                zip(
                    getattr(n, sockets),
                    getattr(default, sockets),
                )
        ):

            compare(a, b, fstring='node.{sockets}[{name}].{k} = {va}', i=i, sockets=sockets)
    output()


def material_to_text(m):
    try:
        dummy = bpy.data.node_groups.get(&quot;DUMMY&quot;)
        if not dummy:
            output(&quot;import bpy&quot;)
            dummy = bpy.data.node_groups.new(&quot;DUMMY&quot;, &quot;ShaderNodeTree&quot;)
            output(&quot;groups = {}  # for node groups&quot;)

        if hasattr(m, &quot;use_nodes&quot;):
            # material
            for gn in set(groups_in_tree(m.node_tree)):
                material_to_text(gn)
            nt = m.node_tree
            output(
                f&quot;\n&quot;
                f&quot;{ul}#  Material: {m.name} \n{ul}\n&quot;
                f'mat = bpy.data.materials.new(&quot;{m.name}&quot;)\n'
                f&quot;mat.use_nodes = True\n&quot;
                f&quot;node_tree = mat.node_tree\n&quot;
                f&quot;nodes = node_tree.nodes\n&quot;
                f&quot;nodes.clear()\n&quot;
                f&quot;links = node_tree.links\n&quot;
            )

        else:
            # group
            nt = m
            output(
                f&quot;\n&quot;
                f&quot;{ul}#  NodeGroup: {m.name} \n{ul}\n&quot;
                f'group = bpy.data.node_groups.new(&quot;{m.name}&quot;, &quot;{m.bl_rna.identifier}&quot;)\n'
                f'groups[&quot;{m.name}&quot;] = group\n'
                f&quot;nodes = group.nodes\n&quot;
                f&quot;links = group.links\n&quot;
            )

        for n in sorted(
            nt.nodes,
            key=lambda n: [n.location.x, n.location.y]
        ):
            pnode(n, dummy)
        if nt.links:
            output(&quot;#Links\n&quot;)
        for l in nt.links:
            output(
                f&quot;links.new(\n&quot;
                f'    nodes[&quot;{l.from_node.name}&quot;].outputs[&quot;{l.from_socket.name}&quot;],\n'
                f'    nodes[&quot;{l.to_node.name}&quot;].inputs[&quot;{l.to_socket.name}&quot;]\n    )\n'
            )

    except Exception as e:
        print(&quot;There has been an ERROR&quot;)
        print(e, e.__traceback__.tb_lineno)
        return False  # failure

    if hasattr(m, &quot;use_nodes&quot;):
        bpy.data.node_groups.remove(dummy)
    return True  # success


if __name__ == &quot;__main__&quot;:
    m = bpy.context.object.active_material
    material_to_text(m)

    text = bpy.data.texts.new(m.name)
    text.write(&quot;\n&quot;.join(buffer))

Test Run on default &quot;Material&quot; with base color set to Red.  AFAICT Generates the material in test file linked Ok.
import bpy
groups = {}  # for node groups

#--------------------------------------------
#  Material: Material 
#--------------------------------------------

mat = bpy.data.materials.new(&quot;Material&quot;)
mat.use_nodes = True
node_tree = mat.node_tree
nodes = node_tree.nodes
nodes.clear()
links = node_tree.links

node = nodes.new(&quot;ShaderNodeBsdfPrincipled&quot;)
node.location = (10.0, 300.0)
node.inputs[&quot;Base Color&quot;].default_value = (1.0, 0.0, 0.0, 1.0)

node = nodes.new(&quot;ShaderNodeOutputMaterial&quot;)
node.location = (300.0, 300.0)

#Links

links.new(
    nodes[&quot;Principled BSDF&quot;].outputs[&quot;BSDF&quot;],
    nodes[&quot;Material Output&quot;].inputs[&quot;Surface&quot;]
    )

Revision
Unlike Madonna and @Gorgeous not so much of a &quot;Material Guy&quot;.  TBH I'm a sub-feather-weight when it comes to blenders materials and nodes, so this was a nice little excersize for me.
Ultimately the idea, as I see it,  is to be able to copy a material via a script in one blend, and re-create it in another.
Default Values.
Have kept the verbosity down a bit by not outputting default values. Could turn this off with a flag.  Since non-default values are determined from a newly instanced copy they will be non-default at time of creation. As noted if the defaults change, will need to run script again.
Node Groups
Prior handled a  group node by simply pointing the node tree  to its bpy.data.node_groups item. Instead this version makes a copy of each node group used in the material. Was a very easy step, since nodes of both is a collection of nodes. To make sure the new group is used in the generated material by means of  a dictionary groups  to associate new with old name
groups = {}  # for node groups

#--------------------------------------------
#  NodeGroup: NodeGroup.001 
#--------------------------------------------

group = bpy.data.node_groups.new(&quot;NodeGroup.001&quot;, &quot;ShaderNodeTree&quot;)
groups[&quot;NodeGroup.001&quot;] = group

could turn this on or off to use existing node groups.
Curves and Ramps.
Wired it up to generate mapping and colorramp nodes.  Used foreach_set which enables to add an arbitrary point for each extra (over default) and set from a list.
Color Ramp
node = nodes.new(&quot;ShaderNodeValToRGB&quot;)
node.location = (-345.2741394042969, 142.6455841064453)
node.parent = nodes.get(&quot;Frame&quot;)
ramp = node.color_ramp
for i in range(4):
    ramp.elements.new(0.0)
ramp.elements.foreach_set(
       &quot;position&quot;, [
        0.0,
        0.25,
        0.45396339893341064,
        0.6530487537384033,
        0.7999999523162842,
        1.0
        ])
ramp.elements.foreach_set(
       &quot;color&quot;, [
        0.0, 0.0, 0.0, 1.0,
        0.41859403252601624, 0.000635193195194006, 0.0, 1.0,
        0.0, 0.006493096239864826, 0.21146051585674286, 1.0,
        0.14895662665367126, 0.17292265594005585, 0.2819954454898834, 1.0,
        0.5389295816421509, 0.18324723839759827, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0
        ])

RGB Curve
node = nodes.new(&quot;ShaderNodeRGBCurve&quot;)
node.location = (211.58743286132812, 275.4912414550781)
node.parent = nodes.get(&quot;Frame&quot;)
map = node.mapping
map.tone = 'FILMLIKE'
map.clip_max_x = 0.8999999761581421
for i in range(5):
    map.curves[0].points.new(0.0, 1.0)

map.curves[0].points.foreach_set(
       &quot;location&quot;, [
        0.0, 0.0,
        0.15146341919898987, 0.4256756901741028,
        0.24731720983982086, 0.7837838530540466,
        0.4675609767436981, 0.5506754517555237,
        0.5421952605247498, 0.8445945978164673,
        0.6585365533828735, 0.5608108639717102,
        1.0, 1.0
        ])
for i in range(2):
    map.curves[1].points.new(0.0, 1.0)

map.curves[1].points.foreach_set(
       &quot;location&quot;, [
        0.0, 0.0,
        0.3512195348739624, 0.6621621251106262,
        0.5926830172538757, 0.3581080138683319,
        1.0, 1.0
        ])
for i in range(3):
    map.curves[2].points.new(0.0, 1.0)

map.curves[2].points.foreach_set(
       &quot;location&quot;, [
        0.0, 0.0,
        0.16463413834571838, 0.581081211566925,
        0.5004880428314209, 0.5777024626731873,
        0.7858536243438721, 0.28378361463546753,
        1.0, 1.0
        ])
for i in range(1):
    map.curves[3].points.new(0.0, 1.0)

map.curves[3].points.foreach_set(
       &quot;location&quot;, [
        0.0, 0.0,
        0.6782926321029663, 0.4425675868988037,
        1.0, 1.0
        ])

Frames
Added  the frames and set as parents to respective nodes, haven't wired up re the location changing, as demonstrated by @Gorgeous.