<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Harley Hicks</title>
    <description>The latest articles on DEV Community by Harley Hicks (@hmhrex).</description>
    <link>https://dev.to/hmhrex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F22808%2F85e3c365-5df3-4492-8774-0ddbae3ac6a4.png</url>
      <title>DEV Community: Harley Hicks</title>
      <link>https://dev.to/hmhrex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hmhrex"/>
    <language>en</language>
    <item>
      <title>Coding My Way Into The Magic Kingdom</title>
      <dc:creator>Harley Hicks</dc:creator>
      <pubDate>Wed, 02 Nov 2022 15:14:00 +0000</pubDate>
      <link>https://dev.to/hmhrex/coding-my-way-into-the-magic-kingdom-1ok2</link>
      <guid>https://dev.to/hmhrex/coding-my-way-into-the-magic-kingdom-1ok2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Originally posted on my &lt;a href="https://harley.hicks.house/coding-my-way-into-the-magic-kingdom/" rel="noopener noreferrer"&gt;personal site&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In April of 2022, we took our family to Disney World for the first time. We were excited, the kids were excited, and everything was looking up. I planned everything 6 months in advance booking lodging, plane tickets and a rental vehicle. Everything except Disney World tickets. My thinking was that in the unlikely event of a sale, I could save some hard-earned cash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I felt like I had everything figured out.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I was the smartest person because I had thought of everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I wasn't aware of though, was the new ✨park reservation system✨.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reservation System
&lt;/h2&gt;

&lt;p&gt;If I had done a little more research, I would have found out that starting in 2020, as a response to the pandemic, Disney put a reservation system in place for their parks. Meaning that they now limit the amount of people in each park each day. When you buy your tickets, you also have to reserve your spot in the park you want to go to. This allows them to keep numbers down for their parks and probably also makes it a little easier to manage other things like staffing.&lt;/p&gt;

&lt;p&gt;So, when I went to buy our tickets, I was surprised and disappointed to find out that the only park that wasn't completely booked for the 2 days we had scheduled, was EPCOT.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kkcw7jh40t2cdzupx9j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kkcw7jh40t2cdzupx9j.jpg" alt="EPCOT - Photo by Robert Horvick on Unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't get me wrong, EPCOT is a really cool! There's lots of great stuff there, but I knew our 4 young kids (and us two parents) would be disappointed with not being able to see the castle and other cool parts of the Magic Kingdom. After talking about it with my incredibly patient and forgiving partner, we decided to just go with the flow and do 2 days at EPCOT.&lt;/p&gt;

&lt;p&gt;But I wasn't satisfied. I needed to right my wrongs. I started to wonder if I could put my skills to use get us into the Magic Kingdom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pondering
&lt;/h2&gt;

&lt;p&gt;Disney has a &lt;a href="https://disneyworld.disney.go.com/availability-calendar/?segments=tickets,resort,passholder&amp;amp;defaultSegment=tickets" rel="noopener noreferrer"&gt;page on their site that shows the reservation availability&lt;/a&gt;, which is what I used to find out that only EPCOT was available. When I was on the phone talking to a representative buying tickets, they mentioned that sometimes people cancel and you can grab that reservation. I asked how often that happens and they told me that it's rare, but if you watch that reservation availability page, you might get lucky.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvupuxdj0mtih2c77mc6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvupuxdj0mtih2c77mc6x.png" alt="The reservation availability system"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting two weeks before our Disney World visit, I checked this page nearly every chance I got every single day. It became an all-consuming task. I really wanted to pick up that cancelled reservation before someone else snagged it. That's when I decided to automate the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time For Some Recon
&lt;/h2&gt;

&lt;p&gt;Looking at the calendar, I realized that when I clicked to the next month, it was probably grabbing data from their server to show what was available. Checking the Network tab in the inspector tools confirmed this.&lt;/p&gt;

&lt;p&gt;The response is a JSON object with all the dates, and for each date, what parks had reservations available. Taking a look at the URL being used to fetch this data, I noticed it had very simple arguments.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://disneyworld.disney.go.com/availability-calendar/api/calendar?segment=tickets&amp;amp;startDate=2022-05-01&amp;amp;endDate=2022-05-31&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;segment&lt;/code&gt; - Can be &lt;code&gt;ticket&lt;/code&gt;, &lt;code&gt;resort&lt;/code&gt;, or &lt;code&gt;passholder&lt;/code&gt;. We want &lt;code&gt;ticket&lt;/code&gt; to get the ticket data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;startDate&lt;/code&gt; - The start date of the range of data you want.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;endDate&lt;/code&gt; - The end date of the range of data you want.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple!&lt;/p&gt;

