Not sure this is still helpful, but I had the very same problem, I was trying to load pyESN by doing:
!git clone https://github.com/cknd/pyESN.git
!cp /content/pyESN/pyESN.py .
from pyESN import ESN
And I got the very same
ModuleNotFoundError: No module named 'pyESN'
I loaded pyESN on google drive, mounted the drive and followed the methods above, same result.
Eventually I restarted the Runtime, and now it seems to be working. In particular if I do:
import pyESN
help(pyESN)
I get:
Help on module pyESN:
NAME
    pyESN
CLASSES
    builtins.object
        ESN
    
    class ESN(builtins.object)
     |  ESN(n_inputs, n_outputs, n_reservoir=200, spectral_radius=0.95, sparsity=0, noise=0.001, input_shift=None, input_scaling=None, teacher_forcing=True, feedback_scaling=None, teacher_scaling=None, teacher_shift=None, out_activation=<function identity at 0x7f16e6596b00>, inverse_out_activation=<function identity at 0x7f16e6596b00>, random_state=None, silent=True)
     |  
     |  Methods defined here:
     |  
     |  __init__(self, n_inputs, n_outputs, n_reservoir=200, spectral_radius=0.95, sparsity=0, noise=0.001, input_shift=None, input_scaling=None, teacher_forcing=True, feedback_scaling=None, teacher_scaling=None, teacher_shift=None, out_activation=<function identity at 0x7f16e6596b00>, inverse_out_activation=<function identity at 0x7f16e6596b00>, random_state=None, silent=True)
     |      Args:
     |          n_inputs: nr of input dimensions
     |          n_outputs: nr of output dimensions
     |          n_reservoir: nr of reservoir neurons
     |          spectral_radius: spectral radius of the recurrent weight matrix
     |          sparsity: proportion of recurrent weights set to zero
     |          noise: noise added to each neuron (regularization)
     |          input_shift: scalar or vector of length n_inputs to add to each
     |                      input dimension before feeding it to the network.
     |          input_scaling: scalar or vector of length n_inputs to multiply
     |                      with each input dimension before feeding it to the netw.
     |          teacher_forcing: if True, feed the target back into output units
     |          teacher_scaling: factor applied to the target signal
     |          teacher_shift: additive term applied to the target signal
     |          out_activation: output activation function (applied to the readout)
     |          inverse_out_activation: inverse of the output activation function
     |          random_state: positive integer seed, np.rand.RandomState object,
     |                        or None to use numpy's builting RandomState.
     |          silent: supress messages
     |  
     |  fit(self, inputs, outputs, inspect=False)
     |      Collect the network's reaction to training data, train readout weights.
     |      
     |      Args:
     |          inputs: array of dimensions (N_training_samples x n_inputs)
     |          outputs: array of dimension (N_training_samples x n_outputs)
     |          inspect: show a visualisation of the collected reservoir states
     |      
     |      Returns:
     |          the network's output on the training data, using the trained weights
     |  
     |  initweights(self)
     |  
     |  predict(self, inputs, continuation=True)
     |      Apply the learned weights to the network's reactions to new input.
     |      
     |      Args:
     |          inputs: array of dimensions (N_test_samples x n_inputs)
     |          continuation: if True, start the network from the last training state
     |      
     |      Returns:
     |          Array of output activations
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |  
     |  __dict__
     |      dictionary for instance variables (if defined)
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
FUNCTIONS
    correct_dimensions(s, targetlength)
        checks the dimensionality of some numeric argument s, broadcasts it
           to the specified length if possible.
        
        Args:
            s: None, scalar or 1D array
            targetlength: expected length of s
        
        Returns:
            None if s is None, else numpy vector of length targetlength
    
    identity(x)
FILE
    /content/pyESN.py
Notice the
FILE
    /content/pyESN.py
at the end, which to me means that my method eventually worked.
I have no idea how reproducible this solution is, but it really sound just a problem with Google Colab