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

Example doesn't work as expected #46

Open
zaufi opened this issue Oct 10, 2016 · 11 comments
Open

Example doesn't work as expected #46

zaufi opened this issue Oct 10, 2016 · 11 comments

Comments

@zaufi
Copy link
Contributor

zaufi commented Oct 10, 2016

I'm trying to use this module using the following trivial code (taken from examples):

#!/usr/bin/env python3
import artifactory
path = artifactory.ArtifactoryPath('https://mycompany.artifactoryonline.com/mycompany/some-repo')
for p in path:
    print(p)

Note, we use JFrog Artifactory as a SaaS. Without any config file (i.e. ~/.artifactory_python.cfg) it gives me the following error:

Traceback (most recent call last):
File "./a.py", line 7, in <module>
    for p in path:
File "/work/GitHub/artifactory/artifactory.py", line 990, in __iter__
    for name in self._accessor.listdir(self):
File "/work/GitHub/artifactory/artifactory.py", line 546, in listdir
    stat = self.stat(pathobj)
File "/work/GitHub/artifactory/artifactory.py", line 492, in stat
    jsn = self.get_stat_json(pathobj)
File "/work/GitHub/artifactory/artifactory.py", line 467, in get_stat_json
    cert=pathobj.cert)
File "/work/GitHub/artifactory/artifactory.py", line 415, in rest_get
    cert=cert)
File "/usr/lib64/python3.5/site-packages/requests/api.py", line 70, in get
    return request('get', url, params=params, **kwargs)
File "/usr/lib64/python3.5/site-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
File "/usr/lib64/python3.5/site-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
File "/usr/lib64/python3.5/site-packages/requests/sessions.py", line 590, in send
    adapter = self.get_adapter(url=request.url)
File "/usr/lib64/python3.5/site-packages/requests/sessions.py", line 672, in get_adapter
    raise InvalidSchema("No connection adapters were found for '%s'" % url)
requests.exceptions.InvalidSchema: No connection adapters were found for '/api/storage/https:/mycompany.artifactoryonline.com/mycompany/some-repo'

If I'm going to add the config file:

[https://mycompany.artifactoryonline.com/mycompany/]
username = myuser
password = mypass
verify = false

it throws another error:

Traceback (most recent call last):
File "./a.py", line 7, in <module>
    for p in path:
File "/work/GitHub/artifactory/artifactory.py", line 990, in __iter__
    for name in self._accessor.listdir(self):
File "/work/GitHub/artifactory/artifactory.py", line 546, in listdir
    stat = self.stat(pathobj)
File "/work/GitHub/artifactory/artifactory.py", line 492, in stat
    jsn = self.get_stat_json(pathobj)
File "/work/GitHub/artifactory/artifactory.py", line 464, in get_stat_json
    str(pathobj.relative_to(pathobj.drive)).strip('/')])
File "/work/GitHub/artifactory/artifactory.py", line 929, in relative_to
    obj = super(ArtifactoryPath, self).relative_to(*other)
File "/usr/lib64/python3.5/pathlib.py", line 864, in relative_to
    .format(str(self), str(formatted)))
ValueError: 'https://mycompany.artifactoryonline.com/mycompany/some-repo/' does not start with 'https:/mycompany.artifactoryonline.com/mycompany'

I would really appreciate if someone point me on my mistake, but actually I think it is a bug…

PS. As one may notice, I'm using Python 3.5, with pathlib builtin.

@sldenazis
Copy link

Hello, I have the same issue here, I'm working with the SaaS solution (https://$mycompany.jfrog.io/..).

Thanks!

@rbtcollins
Copy link