&lt;p&gt;So if we want to look at what might be available in the third week of May (15th through 21st), we can use this URL:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://disneyworld.disney.go.com/availability-calendar/api/calendar?segment=tickets&amp;amp;startDate=2022-05-15&amp;amp;endDate=2022-05-21&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And we get the following data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007944"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007998"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007838"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007838"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-18"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"partial"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007838"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2022-05-21"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007944"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007823"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007998"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"80007838"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The availability variable is pretty obvious. It just tells us if there is availability or not that day. It has three states - none, partial, and full. The parks array shows us what parks are available, but instead of names, we get some sort of ID for each park. This took a little work to figure out, but looking between the website and the JSON data, I was able to determine which ID represented what park.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;80007823 = Animal Kingdom
80007838 = EPCOT
80007944 = Magic Kingdom
80007998 = Hollywood Studios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With all this information gathered, it was time to start putting it to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Get Coding
&lt;/h2&gt;

&lt;p&gt;First, I decided on a few tools to get this automation in place. I'm using the free tiers for all the services, so they didn't cost me a penny 💅&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python - Usually my language (weapon) of choice, especially for automation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.python-requests.org/en/latest/" rel="noopener noreferrer"&gt;Requests&lt;/a&gt; - If you have ever used Python, you have probably used this library. It allows you to send and receive requests and responses using HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/functions/" rel="noopener noreferrer"&gt;Google Cloud Functions&lt;/a&gt; - Used to run our code on a schedule.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.twilio.com/messaging" rel="noopener noreferrer"&gt;Twilio Messaging&lt;/a&gt; - To send ourselves a text message alert if the Magic Kingdom becomes available!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's start with how we receive our data. Here we're using Requests. Here's our code, with comments to explain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# Set our variables for the request we want to make
&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://disneyworld.disney.go.com/availability-calendar/api/calendar&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;start_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2022-05-15&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;end_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2022-05-21&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;# Add a header so that the request looks legit
&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:98.0) Gecko/20100101 Firefox/98.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Set our URL parameters to get the data we want
&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;segment&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tickets&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;startDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;endDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Using the above data, make our request, and get our response
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Convert the data from a JSON string to a python dictionary
&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was fairly painless. Now that we have the data we need, let's use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Map the IDs with the parks
&lt;/span&gt;&lt;span class="n"&gt;parks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007823&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Animal Kingdom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007838&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EPCOT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007944&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Magic Kingdom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007998&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hollywood Studios&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# The park we're looking for
&lt;/span&gt;&lt;span class="n"&gt;park_wanted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007944&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;# An array of available dates
&lt;/span&gt;&lt;span class="n"&gt;dates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="c1"&gt;# data is from the response in the code block above
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Check if there's availability
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;availability&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Check if the park we want is available
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;park_wanted&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;parks&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="c1"&gt;# Add the date to our available dates array
&lt;/span&gt;            &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I won't go into setting up Twilio, because they do a great job on-boarding their clients and explaining how to get started. Our code is pretty simple. We're just creating a Twilio client with our account information, crafting a text message, and sending it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Import the Twilio client
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;twilio.rest&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;

&lt;span class="n"&gt;account_sid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;A*******&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;             &lt;span class="c1"&gt;# Twilio account SID
&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;b*******&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;              &lt;span class="c1"&gt;# Twilio auth token
&lt;/span&gt;&lt;span class="n"&gt;twilio_phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;+1**********&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;# Phone number Twilio account sends from 
&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;+1**********&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;        &lt;span class="c1"&gt;# Our phone number
&lt;/span&gt;
&lt;span class="c1"&gt;# Check if we found any available dates
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Create our Twilio client
&lt;/span&gt;    &lt;span class="n"&gt;twilio_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account_sid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Create and send our message
&lt;/span&gt;    &lt;span class="n"&gt;twilio_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reservations are now available for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="n"&gt;parks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;park_wanted&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Reserve now: https://disneyworld.disney.go.com/park-reservations/create-party&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;from_&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;twilio_phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to combine it all, and make it usable by Google Cloud Functions. We need to wrap the important parts in a function for Google Cloud Functions to call, and then we also need to return something at the end of that function. Here's our finished code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;twilio.rest&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;

&lt;span class="n"&gt;parks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007823&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Animal Kingdom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007838&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EPCOT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007944&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Magic Kingdom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007998&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hollywood Studios&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;park_wanted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80007944&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;account_sid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;A*******&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;auth_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;b*******&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;twilio_phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;+1**********&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;+1**********&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://disneyworld.disney.go.com/availability-calendar/api/calendar&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;start_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2022-05-15&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;end_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2022-05-21&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:98.0) Gecko/20100101 Firefox/98.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;segment&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tickets&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;startDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;endDate&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;dates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;availability&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;park_wanted&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;parks&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;twilio_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account_sid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;twilio_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reservations are now available for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="n"&gt;parks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;park_wanted&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Reserve now: https://disneyworld.disney.go.com/park-reservations/create-party&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;from_&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;twilio_phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;complete&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing to do, is put this on Google Cloud Functions. There are plenty of articles on the internet about how to get going with Google Cloud Functions, so I won't get into that here.&lt;/p&gt;

