Skip to main content
===============================
Auth0+ python
===============================


.. image:: https://img.shields.io/pypi/v/auth0plus.svg
:target: https://pypi.python.org/pypi/auth0plus

.. image:: https://img.shields.io/travis/bretth/auth0plus.svg
:target: https://travis-ci.org/bretth/auth0plus

.. image:: https://coveralls.io/repos/github/bretth/auth0plus/badge.svg?branch=master :target: https://coveralls.io/github/bretth/auth0plus?branch=master


An unofficial python interface for the Auth0 management api v2 that speeds up integration in python projects.

* Free software: ISC license


Installation
------------
::

$ pip install auth0plus

Usage
------

We'll get started with the simplest scenario which is using Auth0 to store a database of users to authenticate against. For this you need to configure a domain and a non-interactive client to access a connection (database). You will also need a JSON web token (jwt) for the client application to access the parts of the api you specify (scopes). This can be generated manually or as I will show here it can be programmatically granted every 24 hours by a separate call to an oauth/token endpoint:

- Login to auth0.com
- Go to the `clients menu <https://manage.auth0.com/#/clients>`_
- Create a client and click on it's settings to get the *Domain* *Client ID* and *Client Secret*
- Go to the `APIs menu <https://manage.auth0.com/#/apis>`_ and click *Auth0 Management API*
- Click *Non Interactive Clients* and authorise your client then expand the selection to select scopes.
- Select read:users, update:users, delete:users, create:users, read:users_app_metadata, update:users_app_metadata, delete:users_app_metadata, create:users_app_metadata and create:user_tickets then *update*.

For more information on the above process read `<https://auth0.com/docs/api/management/v2/tokens>`_.

In your code import the Auth0 class.
::
>>> from auth0plus.management import Auth0
>>> from auth0plus.oauth import get_token

This example doctest uses python-dotenv to hold the secrets and variables in a .env file. You can configure and run it your self with **make doctests**.
::
>>> import os
>>> from dotenv import load_dotenv
>>> load_dotenv('.env')
True
>>> domain = os.getenv('DOMAIN')
>>> client_id = os.getenv('CLIENT_ID')
>>> client_secret = os.getenv('CLIENT_SECRET')
>>> db = os.getenv('CONNECTION')

Get the 24 hour jwt token dictionary which you would normally store somewhere::

>>> token = get_token(domain, client_id, client_secret)

Create the lazy connection. We're going to connect to a database backed store.
::
>>> auth0 = Auth0(domain, token['access_token'], client_id=client_id, default_connection=db)

The api follows the documented api for v2. So the endpoint of /api/v2/users is going to be *auth0.users*, and to get an empty user instance you would call the constructor.
::
>>> user = auth0.users()

Now we'll actually create a few users for my 4 year old's favourite band:

1. In one step using the endpoint *create* method.
::
>>> angus = auth0.users.create(email='angus.young@acdc.com', email_verified=True,
... password='Jailbreak', user_metadata={'family_name': 'Young'})

2. With the convience *get_or_create* method which follows the django equivalent.
::
>>> malcolm, created = auth0.users.get_or_create(
... defaults={'email_verified': True, 'password': 'ChuckB',
... 'user_metadata': {'family_name': 'Young'}}, email='malcolm.young@acdc.com')
>>> malcolm.user_metadata
{'family_name': 'Young'}
>>> malcolm.picture
'https://s.gravatar.com/avatar/...'

3. In two steps with init and *save*.
::
>>> singer = auth0.users(email='dave.evans@acdc.com', email_verified=True,
... password='CanISitNextToYouGirl')
>>> singer.save()
>>> print(singer.user_id)
auth0|...

*Save* also updates the user (which may need to make multiple calls to the endpoint).
::
>>> singer.email = 'bon.scott@acdc.com'
>>> singer.password = 'HighwayToHell'
>>> singer.save()

One thing to note is that the password is not available once it's saved.
::
>>> singer.password
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/doctest.py", line 1320, in __run
compileflags, 1), test.globs)
File "<doctest README.rst[21]>", line 1, in <module>
singer.password
File ".../auth0plus/auth0plus/management/users.py", line 118, in password
raise AttributeError("'User' object does not have a new password")
AttributeError: 'User' object does not have a new password

