Skip to content

Commit a1907c0

Browse files
authored
Update code blocks in docs (jpadilla#545)
Update Python 2 syntax and drop Python-2-only examples. Fix all Python console prompts to the full ">>> " for correct highlighting. Use "pycon" instead of "python" for interactive Python console session. The "python" lexer is for Python scripts and doesn't interpret the ">>>" prompt. Fix all Python console code blocks to more accurately display what the user will see. For example, when assigning a value to a variable, it isn't also echoed. Fix typo ".. code::" → ".. code-block::". Use "console" instead of "sh" for shell sessions. The "sh" lexer is for shell scripts. For a complete list of lexers, see: https://pygments.org/docs/lexers/ Use blacken-docs to run black on code blocks. This is now included as a pre-commit hook.
1 parent e3a1ba5 commit a1907c0

File tree

8 files changed

+82
-95
lines changed

8 files changed

+82
-95
lines changed

.github/ISSUE_TEMPLATE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ What happened instead.
1212

1313
```python
1414
import jwt
15-
1615
```
1716

1817
## System Information

.github/ISSUE_TEMPLATE/Bug.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ What happened instead.
1717

1818
```python
1919
import jwt
20-
2120
```
2221

2322
## System Information

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ repos:
55
- id: black
66
args: ["--target-version=py36"]
77

8+
- repo: https://github.com/asottile/blacken-docs
9+
rev: v1.8.0
10+
hooks:
11+
- id: blacken-docs
12+
args: ["--target-version=py36"]
13+
814
- repo: https://gitlab.com/pycqa/flake8
915
rev: 3.7.9
1016
hooks:

README.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,21 @@ Installing
2929

3030
Install with **pip**:
3131

32-
.. code-block:: sh
32+
.. code-block:: console
3333
3434
$ pip install PyJWT
3535
3636
3737
Usage
3838
-----
3939

40-
.. code:: python
40+
.. code-block:: pycon
4141
4242
>>> import jwt
43-
>>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')
43+
>>> encoded = jwt.encode({"some": "payload"}, "secret", algorithm="HS256")
4444
>>> print(encoded)
4545
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg
46-
47-
>>> jwt.decode(encoded, 'secret', algorithms=['HS256'])
46+
>>> jwt.decode(encoded, "secret", algorithms=["HS256"])
4847
{'some': 'payload'}
4948
5049
Documentation
@@ -58,6 +57,6 @@ Tests
5857

5958
You can run tests from the project root after cloning with:
6059

61-
.. code-block:: sh
60+
.. code-block:: console
6261
6362
$ tox

docs/algorithms.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,20 @@ Specifying an Algorithm
3939
You can specify which algorithm you would like to use to sign the JWT
4040
by using the `algorithm` parameter:
4141

42-
.. code-block:: python
42+
.. code-block:: pycon
4343
44-
>>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS512')
45-
'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.WTzLzFO079PduJiFIyzrOah54YaM8qoxH9fLMQoQhKtw3_fMGjImIOokijDkXVbyfBqhMo2GCNu4w9v7UXvnpA'
44+
>>> encoded = jwt.encode({"some": "payload"}, "secret", algorithm="HS512")
45+
>>> print(encoded)
46+
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.WTzLzFO079PduJiFIyzrOah54YaM8qoxH9fLMQoQhKtw3_fMGjImIOokijDkXVbyfBqhMo2GCNu4w9v7UXvnpA
4647
4748
When decoding, you can also specify which algorithms you would like to permit
4849
when validating the JWT by using the `algorithms` parameter which takes a list
4950
of allowed algorithms:
5051

51-
.. code-block:: python
52+
.. code-block:: pycon
5253
53-
>>> jwt.decode(encoded, 'secret', algorithms=['HS512', 'HS256'])
54-
{u'some': u'payload'}
54+
>>> jwt.decode(encoded, "secret", algorithms=["HS512", "HS256"])
55+
{'some': 'payload'}
5556
5657
In the above case, if the JWT has any value for its alg header other than
5758
HS512 or HS256, the claim will be rejected with an ``InvalidAlgorithmError``.

docs/faq.rst

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,9 @@ extract the public or private keys from a x509 certificate in PEM format.
99

1010
.. code-block:: python
1111
12-
# Python 2
1312
from cryptography.x509 import load_pem_x509_certificate
1413
15-
cert_str = "-----BEGIN CERTIFICATE-----MIIDETCCAfm..."
16-
cert_obj = load_pem_x509_certificate(cert_str)
17-
public_key = cert_obj.public_key()
18-
private_key = cert_obj.private_key()
19-
20-
.. code-block:: python
21-
22-
# Python 3
23-
from cryptography.x509 import load_pem_x509_certificate
24-
25-
cert_str = "-----BEGIN CERTIFICATE-----MIIDETCCAfm...".encode()
14+
cert_str = b"-----BEGIN CERTIFICATE-----MIIDETCCAfm..."
2615
cert_obj = load_pem_x509_certificate(cert_str)
2716
public_key = cert_obj.public_key()
2817
private_key = cert_obj.private_key()

docs/index.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ Example Usage
3030
.. doctest::
3131

3232
>>> import jwt
33-
34-
>>> encoded_jwt = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')
33+
>>> encoded_jwt = jwt.encode({"some": "payload"}, "secret", algorithm="HS256")
3534
>>> print(encoded_jwt)
3635
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg
37-
38-
>>> jwt.decode(encoded_jwt, 'secret', algorithms=['HS256'])
36+
>>> jwt.decode(encoded_jwt, "secret", algorithms=["HS256"])
3937
{'some': 'payload'}
4038

4139
See :doc:`Usage Examples <usage>` for more examples.

docs/usage.rst

Lines changed: 61 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ Usage Examples
44
Encoding & Decoding Tokens with HS256
55
-------------------------------------
66

7-
.. code-block:: python
8-
9-
>>import jwt
10-
>>key = 'secret'
11-
>>encoded = jwt.encode({'some': 'payload'}, key, algorithm='HS256')
12-
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg'
13-
>>decoded = jwt.decode(encoded, key, algorithms='HS256')
7+
.. code-block:: pycon
8+
9+
>>> import jwt
10+
>>> key = "secret"
11+
>>> encoded = jwt.encode({"some": "payload"}, key, algorithm="HS256")
12+
>>> print(encoded)
13+
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg
14+
>>> jwt.decode(encoded, key, algorithms="HS256")
1415
{'some': 'payload'}
1516
1617
Encoding & Decoding Tokens with RS256 (RSA)
1718
-------------------------------------------
1819

19-
.. code-block:: python
20+
.. code-block:: pycon
2021
21-
>>import jwt
22-
>>private_key = b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBS...'
23-
>>public_key = b'-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEAC...'
24-
>>encoded = jwt.encode({'some': 'payload'}, private_key, algorithm='RS256')
25-
'eyJhbGciOiJIU...'
26-
>>decoded = jwt.decode(encoded, public_key, algorithms=['RS256'])
22+
>>> import jwt
23+
>>> private_key = b"-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBS..."
24+
>>> public_key = b"-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEAC..."
25+
>>> encoded = jwt.encode({"some": "payload"}, private_key, algorithm="RS256")
26+
>>> print(encoded)
27+
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg
28+
>>> decoded = jwt.decode(encoded, public_key, algorithms=["RS256"])
2729
{'some': 'payload'}
2830
2931
If your private key needs a passphrase, you need to pass in a ``PrivateKey`` object from ``cryptography``.
@@ -33,20 +35,21 @@ If your private key needs a passphrase, you need to pass in a ``PrivateKey`` obj
3335
from cryptography.hazmat.primitives import serialization
3436
from cryptography.hazmat.backends import default_backend
3537
36-
pem_bytes = b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBS...'
37-
passphrase = b'your password'
38+
pem_bytes = b"-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBS..."
39+
passphrase = b"your password"
3840
3941
private_key = serialization.load_pem_private_key(
40-
pem_bytes, password=passphrase, backend=default_backend())
41-
encoded = jwt.encode({'some': 'payload'}, private_key, algorithm='RS256')
42+
pem_bytes, password=passphrase, backend=default_backend()
43+
)
44+
encoded = jwt.encode({"some": "payload"}, private_key, algorithm="RS256")
4245
4346
4447
Specifying Additional Headers
4548
-----------------------------
4649