&lt;p&gt;And now we wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  Waiting
&lt;/h2&gt;

&lt;p&gt;We got on the plane, and I still hadn't gotten a text.&lt;/p&gt;

&lt;p&gt;Two days later, we settled in at the resort, still no text.&lt;/p&gt;

&lt;p&gt;The next day we arrived at EPCOT for our first day at Disney World with still no text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then It Happened
&lt;/h2&gt;

&lt;p&gt;I don't think I'll ever forget the moment. We had just watched the EPCOT fireworks show feeling like we were on top of the world. My partner and I were walking side-by-side both pushing double strollers with our near-sleeping children surrounded by all the other families. We talked about all the things we missed that day that we would check out on our second day...&lt;/p&gt;

&lt;p&gt;Then it dawned on me that I had gotten several notifications on my phone in the last couple minutes. I pulled my phone out of my pocket and shouted to my partner, "THE MAGIC KINGDOM IS OPEN!". We found a table, parked the strollers, frantically tried to cancel our second day EPCOT reservation, and then finally reserved our second day for Magic Kingdom.&lt;/p&gt;

&lt;p&gt;We had done it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs312yw33crwn6po9l27f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs312yw33crwn6po9l27f.jpg" alt="Magic Kingdom Castle - Photo by Capricorn song on Unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrospective
&lt;/h2&gt;

&lt;p&gt;After coming down from the adrenaline rush of the trip, I thought about if this could be made into a service for others to use. There were a couple problems I noticed as I did the thought experiment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I don't think there would be enough clients to warrant this as a service.&lt;/li&gt;
&lt;li&gt;If there were more than one customer trying to secure a specific park on a certain date, it would pit them against each other. That doesn't seem fair.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've also learned lately that sometimes you can build something that's just for you. It doesn't need to be for everyone. I think that can make it special.&lt;/p&gt;

</description>
      <category>python</category>
      <category>twilio</category>
      <category>googlecloud</category>
      <category>automation</category>
    </item>
    <item>
      <title>A Comparison Of The Top 3 Privacy-Focused Analytics Platforms</title>
      <dc:creator>Harley Hicks</dc:creator>
      <pubDate>Mon, 11 Nov 2019 19:59:53 +0000</pubDate>
      <link>https://dev.to/hmhrex/a-comparison-of-the-top-3-privacy-focused-analytics-platforms-209m</link>
      <guid>https://dev.to/hmhrex/a-comparison-of-the-top-3-privacy-focused-analytics-platforms-209m</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr : View the chart at the bottom for a quick rundown between the top 3 privacy-focused analytics platforms.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have a huge problem with Google Analytics. The idea is that you get free analytics on the users of your site in exchange for sharing those analytics with Google. All that data is getting matched with other site data all over the web. You're essentially giving away your user's personal data to Google so that it can be used against them. Not exactly a fair, or ethical, trade.&lt;/p&gt;

&lt;p&gt;Originally, I built my own analytics platform for &lt;a href="https://routinehub.co" rel="noopener noreferrer"&gt;RoutineHub&lt;/a&gt;, but I found over time that it was hard to maintain, and probably wasn't filtering out bad data. So I did some research and found that there are a few privacy-focused analytics platforms out there doing exactly what I'm looking for. I trialed three of these platforms simultaneously to see which one works best for my needs. Here are the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plausible
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://plausible.io/routinehub.co" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plausible is a single-person project built by Uku Täht launched in April of 2019. Even though it's only been out for a short period of time, it boasts some interesting features.&lt;/p&gt;

&lt;p&gt;Plausible has basic analytics like unique visitors, current visitors, total page-views, top referrers, top pages, top countries, screen size, operating system, and browser. It also has support for Google Search Keywords which is a pretty nifty feature. It's really simple, loads quickly and keeps up to date very well.&lt;/p&gt;

&lt;p&gt;One thing I've had a problem with is that the data doesn't match up with my timezone completely. I've reached out to Uku about this, and he's pretty easy to get a hold of and is working on fixing the issue.&lt;/p&gt;

&lt;p&gt;The price-point is much less than the competitors which makes it a great way to get into basic privacy-focused analytics. You can track as many sites as you want, the tiers are based on number of page-views.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Up to 10K page-views a month - $6/month&lt;/li&gt;
&lt;li&gt;Up to 100K page-views a month - $12/month&lt;/li&gt;
&lt;li&gt;Up to 1M page-views a month - $36/month&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Simple Analytics
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://plausible.io/routinehub.co" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simple Analytics was launched in September of 2018 by Adriaan van Rossum. He has added a couple other people to the now 3-person team. &lt;/p&gt;

