2

I have a program that will auto create a Github issue via the API. It works in Python 2.7, but when I run it with Python 3 I get the following error:

Traceback (most recent call last):
  File "/home/baal/bin/python/zeus-scanner/var/auto_issue/github.py", line 92, in request_issue_creation
    urllib2.urlopen(req, timeout=10).read()
  File "/usr/lib/python3.5/urllib/request.py", line 163, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.5/urllib/request.py", line 464, in open
    req = meth(req)
  File "/usr/lib/python3.5/urllib/request.py", line 1183, in do_request_
    raise TypeError(msg)
TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.

I have the following method that creates a github issue (successful in python 2 unsuccessful in python 3):

def request_issue_creation():
    logger.info(set_color(
        "Zeus got an unexpected error and will automatically create an issue for this error, please wait..."
    ))

    def __extract_stacktrace(file_data):
        logger.info(set_color(
            "extracting traceback from log file..."
        ))
        retval, buff_mode, _buffer = [], False, ""
        with open(file_data, "r+") as log:
            for line in log:
                if "Traceback" in line:
                    buff_mode = True
                if line and len(line) < 5:
                    buff_mode = False
                    retval.append(_buffer)
                    _buffer = ""
                if buff_mode:
                    if len(line) > 400:
                        line = line[:400] + "...\n"
                    _buffer += line
        return "".join(retval)

    logger.info(set_color(
        "getting authorization..."
    ))

    encoded = __get_encoded_string()
    n = get_decode_num(encoded)
    token = decode(n, encoded)

    current_log_file = get_latest_log_file(CURRENT_LOG_FILE_PATH)
    stacktrace = __extract_stacktrace(current_log_file)
    issue_title = stacktrace.split("\n")[-2]

    issue_data = {
        "title": issue_title,
        "body": "Error info:\n```{}````\n\n"
                "Running details:\n`{}`\n\n"
                "Commands used:\n`{}`\n\n"
                "Log file info:\n```{}```".format(
                     str(stacktrace),
                     str(platform.platform()),
                     " ".join(sys.argv),
                     open(current_log_file).read()
                ),
    }

    try:
        req = urllib2.Request(
            url="https://api.github.com/repos/<API-REPO>/issues", data=json.dumps(issue_data),
            headers={"Authorization": "token {}".format(token)}
        )
        urllib2.urlopen(req, timeout=10).read()
        logger.info(set_color(
            "issue has been created successfully with the following name '{}'...".format(issue_title)
        ))
    except Exception as e:
        logger.exception(set_color(
            "failed to auto create the issue, got exception '{}', "
            "you may manually create an issue...".format(e), level=50
        ))

I read online that encoding the string to utf-8 will fix the issue, however I'm not sure if that is possible here? Any help would be greatly appreciated, thank you.

1 Answer 1

4

You need to encode your JSON payload:

data = json.dumps(issue_data)
if sys.version_info > (3,):  # Python 3
    data = data.encode('utf8')

req = urllib2.Request(
    url="https://api.github.com/repos/<API-REPO>/issues", data=data,
    headers={"Authorization": "token {}".format(token),
             "Content-Type": "application/json; charset=utf-8"}
)

I added a Content-Type header with a charset parameter to communicate the codec used to the server. This is not always needed, JSON's default codec is UTF-8. If you don't specify the header, a (wrong) default would be supplied; it depends on the server whether or not that matters.

Sign up to request clarification or add additional context in comments.

1 Comment

@wahwahwah: that should be enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.