47-
.. code-block:: python
50+
.. code-block:: pycon
4851
49-
>>jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256', headers={'kid': '230498151c214b788dd97f22b85410a5'})
52+
>>> jwt.encode({"some": "payload"}, "secret", algorithm="HS256", headers={"kid": "230498151c214b788dd97f22b85410a5"})
5053
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjIzMDQ5ODE1MWMyMTRiNzg4ZGQ5N2YyMmI4NTQxMGE1In0.eyJzb21lIjoicGF5bG9hZCJ9.DogbDGmMHgA_bU05TAB-R6geQ2nMU2BRM-LnYEtefwg'
5154
5255
@@ -61,10 +64,10 @@ Note: It is generally ill-advised to use this functionality unless you
6164
clearly understand what you are doing. Without digital signature information,
6265
the integrity or authenticity of the claimset cannot be trusted.
6366

64-
.. code-block:: python
67+
.. code-block:: pycon
6568
66-
>>jwt.decode(encoded, options={"verify_signature": False})
67-
{u'some': u'payload'}
69+
>>> jwt.decode(encoded, options={"verify_signature": False})
70+
{'some': 'payload'}
6871
6972
Reading Headers without Validation
7073
----------------------------------
@@ -75,10 +78,10 @@ way of knowing in advance which one of the issuer's public keys or shared
7578
secrets to use for validation, the issuer may include an identifier for the
7679
key in the header.
7780