&lt;p&gt;The data points Simple Analytics stores are pretty much the same as Plausible, except they don't have unique visitors. They probably are trying to make it more anonymous, but there are ways to check for uniqueness without storing actual IP addresses.&lt;/p&gt;

&lt;p&gt;I do really like that they have an API. Having that access is nice for if you need granular data for your users.&lt;/p&gt;

&lt;p&gt;I also like that they have support for a custom domain. This means you can have the analytics requests coming from within your own domain which helps lessen the amount of traffic getting stopped by ad blockers.&lt;/p&gt;

&lt;p&gt;Simple Analytics is the most expensive compared to its competitors. All tiers have unlimited amount of sites.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Up to 100K page-views a month - $19/month&lt;/li&gt;
&lt;li&gt;Up to 1M page-views a month - $59/month&lt;/li&gt;
&lt;li&gt;Over 1M page-views a month - Call for pricing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fathom
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://app.usefathom.com/share/pisdlnji/routinehub" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fathom is a project built between Paul Jarvis and Jack Ellis and launched in April of 2018. Out of the three analytics platforms discussed here, it's been around the longest.&lt;/p&gt;

&lt;p&gt;Fathom has all the normal data points you would need, plus some extra ones that I find very useful. For instance, being able to see where current users are coming from right now is a handy feature. If you have a huge spike in traffic, you can see where it's coming from and act accordingly. Some other good data points are average time on site and bounce rate.&lt;/p&gt;

&lt;p&gt;Fathom's pricing is right in the middle of the other two services. You can track as many sites as you want, the tiers are based on number of page-views.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Up to 100K page-views a month - $14/month&lt;/li&gt;
&lt;li&gt;Up to 1M page-views a month - $44/month&lt;/li&gt;
&lt;li&gt;Up to 5M page-views a month - $114/month&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Analytics Differences
&lt;/h2&gt;

&lt;p&gt;Obviously there are going to be some difference in analytics numbers, but I found some interesting discrepancies between the three. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Plausible&lt;/th&gt;
&lt;th&gt;Simple Analytics&lt;/th&gt;
&lt;th&gt;Fathom&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unique Visitors&lt;/td&gt;
&lt;td&gt;38.1K&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;42.9K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total Page Views&lt;/td&gt;
&lt;td&gt;156K&lt;/td&gt;
&lt;td&gt;134K&lt;/td&gt;
&lt;td&gt;155.6K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current Visitors&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This data is for all traffic between November 1st (12AM) and November 11th (10AM).&lt;/p&gt;

&lt;p&gt;I found these differences quite interesting. Simple Analytics seems to be more on the conservative side, but this is probably because some ad blockers block it. Plausible and Fathom have around the same amount. I'm not sure which one is more accurate. All three are less than the amount my own system was recording, probably due to filtering out spam and other bad requests.&lt;/p&gt;

&lt;p&gt;Here are the screenshots that this data is coming from:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdtvxg8f8e1vpqxx1aogu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdtvxg8f8e1vpqxx1aogu.png" title="Plausible" alt="Plausible"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7z1prhaeguhufsrxui3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7z1prhaeguhufsrxui3e.png" title="Fathom" alt="Fathom"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5cd63n66sucogk19psoe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5cd63n66sucogk19psoe.png" title="Simple Analytics" alt="Simple Analytics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;All three have their pros and cons, as you can see from the chart below. However, for the price and it's feature set, Fathom seems to be a good fit for my site. Google Search Keywords and custom domain support would both be nice, but I can live without them for now. Current visitor details, average time on site and bounce rate are all killer features that help me make better decisions.&lt;/p&gt;

&lt;p&gt;Simple Analytics are a bit &lt;em&gt;too&lt;/em&gt; simple for me at the moment for its price point, but the roadmap looks very positive.&lt;/p&gt;

&lt;p&gt;Plausible is really affordable with its price point, but it doesn't have quite as many features as the other two platforms.&lt;/p&gt;

