ievv_sms — SMS sending - multiple backends supported

Setup

Add it to your INSTALLED_APPS setting:

INSTALLED_APPS = [
    # Other apps ...
    'ievv_opensource.ievv_sms'
]

For development, you probably also want to use the ievv_opensource.ievv_sms.backends.debugprint.Backend backend. You configure that with the following setting:

IEVV_SMS_DEFAULT_BACKEND_ID = 'debugprint'

Sending SMS

Send an SMS using the default backend with:

from ievv_opensource.ievv_sms.sms_registry import send_sms
send_sms(phone_number='12345678', message='This is a test')

Send using another backend using the backend_id argument:

from ievv_opensource.ievv_sms.sms_registry import send_sms
send_sms(phone_number='12345678', message='This is a test',
         backend_id='some_backend_id')

See ievv_opensource.ievv_sms.sms_registry.send_sms() for more details.

Creating a custom backend

See the example in AbstractSmsBackend.

Specifying the default backend

Just set the backend ID (see get_backend_id()) of a backend in the IEVV_SMS_DEFAULT_BACKEND_ID setting.

Core API

send_sms()

ievv_opensource.ievv_sms.sms_registry.send_sms(phone_number, message, backend_id=None, **kwargs)[source]

Send SMS message.

Just a shortcut for Registry.send() (Registry.get_instance().send(...)).

Parameters:
  • phone_number (str) – The phone number to send the message to.
  • message (str) – The message to send.
  • backend_id (str) – The ID of the backend to use for sending. If this is None, we use the default backend (see get_default_backend_id()).
  • **kwargs – Extra kwargs for the AbstractSmsBackend constructor.
Returns:

An instance of a subclass of AbstractSmsBackend.

Return type:

AbstractSmsBackend

AbstractSmsBackend

class ievv_opensource.ievv_sms.sms_registry.AbstractSmsBackend(phone_number, message, **kwargs)[source]

Bases: object

Base class for SMS backends.

An instance of this class is created each time an SMS is created.

This means that you can store temporary information related to building the SMS on self.

Example (simple print SMS backend):

class PrintBackend(sms_registry.AbstractSmsBackend):
    @classmethod
    def get_backend_id(cls):
        return 'print'

    def send(self):
        print(
            'Phone number: {phone_number}. '
            'Message: {message}'.format(
                phone_number=self.cleaned_phone_number,
                message=self.cleaned_message
            )
        )

To use the PrintBackend, add it to the registry via an AppConfig for your Django app:

from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'myapp'

    def ready(self):
        from ievv_opensource.ievv_sms import sms_registry
        from myapp import sms_backends
        sms_registry.Registry.get_instance().add(sms_backends.PrintBackend)

Now you can use the backend to send an SMS:

from ievv_opensource.ievv_sms import sms_registry
sms_registry.Registry.get_instance().send(
    phone_number='12345678',
    message='This is a test',
    backend_id='print')

You can also set the backend as the default backend for SMS sending by adding IEVV_SMS_DEFAULT_BACKEND_ID = 'print' to your django settings. With this setting you can call send() without the backend_id argument, and the SMS will be sent with the print backend.

All the arguments are forwarded from Registry.send() / Registry.make_backend_instance().

Parameters:
  • phone_number (str) – The phone number to send the message to.
  • message (str) – The message to send.
  • **kwargs – Extra kwargs. Both for future proofing, and to make it possible for backends to support extra kwargs.
classmethod get_backend_id()[source]

The ID this backend will get get in the Registry singleton.

Defaults to the full python path for the class.

classmethod validate_backend_setup()[source]

Validate backend setup (required settings, etc).

Raises:SmsBackendSetupError – When the setup validation fails.
clean_phone_number(phone_number)[source]

Clean/validate the phone number.

By default this does nothing. It is here for backends that need to format phone numbers in a specific way.

Parameters:phone_number (str) – The phone number to clean.
Raises:django.core.exceptions.ValidationError – If validation of the phone number fails.
Returns:The cleaned phone number.
Return type:str
clean_message(message)[source]

Clean/validate the message.

By default this does nothing. It is here for backends that need to format or validate the message in a specific way.

Parameters:message (str) – The message to clean.
Raises:django.core.exceptions.ValidationError – If validation of the message fails.
Returns:The cleaned message.
Return type:str
clean()[source]

Clean the phone number, message, and kwargs.

Calls clean_phone_number() and clean_message().

If you need to clean extra kwargs, you should override this method, but make sure you call super().clean().

Raises:django.core.exceptions.ValidationError – If validation fails.
send()[source]

Send the message.

Must be overridden in subclasses.

Should send self.cleaned_message to self.cleaned_phone_number.

Registry

class ievv_opensource.ievv_sms.sms_registry.Registry[source]

Bases: ievv_opensource.utils.singleton.Singleton

Registry of AbstractSmsBackend objects.

add(backend_class)[source]

Add the given backend_class to the registry.

Parameters:backend_class – A subclass of AbstractSmsBackend.
remove_by_backend_id(backend_id)[source]

Remove the backend class with the provided backend_id from the registry.

remove(backend_class)[source]

Remove the provided backend class from the registry.

iter_backend_classes()[source]

Returns an iterator over all backend classes in the registry.

get_default_backend_id()[source]

Get the default backend ID.

Retrieved from the IEVV_SMS_DEFAULT_BACKEND_ID setting.

Defaults to debugprint if the setting is not defined, or if it boolean False (None, empty string, …).

get_backend_class_by_id(backend_id)[source]

Get backend class by ID.