78-
.. code-block:: python
81+
.. code-block:: pycon
7982
80-
>>jwt.get_unverified_header(encoded)
81-
{u'alg': u'RS256', u'typ': u'JWT', u'kid': u'key-id-12345...'}
83+
>>> jwt.get_unverified_header(encoded)
84+
{'alg': 'RS256', 'typ': 'JWT', 'kid': 'key-id-12345...'}
8285
8386
Registered Claim Names
8487
----------------------
@@ -108,18 +111,19 @@ datetime, which will be converted into an int. For example:
108111

109112
.. code-block:: python
110113
111-
jwt.encode({'exp': 1371720939}, 'secret')
112-
jwt.encode({'exp': datetime.utcnow()}, 'secret')
114+
jwt.encode({"exp": 1371720939}, "secret")
115+
jwt.encode({"exp": datetime.utcnow()}, "secret")
113116
114117
Expiration time is automatically verified in `jwt.decode()` and raises
115118
`jwt.ExpiredSignatureError` if the expiration time is in the past:
116119

117120
.. code-block:: python
118121
119122
try:
120-
jwt.decode('JWT_STRING', 'secret', algorithms=['HS256'])
123+
jwt.decode("JWT_STRING", "secret", algorithms=["HS256"])
121124
except jwt.ExpiredSignatureError:
122125
# Signature has expired
126+
...
123127
124128
Expiration time will be compared to the current UTC time (as given by
125129
`timegm(datetime.utcnow().utctimetuple())`), so be sure to use a UTC timestamp
@@ -135,22 +139,24 @@ you can set a leeway of 10 seconds in order to have some margin:
135139