&lt;p&gt;If you're just starting out or have a smaller budget, Plausible is a great choice. If you're looking for more data and can spend a little more, Fathom is your best bet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison Chart
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Plausible&lt;/th&gt;
&lt;th&gt;Simple Analytics&lt;/th&gt;
&lt;th&gt;Fathom&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Price (1M page-views)&lt;/td&gt;
&lt;td&gt;$36/month&lt;/td&gt;
&lt;td&gt;$59/month&lt;/td&gt;
&lt;td&gt;$44/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trial&lt;/td&gt;
&lt;td&gt;30 days&lt;/td&gt;
&lt;td&gt;7 days&lt;/td&gt;
&lt;td&gt;7 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current Visitors&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unique Visitors&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total Pageviews&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Date Range&lt;/td&gt;
&lt;td&gt;✔️/❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top Referrers&lt;/td&gt;
&lt;td&gt;✔️+&lt;/td&gt;
&lt;td&gt;✔️+&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top Pages&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top Countries&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screen Size&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operating System&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avg Time On Site&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bounce Rate&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;🗺️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Goals/Events&lt;/td&gt;
&lt;td&gt;🗺️&lt;/td&gt;
&lt;td&gt;👨‍💻&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bypass Privacy Badger&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bypass uBlock&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Search Keywords&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;🗺️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom Domain&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download your data&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public Visibility&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Source&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️/ ❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;🗺️&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GDPR compliant&lt;/td&gt;
&lt;td&gt;❓&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️+&lt;/td&gt;
&lt;td&gt;Yes with details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🗺️&lt;/td&gt;
&lt;td&gt;On roadmap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👨‍💻&lt;/td&gt;
&lt;td&gt;In beta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️/❌&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❓&lt;/td&gt;
&lt;td&gt;Unsure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>privacy</category>
      <category>analytics</category>
      <category>fathom</category>
      <category>plausible</category>
    </item>
    <item>
      <title>Let's get back to basics with online advertising</title>
      <dc:creator>Harley Hicks</dc:creator>
      <pubDate>Fri, 07 Jun 2019 17:33:25 +0000</pubDate>
      <link>https://dev.to/hmhrex/let-s-get-back-to-basics-with-online-advertising-1ol0</link>
      <guid>https://dev.to/hmhrex/let-s-get-back-to-basics-with-online-advertising-1ol0</guid>
      <description>&lt;p&gt;Advertising gets a bad rap these days. Many companies that provide data as a product for advertising have recently come under the microscope of not only tech gurus but governments as well. How did we get here and how can we get out of this mess? Is there a future for online ads in the wake of Ad Blockers? Can we ethically advertise to people without the mass collection of data?&lt;/p&gt;

&lt;h3&gt;
  
  
  How modern advertising helps
&lt;/h3&gt;

&lt;p&gt;Modern online advertising services promise better targeting of your advertisements which gets you in front of the right people while also preventing you from wasting money on showing it to the wrong audience. Each impression and click costs money after all, and your product is going to change people's lives, they just don't know it yet! &lt;/p&gt;

&lt;p&gt;This seems like a win-win-win situation. Businesses get their ads in front of the right audience, consumers get ads that they might actually care about, and websites can keep up and running by hosting advertisements that are specific to their audience. It's a vast improvement from back when you just threw money at a site and hoped it connected with the some of the audience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuefl0u684l503kqwyms0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuefl0u684l503kqwyms0.gif"&gt;&lt;/a&gt;&lt;/p&gt;
Everybody is looking for a better price for internet and love in their life, right?



&lt;p&gt;And it's simple too! A business pays an advertising service to serve advertisements to their target market, a website owner adds a tiny of code to their site, and bam, everyone's happy!&lt;/p&gt;

&lt;h3&gt;
  
  
  How modern advertising hurts
&lt;/h3&gt;

&lt;p&gt;Except, these advertising platforms start to show their ugly side.&lt;/p&gt;

&lt;p&gt;Users begin to realize that sites they like to visit are getting increasingly slower. They also notice that they are hitting their phone service data cap a lot quicker. Then they notice that the next three sites they visit show them a watch they viewed a half an hour earlier, but don't actually care for.&lt;/p&gt;

&lt;p&gt;At first, everyone just sees it as a necessary evil. What else is going to pay for the servers these sites are running on? So for several years, sites get slower, more data on site visitors is gathered and people slowly become numb to advertisements. Governments start taking an interest in data that once seemed benign and start using it to their advantage.&lt;/p&gt;

&lt;h3&gt;
  
  
  The rise of Ad Blocking
&lt;/h3&gt;

&lt;p&gt;Then people decide that they've had enough and start to fight back. They realize that they can block these advertisements. This saves space on the page, makes site loading incredibly faster, and prevents sites from gathering data that they don't really want in databases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.raymond.cc%2Fblog%2Fwp-content%2Fuploads%2F2015%2F08%2Fchrome_ad_blocker_combined_scores.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.raymond.cc%2Fblog%2Fwp-content%2Fuploads%2F2015%2F08%2Fchrome_ad_blocker_combined_scores.png"&gt;&lt;/a&gt;&lt;/p&gt;
The incredible speed difference Ad Blockers make (Data from an article 2 years ago on Raymond.cc)



&lt;p&gt;The people rejoice! They're taking back the internet and making it easier to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  The wrong response to Ad Blocking
&lt;/h3&gt;

