Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module 'motuclient' has no attribute 'motu_api' #35

Open
colinemathias opened this issue Jan 15, 2024 · 1 comment
Open

module 'motuclient' has no attribute 'motu_api' #35

colinemathias opened this issue Jan 15, 2024 · 1 comment

Comments

@colinemathias
Copy link

Hello,

I'm trying to extract data from Copernicus Marine Data Store with motuclient (python 3.11.7 powered by Anaconda, motuclient 3.0.0). My code used to run correctly in the past, but now I have the error:

File \\creo17-0069\0069_d\travail\coline_mathias\codes\class_copernicus.py:398 in send_request
    motuclient.motu_api.execute_request(MotuOptions(list_requests[i_f]))

AttributeError: module 'motuclient' has no attribute 'motu_api'

I can't see what I changed between the moment it could run and the moment it did not work anymore.
When I check in the file "motuclient.py", motuclient should have a motu_api attribute... My guess would be that the initialisation with load_options is not done correctly ?

I did try to uninstall/reinstall motuclient, with pip and removing cache before reinstalling.
I tried also to uninstall and reinstall anaconda.

Is this a problem with motuclient or something exterior ?

Below is the code in which I call motuclient.motu_api :

class MotuOptions:
    """
    class to parse the motuclient options from a dictionary
    """
    def __init__(self, attrs: dict):
        super(MotuOptions, self).__setattr__("attrs", attrs)

    def __setattr__(self, k, v):
        self.attrs[k] = v

    def __getattr__(self, k):
        try:
            return self.attrs[k]
        except KeyError:
            return None

def motu_option_parser(script_template, usr, pwd, output_filename, output_directory):
    """
    Post-process script_template to create a dictionary & return this
    dictionary to send data request.
    """
    dictionary = dict(
        [e.strip().partition(" ")[::2] for e in script_template.split('--')])
    dictionary['variable'] = [value for (var, value) in [e.strip().partition(" ")[::2] for e in script_template.split('--')] if var == 'variable']  # pylint: disable=line-too-long
    for k, v in list(dictionary.items()):
        if v == '<OUTPUT_DIRECTORY>':
            dictionary[k] = output_directory
        if v == '<OUTPUT_FILENAME>':
            dictionary[k] = output_filename
        if v == '<USERNAME>':
            dictionary[k] = usr
        if v == '<PASSWORD>':
            dictionary[k] = pwd
        if k in ['longitude-min', 'longitude-max', 'latitude-min',
                 'latitude-max', 'depth-min', 'depth-max']:
            dictionary[k] = float(v)
        if k in ['date-min', 'date-max']:
            dictionary[k] = v[1:-1]
        dictionary[k.replace('-','_')] = dictionary.pop(k)
    dictionary.pop('python')
    dictionary['auth_mode'] = 'cas'
    return dictionary


# define parameters for request
script_template = f'python -m motuclient \
                    --motu https://my.cmems-du.eu/motu-web/Motu \
                    --service-id {service}-TDS \
                    --product-id {products[i_prod]} \
                    --longitude-min {area[1]} \
                    --longitude-max {area[3]} \
                    --latitude-min {area[2]} \
                    --latitude-max {area[0]} \
                    --date-min "{datemin}" \
                    --date-max "{datemax}" \
                    {template_elev}  {template_var} \
                    --out-dir <OUTPUT_DIRECTORY> --out-name <OUTPUT_FILENAME> \
                    --user <USERNAME> --pwd <PASSWORD>'

data_request_options_dict_automated = motu_option_parser(script_template, username, password,
                                                         OUTPUT_FILENAME, folder)


# launch request
motuclient.motu_api.execute_request(MotuOptions(data_request_options_dict_automated))

@jamesohrussell
Copy link

Not the developers but it seems like the MOTU server may have been taken offline. Having a similar problem where my scripts ran fine just a couple of months ago but I came back to run the same script (with no changes) and now I'm getting errors indicating motuclient cannot access the server:

---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
[<ipython-input-6-4437b974b059>](https://localhost:8080/#) in <cell line: 23>()
     21 
     22 # Data download
---> 23 motuclient.motu_api.execute_request(MotuOptions(data_request_options_dict_manual))
     24 
     25 # Open dataset

7 frames
[/usr/local/lib/python3.10/dist-packages/motu_utils/motu_api.py](https://localhost:8080/#) in execute_request(_options)
    568             stopWatch.start('authentication')
    569             # perform authentication before acceding service
--> 570             download_url = utils_cas.authenticate_CAS_for_URL(url,
    571                                                               _options.user,
    572                                                               _options.pwd, **url_config)

[/usr/local/lib/python3.10/dist-packages/motu_utils/utils_cas.py](https://localhost:8080/#) in authenticate_CAS_for_URL(url, user, pwd, **url_config)
     68     log.info( 'Authenticating user %s for service %s' % (user,server) )
     69 
---> 70     connexion = utils_http.open_url(url, **url_config)
     71 
     72     # connexion response code must be a redirection, else, there's an error (user can't be already connected since no cookie or ticket was sent)

[/usr/local/lib/python3.10/dist-packages/motu_utils/utils_http.py](https://localhost:8080/#) in open_url(url, **kargsParam)
    172 
    173     # open the url, but let the exception propagates to the caller
--> 174     return _opener.open(r)
    175 
    176 def encode(options):

[/usr/lib/python3.10/urllib/request.py](https://localhost:8080/#) in open(self, fullurl, data, timeout)
    523         for processor in self.process_response.get(protocol, []):
    524             meth = getattr(processor, meth_name)
--> 525             response = meth(req, response)
    526 
    527         return response

[/usr/local/lib/python3.10/dist-packages/motu_utils/utils_http.py](https://localhost:8080/#) in https_response(self, request, response)
     88         code, msg, hdrs = response.code, response.msg, response.info()
     89         if code >= 300:
---> 90             response = self.parent.error('http', request, response, code, msg, hdrs)
     91         return response
     92 

[/usr/lib/python3.10/urllib/request.py](https://localhost:8080/#) in error(self, proto, *args)
    561         if http_err:
    562             args = (dict, 'default', 'http_error_default') + orig_args
--> 563             return self._call_chain(*args)
    564 
    565 # XXX probably also want an abstract factory that knows when it makes

[/usr/lib/python3.10/urllib/request.py](https://localhost:8080/#) in _call_chain(self, chain, kind, meth_name, *args)
    494         for handler in handlers:
    495             func = getattr(handler, meth_name)
--> 496             result = func(*args)
    497             if result is not None:
    498                 return result

[/usr/lib/python3.10/urllib/request.py](https://localhost:8080/#) in http_error_default(self, req, fp, code, msg, hdrs)
    641 class HTTPDefaultErrorHandler(BaseHandler):
    642     def http_error_default(self, req, fp, code, msg, hdrs):
--> 643         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    644 
    645 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 503: Service Unavailable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants