Stormpath is the first easy, secure user management and authentication service for developers. This is the Python SDK to ease integration of its features with any Python language based application.
$ pip install stormpath-sdk --pre
-
If you have not already done so, register as a developer on Stormpath and set up your API credentials and resources:
- Create a Stormpath developer account and create your API Keys
downloading the
apiKey.properties
file into a.stormpath
folder under your local home directory.
- Create a Stormpath developer account and create your API Keys
downloading the
-
Create a client using the API key properties file
from stormpath import Client client = Client(api_key_file_location="/some/path/to/apiKey.properties")
-
List all your applications and directories
for application in client.applications: print("Application: ", application.name) for directory in client.directories: print("Directory:", directory.name)
-
Get access to the specific application and directory using the URLs you acquired above.
application = client.applications.get("https://api.stormpath.com/v1/applications/APP_UID") directory = client.directories.get("https://api.stormpath.com/v1/directories/DIR_UID")
-
Create an application and autocreate a directory as the login source.
account = client.applications.create({ 'name':'Holodeck', 'description': "Recreational facility", }, create_directory=True)
-
Create an account for a user on the directory.
account = application.accounts.create({ 'given_name':'John', 'surname':'Smith', 'email':'john.smith@example.com', 'username':'johnsmith', 'password':'4P@$$w0rd!' })
-
Update an account
account.given_name = 'Johnathan' account.middle_name = 'A.' account.save()
-
Authenticate the Account for use with an application:
try: account = application.authenticate_account('johnsmith', '4P@$$w0rd!') except stormpath.Error as e: print(e)
-
Send a password reset request
application.send_password_reset_email('john.smith@example.com')
-
Create a group in a directory
```python
directory.groups.create({'name':'Admins'})
```
- Add the account to the group
```python
group.add_account(account)
```
All Stormpath features are accessed through a
stormpath.Client
instance, or a resource
created from one. A client needs an API key (made up of an id and a
secret) from your Stormpath developer account to manage resources
on that account. That API key can be specified any number of ways
in the hash of values passed on Client initialization:
-
The location of API key properties file:
client = stormpath.Client(api_key_file_location='/some/path/to/apiKey.properties')
You can even identify the names of the properties to use as the API key id and secret. For example, suppose your properties were:
foo=APIKEYID bar=APIKEYSECRET
You could load it with the following parameters:
client = stormpath.Client( api_key_file_location='/some/path/to/apiKey.properties', api_key_id_property_name='foo', api_key_secret_property_name='bar')
-
By explicitly setting the API key id and secret:
client = stormpath.Client(id=api_id, secret=api_secret)
-
Passing in an APIKey dictionary:
client = stormpath.Client(api_key={ 'id': api_id, 'secret': api_secret })
Most of the work you do with Stormpath is done through the applications and directories you have registered. You use the client to access them with their REST URL:
application = client.applications.get(application_url)
directory = client.directories.get(directory_url)
The applications
and directories
property on a
client instance allows you to iterate
and scan for resources via that interface.
Additional resources are accounts
, groups
,
group_memberships
, account_store_mappings
, and the single reference to your
tenant
.
Accounts are created on a directory instance:
account = directory.accounts.create({
given_name: 'John',
surname: 'Smith',
email: 'john.smith@example.com',
username: 'johnsmith',
password: '4P@$$w0rd!'
})
Directory account creation can take an additional flag to indicate if the account can skip any registration workflow configured on the directory.
## Will skip workflow, if any
account = directory.accounts.create({
'given_name': 'John',
'surname': 'Smith',
'email': 'frank@stormpath.com',
'username': 'johnsmith',
'password': 'Temp1234'
}, registration_workflow_enabled=False)
If the directory has been configured with an email verification workflow
and a non-Stormpath URL, you have to pass the verification token sent to
the URL in a sptoken
query parameter back to Stormpath to
complete the workflow. This is done through the
verify_email_token
on the accounts
collection.
Authentication is accomplished by passing a username or an email and a
password to authenticate_account
of an application we've
registered on Stormpath. This will either return an Account
instance if the credentials are valid, or raise a stormpath.Error
otherwise. In the former case, you can get the account
associated with the credentials.
try:
account = application.authenticate_account('johnsmith', '4P@$$w0rd!')
except stormpath.Error as e:
#If credentials are invalid or account doesn't exist
print(e)
A password reset workflow, if configured on the directory the account is
registered on, can be kicked off with the
send_password_reset_email
method on an application:
application.send_password_reset_email('john.smith@example.com')
If the workflow has been configured to verify through a non-Stormpath
URL, you can verify the token sent in the query parameter
sptoken
with the verify_password_reset_token
method on the application.
With the account acquired you can then update the password:
account.password = new_password
account.save()
NOTE : Confirming a new password is left up to the web application code calling the Stormpath SDK. The SDK does not require confirmation.
Memberships of accounts in certain groups can be used as an
authorization mechanism. As the groups
collection property
on an account instance is iterable
, you can use any of
that module's methods to determine if an account belongs to a specific
group.
You can create groups and assign them to accounts using the Stormpath web console, or programmatically. Groups are created on directories:
group = directory.groups.create({'name':'administrators'})
Group membership can be created by:
-
Explicitly creating a group membership resource with your client:
group_memebership = client.group_memberships.create(group, account)
-
Using the
add_group
method on the account instance:account.add_group(group)
-
Using the
add_account
method on the group instance:group.add_account(account)
The tested versions are Python 2.7, 3.2 and 3.3.
The simplest way is to install tox. Tox automatically tests the code on multiple versions of Python by creating virtualenvs:
$ pip install tox
There is a tox.ini file in the root folder of Stormpath SDK. You can modify it to suit your needs and run:
$ tox
What is common in all tests is that our setup.py uses pytest
to run tests and the tests themselves use HTTPretty
with unittest
. Python mock
is also (sometimes) used but in Python 3.3 mock
became part of the unittest
module so you don't have to install it if you're using Python 3.3. The tests make sure the correct module is used.
To install those dependencies manually, there is a testdep
command that checks the Python version and installs required packages accordingly:
$ python setup.py testdep
To run tests:
$ python setup.py test
All of the above methods use mock
and HTTPretty
and don't query Stormpath. That makes them fast and self-reliant. If you want to run tests that don't patch any of the methods, you have to set the following environment variables to working Stormpath credentials:
$ export STORMPATH_SDK_TEST_API_KEY_ID=YOUR_APIKEY_ID
$ export STORMPATH_SDK_TEST_API_KEY_SECRET=YOUR_APIKEY_SECRET
To run tests
$ python setup.py livetest
WARNING: Since the tests make live changes to Stormpath data, DO NOT run these tests in a production environment!
You can make your own contributions by forking the development
branch, making your changes, and issuing pull-requests on the
development
branch.
To build and install the development branch yourself from the latest source:
$ git clone git@github.com:stormpath/stormpath-sdk-python.git
$ cd stormpath-sdk-python
$ python setup.py install # if you want to install
$ python setup.py sdist # if you want to build a package
To generate docs from docstrings you need to install sphinx
:
$ pip install sphinx
And then run:
$ python setup.py docs
+-------------+
| Application |
| |
+-------------+
+ 1
|
| +------------------------+
| | AccountStore |
o- - - - | |
| +------------------------+
| ^ 1..*
| |
| |
| +---------OR---------+
| | |
| | |
v 0..* 1 + + 1
+---------------------+ +--------------+
| Directory | 1 1 | Group |1
| |<----------+| |+----------+
| | | | |
| | 1 0..* | |0..* |
| |+---------->| |<-----+ |
| | +--------------+ | | +-----------------+
| | | | | GroupMembership |
| | o- - o - - - - | |
| | +--------------+ | | +-----------------+
| | 1 0..* | Account |1 | |
| |+---------->| |+-----+ |
| | | | |
| | 1 1 | |0..* |
| |<----------+| |<----------+
+---------------------+ +--------------+
Copyright © 2012, 2013 Stormpath, Inc. and contributors.
This project is licensed under the Apache 2.0 Open Source License.
For additional information, please see the full Project Documentation.