Parameters:backend_id (str) – The backend ID. If this is None, we use the default backend (see get_default_backend_id())
make_backend_instance(phone_number, message, backend_id=None, **kwargs)[source]

Make a backend instance. Does not send the message.

Parameters:
  • phone_number (str) – The phone number to send the message to.
  • message (str) – The message to send.
  • backend_id (str) – The ID of the backend to use for sending. If this is None, we use the default backend (see get_default_backend_id()).
  • **kwargs – Extra kwargs for the AbstractSmsBackend constructor.
Returns:

An instance of a subclass of AbstractSmsBackend.

Return type:

AbstractSmsBackend

send(phone_number, message, backend_id=None, **kwargs)[source]

Send an SMS message.

Shortcut for make_backend_instance(...).send().

See make_backend_instance().

Parameters:
Raises:

django.core.exceptions.ValidationError – If validation of the phone number, message or kwargs fails.

Returns:

An instance of a subclass of AbstractSmsBackend.

Return type:

AbstractSmsBackend

Backends

Debug/develop backends

class ievv_opensource.ievv_sms.backends.debugprint.Backend(phone_number, message, **kwargs)[source]

Bases: ievv_opensource.ievv_sms.sms_registry.AbstractSmsBackend

Backend that just prints the phone number and message. Does not send an SMS.

Useful for development.

The backend_id for this backend is debugprint.

All the arguments are forwarded from Registry.send() / Registry.make_backend_instance().

Parameters:
  • phone_number (str) – The phone number to send the message to.
  • message (str) – The message to send.
  • **kwargs – Extra kwargs. Both for future proofing, and to make it possible for backends to support extra kwargs.
classmethod get_backend_id()[source]

The ID this backend will get get in the Registry singleton.

Defaults to the full python path for the class.

send()[source]

Send the message.

Must be overridden in subclasses.

Should send self.cleaned_message to self.cleaned_phone_number.

class ievv_opensource.ievv_sms.backends.debugprint.Latin1Backend(phone_number, message, **kwargs)[source]

Bases: ievv_opensource.ievv_sms.backends.debugprint.Backend

Just like Backend, but this backend crashes if you try to send any characters outside the latin1 charset.

The backend_id for this backend is debugprint_latin1.

Very useful when the targeted production backend only supports latin1.

All the arguments are forwarded from Registry.send() / Registry.make_backend_instance().

Parameters:
  • phone_number (str) – The phone number to send the message to.
  • message (str) – The message to send.
  • **kwargs – Extra kwargs. Both for future proofing, and to make it possible for backends to support extra kwargs.
classmethod get_backend_id()[source]

The ID this backend will get get in the Registry singleton.

Defaults to the full python path for the class.

clean_message(message)[source]

Clean/validate the message.

By default this does nothing. It is here for backends that need to format or validate the message in a specific way.

Parameters:message (str) – The message to clean.
Raises:django.core.exceptions.ValidationError – If validation of the message fails.
Returns:The cleaned message.
Return type:str

PSWIN backend

class ievv_opensource.ievv_sms.backends.pswin.Backend(phone_number, message, pswin_sender=None, pswin_username=None, pswin_password=None, pswin_default_country_code=None, **kwargs)[source]

Bases: ievv_opensource.ievv_sms.sms_registry.AbstractSmsBackend

A pswin (https://pswin.com) backend.

To use this backend, you should set the following Django settings:

  • PSWIN_USERNAME: The pswin username (USER).
  • PSWIN_PASSWORD: The pswin password (PWD).
  • PSWIN_SENDER: The pswin sender (SND).
  • PSWIN_DEFAULT_COUNTRY_CODE: The country code to use if received phone numbers do not start with +<code> or 00<code>. E.g.: 47 for norway.

If you do not set these settings, you must include them as kwargs each time you send a message, and this makes it hard to switch SMS sending provider.

The backend_id for this backend is pswin.

classmethod get_backend_id()[source]

The ID this backend will get get in the Registry singleton.

Defaults to the full python path for the class.

clean_message(message)[source]

Clean/validate the message.

By default this does nothing. It is here for backends that need to format or validate the message in a specific way.

Parameters:message (str) – The message to clean.
Raises:django.core.exceptions.ValidationError – If validation of the message fails.
Returns:The cleaned message.
Return type:str
clean_phone_number(phone_number)[source]

Clean/validate the phone number.

By default this does nothing. It is here for backends that need to format phone numbers in a specific way.

Parameters:phone_number (str) – The phone number to clean.
Raises:django.core.exceptions.ValidationError – If validation of the phone number fails.
Returns:The cleaned phone number.
Return type:str
send()[source]

Send the message using pswin.

DebugSmsMessage backend

class ievv_opensource.ievv_sms.backends.debug_dbstore.Backend(phone_number, message, **kwargs)[source]

Bases: ievv_opensource.ievv_sms.sms_registry.AbstractSmsBackend

Backend that creates DebugSmsMessage object

Useful for development.

The backend_id for this backend is debug_dbstore.

All the arguments are forwarded from Registry.send() / Registry.make_backend_instance().

Parameters:
  • phone_number (str) – The phone number to send the message to.
  • message (str) – The message to send.
  • **kwargs – Extra kwargs. Both for future proofing, and to make it possible for backends to support extra kwargs.
classmethod get_backend_id()[source]

The ID this backend will get get in the Registry singleton.

Defaults to the full python path for the class.

send()[source]

Send the message.

Must be overridden in subclasses.

Should send self.cleaned_message to self.cleaned_phone_number.