&lt;p&gt;Web site owners fight back. They create pay walls that don't allow you to enjoy the content unless you turn off your Ad Blocker or pay a monthly subscription. They decide to try and circumvent Ad Blockers. Or they simply show a pop-up trying to explain to you their position and attempt to persuade you to make an exception in your Ad Blocker for just their site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmagnetolabs.com%2Fwp-content%2Fuploads%2F2017%2F09%2FBusiness-Insider-Adblock-Example.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmagnetolabs.com%2Fwp-content%2Fuploads%2F2017%2F09%2FBusiness-Insider-Adblock-Example.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can't blame them. They aren't the ones tracking you. All they're doing is putting a little extra code on the site that generates money so that they can keep creating quality content for you. It's not even the fault of the business who's advertising. They just want to sell product.&lt;/p&gt;

&lt;p&gt;However, web site owners and businesses fail to realize that ad blockers aren't fighting &lt;em&gt;advertisements&lt;/em&gt;, they're fighting &lt;em&gt;tracking and over-the-top data gathering&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  The real problem
&lt;/h3&gt;

&lt;p&gt;Advertising services real product to their clients is consumer data. If they can just get the right data for each internet user, they can leverage that for their customers and generate more profit. &lt;/p&gt;

&lt;p&gt;They build huge warehouses full of servers that continuously grab little bits of information and store it alongside an "anonymous" profile for each internet user they come in contact with. They leverage the code web site owners put on their site by adding tracking code. They also start paying companies to give them data on their customers. What applications you download, how you use your digital devices, your credit card purchasing habits and your daily interactions with family and friends all end up in these data warehouses. Your digital self is replicated by an "anonymous" profile all for the sake of tailoring your advertising experience.&lt;/p&gt;

&lt;p&gt;And businesses know this. They aren't totally blind to it, but it has become the norm for it to be morally and ethically OK because, well, everyone else is doing it.&lt;/p&gt;

&lt;p&gt;Despite popular belief however, it turns out that consumer data isn't all that necessary for advertising.&lt;/p&gt;

&lt;h3&gt;
  
  
  Going back to basics
&lt;/h3&gt;

&lt;p&gt;Where do you go for specific information? Do you go to a blog that reviews ice cream when your car is making a funny noise? Do you head over to the "Tired Moms" Facebook Group to find the latest news about video games?&lt;/p&gt;

&lt;p&gt;Think about this for a minute.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Websites are already targeting markets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Facebook could easily be targeting ads by specified Group categories instead of by single user data. Google could target ads only by raw search terms like up-and-comer DuckDuckGo. Businesses could contact sites that are specific to their market and work with them directly to show advertisements and vice versa.&lt;/p&gt;

&lt;p&gt;As I typed that last paragraph, I realized how silly of an "ah-ha" moment that truly sounds because we're already doing these things. So why not just cut out the tracking?&lt;/p&gt;

&lt;h3&gt;
  
  
  How I envision it
&lt;/h3&gt;

&lt;p&gt;Say we run a site about raising Angora rabbits. We need advertisers to keep our site up and running, so we need to figure out what our markets are.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rabbits need to eat. Market - Rabbit food&lt;/li&gt;
&lt;li&gt;Rabbits need shelter. Market - Rabbit hutches&lt;/li&gt;
&lt;li&gt;Did you know that some people shear Angora rabbits and spin their fur into yarn? Markets - Needles, tools to spin wool, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we go to those companies and convince them that our website is a perfect place to advertise their products. We run non-intrusive ads that contain text, a small image and a link at a fair price and the money goes straight into our pockets. The ads load quickly and doesn't get blocked by Ad Blockers because you are hosting it yourself and not tracking data except for impressions and clicks.&lt;/p&gt;

&lt;p&gt;Businesses are happy because you drive traffic and sales to their sites, site visitors are happy because they found the perfect hutch for their new rabbits, and you can sleep at night knowing that you aren't sending your visitors user data over to a warehouse somewhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  It's already begun
&lt;/h3&gt;

&lt;p&gt;The Ethical Advertising revolution has already begun, but quietly and slowly. Several companies have been working to make Ethical Advertising more normal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/coderberry" rel="noopener noreferrer"&gt;Eric Berry&lt;/a&gt; runs &lt;a href="https://codefund.io" rel="noopener noreferrer"&gt;CodeFund&lt;/a&gt;, an ethical advertising network. They run tech ads on sites that host open-source programming projects. The ads are light-weight, simply targeted, and don't track any extra data than necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/djfische" rel="noopener noreferrer"&gt;David Fischer&lt;/a&gt;, the Advertising Director at Read the Docs, has worked to enforce their &lt;a href="https://docs.readthedocs.io/en/stable/advertising/ethical-advertising.html" rel="noopener noreferrer"&gt;Ethical Ads guidelines&lt;/a&gt; across their site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/galoppini" rel="noopener noreferrer"&gt;Roberto Gallopini&lt;/a&gt; who works with Filezilla, has also enforced their &lt;a href="https://filezilla-project.org/ethical_ads.php" rel="noopener noreferrer"&gt;Ethical Ads guidelines&lt;/a&gt; on their project site.&lt;/p&gt;

