Control Cycles material nodes and material properties in Python
Here is how to change material properties, you can see all of them here or see the python path when you hover over in the UI on some material attribute:
    import bpy

    # get the material
    mat = bpy.data.materials['Material_Name']
    # change its parameters - example viewport diffuse color:
    mat.diffuse_color = (1,0,0)

Here is how to manipulate material nodes and thus the material look itself:

Get the nodes:
  import bpy

  # get the material
  mat = bpy.data.materials['Material_Name']
  # get the nodes
  mat.use_nodes = True
  nodes = mat.node_tree.nodes

  # get some specific node:
  # returns None if the node does not exist
  diffuse = nodes.get(&quot;Diffuse BSDF&quot;)


Create driver:
  # insert driver to roughness
  driver = diffuse.inputs[1].driver_add(&quot;default_value&quot;)
  var = driver.driver.variables.new()
  var.name = &quot;variable&quot;
  var.targets[0].data_path = &quot;PATH&quot;
  var.targets[0].id = &quot;Target_Object_Name&quot;
  driver.driver.expression = &quot;variable&quot;

  # remove driver
  diffuse.inputs[1].driver_remove(&quot;default_value&quot;)


Keyframes:
  # insert key frame to roughness at frame 10
  diffuse.inputs[1].keyframe_insert(&quot;default_value&quot;, frame=10)


Create nodes, here are all the node types you can create (look for subclasses):
  # remove specific node
  nodes.remove(diffuse)

  # clear all nodes to start clean
  nodes.clear()

  # create emission node
  node_emission = nodes.new(type='ShaderNodeEmission')
  node_emission.inputs[0].default_value = (0,1,0,1)  # green RGBA
  node_emission.inputs[1].default_value = 5.0 # strength
  node_emission.location = 0,0

  # create output node
  node_output = nodes.new(type='ShaderNodeOutputMaterial')   
  node_output.location = 400,0


Link nodes:
  # link nodes
  links = mat.node_tree.links
  link = links.new(node_emission.outputs[0], node_output.inputs[0])

  # get specific link
  from_s = node_emission.outputs[0]
  to_s = node_output.inputs[0]
  link = next((l for l in links if l.from_socket == from_s and l.to_socket == to_s), None)

  # remove links
  links.remove(link)

As before hower over node atributes in UI to see the python paths