Skip to main content

Mouth contains a service to run outgoing communications like email and sms messages

Project description

mouth2_oc

pypi version Custom License

body_oc 2.0 service that handles locale options, as well as templating and sending email (smtp) and sms (twilio) messages.

Please see LICENSE for further information.

See Releases for changes from release to release.

RESTlike Documentation

If you're only connecting to mouth through the RESTlike API, check out the full documentation on the individual requests.

JavaScript/TypeScript

Also check out @ouroboros/mouth on npm if you want to easily connect to mouth in your choice of javascript / typescript framework.

Contents

Module Install

Requires

mouth2_oc requires python 3.10 or higher

Install

pip install mouth2_oc

[ mouth2_oc / contents ]

Module Configuration

Mouth and all body_oc services use JSON to store their server side settings. For more information on how to setup and store these configuration files, visit config_oc.

Example Configuration

Below is a sample configuration file, we'll break it down section by section immediately after.

{
  "body": {
    "rest": {
      "allowed": [ "mydomain.com" ],
      "default": {
        "domain": "localhost",
        "host": "0.0.0.0",
        "protocol": "http"
      },
      "services": {
        "brain": { "port": 8000, "workers": 10 },
        "mouth": { "port": 8001, "workers": 2 }
      },
      "verbose": true
    }
  },

  "email": {
    "error_to": "me+errors@mydomain.com",
    "allowed": null,
    "from": "MyApp! <contact@mydomain.com>",
    "smtp": {
      "host": "smtp.mydomain.com",
      "port": 587,
      "tls": true,
      "user": "contact@mydomain.com",
      "passwd": "********"
    }
  },

  "memory": {
    "redis": "session"
  },

  "mouth": {
    "data": "../.data",
    "mysql": "records",
	"send_error_emails": true
  },

  "mysql": {
    "hosts": {
      "records": {
        "host": "sql.mydomain.com",
        "charset": "utf8mb4",
        "passwd": "********"
      }
    },
    "db": "my_app"
  },

  "sms": {
    "active": true,
    "twilio": {
      "account_sid": "someaccountidfromtwilio",
      "token": "sometokenfromtwilio",
      "from_number": "+5145559876"
    }
  }
}

[ brain2_oc / contents / module configuration ]

Configuration Sections

First, we'll start with the lowest level things we control, the email/smtp, sms, database, and caching software connection settings. Later we'll talk about other Ouroboros Coding software, the memory and body settings.

email section

  "email": {
    "allowed": null,
    "error_to": "me+errors@mydomain.com",
    "from": "MyApp! <contact@mydomain.com>",
    "smtp": {
      "host": "smtp.mydomain.com",
      "port": 587,
      "tls": true,
      "user": "contact@mydomain.com",
      "passwd": "********"
    }
  }

This section will most likely exist in your project in order to handle sending error e-mails on crashes, but for Mouth is even more important as it's used to send all e-mails out.

allowed should be set to null or false by default, as that allows all e-mails to any address allowed. If you want to limit which e-mail addresses can receive e-mails via Mouth, set allowed to an array, e.g.

    "allowed": [ "somename@mydomain.com", "someothername@mydomain.com" ]

Any requests that receive e-mail addresses that aren't in the list will simply not send out the e-mail and return success as if they did.

error_to represents the person or person's who will receive emails whenever mouth has some sort of exception that wasn't handled.

from is the default email address any emails come from. It is only used if no from is passed to the request.

smtp represents the SMTP server connection values.

[ mouth2_oc / contents / module configuration / configuration sections ]

sms section

  "sms": {
    "active": true,
    "twilio": {
      "account_sid": "someaccountidfromtwilio",
      "token": "sometokenfromtwilio",
      "from_number": "+5145559876"
    }
  }

The sms section represents sending SMS messages via Twilio to specific phone numbers.

sms.active

If set to false, any request to send an SMS will be rejected.

sms.twilio

The twilio specific configuration.

account_sid The SID provided by Twilio.

token The token provided by Twilio.

from_number The phone number to "send" the SMS from.

mysql section

  "mysql": {
	"hosts": {
	  "records": {
		"host": "sql.mydomain.com",
		"charset": "utf8mb4",
		"passwd": "********"
	  }
	},
	"db": "my_app"
  }

Each object under hosts represents a named MySQL or MariaDB connection. The important part is the name, we only have one, records.

For more information on what can be entered under each name, see rest_mysql.

[ mouth2_oc / contents / module configuration / configuration sections ]

redis section

  "redis": {
	"records": {
	  "host": "redis.mydomain.com",
	  "db": 0
	},
	"session": {
	  "host": "redis.mydomain.com",
	  "db": 1
	}
  }

Each object under the "redis" section represents a named Redis connection. The important part is the name, we have two here, records and session.

For more info on what can be put under each name, see the extensive list on Connecting to Redis.

[ mouth2_oc / contents / module configuration / configuration sections ]

memory section

  "memory": {
	"redis": "session"
  }

memory_oc is an Ouroboros Coding module that handles the sessions for all services that run on the body_oc framework.

It needs to know which Redis connection it should use to store the session information. We have two from the redis section, records and session, and we are telling memory_oc to use the session one.

[ mouth2_oc / contents / module configuration / configuration sections ]

body section

  "body": {
	"rest": {
	  "allowed": [ "mydomain.com" ],
	  "default": {
		"domain": "localhost",
		"host": "0.0.0.0",
		"protocol": "http"
	  },
	  "services": {
		"mouth": { "port": 8000, "workers": 10 },
		"mouth": { "port": 8001, "workers": 2 }
	  },
	  "verbose": true
	}
  }

body_oc is the rest / service framework that mouth runs on top of. There's a lot of data here, but it's really only setting up two things.

