Telephone is an application that provides an API to manage telephone calls. It receives telephone call registries with the state of a call, like, start or stop, timestamps, and others. Also, the application consolidate these registries into a call and charge them.
Telephone was developed using Python 3.7.2 with Python 3.6 capabilities at last in mind. So, the application should run on Python 3.6.x environments without troubles. If you're gonna use Python 3.6 remember to use the latest 3.6.x release(3.6.8 at the time of this writing).
I've used pyenv to manage python versions, and pipenv to manage virtual environments. Both could be used together. Pipenv can use pyenv and make everything work automagicly.
Also, I've used a Django Starter Template from Heroku guys. It have some facilities to work with Django software on Heroku instances.
Although Telephone was developed thinking about vendors lock-in, Postgres was the best choice for a database. It have special fields like JSONB which could make it work as Document Oriented Database or NoSQL as well. Also, most cloud vendors have a Postgres versions of his own to be used as a Database-as-a-Service. For queue, Redis seems a nice choice too. It have an amazing speed, could be used as cache as well, and vendors also have their version of it as a service.
I've developed Telephone on a Linux Machine running Fedora 30, but it is expected to run flawlessly on any *NIX compatible OS(even Windows 10). It could run well on a simple instance with at least 1GB of RAM and 512MB for each additional queue worker.
Since Telephone was developed with Heroku in mind, of course it runs without much effort. Just clone the project to your machine and get into the directory:
git clone https://github.com/decko/work-at-olist-rq
cd work-at-olist-rq
(If you need any help on configuring Heroku, read their documentation here)
Now, just login to your Heroku account and create a new instance:
heroku login
heroku create --buildpack heroku/python
Remember the URL Heroku is giving to you in this moment. We're gonna need it later.
Add the Heroku Postgres and RedisToGo Add-ons:
heroku addons:create heroku-postgresql
heroku addons:create redistogo
Add support to pt_BR locale:
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-locale
You still need to set some environment variables to make it work:
heroku config:set DEBUG=False SECRET_KEY=<any randon sequence 64-letter long at least>
You could find any Telephone environment variable on this documentation.
And finally publish your application to Heroku:
git push heroku master
Make sure your instance is working with:
heroku ps:scale web=1 worker=1
At least:
heroku run python manage.py migrate
And now access your instance using the URL that Heroku gave to you. You should see the Telephone API documentation page.
Docker is a great container solution that ease the work with running app and all the requirements. Consult Docker and docker-compose documentation to get it up and running.
Telephone have one Dockerfile to build an image for the application and a docker-compose.yml to orchestrate all the containers needed to run the application.
After clone the application, run it with:
docker-compose up -d
and it should be available at http://localhost:5000/
.
To run it on bare metal you gonna need to configure:
- Python, at least 3.6.8 version, preferably 3.7.3.
- Postgres 10.
- Redis 3.2.12 or the latest release for 3.2 branch.
I strongly recommend you to use pipenv to manage the virtual environment and dependencies. It do some magics that pip still can't. You can install pipenv using pip itself:
pip install -U pipenv
To create virtualenv and install dependencies, inside cloned application run:
pipenv install
(If you have you use pyenv along with pipenv, the last will ask you to install the recommended Python version. ;))
Consult the documentation of your OS to install Postgres and Redis. On Fedora you could easily go with:
sudo dnf install postgresql-server redis
Remember to configure settings.py with the credentials for Postgres and Redis, or set the DATABASE_URL and REDISTOGO_URL and other environment variables. Now, you could run it with:
pipenv run honcho start web worker
and access it on http://localhost:5000/
You can find the documentation after turn up an instance and accessing the URL. It's on root
URL. ;)
Also you can access /redoc
which are different versions for the same documentation.
I've developed Telephone using Neovim, on Kitty terminal using tmux and zsh with prezto. You can find my configuration files here. I've worked with two machines, a Lenovo T470 Laptop and a Ryzen7 Desktop, both with 16GB of RAM. Used docker to run Postgres and Redis, and executed the code inside a pipenv virtual environment.
To run the tests you must build up a virtualenv and install development dependencies. NOTE: Tests must run with DEBUG=True since we didn't run any worker along with the tests.
pipenv install --dev
DEBUG=True pipenv run pytest --create-db
and it should run all the tests.
The application is developed around a Service concept. A Service is a subclass of
ServiceAbstractClass with a trigger and queue attributes. Every time a message is
sent with dispatch
, a Service is triggered, instantiated with a message.
A message could be anything, since a complete json set, an id, or other.
Then, a sequence of functions runs to obtain, validate, transform, persist and
propagate information to a queue, where a new trigger is fired and the process goes on.
So, if you want to build a service you need to subclass ServiceAbstractClass and explicitly create all methods needed to make it run. Set a trigger attribute and a queue one. The queue is where the result or anything you want goes after the process is done.
You could easily use Docker to run Postgres and Redis containers. To run Postgres:
docker run -d -p 5432:5432 -e POSTGRES_DB=telephonedb -e POSTGRES_USER=olist_telephone -e POSTGRES_PASSWORD=olist_telephone --name olist-pgdb postgres:10
and Redis:
docker run -d -p 6379:6379/tcp --name olist-redis redis:3-alpine
And, you could use podman which runs Docker images as normal users, without user escalation.