The first part of this project will be, of course, research. In order to get a good idea of a) where ‘gin’ stands in popular culture/what does that say about us/is there a wider picture/does this fit in a wider subject matter b) key flavour pairings of gin/popular usage and forms/what sort of data can be retrieved and how useful it can be/current gin projects c) commercial ‘gin’ & the economy/bars/what the professionals say d) ………..what next?
Therefore I thought it may be a good idea to get a base collection of ~500 gin cocktail recipes, and see what information I can retrieve from that.
Previously, I have used scraping methods to collect data, and I did consider doing the same for this project. But in early meanderings, I discovered a website called Yummly, a huge compendium of indexed recipes submitted by the public. The interface is great and simple, and scraping via CSS selectors would be very straightforward, but the best thing is that it has a developer REST API. OK, the free package only allows 500 calls a day, which can be awkward for testing, but ideally I would only make 500 calls overall. This allows straightforward access and flexibility, being able to request certain useful snippets of each cocktail recipe (ingredient, flavours, star rating, time to make), most notably the flavours of each cocktail, which will be incredibly useful. However it does have its limitations, but more on that later.
See link below. This is a super simple implementation of the Yummly API and I kind of expected it to be simple. The example below prints out the simpler parameters in a simple HTML table, and an API call is made each time the browser is refreshed, there is no underlying storage as such. This example utilises the ‘Search Recipe’ API call, where search criteria is passed as parameters through the AJAX request. This call returns (for each result) attributes (such as course – beverages), flavours (salty, sour, sweet, bitter, meaty, piquant), ingredients and images, nutritional info. However, units and quantities of each ingredient are not included in this call. The other Yummly API call, ‘Get Recipe’, is incredibly similar to the ‘Search Recipe’ call, however it returns the ingredient quantity, unit and name as a whole string. At this point, that was a problem & a big warning flag. If I were to continue with JS, I would have considered using node.js to handle the server side, as I had worked with it previously and did not hate it, and acknowledge just how great it is to use JS server side.
PHP + Yummly
Again, a simple implementation of the Yummly API with PHP. With this example, however, I also submitted each recipe to a MySQL database..
At this stage, I was incredibly scared of database relations, especially many-to-many relationships. Yes, the database model for this gin-hunt is linear and clunky. But I was pleased to make progress by storing data.
I have relied on PHP quite often for projects, but have found myself recently moving away from it. Like in this example, it works just fine, but I felt like there must be a more suitable way to move forward with the project and get the most from it. As previously, I utilised the ‘Search Recipe’ call, for much the same results. Also in this script, I stored singular ingredients in a separate table (note, no relation to the main table, oh dear). I had the idea that I would use the values stored in the ‘ingredients’ table to use against full ingredient strings in a future ‘Get Recipe’ call in order to separate the ingredient from the quantity and unit.
Python + Yummly API
See link below. Well, I made an awful lot of progress using Python and an “of course that’s possible” mindset instilled in me by Alcwyn. Recently I have used Python in my Computing Development job for processing .CSVs and rendering graphs and maps from them, and discovered that Python is pretty powerful in terms of pattern matching and Regex, so I felt determined to split those ingredient strings from the ‘Get Recipe’ API call to get the data I really require, which so far I have been fairly successful with. It turns out someone else had the same problem as me, and although the Regex itself needed tweaking, it has been effective in splitting the strings. But I feel that is another blog post in itself, as the process is actually pretty interesting and I learnt a lot.
Further to this, I started to implement the Flask framework for Python. It is similar in form to Django, but describes itself as a “microframework”. So far, I have found it to be lightweight but mighty powerful, and works wonderfully at rendering my data. The routing methods are absolutely spot-on and surprisingly simple, in my case using Flask-SQLalchemy with an SQLite database. Again, that’s another blog post. The most significant development within the Python test was the REST-ful style search within the URL, in this example, enabling the user to search for any ingredient, with a list of recipes including the ingredient to be routed to the page.
Also – Object Oriented Programming is wonderful and I am so glad to finally understand it. The way Flask is built, as a developer, you are guided towards using OOP practises within the models/views/framework, the learning curve of which is not very scary and hugely useful.
Live Example – Listing all recipes
Live Example – Search for ‘Gin’ within Cocktail Title Try with other parameters!
Live Example – Search for ‘Gin’ within Cocktail Ingredients Try with other parameters!
Scrape & Store Source Code (Github)
Routing Source Code (Github – see selected lines)