Metadata-Version: 2.1
Name: jwt_pydantic
Version: 0.0.6
Summary: Verify JWT claims using the powerful features of Pydantic.
Author: Adam Powis
License: The MIT License (MIT)
        
        Copyright (c) 2022 Adam Powis
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in
        all copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        THE SOFTWARE.
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.8.0
Description-Content-Type: text/markdown
Provides-Extra: test
License-File: LICENSE

# jwt-pydantic

JWT claim sets are becoming more complex and harder to manage. Writing validators for these claims checks is time consuming.

This package uses the power of Pydantic models, to make life a bit easier.

We have also included a Starlette middleware, which can be easily used in FastAPI, as shown [here](#fastapi-middleware).

## Example

Let's say our JWT token has the claims set below:
```python
claims = {
    "firstname": "David",
    "surname": "Bowie",
    "best_album": "Hunky Dory"
}
```

We can use `jwt-pydantic` to simplify the generation and verification of such tokens. First we declare the Pydantic model, by subclassing `JWTPydantic`:

```python
from jwt_pydantic import JWTPydantic

class MyJWT(JWTPydantic):
    firstname: str
    surname: str
    best_album: str
```

To generate a new JWT token, using the claims above, we do the following:

```python
token = MyJWT.new_token(claims=claims, key="SECRET_KEY")
```

We can then verify this token easily as follows
```python
MyJWT.verify_token(token, key="SECRET_KEY")
```

We can also return the decoded JWT token as our Pydantic model, to be used elsewhere:
```python
decoded_jwt = MyJWT(token, key="SECRET_KEY")
print(decoded_jwt.firstname)  # David
```

## FastAPI Middleware

It is also easy to declare a new JWTPydantic model and use this in middleware, as shown below.

```python
# main.py
from fastapi import FastAPI
from jwt_pydantic import JWTPydantic, JWTPydanticMiddleware

SECRET_KEY = "mykey"

class MyJWT(JWTPydantic):
    foo: int

app = FastAPI()
app.add_middleware(
    JWTPydanticMiddleware,
    header_name="jwt",
    jwt_pydantic_model=MyJWT,
    jwt_key=SECRET_KEY,
)

@app.get("/")
def homepage():
    return "Hello world"
```

We can run this code easily using uvicorn (`uvicorn main:app --reload`), and then using python on a different shell, we can test this to show it in action:
```python
import requests
requests.get('http://127.0.0.1:8000/', headers={'jwt': MyJWT.new_token({'foo': 1}, 'mykey')})  # b'Hello World'
```

If we want to change the response when the JWT token is bad, you can override the method in `bad_response` in `JWTPydanticMiddleware`, such as below:

```python
class MyMiddleware(JWTPydanticMiddleware):
    def bad_response(self, token_error: str) -> JSONResponse:
        """Changing standard response to be a JSONResponse"""
        return JSONResponse(
            {"bad_token": token_error}, status_code=403
        )
```

## python-jose keyword arguments

`JWTPydantic` uses [python-jose](https://pypi.org/project/python-jose/) to manage the JWT tokens. The extra features that are provided using this package can be easily used through the keyword argument `jose_opts`. For instance, we can add the 'at_hash' claim to our JWT token by specifying the keyword argument `access_token`.

```python
MyJWT.new_token(
    claims,
    SECRET_KEY,
    jose_opts={"access_token": "1234"},
)
```