&lt;p&gt;And at RoutineHub, my own project, I host my own &lt;a href="https://routinehub.co/ads" rel="noopener noreferrer"&gt;Ethical Ads&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're a business, find web sites that are in your market and work with them to get advertisements running there.&lt;/p&gt;

&lt;p&gt;If you're an advertising network, be more conscious about how you use user data to target ads.&lt;/p&gt;

&lt;p&gt;If you run a website, host the ads from your own server and look for businesses in your market that want to advertise on your site.&lt;/p&gt;

&lt;p&gt;If you're an internet denizen, keep using Ad Blockers. Keep up the fight against unnecessary tracking. Keep speaking out against companies and websites that are working against creating a better and safer internet.&lt;/p&gt;

&lt;p&gt;I believe in this future strongly, but it will take considerable work and education to get there. Join us. Let's make advertising simpler and more effective &lt;em&gt;without&lt;/em&gt; the unnecessary gathering of user data.&lt;/p&gt;

&lt;p&gt;If you run a site that has Ethical Advertisements, &lt;a href="https://twitter.com/hmhrex" rel="noopener noreferrer"&gt;send it to me on Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ethics</category>
      <category>advertising</category>
      <category>transparency</category>
    </item>
    <item>
      <title>Ethical Advertising</title>
      <dc:creator>Harley Hicks</dc:creator>
      <pubDate>Fri, 08 Mar 2019 19:46:02 +0000</pubDate>
      <link>https://dev.to/hmhrex/ethical-advertising-5157</link>
      <guid>https://dev.to/hmhrex/ethical-advertising-5157</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted over on the RoutineHub blog: &lt;a href="https://routinehub.co/blog/1/ethical-advertising"&gt;https://routinehub.co/blog/1/ethical-advertising&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Modern advertising sucks.
&lt;/h3&gt;

&lt;p&gt;When I think of internet advertising, I usually get angry. Fast. What bubbles up in mind are reminders of so many websites, web apps and social media sites that have become slowly ruined by advertising. There are usually two categories of sites I think of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sites where I only see 20% content and 80% ads.&lt;/li&gt;
&lt;li&gt;Sites that track, package and sell my data to almost anyone who will have it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And most times those sites do &lt;em&gt;both&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QJha0ijy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/routinehub-assets/static/main/images/adsadsads.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QJha0ijy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/routinehub-assets/static/main/images/adsadsads.png" alt="ads ads ads" title="So many ads"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Yes, I had to turn off my adblocker(s) to get this screenshot.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But sites have to generate revenue to continue growing and hosting. Modern internet advertisements are just seen as a necessary evil for most people trying to grow and maintain their site. Plus, they couldn't be bothered to try and find advertisers, that just requires more work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter me.
&lt;/h3&gt;

&lt;p&gt;I've always been a bit of an idealist. I don't mind taking the difficult path if I truly believe it's the most ethically correct one. I sometimes get strange looks when I try to explain my position, but that's fine. I'm not trying to convert others, I just want to do what I think is best so that I can sleep at night. And I &lt;em&gt;could not&lt;/em&gt; sleep at night if I had third-party ad networks tracking my users against their will and without their knowledge.&lt;/p&gt;

&lt;p&gt;I wanted an ad network that would satisfy these requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Doesn't track my users.&lt;/li&gt;
&lt;li&gt;Doesn't sell my user's data.&lt;/li&gt;
&lt;li&gt;Doesn't target users based on profiles.&lt;/li&gt;
&lt;li&gt;Doesn't create a big lag time on my pages to render their ads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I spent a couple of weeks researching, and was completely dissatisfied with the lack of options out there.&lt;/p&gt;

&lt;h3&gt;
  
  
  So I built my own ad service.
&lt;/h3&gt;

