πŸ—„ Credentials Manager#

The credentials managers allows you to store your credentials in your own way.

meapi, needs to store your credentials (access token, refresh token etc.) in order to be able to use them later on without the need to login again every time you want to use the API.

There are number of credentials managers that are already implemented in the project:

  • JsonCredentialsManager: stores the credentials in a json file (meapi_credentials.json by default).
    • This is the default credentials manager.

  • MemoryCredentialsManager: stores the credentials in memory.
    • The credentials will be lost when the program exits

And more… (see the list below)


How to use a credentials manager? simple as that:

>>> from me import Me
>>> me = Me(phone_number=972123456789, credentials_manager=YourCredentialsManager())
  • You are more than welcome to create your own credentials manager and open a pull request to add it to the project.


βž• Creating your own custom CredentialsManager#

  • You must implement the methods get, set, update and delete in order to allow meapi to store and manage the credentials.

class meapi.credentials_managers.CredentialsManager#
Abstract class for credentials managers.
  • You can implement your own credentials manager to store credentials in your own way.

abstract delete(phone_number: str)#
Delete the credentials by phone_number key.
  • If the credentials are not in the manager, do nothing.

  • You can implement your own idea of what delete means (e.g. change the state of your credentials).

abstract get(phone_number: str) Optional[Dict[str, str]]#
Get the credentials by phone_number key.
  • If the credentials are not in the manager, return None.

  • The keys of the dict must be: access, refresh and pwd_token, see example below.

Parameters:

phone_number (str) – The phone number of the client.

Returns:

Optional dict with the credentials. see example below.

Return type:

dict

Example for return value:

{
    'access': 'xxx',
    'refresh': 'xxx',
    'pwd_token': 'xxx'
}
abstract set(phone_number: str, data: Dict[str, str])#
Set the credentials by phone_number key.
  • If the credentials are already in the manager, update them.

Parameters:
  • phone_number (str) – The phone number of the client.

  • data (dict) – Dict with credentials. see example below.

Example for data:

{
    'access': 'xxx',
    'refresh': 'xxx',
    'pwd_token': 'xxx',
}
abstract update(phone_number: str, access_token: str)#

Update the access token in the credentials by phone_number key.

Parameters:
  • phone_number (str) – The phone number of the client.

  • access_token (str) – The new access token.


πŸ—„οΈ Example: Using a database#

Let’s say you want to store the credentials in a database

  • In this example we will use the Pony ORM , but you can use any other ORM or database library you want.

Creating the database#

First, we need to create the database and the table that will store the credentials:

from pony.orm import Database, PrimaryKey, Required

db = Database()
db.bind(provider='sqlite', filename='meapi_credentials.sqlite', create_db=True)

class MeUser(db.Entity):
    _table_ = 'me_user'
    phone_number = PrimaryKey(str)
    pwd_token = Required(str)
    access = Required(str)
    refresh = Required(str)
    status = Required(str, default='active')

db.generate_mapping(create_tables=True)

Implementing the CredentialsManager interface#

Create a new class that implements the CredentialsManager interface:

from meapi.credentials_manager import CredentialsManager
from typing import Optional, Dict
from pony.orm import db_session, TransactionIntegrityError

class DatabaseCredentialsManager(CredentialsManager):
    @db_session
    def set(self, phone_number: str, data: dict):
        try:
            User(phone_number=phone_number, **data)
        except TransactionIntegrityError: # phone_number already exists
            User[phone_number].set(status='active', **data)

    @db_session
    def get(self, phone_number: str) -> Optional[Dict[str, str]]:
        user = User.get(phone_number=phone_number)
        return user.to_dict(only=['pwd_token', 'access', 'refresh']) if
            (user and user.status == 'active') else None

    @db_session
    def update(self, phone_number: str, access_token: str):
        User[phone_number].access = access_token

    @db_session
    def delete(self, phone_number: str):
        User[phone_number].status = 'inactive' # We don't want actually to delete the user from the database

Using the CredentialsManager#

Now we can use the credentials manager by passing it to the Me class:

>>> from meapi import Me
>>> dbcm = DatabaseCredentialsManager()
>>> me = Me(phone_number=972123456789, activation_code='123456', credentials_manager=dbcm)

πŸŽ›οΈ Available Credentials Managers#

class meapi.credentials_managers.json_files.JsonCredentialsManager#
Json Credentials Manager
  • This class is used to store the credentials in a json file/s.

Parameters:
  • config_file (-) –

    (str) The config json file path. Default: meapi_credentials.json.

    {
        "123456789": {"pwd_token": "xxx", "access": "xxx", "refresh": "xxx"},
        "987654321": {"pwd_token": "xxx", "access": "xxx", "refresh": "xxx"},
        "123456789": {"pwd_token": "xxx", "access": "xxx", "refresh": "xxx"}
    }
    

  • separate_files (-) – (bool) If True, each phone number will have its own file: credentials_dir/phone_number.json. Default: False.

  • directory (-) –

    (str) The directory where the credentials files will be stored. Default: meapi_credentials.

    .
    β”œβ”€β”€ meapi_credentials
    β”‚   β”œβ”€β”€ 123456789.json -> {"pwd_token": "xxx", "access": "xxx", "refresh": "xxx"}
    β”‚   β”œβ”€β”€ 987654321.json -> {"pwd_token": "xxx", "access": "xxx", "refresh": "xxx"}
    β”‚   └── 123456789.json -> {"pwd_token": "xxx", "access": "xxx", "refresh": "xxx"}
    └──────────────────────
    

Raises:

- FileExistsError – If the config file is not a valid json file.

Example

>>> from meapi.credentials_managers.json_files import JsonCredentialsManager
>>> from meapi import Me
>>> jcm = JsonCredentialsManager(separate_files=True, directory='/home/david/credentials')
>>> me = Me(phone_number='123456789', credentials_manager=jcm)
class meapi.credentials_managers.memory.MemoryCredentialsManager#
Memory Credentials Manager.
  • This class is storing the credentials in memory.

  • The data will be lost when the program ends.

class meapi.credentials_managers.redis.RedisCredentialsManager#
Redis Credentials Manager.
  • This class is used to store the credentials in a redis cache.

Parameters:

redis (-) – (redis.Redis) The redis object of redis-py library. (https://github.com/redis/redis-py)

Examples

>>> from meapi import Me
>>> from redis import Redis
>>> from meapi.credentials_managers.redis import RedisCredentialsManager
>>> redis = Redis(host='localhost', port=6379, db=0)
>>> rcm = RedisCredentialsManager(redis)
>>> me = Me(phone_number=972123456789, credentials_manager=rcm)
class meapi.credentials_managers.flask.FlaskSessionCredentialsManager#
Flask Session Credentials Manager
  • This class is used to store the credentials in a flask session.

Parameters:

session (-) – (flask.sessions.Session) The flask session.

class meapi.credentials_managers.django.DjangoSessionCredentialsManager#
Django Session Credentials Manager
  • This class is used to store the credentials in a django session.

Parameters:

session (-) – (django.contrib.sessions.backends.base.SessionBase) The django session.