Authentication, JWT, and permission scoping for Sanic

Overview

Sanic JWT

Latest PyPI version Python versions Version status MIT License

Build Status Documentation Codacy Badge Test Coverage Code style: black

Sanic JWT adds authentication protection and endpoints to Sanic.

It is both easy to get up and running, and extensible for the developer. It can act to protect endpoints and also provide authentication scoping, all wrapped into a nice JWT.

Read the documentation | View the source code


What do I do?

It's easy: (1) install, (2) initialize, and (3) authenticate.

Install:

pip install sanic-jwt

Initialize:

from sanic import Sanic
from sanic_jwt import Initialize

def my_authenticate(request, *args, **kwargs):
    ...

app = Sanic()
Initialize(
    app,
    authenticate=my_authenticate
)

Authenticate:

http://localhost/auth

Can I customize it?

Definitely! Sanic JWT is made to allow developers to customize the operation to fit their needs. Check out the documentation to learn how.

Comments
  • is_authenticated raises unauthorized

    is_authenticated raises unauthorized

    Hi! I've noticed that is_authenticated raises unauthorized instead of returning False To me, is_authenticated will be useful before check the payload and retrieve the user giving the fact that extract_payload also raises 400 when the call is anonymous

    am I correct or misunderstanding something?

    enhancement opinions welcome 
    opened by Garito 29
  • Overhaul initialization and configuration

    Overhaul initialization and configuration

    Goal

    Stabilize the package to be able to call it a stable v 1.0 release.

    Approach

    This PR encompasses a number of changes that will allow the developer both greater simplicity to get up and running and greater flexibility to customize for specific use cases.

    In doing so, Sanic JWT is migrating away from the initialize method towards a class based Initialize.

    While I am striving to maintain backwards compatibility as much as possible (for example, initialize is now a wrapper around the new class), there may be some things that break from older versions.

    Target Release Date

    March 1, 2018

    New Features

    • As discussed, there will be a new implementation with Initialize
    • Settings can be configured via the new Configuration class
    • All responses for all endpoints can be extendable and interchangeable

    Example

    This can still be installed very easily on a simple setup:

    from sanic_jwt import Initialize
    
    Initialize(app, authenticate=my_authenticate_method, url_prefix='/myjwt')
    

    Or, you can customize by subclassing:

    from sanic_jwt import Authentication, Configuration, Initialize, Response
    
    class MyAuthentication(Authentication):
        async def build_payload(self, *args, **kwargs):
            payload = super().build_payload(*args, **kwargs)
            payload.update({'foo': 'bar'})
            return payload
    
    class MyConfig(Configuration):
        access_token_name = 'custom-token'
        url_prefix = '/myjwt'
    
    class MyResponse(Response):
        @staticmethod
        def extend_authenticate(request,
                                user=None,
                                access_token=None,
                                refresh_token=None):
            return {'foo': 'bar'}
    
    class MyInitialize(Initialize):
        authentication_class = MyAuthentication
        configuration_class = MyConfig
        response_class = MyResponse
    
    MyInitialize(
        app,
        authenticate=lambda: True,
    )
    
    opened by ahopkins 29
  • Access User Detail in protected routes

    Access User Detail in protected routes

    Is there a way to inject user in protected routes? Something like this?

    @auth_bp.post("delete_account")
    @protected()
    async def delete_account(request):
        email = request['user]['email'] #access user details from request object
        logger.info("Deleting Account for {}".format(email))
        resp = auth_service.delete_account(email)
        return resp
    
    enhancement opinions welcome 
    opened by jaymalik217 26
  • Check init methods for awaitable

    Check init methods for awaitable

    Should run a check to make sure the following methods if implemented are awaitable:

    store_refresh_token retrieve_user retrieve_refresh_token authenticate

    bug enhancement warning documentation 
    opened by ahopkins 24
  • retrieve_user not async?

    retrieve_user not async?

    Hi! Is this error:

    2017-11-03 02:13:53 - (sanic)[ERROR]: Exception occurred while handling uri: "http://localhost:8000/auth/me"
    Traceback (most recent call last):
      File "/Users/garito/Lab/sanic/testRestAPI2/env/lib/python3.6/site-packages/sanic/app.py", line 503, in handle_request
        response = await response
      File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/coroutines.py", line 109, in __next__
        return self.gen.send(None)
      File "/Users/garito/Lab/sanic/testRestAPI2/env/lib/python3.6/site-packages/sanic_jwt/blueprint.py", line 80, in retrieve_user
        me = user.to_dict() if hasattr(user, 'to_dict') else dict(user)
    AssertionError: yield from wasn't used with future
    

    because retrieve_user can't be a coroutine? (async def retrieve_user)

    Thanks!

    opened by Garito 24
  • "Mixed" auth methods - headers and cookies

    Reading the docs and code, I saw that SANIC_JWT_COOKIE_SET is indeed a switch between using a cookie or a http header to authorize the request. Since I would like to use the same endpoint for browsers (that can use cookies) and other consumers (that doesn't use cookies, like a simple cURL call), is there a way to accomplish this "mixed" behavior? I can help with PRs, if needed.

    enhancement 
    opened by vltr 23
  • Async OPTIONS function not being awaited

    Async OPTIONS function not being awaited

    Hi. I have the following error:

    <CoroWrapper Tester.options() running at test.py:18, created at /fidessa/uatutils/Tools/Delivery/.pyenv/versions/3.6.4/lib/python3.6/asyncio/coroutines.py:85> was never yielded from
    Coroutine object created at (most recent call last, truncated to 10 last lines):
      File "/fidessa/uatutils/Tools/Delivery/main_venv/UGUI_UAT-480w8wdy/lib/python3.6/site-packages/sanic/server.py", line 609, in serve
        loop.run_forever()
      File "/fidessa/uatutils/Tools/Delivery/.pyenv/versions/3.6.4/lib/python3.6/asyncio/coroutines.py", line 126, in send
        return self.gen.send(value)
      File "/fidessa/uatutils/Tools/Delivery/main_venv/UGUI_UAT-480w8wdy/lib/python3.6/site-packages/sanic/app.py", line 556, in handle_request
        response = await response
      File "/fidessa/uatutils/Tools/Delivery/.pyenv/versions/3.6.4/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
        return self.gen.send(None)
      File "/fidessa/uatutils/Tools/Delivery/main_venv/UGUI_UAT-480w8wdy/lib/python3.6/site-packages/sanic_jwt/decorators.py", line 42, in decorated_function
        return await utils.call(f, request, *args, **kwargs)
      File "/fidessa/uatutils/Tools/Delivery/.pyenv/versions/3.6.4/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
        return self.gen.send(None)
      File "/fidessa/uatutils/Tools/Delivery/main_venv/UGUI_UAT-480w8wdy/lib/python3.6/site-packages/sanic_jwt/utils.py", line 44, in call
        fn = fn(*args, **kwargs)
      File "/fidessa/uatutils/Tools/Delivery/main_venv/UGUI_UAT-480w8wdy/lib/python3.6/site-packages/sanic/views.py", line 63, in view
        return self.dispatch_request(*args, **kwargs)
      File "/fidessa/uatutils/Tools/Delivery/main_venv/UGUI_UAT-480w8wdy/lib/python3.6/site-packages/sanic/views.py", line 46, in dispatch_request
        return handler(request, *args, **kwargs)
      File "/fidessa/uatutils/Tools/Delivery/.pyenv/versions/3.6.4/lib/python3.6/asyncio/coroutines.py", line 85, in debug_wrapper
        return CoroWrapper(gen, None)
    /fidessa/uatutils/Tools/Delivery/.pyenv/versions/3.6.4/lib/python3.6/asyncio/coroutines.py:126: RuntimeWarning: coroutine 'Tester.options' was never awaited
      return self.gen.send(value)
    

    I ran into this issue in my application and was also able to reproduce it with the following code:

    from sanic_cors.core import ALL_METHODS
    from sanic.views import HTTPMethodView
    from sanic.response import text
    from sanic_jwt import Authentication, initialize, protected
    from sanic import Sanic, Blueprint
    
    
    class TestMethodView(HTTPMethodView):
        async def options(self, *args, **kwargs):
            return text('ok')
    
    class Tester(TestMethodView):
        decorators = [protected()]
    
        async def get(self, request):
            return text('ok')
    
    bp = Blueprint('bp')
    bp.add_route(Tester.as_view(), '/test', methods=ALL_METHODS)
    
    
    class CustomAuth(Authentication):
        async def authenticate(self, request, *args, **kwargs):
            return {'username': 'Rich', 'password': 'not secure'}
    
        async def retrieve_user(self, request, payload, *args, **kwargs):
            if payload:
                user_id = payload.get('username', None)
                passwd = payload.get('password', None)
                return {'username': user_id, 'password': passwd}
    
        async def extend_payload(self, payload, user=None, *args, **kwargs):
            if user:
                payload.update({'extra_info': 'awesome!'})
            return payload
    
    
    def make_app():
        app = Sanic(__name__)
        app.config.SANIC_JWT_AUTHORIZATION_HEADER_PREFIX = 'JWT'
        app.config.SANIC_JWT_EXPIRATION_DELTA = 360000
        app.config.SANIC_JWT_USER_ID = 'username'
    
        initialize(app, authentication_class=CustomAuth)
        app.blueprint(bp)
        return app 
    
    make_app().go_fast(debug=True, host='0.0.0.0', port=9000)
    

    I should note that ALL_METHODS from sanic_cors is just a list that contains both 'GET' and 'OPTIONS'

    Replication steps:

    1. Log in
    2. Send an OPTIONS request to /test

    I'm using

    python==3.6.4
    sanic-jwt==1.1.0
    sanic==0.7.0
    

    I've been able to trace the issue to the call function in sanic-jwt/utils.py. The issue appears to be that somehow the options function isn't registered as a coroutine like the get function is. Maybe this issue needs to go to Sanic? I'm not sure. But the issue only occurs with sanic-jwt because the Sanic code automatically calls functions and then checks to see if they are awaitable. Relevant Sanic code:

                    # Run response handler
                    response = handler(request, *args, **kwargs)
                    if isawaitable(response):
                        response = await response
    

    I was able to solve the issue for myself by changing call to:

    async def call(fn, *args, **kwargs):
        if callable(fn):
            fn = fn(*args, **kwargs)
        if inspect.iscoroutinefunction(fn) or inspect.isawaitable(fn):
            fn = await fn                                                                                                                                                                                                                                          
        return fn
    

    I'd be more than happy to raise a PR for this. This is my first gh issue, so please let me know if I do something wrong.

    Please let me know if you need any further information.

    bug example 
    opened by rafmagns-skepa-dreag 16
  • Configuration getter

    Configuration getter

    One of the new ways in Version 1 to create settings is with the setter function on the Configuration class.

    from sanic_jwt import Configuration
    
    class MyConfiguration(Configuration):
        def set_access_token_name(self):
            return 'jwt'
    
    Initialize(
        app,
        configuration_class=MyConfiguration)
    

    Then, the Initialization class goes and installs all the various config settings on a config object.

    >>> print(config.access_token_name)
    'jwt'
    

    I propose that we change the way that config is used throughout the backend to make it a callable. Instead of doing config.access_token_name it would become config.get('access_token_name').

    Why?

    Then, we can not only have dynamic attributes set at initialization, but also when called.

    class MyConfiguration(Configuration):
        async def get_access_token_name(self):
            return await some_fancy_function()
    
    enhancement 
    opened by ahopkins 13
  • Add support for PyJwt_2_0_0

    Add support for PyJwt_2_0_0

    Goal

    PyJWT just released v2.0.0 which breaks sanic-jwt due to https://github.com/jpadilla/pyjwt/issues/529

    Approach

    Type checking before returning access token.

    opened by rahulraina7 12
  • custom authentication control

    custom authentication control

    I'm trying to add in a feature for people to create permanent api tokens for use with my application in conjunction with the normal access/refresh tokens that users experience either via a browser or via CLI. The use case is they want an API token that can be used to easily script out access with my application. When a user creates one of these new API tokens for themselves, I save that token and all of the user's information into a database so I can look it up later. This should theoretically allow me to look up a user's information based on this new token (and allow it to be revoked by simply removing it from the database). However, I'm having some trouble getting this to work.

    I added in the following to successfully return either the normal header token or my new api token:

    class MyConfig(Configuration):
        def get_authorization_header(self, request):
            if "apitoken" in request.headers:
                return "apitoken"
            return "authorization"
    
        def get_authorization_header_prefix(self, request):
            if "apitoken" in request.headers:
                return ""
            return "Bearer"
    

    The above seems to be working, but I can't seem to add in my own custom verification/authentication check anywhere. For an individual endpoint that I create in the my_views section, I can successfully do the following to get all of the user's api tokens (given normal access token or new api token):

    async def get(self, request, *args, **kwargs):
            try:
                payload = self.instance.auth.extract_payload(request, verify=True)
                try:
                    user = await utils.call(
                        self.instance.auth.retrieve_user, request, payload=payload
                    )
                    user_id = await self.instance.auth._get_user_id(user)
                except Exception as e:
                    return json({"status": "error", "error": "failed to get user from token"})
            except Exception as e:
                print("can't parse token as JWT, gonna try database lookup")
                try:
                    if 'apitoken' in request.headers:
                        try:
                            query = await db_model.apitokens_query()
                            db_apitoken = await db_objects.get(query, token=request.headers.get('apitoken'))
                            user_id = db_apitoken.operator.id
                        except Exception as e:
                            print("Failed to find api token in db")
                            return json({"status": "error", "error": "Failed to find api token in db"})
                    else:
                        return json({"failed to find token to authenticate with"})
                except Exception as e:
                    raise e
            query = await db_model.operator_query()
            operator = await db_objects.get(query, id=user_id)
            query = await db_model.apitokens_query()
            tokens = await db_objects.execute(query.where(db_model.APITokens.operator == operator))
            return json({"status": "success", "tokens": [t.to_json() for t in tokens]})
    

    I can't get this to work for any arbitrary endpoint though. With debug True I get: {"reasons":["Not enough segments."],"exception":"Unauthorized"}, with debug False I get {"reasons":["Auth required."],"exception":"Unauthorized"}.

    I've tried extending the responses class, but it never seems to be called:

    class MyResponses(Responses):
        @staticmethod
        async def extend_retrieve_user(request, user=None, payload=None):
            print("called extend retrieve user")
            return await retrieve_user(request, payload)
    
        @staticmethod
        async def extend_verify(request, user=None, payload=None):
            print("called extend verify")
            return {"Verify": True}
    

    and I've even tried extending authenticate:

    class MyAuthentication(Authentication):
        async def authenticate(self, request, *args, **kwargs):
            print("called authenticate")
            return {"user_id": 1}
    

    But i still don't see my print statements showing up, so these aren't getting called. I have all of the following added to my Initialize function as well:

    authenticate=app.routes.authentication.authenticate,
               retrieve_user=app.routes.authentication.retrieve_user,
               cookie_set=True,
               cookie_strict=False,
               cookie_access_token_name='access_token',
               cookie_refresh_token_name='refresh_token',
               cookie_httponly=True,
               scopes_enabled=True,
               add_scopes_to_payload=app.routes.authentication.add_scopes_to_payload,
               scopes_name='scope',
               secret='apfell_secret jwt for signing here',
               url_prefix='/',
               class_views=my_views,
               path_to_authenticate='/auth',
               path_to_retrieve_user='/me',
               path_to_verify='/verify',
               path_to_refresh='/refresh',
               refresh_token_enabled=True,
               expiration_delta=14400,  # initial token expiration time
               store_refresh_token=app.routes.authentication.store_refresh_token,
               retrieve_refresh_token=app.routes.authentication.retrieve_refresh_token,
               configuration_class=MyConfig,
               responses_class=MyResponses,
               authentication_class=MyAuthentication,
               debug=True)
    

    What am I missing to enable this kind of override check?

    question 
    opened by its-a-feature 10
  • Disable blueprint or configure blueprint name?

    Disable blueprint or configure blueprint name?

    For some reason I need two auth instance in a sanic app. But the name of blueprint was hardcode which can't change and can't disable too. So there will be a problem. Can we make add blueprint name configureable?

    documentation 
    opened by jiamo 10
  • The extend_verify method doesn't seem to be useful?

    The extend_verify method doesn't seem to be useful?

    As the title:

    I hope to return some additional user information when requesting the /auth/verify interface, but the parameters of user and payload are not returned from the interface processing class VerifyEndpoint.

    It seems that the extend_verify method is of no use?

    opened by YaoJusheng 0
  • When user secret enabled, user id configuration is not working

    When user secret enabled, user id configuration is not working

    sanic_jwt/authentication.py Line 262: Use configured user_id instead of hardcoded 'user_id'

    user_id = payload.get('user_id') => user_id = payload.get(self.config.user_id())

    Even with a fix for this on the source code, authentication fails when user secret enabled.

    In my case, User object has a ID field named different than user_id.

    I wanted to create a PR to contribute, however, contribution documentation returns 404.

    opened by yusufertekin 0
  • Async extra verifications

    Async extra verifications

    Goal

    I had to make jwt token invalidation, and the best way i have found - is to make it inside extra verifications, but they were not async it is also discussed here #219

    New Features/Changes

    Possibility to use sync/async functions for extra_verifications

    opened by jekel 11
Releases(v1.8.0)
  • v1.8.0(Jun 28, 2022)

    What's Changed

    • Upgrade PyJWT by @ahopkins in https://github.com/ahopkins/sanic-jwt/pull/227

    Full Changelog: https://github.com/ahopkins/sanic-jwt/compare/v1.7.0...v1.8.0

    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Aug 12, 2021)

  • v1.6.0(Jan 5, 2021)

  • v1.3.2(May 16, 2019)

  • v1.3.1(Apr 25, 2019)

  • v1.3.0(Apr 24, 2019)

    Added

    • #40. Page redirection for static page protection
    • Support to be able to individually protect class-based view methods without the decorators property
    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Mar 14, 2019)

    Changed

    • #148. Exception message on refresh token intialization

    Fixed

    • #147. protected decorator properly applied to built in views when initialized on a blueprint
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Dec 4, 2018)

  • v1.2.0(Nov 8, 2018)

  • v1.1.4(Aug 6, 2018)

  • v1.1.3(Aug 6, 2018)

    Changed

    • Exception handling to consistently have a exception and reasons key
    • reasons in exception handling to be consistently formatted
    • 400 responses for debug turned off, and 401 when turned on

    Fixed

    • #110. Preflight methods now properly handled
    • #114. Proper use of utils.call to allow for sync and async retrieve_user functions
    • #116. Proper error reporting on malformed tokens
    • #118. Proper error reporting on expired token for /auth/me and /auth/refresh by applying @protected decorators
    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Jun 18, 2018)

  • v1.1.1(Jun 14, 2018)

  • v1.1.0(Jun 2, 2018)

    Added

    • New handler method: override_scope_validator
    • New handler method: destructure_scopes
    • New decorator method: inject_user
    • Decorator methods copied to Initialize class for convenience
    • New convenience method for extracting user_id from request
    • Feature for decoupling authentication mode for microservices
    • Ability to have custom generated refresh tokens
    • Subclasses are tested for consistency on Initialize

    Changed

    • Authentication.is_authenticated to Authentication._check_authentication
    • Authentication.verify to Authentication._verify
    • Authentication.get_access_token to Authentication.generate_access_token
    • Authentication.get_refresh_token to Authentication.generate_refresh_token
    • Authentication.retrieve_scopes to Authentication.extract_scopes
    • Method for getting and setting configurations made dynamic

    Fixed

    • Verification that a custom payload extender supplies all of the enabled claims
    • abort bug when using Sanic’s convenience method for exceptions
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Mar 4, 2018)

  • v1.0.1(Feb 27, 2018)

    Added

    • OPTIONS handler method for BaseEndpoint

    Fixed

    • Some tests for claims that were not using UTC timestamps
    • Consistency of docs with class_views
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Feb 25, 2018)

    Added

    • Initialize class
    • New methods for adding configuration settings
    • Customizable components
    • Customizable responses
    • Ability to fallback to header based authentication if cookie based fails
    • Initialize on a blueprint and isolate configuration

    Fixed

    • @protected implementation on class based views
    • Usage of signing algorithms with public and private keys

    Deprecated

    • SANIC_JWT_PAYLOAD_HANDLER
    • SANIC_JWT_HANDLER_PAYLOAD_EXTEND
    • SANIC_JWT_HANDLER_PAYLOAD_SCOPES
    Source code(tar.gz)
    Source code(zip)
