Gradient of a function in Python
Several options:


You can use the defintion of the derivative to have an approximation....

def f(x):
    return x[0]**2 + 3*x[1]**3

def der(f, x, der_index=[]):
    # der_index: variable w.r.t. get gradient

    epsilon = 2.34E-10
    grads = []

   for idx in der_index:
       x_ = x.copy()
       x_[idx]+=epsilon

       grads.append((f(x_) - f(x))/epsilon)

   return grads

print(der(f, np.array([1.,1.]), der_index=[0, 1]))

If you can solve it analytically, it is better you write the derivative function by yourself
You can also use symbolic programming, like in Matlab, with the library sympy https://towardsdatascience.com/taking-derivatives-in-python-d6229ba72c64
Another way to do it is going for the "differentiable programming" paradigm or "software 2.0"