4

I have two different software environments (Environment A and Environment B) and I'm trying to run PyJWT on both environments. It is working perfectly fine on one environment Environment A but fail on Environment B.

The error I'm getting on Environment B when I call jwt.encode() with algorithm == ES is: Algorithm not supported.

I'm trying to figure out why it works on Environment A but not Environment B. It seems like the two environments have different versions of PyJWT installed. But determining which version of PyJWT is installed on Environment B is proving difficult for me. How can I do it??

I ran the following instrumented code on both Environment A and Environment B:

import jwt, cryptography, sys, pkg_resources

my_private_key = """XXXXX"""
my_public_key = """YYYYYY"""
original = {"Hello": "World"}
print "sys.version = {}".format(str(sys.version))

try:
    print "dir(jwt) = {}".format(str(dir(jwt)))
except Exception as e:
    print "Failed to get dir of jwt module: {}".format(e)

try:
    print "dir(cryptography) = {}".format(str(dir(cryptography)))
except Exception as e:
    print "Failed to get dir of cryptography module: {}".format(e)

try:
    print "jwt = {}".format(str(jwt.__version__))
except Exception as e:
    print "Failed to get version of jwt module using .__version: {}".format(e)
try:
    print "cryptography = {}".format(str(cryptography.__version__))
except Exception as e:
    print "Failed to get version of cryptography module using .__version: {}".format(e)

try:
    print "pkg_resources.require('jwt')[0].version = {}".format(str(pkg_resources.require("jwt")[0].version))
except Exception as e:
    print "Failed to get version of jwt module via pkg_resources: {}".format(e)

try:
    print "pkg_resources.require('cryptography')[0].version = {}".format(str(pkg_resources.require("cryptography")[0].version))
except Exception as e:
    print "Failed to get version of cryptography module via pkg_resources: {}".format(e)

try:
    print "original = {}".format(str(original))
    encoded = jwt.encode(original, my_private_key, algorithm='ES256')
except Exception as e:
    print "encoding exception = {}".format(str(e))
else:
    try:
        print "encoded = {}".format(str(encoded))
        unencoded = jwt.decode(encoded, my_public_key, algorithms=['ES256'])
    except Exception as e:
        print "decoding exception = {}".format(str(e))
    else:
        print "unencoded = {}".format(str(unencoded))

On Environment A, the encoding succeeds:

sys.version = 2.7.12 (default, Sep  1 2016, 22:14:00)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)]
dir(jwt) = ['DecodeError', 'ExpiredSignature', 'ExpiredSignatureError', 'ImmatureSignatureError', 'InvalidAudience', 'InvalidAudienceError', 'InvalidIssuedAtError', 'InvalidIssuer', 'InvalidIssuerError', 'InvalidTokenError', 'MissingRequiredClaimError', 'PyJWS', 'PyJWT', '__author__', '__builtins__', '__copyright__', '__doc__', '__file__', '__license__', '__name__', '__package__', '__path__', '__title__', '__version__', 'algorithms', 'api_jws', 'api_jwt', 'compat', 'decode', 'encode', 'exceptions', 'get_unverified_header', 'register_algorithm', 'unregister_algorithm', 'utils']
dir(cryptography) = ['__about__', '__all__', '__author__', '__builtins__', '__copyright__', '__doc__', '__email__', '__file__', '__license__', '__name__', '__package__', '__path__', '__summary__', '__title__', '__uri__', '__version__', 'absolute_import', 'division', 'exceptions', 'hazmat', 'print_function', 'sys', 'utils', 'warnings']
jwt = 1.4.2
cryptography = 1.5.2
Failed to get version of jwt module via pkg_resources: jwt
pkg_resources.require('cryptography')[0].version = 1.5.2
original = {'Hello': 'World'}
encoded = eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJIZWxsbyI6IldvcmxkIn0.ciaXCcO2gTqsQ4JUEKj5q4YX6vfHu33XY32g2MNIVEDXHNllpuqDCj-cCrlGPf6hGNifAJbNI9kBaAyuCIwyJQ
unencoded = {u'Hello': u'World'}

On Environment B the the encoding fails. You can see that I cannot tell what version of PyJWT is running. However this version of PyJWT doesn't have the algorithm ES256 that I'm trying to use:

sys.version = 2.7.12 (default, Sep  1 2016, 22:14:00) 
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)]"
dir(jwt) = ['DecodeError', 'ExpiredSignature', 'Mapping', 'PKCS1_v1_5', 'SHA256', 'SHA384', 'SHA512', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'base64', 'base64url_decode', 'base64url_encode', 'binascii', 'constant_time_compare', 'datetime', 'decode', 'encode', 'hashlib', 'header', 'hmac', 'json', 'load', 'signing_methods', 'sys', 'timegm', 'unicode_literals', 'verify_methods', 'verify_signature']
dir(cryptography) = ['__about__', '__all__', '__author__', '__builtins__', '__copyright__', '__doc__', '__email__', '__file__', '__license__', '__name__', '__package__', '__path__', '__summary__', '__title__', '__uri__', '__version__', 'absolute_import', 'division', 'print_function', 'sys', 'warnings']
Failed to get version of jwt module using .__version: 'module' object has no attribute '__version__'
cryptography = 1.5.2
Failed to get version of jwt module via pkg_resources: jwt
pkg_resources.require('cryptography')[0].version = 1.5.2
original = {'Hello': 'World'}
encoding exception = Algorithm not supported
Saqib Ali
  • 11,931
  • 41
  • 133
  • 272

2 Answers2

5

The PyJWT .__version__ attribute appeared in 0.2.2 in this commit.

Generally, to find the version of the package, that was installed via setuptools, you need to run following code:

import pkg_resources
print pkg_resources.require("jwt")[0].version

If pip was used to install the package, you could try from linux shell:

pip show jwt | grep Version

Same thing from inside the python:

import pip
print next(pip.commands.show.search_packages_info(['jwt']))['version']
Dmitry Yantsen
  • 1,145
  • 11
  • 24
  • Do you know why this doesn't work for me here? https://gist.github.com/saqib-zmi/ac3d0f2106b76e729cfb54008995181d – Saqib Ali Oct 23 '16 at 14:47
  • The reason for that is that the package was not installed via *setuptools*. This code lets you determine version only for that case. – Dmitry Yantsen Oct 24 '16 at 05:20
  • Also included in the answer the command to find out version if `pip` was used. – Dmitry Yantsen Oct 24 '16 at 05:22
  • Table, is there a way to show the version of jwt installed by `pip` from within my python code rather than from the Linux command line? – Saqib Ali Oct 24 '16 at 13:03
  • Yeah, you can try `pip` python-binding. `import pip;next(pip.commands.show.search_packages_info(['jwt']))['version']`. Also added in the answer – Dmitry Yantsen Oct 24 '16 at 14:10
  • That's not answer the question, but it's good to know: to get the version of your library/application you can run `python setup.py --version` (with your virtualenv activated). This doesn’t work in your case because `jwt` is a dependancy… – Laurent LAPORTE Oct 26 '16 at 12:07
  • Using the pip one and got the error message "module 'pip' has no attribute 'commands'". – Jie Dec 28 '20 at 20:45
0

I used

print(jwt.__version__)

and that worked perfectly.

Jie
  • 1,107
  • 1
  • 14
  • 18