&lt;p&gt;I decided that if something doesn't exist out there for what I want, then I'll just build it myself. I was really inspired by &lt;a href="https://overcast.fm/ads"&gt;Overcast's automated ads&lt;/a&gt;, &lt;a href="https://www.codefund.io/"&gt;CodeFund&lt;/a&gt; and &lt;a href="https://docs.readthedocs.io/en/latest/advertising/ethical-advertising.html"&gt;Read the Docs ethical ads&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I adopted a similar framework from Read the Docs and modified it a tiny bit for my own needs, and came up with this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We don't track users.&lt;/li&gt;
&lt;li&gt;We don't sell user data.&lt;/li&gt;
&lt;li&gt;We don't build profiles on users to target ads.&lt;/li&gt;
&lt;li&gt;We only keep track of views and clicks.&lt;/li&gt;
&lt;li&gt;We host everything ourselves. No third-party images or scripts.&lt;/li&gt;
&lt;li&gt;We give 10% of all ad revenue to open-source projects that RoutineHub is built on, such as Django and Bulma.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I had the framework figured out, I use CodeFund's ads as inspiration. I designed the ad space to be minimalist and non-intrusive, but prominent. It's easily ignorable, but still eye-catching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ju7a9wPs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/26gzy9rjcd13iweqcqax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ju7a9wPs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/26gzy9rjcd13iweqcqax.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, I took cue's from Overcast's ad page, and designed the &lt;a href="https://routinehub.co/advertising"&gt;advertising page&lt;/a&gt;. This page both explains, and lets you create, advertisements. It's simple, it's informative, and it's an easy and quick entry point for someone to create an ad.&lt;/p&gt;

&lt;h3&gt;
  
  
  The future is bright
&lt;/h3&gt;

&lt;p&gt;What's crazy is that during the process of creating this, I was contacted by &lt;a href="https://twitter.com/coderberry"&gt;Eric Berry&lt;/a&gt; of CodeFund and was asked to join him and &lt;a href="https://twitter.com/djfische"&gt;David Fischer&lt;/a&gt; (the advertising, privacy and security guru over at Read the Docs) in a monthly meeting to discuss ethical advertising. I joined them for the first time this week and it was great. I learned a lot from them and I'm ecstatic that there are other people out there trying to do the same thing.&lt;/p&gt;

&lt;p&gt;It's going to be hard, and there are going to be bumps, but I feel so much more at peace with this path, and I'm happy to be paying the server bills while knowing my user's data is not being stored in a data warehouse of my own volition.&lt;/p&gt;

</description>
      <category>ads</category>
      <category>advertising</category>
      <category>webdev</category>
      <category>ethics</category>
    </item>
    <item>
      <title>How should I package my Django app?</title>
      <dc:creator>Harley Hicks</dc:creator>
      <pubDate>Mon, 24 Jul 2017 15:54:12 +0000</pubDate>
      <link>https://dev.to/hmhrex/how-should-i-package-my-django-app</link>
      <guid>https://dev.to/hmhrex/how-should-i-package-my-django-app</guid>
      <description>&lt;p&gt;I have a Django application that serves media (in the vein of Plex or Kodi) that I want to make easy to distribute for others to use. It requires three services:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Web server (WSGI)&lt;/li&gt;
&lt;li&gt;Database (MySQL)&lt;/li&gt;
&lt;li&gt;Task Queue (Celery)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Essentially I'm looking to make a one-click application that installs these services, and let's the user host their own version of this application on Windows, Mac and Linux.&lt;/p&gt;

&lt;p&gt;My background is web, so I'm fairly new to the software distribution game. I've learned that you can package Django applications somewhat using cx_Freeze, or pyInstaller, but it's been quite a hassle getting this to work, and documentation is sparse and/or lacking. Also Django does some fancy magic that doesn't always package well. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadrisuno81w74pbmwgm9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadrisuno81w74pbmwgm9.gif" alt="So many options" width="500" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've also thought of using Docker, but I don't want to complicate installation for users that aren't as technically inclined. It would be great if I could "shadow" Docker's installation and a user could install it and my projects containers via a Windows installer.&lt;/p&gt;

&lt;p&gt;What are some options?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>python</category>
      <category>django</category>
      <category>packaging</category>
    </item>
    <item>
      <title>Hi, I'm Harley Hicks</title>
      <dc:creator>Harley Hicks</dc:creator>
      <pubDate>Thu, 22 Jun 2017 17:12:05 +0000</pubDate>
      <link>https://dev.to/hmhrex/hi-im-harley-hicks</link>
      <guid>https://dev.to/hmhrex/hi-im-harley-hicks</guid>
      <description>&lt;p&gt;The CliffsNotes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I have been coding for ~10 years.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can find me on &lt;a href="https://twitter.com/HarlsHicks" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and on &lt;a href="http://github.com/hmhrex" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I live in Northeast Ohio.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I work for &lt;a href="http://www.ventrac.com" rel="noopener noreferrer"&gt;Ventrac&lt;/a&gt; as a Web Developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I mostly program in Python, PHP and Javascript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I am currently learning more about PHP7, Laravel and Vue.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My side project is &lt;a href="http://github.com/tenma" rel="noopener noreferrer"&gt;Tenma&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I like to talk about music with my friend on our &lt;a href="http://therthm.com" rel="noopener noreferrer"&gt;Podcast&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I'm family man of 4 kids, 2 dogs and a beautiful wife.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nice to meet you!&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