136140
.. code-block:: python
137141
138-
jwt_payload = jwt.encode({
139-
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=30)
140-
}, 'secret')
142+
jwt_payload = jwt.encode(
143+
{"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=30)}, "secret"
144+
)
141145
142146
time.sleep(32)
143147
144148
# JWT payload is now expired
145149
# But with some leeway, it will still validate
146-
jwt.decode(jwt_payload, 'secret', leeway=10, algorithms=['HS256'])
150+
jwt.decode(jwt_payload, "secret", leeway=10, algorithms=["HS256"])
147151
148152
Instead of specifying the leeway as a number of seconds, a `datetime.timedelta`
149153
instance can be used. The last line in the example above is equivalent to:
150154

151155
.. code-block:: python
152156
153-
jwt.decode(jwt_payload, 'secret', leeway=datetime.timedelta(seconds=10), algorithms=['HS256'])
157+
jwt.decode(
158+
jwt_payload, "secret", leeway=datetime.timedelta(seconds=10), algorithms=["HS256"]
159+
)
154160
155161
Not Before Time Claim (nbf)
156162
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -167,8 +173,8 @@ The `nbf` claim works similarly to the `exp` claim above.
167173

168174
.. code-block:: python
169175
170-
jwt.encode({'nbf': 1371720939}, 'secret')
171-
jwt.encode({'nbf': datetime.utcnow()}, 'secret')
176+
jwt.encode({"nbf": 1371720939}, "secret")
177+
jwt.encode({"nbf": datetime.utcnow()}, "secret")
172178
173179
Issuer Claim (iss)
174180
~~~~~~~~~~~~~~~~~~
@@ -180,13 +186,10 @@ Issuer Claim (iss)
180186

181187
.. code-block:: python
182188
183-
payload = {
184-
'some': 'payload',
185-
'iss': 'urn:foo'
186-
}
189+
payload = {"some": "payload", "iss": "urn:foo"}
187190
188-
token = jwt.encode(payload, 'secret')
189-
decoded = jwt.decode(token, 'secret', issuer='urn:foo', algorithms=['HS256'])
191+
token = jwt.encode(payload, "secret")
192+
decoded = jwt.decode(token, "secret", issuer="urn:foo", algorithms=["HS256"])
190193
191194
If the issuer claim is incorrect, `jwt.InvalidIssuerError` will be raised.
192195

@@ -205,39 +208,32 @@ sensitive strings, each containing a StringOrURI value.
205208

206209
.. code-block:: python
207210
208-
payload = {
209-
'some': 'payload',
210-
'aud': ['urn:foo', 'urn:bar']
211-
}
211+
payload = {"some": "payload", "aud": ["urn:foo", "urn:bar"]}
212212
213-
token = jwt.encode(payload, 'secret')
214-
decoded = jwt.decode(token, 'secret', audience='urn:foo', algorithms=['HS256'])
213+
token = jwt.encode(payload, "secret")
214+
decoded = jwt.decode(token, "secret", audience="urn:foo", algorithms=["HS256"])
215215
216216
In the special case when the JWT has one audience, the "aud" value MAY be
217217
a single case-sensitive string containing a StringOrURI value.
218218

219219
.. code-block:: python
220220
221-
payload = {
222-
'some': 'payload',
223-
'aud': 'urn:foo'
224-
}
221+
payload = {"some": "payload", "aud": "urn:foo"}
225222
226-
token = jwt.encode(payload, 'secret')
227-
decoded = jwt.decode(token, 'secret', audience='urn:foo', algorithms=['HS256'])
223+
token = jwt.encode(payload, "secret")
224+
decoded = jwt.decode(token, "secret", audience="urn:foo", algorithms=["HS256"])
228225
229226
If multiple audiences are accepted, the ``audience`` parameter for
230227
``jwt.decode`` can also be an iterable
231228

232229
.. code-block:: python
233230
234-
payload = {
235-
'some': 'payload',
236-
'aud': 'urn:foo'
237-
}
231+
payload = {"some": "payload", "aud": "urn:foo"}
238232
239-
token = jwt.encode(payload, 'secret')
240-
decoded = jwt.decode(token, 'secret', audience=['urn:foo', 'urn:bar'], algorithms=['HS256'])
233+
token = jwt.encode(payload, "secret")
234+
decoded = jwt.decode(
235+
token, "secret", audience=["urn:foo", "urn:bar"], algorithms=["HS256"]
236+
)
241237
242238
The interpretation of audience values is generally application specific.
243239
Use of this claim is OPTIONAL.
@@ -255,15 +251,15 @@ Issued At Claim (iat)
255251

256252
.. code-block:: python
257253
258-
jwt.encode({'iat': 1371720939}, 'secret')
259-
jwt.encode({'iat': datetime.utcnow()}, 'secret')
254+
jwt.encode({"iat": 1371720939}, "secret")
255+
jwt.encode({"iat": datetime.utcnow()}, "secret")
260256
261257
Requiring Presence of Claims
262258
----------------------------
263259

264260
If you wish to require one or more claims to be present in the claimset, you can set the ``require`` paramenter to include these claims.
265261

266-
.. code-block:: python
262+
.. code-block:: pycon
267263
268-
>>jwt.decode(encoded, options={'require': ['exp', 'iss', 'sub']})
269-
{u'exp': 1371720939, u'iss': u'urn:foo', u'sub': u'25c37522-f148-4cbf-8ee6-c4a9718dd0af'}
264+
>>> jwt.decode(encoded, options={"require": ["exp", "iss", "sub"]})
265+
{'exp': 1371720939, 'iss': 'urn:foo', 'sub': '25c37522-f148-4cbf-8ee6-c4a9718dd0af'}

0 commit comments

Comments
 (0)