body.rest.allowed

Represents the domains that can make cross origin requests to the RESTlike interface. This is mandatory if requests are being made from browsers, but in no way affects direct requests via curl / requests / postman / etc. In this case, we are allowing any pages across https://mydomain.com, this includes https://mydomain.com/some/page/, https://mydomain.com/other, and even https://admin.mydomain.com/.

To limit to a specific subdomain, change "allowed" to be more specific

	  "allowed": [ "admin.mydomain.com" ]

this way https://admin.mydomain.com/ and https://bob.admin.mydomain.com/ work, but not https://mydomain.com/.

[ mouth2_oc / contents / module configuration / configuration sections / body section ]

body.rest.services

Second, in order to know how to both run and connect to body_oc services, we need to indicate, what protocol, domain, and port to use to connect, what interface they will respond to, and how many instances of each we can spin up.

In the above instance we have two services, brain and mouth. Brain is available at http://localhost:8000 and will be running 10 threads that will be listening on ip 0.0.0.0, or internal only traffic. Mouth is available at http://localhost:8001 and will be running 2 threads that will also be listening on ip 0.0.0.0.

We are relying on the defaults to generate some of the data, and this is a very simplistic initial launch setup. As we launch more servers and spread the load, you might have the config on the mouth server be something more like this where brain is running on another server inside the network.

	  "services": {
		"brain": {
		  "domain": "brain.mydomain",
		  "port": 80,
		  "protocol": "http"
		},
		"mouth": {
		  "domain": "localhost",
		  "host": "192.168.0.1",
		  "port": 80,
		  "protocol": "http",
		  "workers": 2
		}
	  }

...or like this, where it's running outside the network

		"brain": {
		  "domain": "brain.mydomain.com",
		  "port": 443,
		  "protocol": "https"
		}
body.rest.verbose

This flags decides whether all body services using the config print out the requests they receive and the responses they send, to stdout. This can be unbelievably helpful during development and debugging.

[ mouth2_oc / contents / module configuration / configuration sections / body section ]

mouth section

  "mouth": {
    "data": "../.data",
    "mysql": "records",
	"send_error_emails": true
  },

With the rest of the sections cleared up, hopefully the mouth section is easier to digest.

mouth.data

A directory where mouth will store any files it needs. Things like the version file "mouth.ver" which keeps track of what is installed and upgraded. We want this directory outside of the root of mouth or the project it's in, in case that folder ever gets deleted.

[ mouth2_oc / contents / module configuration / configuration sections / mouth section ]

mouth.mysql

References the only named connection from the mysql configuration, records. This is the connection mouth will use to store its tables.

[ mouth2_oc / contents / module configuration / configuration sections / mouth section ]

mouth.send_error_emails

If true, error emails will be sent to the address in config.email.error_to whenever a request to mouth causes an uncaught exception.

[ mouth2_oc / contents / module configuration / configuration sections / mouth section ]

Install Tables and Records

After installing the module into the project via pip, you will need to install the tables to your database.

(myenv) foo@bar:~$ mouth install
Installing tables
Setting lastest version
Done
(myenv) foo@bar:~$

[ mouth2_oc / contents ]

Upgrade Tables and/or Records

If you upgrade to a new version of mouth2_oc be sure to run the upgrade script. This will ensure any data and tables are up to date with the version.

(myenv) foo@bar:~$ mouth upgrade
Already up to date
(myenv) foo@bar:~$

This process works by checking the "mouth.ver" in the mouth.data directory to see what, if any, scripts need to be run to upgrade tables and/or data. This is one reason why it's very important not to keep the mouth.data directory inside your repository or some directory that might get wiped out.

Have no fear though, if the file does get wiped out, the next time the upgrade process is run you will be prompted to pick the current version you are on and the file will be re-created.

Take note though, the options you will be given will not correspond directly to every version of mouth2_oc, only to the versions where data or tables changed in a way that the software couldn't support alone. When prompted, ALWAYS pick the version which is closest to, but under, the version of mouth2_oc you have installed in your project. If you're on 8.1.0 and the choices are between 1.0.0 and 8.1.1, you pick 1.0.0.

[ mouth2_oc / contents ]

Project details


Download files

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

Source Distribution

mouth2_oc-2.2.1.tar.gz (22.3 kB view details)

Uploaded Source

Built Distribution

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

mouth2_oc-2.2.1-py3-none-any.whl (28.5 kB view details)

Uploaded Python 3

File details

Details for the file mouth2_oc-2.2.1.tar.gz.

File metadata

  • Download URL: mouth2_oc-2.2.1.tar.gz
  • Upload date:
  • Size: 22.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for mouth2_oc-2.2.1.tar.gz
Algorithm Hash digest
SHA256 7e147e05b2c9734fe8910aeb94d076120470e023432ebfd5e750131184307a1d
MD5 2e1ec86c440c6edc1fbe43499b9f6a30
BLAKE2b-256 9692a6a3b5e16e76654274c208071260b687807fe7a411d029df5076ec45b50c

See more details on using hashes here.

File details

Details for the file mouth2_oc-2.2.1-py3-none-any.whl.

File metadata

  • Download URL: mouth2_oc-2.2.1-py3-none-any.whl
  • Upload date:
  • Size: 28.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for mouth2_oc-2.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9c0226151ec5ad35f80d4d140db85af0441f38aa6c54b33cde00701bf2b0b4f0
MD5 f8db5319e0784f5ae28a0354023fe8ed
BLAKE2b-256 db1fbe44b4f85d1fdf12bf9069f6e76185c1fd75820bb8c54cda10aefec3d234

See more details on using hashes here.

Supported by

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