Owner
Adam Hopkins
the brew·mas·ter (noun) /bro͞o ˈmastər/
Adam Hopkins
The ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS,JWE,JWK,JWA,JWT included.

Authlib The ultimate Python library in building OAuth and OpenID Connect servers. JWS, JWK, JWA, JWT are included. Authlib is compatible with Python2.

Hsiaoming Yang 3.4k Jan 04, 2023
A Python package, that allows you to acquire your RecNet authorization bearer token with your account credentials!

RecNet-Login This is a Python package, that allows you to acquire your RecNet bearer token with your account credentials! Installation Done via git: p

Jesse 6 Aug 18, 2022
A simple username/password database authentication solution for Streamlit

TL;DR: This is a simple username/password login authentication solution using a backing database. Both SQLite and Airtable are supported.

Arvindra 49 Nov 25, 2022
Django Rest Framework App wih JWT Authentication and other DRF stuff

Django Queries App with JWT authentication, Class Based Views, Serializers, Swagger UI, CI/CD and other cool DRF stuff API Documentaion /swagger - Swa

Rafael Salimov 4 Jan 29, 2022
A JSON Web Token authentication plugin for the Django REST Framework.

Simple JWT Abstract Simple JWT is a JSON Web Token authentication plugin for the Django REST Framework. For full documentation, visit django-rest-fram

