Может получить доступ к частному репозиторию Bitbucket с помощью curl, но не с Python - PullRequest
0 голосов
/ 30 апреля 2020

Я хочу использовать Bitbucket API для получения информации о частном репозитории.

Он отлично работает с curl:

curl -u username:apppassword https://api.bitbucket.org/2.0/repositories/company/repo

Но не с Python (К сожалению, я должен используйте Python 3.4):

    #!/usr/bin/env python3

    from pybitbucket.auth import BasicAuthenticator
    from pybitbucket.bitbucket import Client
    from pybitbucket.repository import Repository
    from pybitbucket.user import User

    client = Client(BasicAuthenticator('username', 'apppassword ', 'usermail'))
    print(User.find_current_user(client).display_name)
    print(Repository.find_repository_by_full_name("company/repo"))

Имя пользователя напечатано правильно. Но Repository.find_repository_by_full_name вызывает 403 (запрещено).

То же самое, когда я пытаюсь сделать это с помощью urllib:

    import urllib.request

    base_url = 'https://api.bitbucket.org/2.0/'
    password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
    password_mgr.add_password(None, base_url, 'username', 'apppassword ')
    handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
    opener = urllib.request.build_opener(handler)

    with opener.open(base_url + 'user') as f:
        print(f.read())

    with opener.open(base_url + 'repositories/company/repo') as f:
        print(f.read())

Аутентификация должна работать, иначе она не сможет вернуть мое имя пользователя правильно. Кроме того, когда я ввожу неправильные учетные данные, я получаю 401 (не авторизованный) вместо 403 (запрещенный). С другой стороны, он прекрасно работает, когда я использую curl.

О, он также не работает с wget:

wget --http-user=username --http-passwd=apppassword https://api.bitbucket.org/2.0/repositories/company/repository

Что делает curl отличным от wget и Python

1 Ответ

0 голосов
/ 30 апреля 2020

API Bitbucket не отвечает с 401 Unauthorized, когда я звоню https://api.bitbucket.org/2.0/repositories/company/repository. Это легко проверить с помощью браузера. Он не запрашивает учетные данные, но показывает Access denied. You must have write or admin access., поэтому аутентификация не выполняется.

Но когда я открываю https://api.bitbucket.org/2.0/user, Bitbucket отвечает 401 Unauthorized и заголовком www-authenticate: Basic realm="Bitbucket.org HTTP", поэтому браузер знает показать диалог аутентификации. Вот почему получение пользовательских данных работает на Python.

. Чтобы решить эту проблему, я должен принудительно отправить аутентификацию, даже если сервер ее не запрашивает. Я не нашел способа сделать это с urllib.request.HTTPBasicAuthHandler, но добавив заголовок Authorization вручную:

    import base64
    import urllib.request

    request = urllib.request.Request('https://api.bitbucket.org/2.0/repositories/company/repository')
    base64string = base64.b64encode('{}:{}'.format('username', 'apppassword').encode('ascii'))
    request.add_header('Authorization', 'Basic {}'.format(base64string.decode('ascii')))

    with urllib.request.urlopen(request) as response:
        print(response.read())
...