To distinguish between a User instance that has been created locally and one that has been fetched from Auth0 the boolean attribute *_fetched* determines whether saving the record would be an update (*True*) or a create (*False*).

The *get* classmethod allows returning a single instance, and class specific *ObjectDoesNotExist* exception (*User.DoesNotExist*) if it doesn't exist.
::
>>> try:
... brian = auth0.users.get(email='brian.johnson@acdc.com')
... except auth0.users.DoesNotExist as err:
... print(err)
User Does Not Exist

>>> brian, created = auth0.users.get_or_create(
... defaults={'email_verified': True, 'password': 'BackInBlack'},
... email='brian.johnson@acdc.com')


The *get* method uses the auth0 lucene search which means for anything other than the id you can potentially get multiple results (and a *MultipleObjectsReturned* exception), but beware you also need to ensure enough time has passed for newly created users to be indexed.
::
>>> from auth0plus.exceptions import MultipleObjectsReturned
>>> import time
>>> time.sleep(5)
>>> try:
... singers = auth0.users.get(email='b*')
... except MultipleObjectsReturned as err:
... print(err)
User.get returned multiple users

When you actually want multiple results use a *query* or *all* which return a sliceable lazy object.
::
>>> singers = auth0.users.query(email='b*')
>>> singers.count() # the total returned by include_totals=true, no iteration necessary
2
>>> singers[:] # evaluate the whole query
[<User auth0|...>, <User auth0|...>]

You can also construct your own 'q' syntax instead of keyword arguments and pass additional endpoint parameters. In this case we'll just get the user_id and email.
::
>>> brothers = auth0.users.query(
... q='user_metadata.family_name:"Young"',
... fields='user_id,email')
>>> brothers.count()
2

If you want to do something with the user data returned then *as_dict* is your friend.
::
>>> serialized = brothers[0].as_dict()

To maintain state such as whether it has been *_fetched* from auth0 you would pickle the instance, otherwise *as_dict* is the safer choice to reconstitute the object making no assumptions about any changes that might have been made.
::
>>> new_angus = auth0.users(**serialized)
>>> new_angus.password = 'MoneyTrain'
>>> from auth0plus.exceptions import Auth0Error
>>> try:
... new_angus.save()
... except Auth0Error as err:
... print(err)
400: The user already exists.

Delete instances with classmethods or instance method.
::
>>> singer.delete() # Remove Bon Scott
>>> auth0.users.delete(brian.get_id())

Get all the remaining band members (and delete them). Sorry Angus, it's time to retire.
::
>>> band = auth0.users.all()
>>> band.count()
2
>>> for member in band:
... member.delete()


Credits
---------

This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage


=======
History
=======

0.3.0 (09-May-2017)
--------------------

* Add get_token function to work with the new temporary client tokens

0.2.4 (20-June-2016)
--------------------

* Fix issue with pickling
* Fix issue with shared nested dictionary

0.2.3 (10-May-2016)
-------------------

* And so does unicode

0.2.2 (10-May-2016)
-------------------

* Setuptools always catches me out

0.2.1 (05-May-2016)
-------------------

* Fix issue with get and save flow

0.2.0 (04-May-2016)
-------------------

* Package as wheel
* Import auth0 from auth0plus.management

0.1.0 (01-May-2016)
-------------------

* First release on PyPI.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

auth0plus-0.3.0.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

auth0plus-0.3.0-py2.py3-none-any.whl (17.5 kB view details)

Uploaded Python 2Python 3

File details

Details for the file auth0plus-0.3.0.tar.gz.

File metadata

  • Download URL: auth0plus-0.3.0.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for auth0plus-0.3.0.tar.gz
Algorithm Hash digest
SHA256 6c85a081b159238e0db8a55aaa15a5c328bc71f6a5e23a2f36d34478d13fd1f9
MD5 1cfcdaae32d2611d53eb4b501507d7f3
BLAKE2b-256 e681a063df45b9d2817306cd310197e060fcee7f766839adfb3b1ba4647f7ad9

See more details on using hashes here.

File details

Details for the file auth0plus-0.3.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for auth0plus-0.3.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 0128dff0b4eee6f7cab6491e520118c4a9a841337b479c44321f1bfa352263d4
MD5 90d93219f33e233bcf5d99c616ec27cc
BLAKE2b-256 e7c3c721d083e8251c1cf286779059835cd930cd78a95f8dd48da7187f78421f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page