Thursday, June 29, 2017

Up and Running with Django, Docker and Let’s Encrypt

This post first appeared here


In an ideal world, software companies would have dedicated teams for tasks such as managing infrastructure, software development or deployments. However, depending on the size of the company/team, this separation between Development and Ops (information technology operations) may not always be feasible.

At Ubiwhere we try to adhere to this methodology as much as possible, but there are times when our team becomes overwhelmed with their daily tasks. This means a developer can get “held up” waiting for the Sysadmin/Devops team to have time to help deploy a new app following recommended best practices.
This issue prompted a co-worker to spearhead the development of django-yadpt-starter, a small open-source tool to bootstrap new projects in Django, a Web Framework very near and dear to our heart. This tool essentially allows a developer to create a new Django project, based on our own custom Django Project Template with a fully automated setup using Docker Containers and a Let's Encrypt SSL certificate, all while adhering to recommended best practices.
A few key features:
  • Simplified initial setup with a single command and a couples answers;
  • Automatic generation and renewal of Let's Encrypt certificates;
  • Adheres to best practices;
  • Uses Docker and Docker-Compose;
  • Provides different environments: One without a valid certificate for local development and another with a valid certificate (for Production or Staging).
Now, any developer can create Production Ready Web Apps in minutes without “bothering” our sysadmin team, since this has already been validated by them.
Our main goal while building this tool was to package many moving parts in a consistent and reusable manner, all while keeping its usage simple.
We started with the obvious choice, Django Project Template, but quickly hit our first hurdle. At the time, Django didn’t have native support for passing extra context variables to project templates. Fortunately, we found a django package that allowed us to achieve this.
The next step was to create a docker-compose.yml configuration file with the “correct dependencies”. The nice thing about this approach is its pluggable nature. In other words, if your use case dictates you must use MongoDB instead of PostgreSQL, you can easily swap them in the compose file. We’ve added the stack we use at Ubiwhere but any component of the stack can be changed or upgraded.
Last but not least, security! The internet is teeming with insecure websites and we have no desire or intention to add yet another to the list. Fortunately, Let’s Encrypt allows anyone to generate free and valid SSL/TLS certificates. Since setting up SSL/TLS isn’t always trivial, another co-worker stepped in and containerized certbot, allowing us to easily add it to the mix.
In essence, the certbot container simplifies the process of generating and renewing a Let’s Encrypt certificate. This certificate is stored in a docker named volume, shared with the nginx container.
django-yadpt-starter still needs work, but despite that we’re already using it in production on a few of our sites and we couldn't be prouder.

Thursday, March 5, 2015

Using Django Rest Framework with Model Translations


This post first appeared here

If you are a Django developer, you have probably heard of the great Django Rest Framework. It is simply one of the best, most powerful frameworks to build RESTFul Web APIs.



Recently, in one of our company projects we decided to build a Rest API. But as an extra requirement, it had to support model translations in order to provide multilingual content in our database. 
In previous projects we used our own in-house solution. Although its core implementation was basically similar to most model translation API's, it lacked the “API” component, in other words, a set of reusable methods to ease the development pain especially when switching across different projects.
That's when we met django-hvad a very powerful Model Translation API, with an awesome community and a very promising future.
In this post, we are going to understand how we can make Django Rest Framework (DRF) work alongside a Model Translation API such as django-hvad. We assume that you are familiar with the basics of DRF and django-hvad.
Please note that the versions that we are going to be talking about are djangorestframework==2.4.3 and django-hvad==1.0.0 and you can easily install both of them through PIP.
Note also that future versions of django-hvad will have official DRF support as mentioned here, but at the time of the writing of this Post this was still work in progress. Basically in older versions we will need some of the “glue” provided here to make these two work nicely.
After installing DRF and django-hvad, we should create our own “custom” model serializers that will be used as a base to all of our Translatable Models. From there, you just inherit your serializers from TranslatableModelSerializer or HyperlinkedTranslatableModelSerializer
When posting, you should simply add language_code as a normal field as part of your JSON / XML / etc.
After this, things become really straight forward. For example:

The company has been quite impressed with the advantages that django-hvad has brought to the table. 
We are definitely going to use them in future projects that require model translations and a Django Rest Framework API.

Sunday, September 7, 2014

Django + Amazon S3

Let me start by saying that there are a lot of good tutorials on the internet, and my motivation for writing this one is simply because its a "different" way for setting up Django with Amazon S3 storage.

As i said i am taking a different approach and although i am not certain if it is the best approach or not it does seem to work for me. If you find that this is not right please let me know in the comments and ill fix it.

Scenario

So the main idea here is to simply create a S3 Bucket that will hold both the static files and the media files, where you can set you static files to be public and your media to be private.


Amazon S3 Steps:

1 - CREATE THE BUCKET

2 - EDIT CORS CONFIGURATION TO BE:



If you do not to this you might end up having JavaScript errors like for example:

XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access


3- CREATE STATIC FOLDER AND SET IT TO PUBLIC:
You can use the s3 amazon console and right click on top of the static folder and choose the option `make public`

4 - CREATE MEDIA FOLDER
After crating this folder do not attempt to make it public otherwise it will beat the purpose of this tutorial

5 - YOU CAN START UPLOADING CONTENT BUT PLEASE NOTE THAT:
"It seems that this is a common issue when uploading files to a new bucket.
Something to do with the DNS propagation means it takes a little while before your bucket can successfully accept files. More info here.
After waiting a few hours running the same command completes successfully."
(http://tinyurl.com/q7cpjju)

This means that if you attempt to do a `python manage.py collectstatic` and get a broken pipe

it might be just because the DNS propagation is not finished.


Django Configurations:

Install django-storages and boto, read django-storages documentation and then you can just replace this settings.





You may read in other places that you need to set S3 bucket policies but i found that i really did not need to do that, by setting specifically the folders i want to be public.

Sunday, May 19, 2013

Python client Post to REST API using Basic Authentication

This is a simple post request to a REST API using python with basic authentication.

If you want to do a PUT, just uncomment the commented line and replace with the proper URL. Every other CRUD actions will follow the same approach.

Thursday, May 16, 2013

Using celery periodic tasks with Django

Although there are some documents and tutorials regarding this subject, i belive they are not well "explained" or are just a little confusing. So i decided to do my own tutorial.

its pretty simple actually, basically you just have to edit your settings.py and add this lines:


Monday, November 5, 2012

Quick guide to using django South migrations

Using django django South migrations at a basic level is fairly easy (for wasn't really had to bang my head for a while until i decided to write this guide).

First make sure you install south and add to your apps in settings.py.

"South is an intelligent schema and data migrations for Django projects." 

So after you have created your app and added some fields, you decided to add a new field.

First you have to make sure that your app is already converted to south, if not just run:

./manage.py convert_to_south app
Then everytime you make a change in your models just:

./manage.py schemamigration app --auto
./manage.py migrate app

To undo the migration or change a field just

python manage.py migrate profiles 0025

 - Soft matched migration 0025 to 0025_auto__add_field_locumprofile_one_line_description.
Running migrations for profiles:
 - Migrating backwards to just after 0025_auto__add_field_locumprofile_one_line_description.
 < profiles:0026_auto__add_field_locumprofile_plc_accepted_terms

then delete the migration file 0026

change the model

Thats it,  simple!!

Tuesday, May 15, 2012

Install Pip + Heroku + Foreman in Ubuntu 12.04

UPDATE:
Heroku has released their own toolkit, so this steps may no longer be required.
https://toolbelt.heroku.com/


Installing rails

You need to have ruby installed on your system
To install ruby, type in:

sudo apt-get install ruby

You can install rails either through gem or apt-get. I installed it using apt-get. You can do that by typing

sudo apt-get install rails

Installing heroku:

For heroku you need to have gem installed, to install gem, using apt-get type:

sudo apt-get install rubygems1.8

Also, before installing heroku you need to install rubydev as directly installing heroku gave me problems. To install rubydev type:

sudo apt-get install ruby1.8-dev

To add the .gem directory to your path type in:

gedit ~/.bashrc

At the end of the file type in:

sudo apt-get install python-pip
sudo apt-get install libpq-dev python-dev


PATH=$PATH:/home/_username_/.gem/ruby/1.8/bin
export PATH
(Replace _username_ with your username)

Now type in

source ~/.bashrc

This will add gem to your path. Now install heroku

now install heroku by typing:

sudo gem install heroku

And you are done! Heroku is installed. You may want to install additional tools needed by heroku, documented as following.

sudo gem install foreman

Install virtualenv
sudo apt-get install python-virtualenv

You can also install django in env in order to deploy django to Heroku see this tutorial for further instructions
pip install Django psycopg2