Confused about signing JWT

I’m currently trying to understand the Pubsub API, specifically how I can send messages to it from my EBS. However after a long time of trying I still can’t send any request that doesn’t result in an authenthication failure. For testing purposes I am just trying to request my extension secret from the command line using curl. I hope somebody can help me figure out why this won’t generate valid JWTs.

Here is the Python script I use to generate the JWT:

import jwt;
import time;
import math;
import base64;

payload = {
        'exp': math.floor(time.time())+(60*60),
        'user_id': 61960862,
        'role' : 'external'
};

secret = base64.decodebytes(b'my_secret');
result = jwt.encode(payload,secret, algorithm = 'HS256');
print(result);

my_secret is the secret I get from the secret keys section of my extension’s settings.
jwt is a library called pyjwt

I then try to send my request using the following command:

    curl -H 'Authorization: Bearer '`python generateJWT.py` \
        -H 'Client-Id: extension_client_id'  \
        -X GET https://api.twitch.tv/extensions/extension_client_id/auth/secret

extension_client_id represents the client ID from the overview page of my extension

As a response I get {“error”:“Unauthorized”,“status”:401,“message”:"{“code”:401,“status”:“authentication failed”}\n"}

I’m assuming that I’m getting this response because I’m somehow signing my JWT wrong but I’m at wit’s end as to why that is.

You need to cast user_id to a string

payload = {
    'exp': math.floor(time.time())+(60*60),
    'user_id': str(61960862),
    'role' : 'external'
};

Should work for python

Thank you for your help, you were certainly right. There was also an issue with my script where it printed the JWT in byte format (b’token’). For future reference I solved this by decoding the result in utf-8.
(result = result.decode(“utf-8”)). Just in case anyone stumbles upon this with a similar problem.