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

client: default server URL is used instead of the configured one #722

Open
mdonadoni opened this issue Jul 18, 2024 · 1 comment
Open

client: default server URL is used instead of the configured one #722

mdonadoni opened this issue Jul 18, 2024 · 1 comment

Comments

@mdonadoni
Copy link
Member

mdonadoni commented Jul 18, 2024

Reported by @rubenperezm

Consider this example publish on our blog: https://blog.reana.io/posts/2021/reana-client-python-api/

import os

if not os.getenv('REANA_SERVER_URL'):
    os.environ['REANA_SERVER_URL'] = 'https://reana.cern.ch'

# ...

from reana_client.api.client import ping

ping(my_reana_token)

However, if the REANA_SERVER_URL env variable is set after importing reana-client (or reana-commons), then the first request is always made to the default URL http://0.0.0.0:80:

import os
from reana_client.api.client import ping

os.environ['REANA_SERVER_URL'] = 'https://reana.cern.ch'
my_reana_token = 'API_KEY' # My API KEY

print(os.getenv('REANA_SERVER_URL')) # https://reana.cern.ch
print(ping(my_reana_token)) # {'status': 'ERROR: INVALID SERVER', 'error': True}
print(os.getenv('REANA_SERVER_URL')) # https://reana.cern.ch
print(ping(my_reana_token)) # {..., 'status': 'Connected', 'error': False}

The issue is due to the fact that the env variable is loaded after the bravado client has been created (source):

### default value is read here ###
        server_url, spec_file = OPENAPI_SPECS[service]  
        json_spec = self._get_spec(spec_file)
        current_instance = BaseAPIClient._bravado_client_instance
        # We reinstantiate the bravado client instance if
        # 1. The current instance doesn't exist, or
        # 2. We're passing an http client (likely a mock), or
        # 3. The current instance is a Mock, meaning that either we want to
        #    use the `RequestClient` or we're passing a different mock.
        if (
            current_instance is None
            or http_client
            or isinstance(current_instance.swagger_spec.http_client, Mock)
        ):
            BaseAPIClient._bravado_client_instance = SwaggerClient.from_spec(
                json_spec,
                http_client=http_client or RequestsClient(ssl_verify=False),
                config={"also_return_response": True},
            )
### custom value is read after creating the client ###
        self._load_config_from_env() 

PS: let's also check the usage of LocalProxy here, because the get_current_api_client is called anyway on each API call:

current_rs_api_client = LocalProxy(
partial(get_current_api_client, component="reana-server")
)

@mdonadoni mdonadoni changed the title c client: default server URL is used instead of the configured one Jul 18, 2024
@mdonadoni mdonadoni added this to 0.95.0 Aug 8, 2024
@mdonadoni mdonadoni moved this to Ready for work in 0.95.0 Aug 8, 2024
@mdonadoni
Copy link
Member Author

Note that LocalProxy is probably not doing what we think it should do, in particular it's NOT keeping one instance per thread, but it's instead recreating the client on each call

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Ready for work
Development

No branches or pull requests

1 participant