简体   繁体   中英

Can someone give a python requests example of uploading a release asset in github?

url = 'https://github.abc.defcom/api/v3/repos/abc/def/releases/401/assets?name=foo.sh'
r = requests.post(url, headers={'Content-Type':'application/binary'}, data=open('sometext.txt','r'), auth=('user','password'))

This is giving me

>>> r.text
u'{"message":"Not Found","documentation_url":"https://developer.github.com/enterprise/2.4/v3"}'

Where am I going wrong?

So I'll preface this with the advice that if you use a library it's as easy as:

from github3 import GitHubEnterprise

gh = GitHubEnterprise(token=my_token)
repository = gh.repository('abc', 'def')
release = repository.release(id=401)
asset = release.upload_asset(content_type='application/binary', name='foo.sh', asset=open('sometext.txt', 'rb'))

With that in mind, I'll also preface this with "application/binary" is not a real media type (see: https://www.iana.org/assignments/media-types/media-types.xhtml )

Next, if you read the documentation , you'll notice that GitHub requires clients that have real SNI (Server Name Indication), so depending on your version of Python, you may also have to install pyOpenSSL , pyasn1 , and ndg-httpsclient from PyPI.

I'm not sure what the URL looks like for enterprise instances, but for public GitHub, it looks like:

https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets?name=foo.sh

So you're going to have that as url , plus you're going to want your auth credentials (in your case you seem to want to use basic auth). Then you're going to want a valid media-type in the headers, eg,

headers = {'Content-Type': 'text/plain'}

And your call would look pretty much exactly correct:

requests.post(url, headers=headers, data=open('file.txt', 'rb'), auth=(username, password))

To get the correct url, you should do:

release = requests.get(release_url, auth=(username, password))
upload_url = release.json().get('upload_url')

Note this is a URITemplate. You'll need to remove the templating or use a library like uritemplate.py to parse it and use it to build your URL for you.

One last reminder, github3.py (the library in the original example) takes care of all of this for you.

APIv3 upload example without any external dependencies

Usage:

GITHUB_TOKEN=<token> ./create-release username/reponame <tag-name> <path-to-upload>

Script:

#!/usr/bin/env python3

import json
import os
import sys

from urllib.parse import urlencode
from urllib.request import Request, urlopen

repo = sys.argv[1]
tag = sys.argv[2]
upload_file = sys.argv[3]

token = os.environ['GITHUB_TOKEN']

url_template = 'https://{}.github.com/repos/' + repo + '/releases'

# Create.
_json = json.loads(urlopen(Request(
    url_template.format('api'),
    json.dumps({
        'tag_name': tag,
        'name': tag,
        'prerelease': True,
    }).encode(),
    headers={
        'Accept': 'application/vnd.github.v3+json',
        'Authorization': 'token ' + token,
    },
)).read().decode())
release_id = _json['id']

# Upload.
with open(upload_file, 'br') as myfile:
    content = myfile.read()
_json = json.loads(urlopen(Request(
    url_template.format('uploads') + '/' + str(release_id) + '/assets?' \
      + urlencode({'name': os.path.split(upload_file)[1]}),
    content,
    headers={
        'Accept': 'application/vnd.github.v3+json',
        'Authorization': 'token ' + token,
        'Content-Type': 'application/zip',
    },
)).read().decode())

Superset question with any language: How to release a build artifact asset on GitHub with a script?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM