My Website
Given that I wrote this site as a learning exercise, it seems appropriate that I write about how I made it. I’m running a LAMP Server, using Amazon Web Services to host it. There are various versions of LAMP, but given my familiarity with Python I decided to go with Python as my language of choice. I’m using MySQL and Apache for my database and webserver, and I’m using Ubuntu 16.04 LTS as my base OS. These are mostly because they’re all offered by Amazon as a pre-installed instance so it’s nice and simple. I’m a firm believe in the concept of only doing 1 new thing at a time, rather than everything at once. On the other hand, to totally contradict myself, I also agree with Elon Musk’s dictum that ’If things are not failing, you are not innovating enough’. I would argue that the prototypes of this site failed often enough for me to claim both! The saying about not testing in production also springs to mind.
The majority of the work of the server is done by Python, using the Flask framework. I think Flask is one of the best third party tools I’ve ever coded with: It’s genuinely simple to work with, and adding a new page to the server can be done in 3 lines of code. You have access to all of the utility of Python, without adding a huge amount of boilerplate code to achieve anything. I’ve learned everything I know about Flask from Miguel Grinberg's Tutorial, which walks through creating a blog. Once again, I have massively diverged from the guide (He is creating something akin to Twitter), but used it as a valuable source of background knowledge.
The standard way of creating webpages, using HTML, CSS and Javascript is set up such that the content (HTML) is broadly independent of the styling (CSS), and the interactive functionality (Javascript). While there are some areas in which they overlap, it is both possible and advantageous to write each in it’s own file. Flask takes this principal further, by removing all of the web elements from the Python Code. It manages to avoid The Law of Leaky Abstractions pretty well, meaning that when I’m writing backend logic I never have to think about HTML. I think the only HTML in my code is one section where I’m embedding 2 pages in 1 to create the index, and have to search through for a particular tag. For that purpose, I’m using BeautifulSoup, a Python library designed for manipulating HTML (and XML, but I haven’t tried that).
The HTML is generated entirely using Jinga2 Templates, which is a templating language written for Python. I was initially dubious about learning yet another language, but it is basically just Python embedded in curley braces. It allows you to put any python variable into the HTML, and include other HTML files wherever. This massively benefits code reuse, and makes the file for each page very simple to write and maintain. It also makes it very easy to create a new page - I don’t have to worry about including the header and title - I just type the content I want and the templating engine does the rest.
I’m using SQL-Alchemy to interface with my database. This is another very well written framework, allowing me to change databases with a single line of a config file. I use MySQL in production, but SQLite in development. For development purposes this abstracts the DB away to a single file, which I only interact with via python. This again, avoids trying to do lots of things at once - I’ll leave a detailed exploration of SQL for a future project. SQL-Alchemy allows my to change with DB I’m using on the backend by altering the URI, which happens automatically depending on which environment I’m working in.
I’ve currently only got login via Username and Password. While I am not personally a fan of forcing people to use usernames and passwords, and I fully intend to implement OAuth in the near future, I wanted to create a username and password system as an education piece for myself. It also gave me an opportunity to go down a pretty epically sized rabbit hole about password security and breaches. On the back of much of this research, I decided to go with an unusual password policy, based on Jeff Atwood's advice. I’ve prevented passwords of less than 10 characters, and I’m checking passwords against a blacklist of around 130,000 entries. Other than that (and the obvious things like don’t make your password the same as your email), THERE ARE NO RULES. This is because I want to make passwords as easy as possible to remember. (Oh, and use a password manager. It’s a million times easier, but that’s another post!)