Simple JWT 3.3k Jan 01, 2023
Out-of-the-box support register, sign in, email verification and password recovery workflows for websites based on Django and MongoDB

Using djmongoauth What is it? djmongoauth provides out-of-the-box support for basic user management and additional operations including user registrat

hao 3 Oct 21, 2021
Boilerplate/Starter Project for building RESTful APIs using Flask, SQLite, JWT authentication.

auth-phyton Boilerplate/Starter Project for building RESTful APIs using Flask, SQLite, JWT authentication. Setup Step #1 - Install dependencies $ pip

sandhika 0 Aug 03, 2022
Ready to use and customizable Authentications and Authorisation management for FastAPI ⚡

AuthenticationX 💫 Ready-to-use and customizable Authentications and Oauth2 management for FastAPI ⚡

Yasser Tahiri 408 Jan 05, 2023
:couple: Multi-user accounts for Django projects

django-organizations Summary Groups and multi-user account management Author Ben Lopatin (http://benlopatin.com) Status Separate individual user ident

Ben Lopatin 1.1k Jan 09, 2023
Creation & manipulation of PyPI tokens

PyPIToken: Manipulate PyPI API tokens PyPIToken is an open-source Python 3.6+ library for generating and manipulating PyPI tokens. PyPI tokens are ver

Joachim Jablon 8 Nov 01, 2022
Login qr line & qr image

login-qr-line-qr-image login qr line & qr image python3 & linux ubuntu api source: https://github.com/hert0t/BEAPI-BETA import httpx import qrcode fro

Alif Budiman 1 Dec 27, 2021
Basic auth for Django.

easy-basicauth WARNING! THIS LIBRARY IS IN PROGRESS! ANYTHING CAN CHANGE AT ANY MOMENT WITHOUT ANY NOTICE! Installation pip install easy-basicauth Usa

bichanna 2 Mar 25, 2022
Get inside your stronghold and make all your Django views default login_required

Stronghold Get inside your stronghold and make all your Django views default login_required Stronghold is a very small and easy to use django app that

Mike Grouchy 384 Nov 23, 2022
A simple model based API maker written in Python and based on Django and Django REST Framework

Fast DRF Fast DRF is a small library for making API faster with Django and Django REST Framework. It's easy and configurable. Full Documentation here

Mohammad Ashraful Islam 18 Oct 05, 2022
Complete Two-Factor Authentication for Django providing the easiest integration into most Django projects.

Django Two-Factor Authentication Complete Two-Factor Authentication for Django. Built on top of the one-time password framework django-otp and Django'

Bouke Haarsma 1.3k Jan 04, 2023
An open source Flask extension that provides JWT support (with batteries included)!

Flask-JWT-Extended Features Flask-JWT-Extended not only adds support for using JSON Web Tokens (JWT) to Flask for protecting views, but also many help

Landon Gilbert-Bland 1.4k Jan 04, 2023
Script that provides your TESLA access_token and refresh_token

TESLA tokens This script helps you get your TESLA access_token and refresh_token in order to connect to third party applications (Teslamate, TeslaFi,

Bun-Ny TAN 3 Apr 28, 2022
Django x Elasticsearch Templates

Django x Elasticsearch Requirements Python 3.7 Django = 3 Elasticsearch 7.15 Setup Elasticsearch Install via brew Install brew tap elastic/tap brew

Aji Pratama 0 May 22, 2022
Connect-4-AI - AI that plays Connect-4 using the minimax algorithm

Connect-4-AI Brief overview I coded up the Connect-4 (or four-in-a-row) game in

Favour Okeke 1 Feb 15, 2022
python-social-auth and oauth2 support for django-rest-framework

Django REST Framework Social OAuth2 This module provides OAuth2 social authentication support for applications in Django REST Framework. The aim of th

1k Dec 22, 2022