Same, just started looking into Python API clients for artifactory :(

@sweetib
Copy link

sweetib commented Jun 29, 2017

I am also facing the same issue.

@thaney071
Copy link

thaney071 commented Aug 30, 2017

I was looking to use this library for work also, but am seeing this same issue. Looks to me like the library is not parsing the path given to ArtifactoryPath function correctly. When I look at the error output, I can see '/api/storage' is placed at the start of the url call. It needs to be placed between the Artifactory server url and the remaining path in Artifactory to search.

Looking into how this library is getting the base URI, that seems to be why it is not working, atleast for me.

def splitroot(self, part, sep=sep):
        """
        Splits path string into drive, root and relative path
        Uses '/artifactory/' as a splitting point in URI. Everything
        before it, including '/artifactory/' itself is treated as drive.
        The next folder is treated as root, and everything else is taken
        for relative path.

Using /artifactory/ as a splitting point doesn't work in all cases since you don't know what the server's URI is going to be. This is assuming information about how Artifactory was set up. If your Artifactory server URI does not contain /artifactory/ at the end of the URI this library does not work. The example in this case fails to mention the path http://repo.jfrog.org/artifactory/gradle-ivy-local works because the library is using the /artifactory/ as a split point when inserting API calls for the generated URL.

@thaney071
Copy link

I did some more digging around. Looks like support for custom base URIs was added, but only when using the config file. This work was done in commit 2f1656a.

The README needs to be updated to tell users about this functionality of the config file.

@al4
Copy link

al4 commented Sep 4, 2017

I have just spent an hour trying to figure this out, we also use the SaaS version. Thank you @thaney071 for pointing to that commit!

For anyone else who comes across this issue and doesn't want to rely on a .artifactory_python.cfg file being in the user's home directory, you can set the configuration manually like so:

import artifactory

artifactory.global_config = {
    'https://my_company.jfrog.io/my_artifactory': {
        'username': None,
        'verify': True,
        'cert': None,
        'password': None
    }
}

artifactory skips reading the config if it is set in advance.

Obviously this is implementation-dependant, so make sure you fix your dependency to the version of artifactory (artifactory==0.1.17 currently).

A slightly more robust solution is to set the config path (in my case a file the script's directory), and call the read method:

from os import path
import artifactory

artifactory.default_config_path = path.abspath(
    path.join(path.dirname(__file__), '.artifactory_python.cfg')
)
artifactory.read_global_config(artifactory.default_config_path)

But I just went with setting artifactory.global_config in the end.

@alainchiasson
Copy link

@al4 : You mention "so make sure you fix your dependency to the version of artifactory" - is there a place to find this information ?

@al4
Copy link

al4 commented Jan 29, 2018

@alainchiasson I was referring to the python package version, so the place to find it would be: https://pypi.python.org/pypi/artifactory

To clarify, the solution relies on an implementation detail of the artifactory package, thus to avoid a future version breaking it, you should ensure you always use a version that you've tested with. Usually this would be done by putting artifactory==0.1.17 (or whatever version you tested) in a requirements.txt file, or as a dependency in setup.py.

If your code isn't in a python package or you don't fix the version, and a future version of artifactory breaks this solution (e.g. by renaming or refactoring artifactory.global_config), the only way would be to manually ensure you pip install a version for which this fix applies (e.g. pip install artifactory==0.1.17).

It's not in any way essential, but it does guarantee that a future release of artifactory won't break your build. http://blog.danlew.net/2015/09/09/dont-use-dynamic-versions-for-your-dependencies/ is a good read on the subject.

@alainchiasson
Copy link

Thanks for the followup.

As for myself - adding /artifactory/ made it work !! Maybe I missed what the endpoint definition is - our url is : http://artifacts.company.com/ and I had been trying (as described in the setup block) http://artifacts.company.com/jenkin-plugin/ and it was not working (giving the above error). Changing it to http://artifacts.company.com/artifactory/jenkin-plugin/ made it work.

@rsgoud
Copy link

rsgoud commented Aug 2, 2018

Hi I am newbie to python, I am trying to find out where is this file "artifactory_python.cfg" located in windows machine , will this file auto created when i do pip install or do i have to manually create this file at a specific location on my windows machine so that python can automatically use it.

Any answers are much appreciated , I have a requirement to upload binaries to artifactory using python scripts.

@al4
Copy link

al4 commented Aug 29, 2018

@rsgoud you will have to manually create .artifactory_python.cfg (note leading dot). I think it would look for this file in %UserProfile% on windows (assuming artifactory uses os.expanduser or a cross-platform method of obtaining the user's home directory).

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

8 participants