<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Avery Uslaner</title><description>Software engineer in Salt Lake City. A live dashboard for the bird feeder in the yard, a blog about Python, Django and homelab infrastructure, and a resume.</description><link>https://averyuslaner.com/</link><language>en-us</language><item><title>(Failing to) Run a VM on Fedora 35 with the Framework Laptop</title><link>https://averyuslaner.com/blog/running-a-vm-on-fedora-35/</link><guid isPermaLink="true">https://averyuslaner.com/blog/running-a-vm-on-fedora-35/</guid><description>An attempt to run a Parrot OS VM on Fedora 35 by any means necessary.</description><pubDate>Sun, 20 Mar 2022 17:35:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;virt-manager-qemukvm&quot;&gt;Virt-Manager (QEMU/KVM)&lt;/h2&gt;
&lt;p&gt;The first blocker encountered during setup of my Parrot OS VM is that the VM creation wizard reports that it “&lt;strong&gt;Failed to find a suitable default network.&lt;/strong&gt;”&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;&lt;img alt=&quot;Virt-Manager netword device&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;588&quot; height=&quot;246&quot; src=&quot;https://averyuslaner.com/_astro/Screenshot_from_2022-03-20_11-47-30.BVaUSpsl_Z1GAK3h.webp&quot;&gt;&lt;/figure&gt;
&lt;p&gt;If I ignore the problem and attempt to hit finish, it tells me it is “&lt;strong&gt;Unable to complete install: ’internal error: No &amp;lt;source&amp;gt; ‘bridge’ attribute specified with &amp;lt;interface type=‘bridge’/&amp;gt;’&lt;/strong&gt;”.&lt;/p&gt;
&lt;p&gt;I’m not entirely sure what device name it’s looking for but I’ll try giving it the name of my wireless network device which I’ll grab from &lt;strong&gt;ip addr show&lt;/strong&gt;. With that, I get the error “&lt;strong&gt;Unable to complete install: ‘Unable to add bridge wlp170s0 port vnet0: Operation not supported’&lt;/strong&gt;”.&lt;/p&gt;
&lt;p&gt;I’ll take that to mean the device name is valid, but it doesn’t support being used in this way? Googling around seems to suggest I can create my own bridge interface which sounds useful so we can try that.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; virsh&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; iface-bridge&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; wlp170s0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; br0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;error:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Failed&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; define&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bridge&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; interface&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; br0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;error:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; this&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; function&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; is&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; not&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; supported&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; by&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; connection&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; driver:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; virInterfaceDefineXML&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ah nuts. Well that error leads me to &lt;a href=&quot;https://help.ubuntu.com/community/KVM/Networking#bridgednetworking&quot;&gt;https://help.ubuntu.com/community/KVM/Networking#bridgednetworking&lt;/a&gt; which helpfully explains that wireless devices can’t be used for creating a network bridge. That’s a bummer because my laptop does not contain an ethernet card. So maybe I’m out of luck?&lt;/p&gt;
&lt;p&gt;Let’s try a few more things gathered from google:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; link&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; add&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; br0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; type&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bridge&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok cool, I’ve successfully created a bridged network interface called &lt;strong&gt;br0,&lt;/strong&gt; virtual machine manager happily accepts it as the device name and actually lets me boot into my new VM. So that’s pretty good. But I still haven’t specified a network device to actually bridge to so not surprisingly my VM doesn’t seem to have any network connectivity. It’s possible I’m still doomed to failure.&lt;/p&gt;
&lt;p&gt;I’ll try linking it my built in wireless card and a USB wireless adapter:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; link&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; wlp170s0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; master&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; br0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;                                                                   ─╯&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Error:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Device&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; does&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; not&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; allow&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; enslaving&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bridge.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; link&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; wlp0s20f0u3&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; master&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; br0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Error:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Device&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; does&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; not&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; allow&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; enslaving&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bridge.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Balls. So I guess bridge networking is off the table until the Framework laptop comes out with an ethernet expansion card.&lt;/p&gt;
&lt;p&gt;Alright, well I don’t see why I shouldn’t be able to pass my USB wireless adapter directly to the VM so it can get it’s own IP address that way.&lt;/p&gt;
&lt;p&gt;Fortunately, that seems to be as easy as choosing &lt;strong&gt;Virtual Machine &amp;gt; Redirect USB Device&lt;/strong&gt; and selecting my adapter.&lt;/p&gt;
&lt;p&gt;I can see it in the VM with &lt;strong&gt;ip link show&lt;/strong&gt; but don’t seem to be able to use it yet. Attempting to bring it up:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ifconfig&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; wlxe8de270574fd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; up&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;SIOCSIFFLAGS:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Input/output&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; link&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; wlxe8de270574fd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; up&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;RTNETLINK&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; answers:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Input/output&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Attempting to reload the &lt;strong&gt;ath9k_htc&lt;/strong&gt; kernel driver doesn’t seem to help.&lt;/p&gt;
&lt;p&gt;Dmesg shows the error: “&lt;strong&gt;ath: phy3: Unable to reset hardware; reset status -5 (freq 2412 MHz)&lt;/strong&gt;”. The only guess I have at this point is that it’s a driver issue which seems difficult to resolve when I don’t have network connectivity to attempt other drivers. I’ll attempt a different distro.&lt;/p&gt;
&lt;p&gt;Bleh same issue with Ubuntu 20.04 :(&lt;/p&gt;
</content:encoded><category>fedora</category><category>vm</category></item><item><title>Setting up Geodjango on Arch Linux</title><link>https://averyuslaner.com/blog/setting-up-geodjango-on-arch-linux/</link><guid isPermaLink="true">https://averyuslaner.com/blog/setting-up-geodjango-on-arch-linux/</guid><description>Setting up postgres with PostGIS for geodjango on Arch.</description><pubDate>Thu, 24 Jun 2021 02:02:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;installing-postgres&quot;&gt;Installing Postgres&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pacman&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -S&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgresql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Setting up data directory within my &lt;strong&gt;/home&lt;/strong&gt; partition:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /home/myuser/postgresdb_data/data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chown&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -R&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgres:postgres&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /home/myuser/postgresdb_data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Initializing data:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -iu&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;initdb&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /home/myuser/postgresdb_data/data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Edit the systemd service file:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; systemctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; edit&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgresql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add the following:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;PGROOT&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/home/myuser/postgresdb_data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;PIDFile&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/home/myuser/postgresdb_data/data/postmaster.pid&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ProtectHome&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Edit &lt;strong&gt;/home/myuser/postgresdb_data/data/postgresql.conf&lt;/strong&gt; to listen exclusively through UNIX sockets and we’ll also set password encryption to &lt;strong&gt;scram-sha-256&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;listen_addresses&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;password_encryption&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; scram-sha-256&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Edit &lt;strong&gt;/home/myuser/postgresdb_data/data/pg_hba.conf&lt;/strong&gt; to restrict access rights to the database superuser and configure access for our django user:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# TYPE  DATABASE        USER            ADDRESS                 METHOD&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# &quot;local&quot; is for Unix domain socket connections only&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;   all             postgres				peer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;	geodjango	db_user				scram-sha-256&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;installing-postgis&quot;&gt;Installing PostGIS&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pacman&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -S&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgis&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create the spatial database:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -iu&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;createdb&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; geodjango&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;psql&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; geodjango&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; EXTENSION&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgis&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; EXTENSION&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgis_topology&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; EXTENSION&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; fuzzystrmatch&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; EXTENSION&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgis_tiger_geocoder&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;create-the-database-user&quot;&gt;Create The Database User&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; USER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_user&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; WITH&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PASSWORD&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;secret-password&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ALTER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ROLE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_user&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; SET&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; client_encoding&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; TO&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;utf8&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ALTER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ROLE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_user&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; SET&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; default_transaction_isolation&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; TO&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;read committed&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ALTER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ROLE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_user&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; SET&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; timezone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; TO&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;UTC&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;GRANT&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ALL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PRIVILEGES&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ON&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; DATABASE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; geodjango&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; TO&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_user&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;errors&quot;&gt;Errors&lt;/h2&gt;
&lt;p&gt;At this point if I try to interact with the database, I get an error about a missing pgrouting file so apparently I’m still missing that part.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ERROR:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  could&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; not&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; extension&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; control&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;/usr/share/postgresql/extension/pgrouting.control&quot;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; No&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; such&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; or&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; directory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;installing-pgrouting&quot;&gt;Installing pgRouting&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; clone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; git://github.com/pgRouting/pgrouting.git&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pgrouting&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; checkout&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; v3.1.3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ..&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ah shit, another error:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CMake&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Error&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; at&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /usr/share/cmake-3.20/Modules/FindPackageHandleStandardArgs.cmake:230&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (message):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  Could&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; NOT&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; find&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Boost&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (missing: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;Boost_INCLUDE_DIR&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) (&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Required&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; is&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; at&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; least&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  version&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;1.53.0&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Call&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Stack&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (most &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;recent&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; call&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; first&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  /usr/share/cmake-3.20/Modules/FindPackageHandleStandardArgs.cmake:594&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (_FPHSA_FAILURE_MESSAGE)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  /usr/share/cmake-3.20/Modules/FindBoost.cmake:2345&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (find_package_handle_standard_args)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  CMakeLists.txt:76&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (find_package)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Install boost&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pacman&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -S&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; boost&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Back to installing pgRouting:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pgrouting/build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ..&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; make&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok sweet, now to create the extension:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -iu&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgres&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;psql&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; geodjango&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; EXTENSION&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pgrouting&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Done!&lt;/p&gt;
</content:encoded><category>linux</category><category>django</category><category>arch</category><category>database</category><category>postgis</category><category>geodjango</category><category>postgres</category></item><item><title>Fixing RabbitMQ Sources Repository</title><link>https://averyuslaner.com/blog/fixing-rabbitmq-sources-repository/</link><guid isPermaLink="true">https://averyuslaner.com/blog/fixing-rabbitmq-sources-repository/</guid><description>Updating a repo that is no longer signed.</description><pubDate>Tue, 01 Jun 2021 15:52:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;the-error&quot;&gt;The Error&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Err:10&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://dl.bintray.com/rabbitmq-erlang/debian&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bionic&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; InRelease&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  403&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  Forbidden&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [IP: &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;redacte&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 443]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;E:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Failed&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; fetch&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://dl.bintray.com/rabbitmq-erlang/debian/dists/bionic/InRelease&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;  403&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  Forbidden&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [IP: &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;redacte&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 443]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;E:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; The&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; repository&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;https://dl.bintray.com/rabbitmq-erlang/debian bionic InRelease&apos;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; is&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; no&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; longer&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; signed.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;N:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Updating&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; from&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; such&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; repository&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; can&apos;t be done securely, and is therefore disabled by default.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;N: See apt-secure(8) manpage for repository creation and user configuration details.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-fix&quot;&gt;The Fix&lt;/h2&gt;
&lt;p&gt;Seems to be related to the shutdown of Bintray sometime around April. So the first step is to delete my &lt;strong&gt;/etc/apt/sources.list.d/bintray.erlang.list&lt;/strong&gt; file which contained &lt;strong&gt;deb &lt;a href=&quot;https://dl.bintray.com/rabbitmq-erlang/debian&quot;&gt;https://dl.bintray.com/rabbitmq-erlang/debian&lt;/a&gt; bionic erlang-22.x&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Then I replace my original /etc/apt/sources.list.d/rabbitmq_rabbitmq-server.list which looked like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# this file was generated by packagecloud.io for&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# the repository at https://packagecloud.io/rabbitmq/rabbitmq-server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;deb-src https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## Provides modern Erlang/OTP releases&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;##&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## &quot;bionic&quot; as distribution name should work for any reasonably recent Ubuntu or Debian release.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## See the release to distribution mapping table in RabbitMQ doc guides to learn more.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;deb http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;deb-src http://ppa.launchpad.net/rabbitmq/rabbitmq-erlang/ubuntu bionic main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## Provides RabbitMQ&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;##&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## &quot;bionic&quot; as distribution name should work for any reasonably recent Ubuntu or Debian release.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## See the release to distribution mapping table in RabbitMQ doc guides to learn more.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;deb https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;deb-src https://packagecloud.io/rabbitmq/rabbitmq-server/ubuntu/ bionic main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then update the keys:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## Team RabbitMQ&apos;s main signing key&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; adv&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --keyserver&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;hkps://keys.openpgp.org&quot;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --recv-keys&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;0x0A9AF2115F4687BD29803A206B73A36E6026DFCA&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## Launchpad PPA that provides modern Erlang releases&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; adv&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --keyserver&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;keyserver.ubuntu.com&quot;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --recv-keys&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;F77F1EDA57EBB1CC&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;## PackageCloud RabbitMQ repository&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -1sLf&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey&apos;&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; add&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then a simple:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; upgrade&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we’re good!&lt;/p&gt;
</content:encoded><category>repository</category><category>rabbitmq</category><category>Ubuntu</category></item><item><title>Switching Between Networks With wpa_supplicant</title><link>https://averyuslaner.com/blog/switching-between-networks-with-wpa_supplicant/</link><guid isPermaLink="true">https://averyuslaner.com/blog/switching-between-networks-with-wpa_supplicant/</guid><description>Easy switching between networks when you don&apos;t have a desktop environment</description><pubDate>Sun, 16 May 2021 19:34:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;My setup manages its Wi-Fi connection with wpa_supplicant but doesn’t have a desktop environment so it’s kind of annoying when I want to switch VLANs to manage my IoT devices.&lt;/p&gt;
&lt;p&gt;The two networks I’m switching between are defined in &lt;strong&gt;/etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf&lt;/strong&gt; and their priority set by the &lt;strong&gt;priority&lt;/strong&gt; variable. To make switching easier, I’ve made a script to flip the priorities and restart the &lt;strong&gt;wpa_supplicant&lt;/strong&gt; systemd service.&lt;/p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;#!/usr/bin/python3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; subprocess&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;/etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;r&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; f:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    filedata &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; f.readlines()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; i, line &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; enumerate&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(filedata):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;priority=1&apos;&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; line:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        filedata[i] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; line.replace(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;priority=1&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;priority=0&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    elif&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;priority=0&apos;&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; line:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        filedata[i] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; line.replace(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;priority=0&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;priority=1&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;/etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;w&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; f:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    f.writelines(filedata)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;subprocess.run([&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;systemctl&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;daemon-reload&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;], &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;check&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;subprocess.run([&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;systemctl&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;restart&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;wpa_supplicant@wlp2s0&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;], &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;check&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content:encoded><category>Wi-Fi</category><category>wpa_supplicant</category><category>arch</category></item><item><title>Setting Up The Chia Network On A Synology NAS</title><link>https://averyuslaner.com/blog/setting-up-the-chia-network-on-a-synology-nas/</link><guid isPermaLink="true">https://averyuslaner.com/blog/setting-up-the-chia-network-on-a-synology-nas/</guid><description>Does money grow on hard drives?</description><pubDate>Sun, 16 May 2021 02:21:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;this-is-probably-dumb-but-im-doing-it-anyway&quot;&gt;This is probably dumb but I’m doing it anyway&lt;/h2&gt;
&lt;p&gt;Chia is going to be the next big crypto craze. Or at least that’s what their &lt;a href=&quot;https://www.chia.net/&quot;&gt;website&lt;/a&gt; tries to make the case for.&lt;/p&gt;
&lt;p&gt;Also, it’s just kind of fun to play around with. So that’s what this post is about, especially since the HDDs in my NAS are not the recommended method of plotting and farming Chia.&lt;/p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;
&lt;p&gt;I’ll be using the Virtual Machine Manager of my Synology DS918+ to run a VM with three CPU cores and 2 GB of memory. I configured it to use 3 virtual drives; one with 50 GB of space and the other two with 1 TB each. The 50 GB drive was used to install Ubuntu 20.04.&lt;/p&gt;
&lt;p&gt;During installation of the OS, each virtual physical drive was also configured as its own LVM volume group.&lt;/p&gt;
&lt;h2 id=&quot;post-install-setup&quot;&gt;Post-Install Setup&lt;/h2&gt;
&lt;p&gt;Some further configuration of the volume groups where &lt;strong&gt;farm-vg0&lt;/strong&gt; and &lt;strong&gt;tmp-vg0&lt;/strong&gt; are the names of the volume groups configured during OS installation:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lvcreate&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -l&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 100%FREE&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -n&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; farm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; farm-vg0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lvcreate&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -l&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 100%FREE&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -n&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; farm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tmp-vg0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Making the filesystems:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mkfs.ext4&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /dev/farm-vg0/farm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mkfs.ext4&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /dev/tmp-vg0/tmp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I added the following to my fstab file to mount the logical volumes automatically:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;/dev/mapper/farm--vg0-farm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /mnt/farm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ext4&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; defaults&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;/dev/mapper/tmp--vg0-tmp&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /mnt/tmp&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ext4&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; defaults&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;chia-install&quot;&gt;Chia Install&lt;/h2&gt;
&lt;p&gt;Following their &lt;a href=&quot;https://github.com/Chia-Network/chia-blockchain/wiki/INSTALL#ubuntudebian&quot;&gt;install guide&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; clone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://github.com/Chia-Network/chia-blockchain.git&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -b&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; latest&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --recurse-submodules&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chia-blockchain&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sh&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install.sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ./activate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;chia-setup&quot;&gt;Chia Setup&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;chia&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; init&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;chia&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; keys&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; generate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;chia&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; farmer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;chia&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; plots&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; create&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -n&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 3&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -b&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 1536&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -t&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /mnt/tmp&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -d&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /mnt/farm&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -r&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;The above command took about 5 days to complete. That’s bad. This setup is bad. But also fun and interesting.&lt;/p&gt;
</content:encoded><category>cryptocurrency</category><category>chia</category><category>NAS</category></item><item><title>Installing &amp; Configuring Mariadb for Arch Linux</title><link>https://averyuslaner.com/blog/installing-configuring-mariadb-for-arch-linux/</link><guid isPermaLink="true">https://averyuslaner.com/blog/installing-configuring-mariadb-for-arch-linux/</guid><description>A guide to installing and configuring Mariadb on Arch Linux</description><pubDate>Thu, 15 Apr 2021 23:13:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;This website runs on a &lt;a href=&quot;https://m.do.co/c/5c2ac855bd07&quot;&gt;Digital Ocean Ubuntu VPS&lt;/a&gt;, and uses MySQL as it’s backend database. I want to use my Arch Linux laptop to develop and test new code for the website so I need a database to use for the test environment. I could use Docker which would probably be the better option if I wanted to emulate the production database on this VPS as closely as possible but I’ve never used Mariadb so I want to give it a try.&lt;/p&gt;
&lt;h3 id=&quot;special-considerations&quot;&gt;Special Considerations&lt;/h3&gt;
&lt;p&gt;My laptop is setup with separate partitions for root, home, and swap with the home partition being the largest so I’m going to be configuring Mariadb to use a location on my home partition as the data directory.&lt;/p&gt;
&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
&lt;p&gt;Following along with the &lt;a href=&quot;https://wiki.archlinux.org/index.php/MariaDB&quot;&gt;official Arch Linux docs on Mariadb&lt;/a&gt;, we install the &lt;strong&gt;mariadb&lt;/strong&gt; package:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pacman&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -S&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mariadb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We need to set the &lt;strong&gt;datadir&lt;/strong&gt; in &lt;strong&gt;/etc/my.cnf.d/server.cnf&lt;/strong&gt; so we’ll back up that file and make the change:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/my.cnf.d/server.cnf&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/my.cnf.d/server.cnf.bak&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;vi&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/my.cnf.d/server.cnf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[mysqld]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;datadir&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/home/myuser/mariadb_data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;skip-networking&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/tmp/mysql.sock&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[mariadb]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/tmp/mysql.sock&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/my.cnf.d/client.cnf&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/my.cnf.d/client.cnf.bak&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;vi&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/my.cnf.d/client.cnf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[client]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/tmp/mysql.sock&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can run the &lt;strong&gt;mariadb-install-db&lt;/strong&gt; command:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mariadb-install-db&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --user=myuser&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --basedir=/usr&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --datadir=/home/myuser/mariadb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create an override for the mariadb systemd unit file and run it as my user with &lt;strong&gt;ProtectHome&lt;/strong&gt; set to &lt;strong&gt;false&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; systemctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; edit&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mariadb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=myuser&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Group&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=myuser&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;ProtectHome&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;PrivateTmp&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can run the service and if it’s successful, we can enable it to start automatically.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; systemctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mariadb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; systemctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; enable&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mariadb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content:encoded><category>mariadb</category><category>linux</category><category>database</category><category>arch</category></item><item><title>Resizing Partitions</title><link>https://averyuslaner.com/blog/resizing-partitions/</link><guid isPermaLink="true">https://averyuslaner.com/blog/resizing-partitions/</guid><description>Reallocating disk space from home to root partition</description><pubDate>Sun, 14 Feb 2021 19:06:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;the-background&quot;&gt;The Background&lt;/h2&gt;
&lt;p&gt;On my recent Arch install, I decided to create separate partitions for my &lt;strong&gt;root&lt;/strong&gt; and &lt;strong&gt;home&lt;/strong&gt; directories. Unfortunately, I’m a dummy and only allocated 20 GB for the root partition. As it turns out, that’s not enough for a proper workstation setup so now I have to fix my mistake.&lt;/p&gt;
&lt;h2 id=&quot;the-fix&quot;&gt;The Fix&lt;/h2&gt;
&lt;p&gt;My particular install involves two usb drives, one with the Arch boot partition and the other with a cryptographic key to unlock the hard drive in my laptop. So to get started, I remove the usb drive with the boot partition and replace it with another usb that holds the Arch live environment I originally used for the installation. This way, I can boot into the live environment, unlock my drive, and resize the partitions while they’re not in use.&lt;/p&gt;
&lt;h3 id=&quot;decrypting-the-drive&quot;&gt;Decrypting the Drive&lt;/h3&gt;
&lt;p&gt;I used dm-crypt plain mode to encrypt the drive so the first step is to unlock it so I can see the partitions. That looks like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cryptsetup&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --cipher=aes-xts-plain64&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --offset=0&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --key-file=/dev/sdc&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --key-size=512&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --type&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; plain&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /dev/sda&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cryptlvm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above code snippet, &lt;strong&gt;/dev/sdc&lt;/strong&gt; is the usb drive containing nothing but my cryptographic key and &lt;strong&gt;/dev/sda&lt;/strong&gt; is the drive I’m decrypting.&lt;/p&gt;
&lt;p&gt;At this point, I can see my logical volume group which look something like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;                  MAJ:MIN&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; RM&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;   SIZE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; RO&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; TYPE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  MOUNTPOINT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sda&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;                   8:0&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;      0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;   400G&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;  0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; disk&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  └─cryptlvm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;          254:0&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;   400G&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;  0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; crypt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    ├─MyVolGroup-swap&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 254:1&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;     8G&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;  0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lvm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;   [SWAP]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    ├─MyVolGroup-root&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 254:2&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;    20G&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;  0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lvm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;   /mnt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    └─MyVolGroup-home&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 254:3&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;   372G&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;  0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lvm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;   /mnt/home&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point, I can hopefully use &lt;strong&gt;lvresize&lt;/strong&gt; to reduce the size of my home partition and add that extra space to my root partition. So let’s give that a go:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;lvresize&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -L&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -20G&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --resizefs&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MyVolGroup/home&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;lvresize&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -l&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; +100%FREE&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --resizefs&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MyVolGroup/root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It worked!&lt;/p&gt;
&lt;p&gt;Surprisingly painless. And now my root partition is twice the size it used to be so I can install more packages without fear of running out of space.&lt;/p&gt;
</content:encoded><category>disk usage</category><category>linux</category><category>partition</category><category>arch</category></item><item><title>Setting up a Video Background Login Screen</title><link>https://averyuslaner.com/blog/setting-up-a-video-background-login-screen/</link><guid isPermaLink="true">https://averyuslaner.com/blog/setting-up-a-video-background-login-screen/</guid><description>Documenting my setup for creating a login screen with a video background.</description><pubDate>Mon, 08 Feb 2021 02:16:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;Recently I was inspired to switch over to Arch Linux after seeing &lt;a href=&quot;https://www.reddit.com/r/unixporn/comments/hpakeu/awesome_afternoon_in_a_perfect_world/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3&quot;&gt;this post by u/EmpressNoodle&lt;/a&gt; over at &lt;a href=&quot;https://www.reddit.com/r/unixporn/&quot;&gt;/r/unixporn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;During my Arch install, I decided to use &lt;a href=&quot;https://wiki.archlinux.org/index.php/SDDM&quot;&gt;SDDM&lt;/a&gt; as my display manager. One of it’s features is the ability to use videos as the background of the login screen so I figured I’d give that a go.&lt;/p&gt;
&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;First, I had to decide on the base theme that I wanted to customize. My install came with elarun, maldives, and maya (all of which live in &lt;strong&gt;/usr/share/sddm/themes)&lt;/strong&gt; so I used &lt;strong&gt;sddm-greeter –test-mode –theme /path/to/theme&lt;/strong&gt; to preview them and see which one I liked best. I believe Arch defaults to breeze, though I’m not exactly sure where that theme lives and it didn’t matter to me since I ended up picking the maldives theme to base my custom theme on.&lt;/p&gt;
&lt;p&gt;To begin, I simply copied the maldives theme to my own custom theme directory so I would have the original to refer back to in case I screwed something up.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cp&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -r&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /usr/share/sddm/themes/maldives&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /usr/share/sddm/themes/custom&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point, I needed to edit the &lt;strong&gt;Main.qml&lt;/strong&gt; file which handles how the layout looks. I used the guide here to help me get my bearings in terms of how to get it to use a video background: &lt;a href=&quot;https://nixdaily.com/how-to/add-video-background-to-sddm-login-screen/&quot;&gt;https://nixdaily.com/how-to/add-video-background-to-sddm-login-screen/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here are the changes I made to the file. I’m not sure if those width and height changes had any effect at all but they didn’t hurt.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;diff&quot; role=&quot;region&quot; aria-label=&quot;Code, diff&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;➜  ~ diff /usr/share/sddm/themes/maldives/Main.qml /usr/share/sddm/themes/custom/Main.qml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 slfw-bold sd-dcbdfb sdfw-bold&quot;&gt;24a25&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt; import QtMultimedia 5.15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 slfw-bold sd-dcbdfb sdfw-bold&quot;&gt;30,31c31,32&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;     width: 640&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;     height: 480&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 slfw-bold sd-6cb6ff sdfw-bold&quot;&gt;&lt;span class=&quot;diff-marker&quot;&gt;-&lt;/span&gt;--&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;     width: 1920&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;     height: 1080&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 slfw-bold sd-dcbdfb sdfw-bold&quot;&gt;55,56c56,57&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;     Background {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;         anchors.fill: parent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 slfw-bold sd-6cb6ff sdfw-bold&quot;&gt;&lt;span class=&quot;diff-marker&quot;&gt;-&lt;/span&gt;--&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;     MediaPlayer {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;         id: videoPlayer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 slfw-bold sd-dcbdfb sdfw-bold&quot;&gt;58,63c59,65&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;         fillMode: Image.PreserveAspectCrop&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;         onStatusChanged: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;             if (status == Image.Error &amp;amp;&amp;amp; source != config.defaultBackground) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;                 source = config.defaultBackground&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;             }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-b31d28 sd-ff938a&quot;&gt;&amp;lt;         }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 slfw-bold sd-6cb6ff sdfw-bold&quot;&gt;&lt;span class=&quot;diff-marker&quot;&gt;-&lt;/span&gt;--&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;         autoPlay: true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;     }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;     VideoOutput {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;         source: videoPlayer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;         anchors.fill: parent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-22863a sd-8ddb8c&quot;&gt;&amp;gt;         fillMode: VideoOutput.PreserveAspectCrop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the video background file is being pulled from config.defaultBackground. That setting is found in theme.conf in the same directory as &lt;strong&gt;Main.qml&lt;/strong&gt;. It’s a simple file that looks like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[General]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;background_video.mp4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, you’ll need to make sure that background_video.mp4 actually exists. I tried setting the path to a video located in my home directory but it didn’t work. Not sure if that’s because my home directory is on a separate encrypted partition, but the simple fix is just to save the video into the theme directory alongside the config files.&lt;/p&gt;
&lt;p&gt;At this point you can start testing your theme with &lt;strong&gt;sddm-greeter –test-mode –theme /path/to/custom/theme&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I needed to install a few other packages to get my video to play properly. Your mileage my vary.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pacman&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -S&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; gst-libav&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; gstreamer-vaapi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once you have it working, the last step to to tell sddm to use the them by creating a new file in &lt;strong&gt;/etc/sddm.conf.d/&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I named mine &lt;strong&gt;custom_theme.conf&lt;/strong&gt;. It looks like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[Theme]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;custom&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;final-product&quot;&gt;Final Product&lt;/h2&gt;
&lt;p&gt;You can see a short demonstration of my new login screen in the video below. The background I’m using is a lightly edited version of another YouTube video you can find here: &lt;a href=&quot;https://youtu.be/BHACKCNDMW8&quot;&gt;https://youtu.be/BHACKCNDMW8&lt;/a&gt;&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=SmjXYu6kApg&quot;&gt;&lt;img alt=&quot;SDDM Login Screen With Video Background&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://averyuslaner.com/_astro/youtube-SmjXYu6kApg-poster.DxjEsnX-_Z9ugIK.svg&quot;&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;The above video isn’t actually a perfect representation of my login screen, but it’s close enough. I’m actually just using ffmpeg to record my main display while I run &lt;strong&gt;sddm-greeter –test-mode&lt;/strong&gt; with my customized theme.&lt;/p&gt;
</content:encoded></item><item><title>Automatic Bird Identification: Part III</title><link>https://averyuslaner.com/blog/automatic-bird-identification-part-iii/</link><guid isPermaLink="true">https://averyuslaner.com/blog/automatic-bird-identification-part-iii/</guid><description>Building our first model.</description><pubDate>Mon, 11 May 2020 20:12:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;training-the-model&quot;&gt;Training the Model&lt;/h2&gt;
&lt;p&gt;Now we can actually write the script that will train the model!&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# USAGE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# python fine_tune_birds.py --vgg vgg16/vgg16 --checkpoints checkpoints --prefix vggnet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; bird_config &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mxnet &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; argparse&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; logging&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# construct the argument parse and parse the arguments&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ap &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; argparse.ArgumentParser()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ap.add_argument(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;-v&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;--vgg&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                help&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;path to pre-trained VGGNet for fine-tuning&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ap.add_argument(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;--checkpoints&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                help&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;path to output checkpoint directory&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ap.add_argument(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;-p&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;--prefix&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                help&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;name of model prefix&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ap.add_argument(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;-s&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;--start-epoch&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                help&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;epoch to restart training at&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;args &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; vars&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(ap.parse_args())&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# set the logging level and output file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;logging.basicConfig(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;logging.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                    filename&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;training_&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;.log&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.format(args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;start_epoch&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                    filemode&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# determine the batch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;batchSize &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_DEVICES&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# construct the training image iterator&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;trainIter &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.io.ImageRecordIter(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    path_imgrec&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TRAIN_MX_REC&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    data_shape&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    batch_size&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;batchSize,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    rand_crop&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    rand_mirror&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    rotate&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    max_shear_ratio&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    mean_r&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;R_MEAN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    mean_g&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;G_MEAN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    mean_b&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;B_MEAN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    preprocess_threads&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_DEVICES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# construct the validation image iterator&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;valIter &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.io.ImageRecordIter(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    path_imgrec&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;VAL_MX_REC&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    data_shape&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    batch_size&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;batchSize,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    mean_r&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;R_MEAN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    mean_g&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;G_MEAN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    mean_b&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;B_MEAN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# initialize the optimizer and the training contexts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;opt &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.optimizer.SGD(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;5e-5&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;momentum&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;wd&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0.0005&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                       rescale_grad&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; /&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; batchSize)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ctx &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [mx.gpu(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# construct the checkpoints path, initialize the model argument and&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# auxiliary parameters, and whether uninitialized parameters should&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# be allowed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;checkpointsPath &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.path.sep.join([args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;checkpoints&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                                    args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;prefix&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;argParams &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; None&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;auxParams &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; None&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;allowMissing &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; False&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# if there is no specific model starting epoch supplied, then we&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# need to build the network architecture&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;start_epoch&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # load the pre-trained VGG16 model&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] loading pre-trained model...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    (symbol, argParams, auxParams) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.model.load_checkpoint(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;vgg&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;], &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    allowMissing &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; True&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # grab the layers from the pre-trained model, then find the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # dropout layer *prior* to the final FC layer (i.e., the layer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # that contains the number of class labels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # HINT: you can find layer names like this:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # for layer in layers:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # 	print(layer.name)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # then, append the string `_output` to the layer name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    layers &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; symbol.get_internals()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    net &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; layers[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;drop7_output&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # construct a new FC layer using the desired number of output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # class labels, followed by a softmax output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    net &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.sym.FullyConnected(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;net,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                                num_hidden&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_CLASSES&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;fc8&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    net &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.sym.SoftmaxOutput(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;net, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;softmax&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # construct a new set of network arguments, removing any previous&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # arguments pertaining to FC8 (this will allow us to train the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # final layer)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    argParams &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; dict&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;({k: argParams[k] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; k &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; argParams&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                      if&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;fc8&quot;&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; not&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; k})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# otherwise, a specific checkpoint was supplied&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # load the checkpoint from disk&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] loading epoch &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.format(args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;start_epoch&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    (net, argParams, auxParams) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.model.load_checkpoint(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        checkpointsPath, args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;start_epoch&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# initialize the callbacks and evaluation metrics&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;batchEndCBs &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [mx.callback.Speedometer(batchSize, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;epochEndCBs &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [mx.callback.do_checkpoint(checkpointsPath)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;metrics &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [mx.metric.Accuracy(), mx.metric.TopKAccuracy(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;top_k&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;           mx.metric.CrossEntropy()]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# construct the model and train it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] training network...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;model &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mx.mod.Module(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;net, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;ctx)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;model.fit(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    trainIter,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    eval_data&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;valIter,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    num_epoch&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    begin_epoch&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;args[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;start_epoch&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    initializer&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;mx.initializer.Xavier(),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    arg_params&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;argParams,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    aux_params&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;auxParams,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    optimizer&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;opt,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    allow_missing&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;allowMissing,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    eval_metric&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;metrics,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    batch_end_callback&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;batchEndCBs,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;    epoch_end_callback&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;epochEndCBs)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A few important things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This script makes use of a pretrained imagenet model so you’ll need to provide those pretrained weights: &lt;a href=&quot;http://data.mxnet.io/models/imagenet/vgg/vgg16-0000.params&quot;&gt;params&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://data.mxnet.io/models/imagenet/vgg/vgg16-symbol.json&quot;&gt;symbols&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I’ve included top k 2 accuracy which is a literally useless metric but the 2 can just be incremented to a more useful metric when I have more categories of training data ready&lt;/li&gt;
&lt;li&gt;The hyperparameters used here are probably terrible but it doesn’t make sense to worry about those when we still have so little training data&lt;/li&gt;
&lt;li&gt;I’m training with a single GTX 1080 graphics card so my &lt;strong&gt;ctx&lt;/strong&gt; variable is set to [mx.gpu(0)]. Add more cards to that list and change the NUM_DEVICES variable in the config file if you have more cards to train with&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;checking-the-output&quot;&gt;Checking the Output&lt;/h2&gt;
&lt;p&gt;The good news is that it runs! An exert of my &lt;strong&gt;training_0.log&lt;/strong&gt; file looks like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Train-accuracy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.710938&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Train-top_k_accuracy_2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=1.000000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Train-cross-entropy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.704148&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] Time &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=4.002&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Saved checkpoint to &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;/ML/Birds/checkpoints/vggnet-0001.params&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Validation-accuracy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.812500&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Validation-top_k_accuracy_2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=1.000000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[0] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Validation-cross-entropy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.392680&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[1] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Train-accuracy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.812500&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[1] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Train-top_k_accuracy_2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=1.000000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[1] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Train-cross-entropy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.394014&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[1] Time &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=3.758&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Saved checkpoint to &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;/ML/Birds/checkpoints/vggnet-0002.params&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[1] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Validation-accuracy&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0.906250&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;INFO:root:Epoch[1] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;Validation-top_k_accuracy_2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=1.000000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Classes&lt;/strong&gt;: 2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Training Images&lt;/strong&gt;: 372&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validation Images&lt;/strong&gt;: 72&lt;/p&gt;
&lt;p&gt;We can also graph the data from the training logs to get a better idea of how it’s doing.&lt;/p&gt;
&lt;figure class=&quot;figure&quot;&gt;&lt;img alt=&quot;Bird Accuracy&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;640&quot; height=&quot;480&quot; src=&quot;https://averyuslaner.com/_astro/myplot-accuracy.Cre5t1vH_Z2auLLe.webp&quot;&gt;&lt;/figure&gt;
&lt;figure class=&quot;figure&quot;&gt;&lt;img alt=&quot;Bird Loss&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;640&quot; height=&quot;480&quot; src=&quot;https://averyuslaner.com/_astro/myplot-loss.CoGmmNxl_2b8lmn.webp&quot;&gt;&lt;/figure&gt;
&lt;p&gt;The graphs look pretty good but that’s just because the model is able to overfit super quickly since there are so few data to learn from. I also haven’t yet fixed the problem of images without birds being incorrectly classified so there’s no reason too read to much into these results. Since we know the data being fed to the model isn’t high quality yet, we know that the output can’t be of high quality. So really this is a good example of why you should be skeptical of the output of machine learning models until you’ve thoroughly scrutinized them.&lt;/p&gt;
&lt;p&gt;Now that I know that the training pipeline is actually functional, I can focus my efforts on building a more robust training set. Then we can fuddle with the hyperparameters and actually start thinking more critically about the results that we’re getting.&lt;/p&gt;
</content:encoded><category>bird</category><category>python</category><category>OpenCV</category><category>machine learning</category></item><item><title>Automatic Bird Identification: Part II</title><link>https://averyuslaner.com/blog/automatic-bird-identification-part-ii/</link><guid isPermaLink="true">https://averyuslaner.com/blog/automatic-bird-identification-part-ii/</guid><description>Building the rec files that our model will consume for training</description><pubDate>Sun, 10 May 2020 20:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this post I’ll be concentrating on creating the &lt;strong&gt;lst&lt;/strong&gt; and &lt;strong&gt;rec&lt;/strong&gt; files needed for model training using the training data that we generated in &lt;a href=&quot;https://averyuslaner.com/blog/automatic-bird-identification-part-i/&quot;&gt;Part I&lt;/a&gt; of this series.&lt;/p&gt;
&lt;p&gt;The model will use the mxnet framework which reads &lt;strong&gt;rec&lt;/strong&gt; files as training data. First we’ll create the &lt;strong&gt;lst&lt;/strong&gt; files guided by a config file that we can define now:&lt;/p&gt;
&lt;h2 id=&quot;the-config-file&quot;&gt;The Config File&lt;/h2&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# top level path to our bird related directories&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;BASE_PATH&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;/ML/Birds&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# based on the base path, derive the images path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;IMAGES_PATH&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;BASE_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;DATA&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;LABELS_PATH&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;/bird_ml/dataset.csv&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; BASE_PATH&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TRAIN_MX_LIST&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;lists/train.lst&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;VAL_MX_LIST&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;lists/val.lst&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TEST_MX_LIST&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;lists/test.lst&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TRAIN_MX_REC&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;rec/train.rec&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;VAL_MX_REC&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;rec/val.rec&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TEST_MX_REC&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;MX_OUTPUT&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;rec/test.rec&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Label encoder used to convert species names to integer categories&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;LABEL_ENCODER_PATH&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; path.sep.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;BASE_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;output/le.cpickle&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# define the RGB means from the ImageNet dataset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;R_MEAN&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 123.68&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;G_MEAN&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 116.779&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;B_MEAN&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 103.939&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# define the percentage of validation and testing images relative&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# to the number of training images&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_CLASSES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_VAL_IMAGES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0.15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_TEST_IMAGES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0.15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# define the batch size&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 32&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_DEVICES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The RBG means are taken from the original Imagenet paper by Simonyan and Zisserman. That way we can fine tune an existing Imagenet trained model rather than training our model entirely from scratch.&lt;/p&gt;
&lt;p&gt;This first model will only attempt to classify 2 classes since we don’t have much training data yet and we only want to make sure our data processing pipeline is functioning properly. We’re not expecting a high quality model just yet.&lt;/p&gt;
&lt;h2 id=&quot;building-the-record-file-dataset&quot;&gt;Building the Record File Dataset&lt;/h2&gt;
&lt;p&gt;While our image dataset is already created, our model actually needs to consume &lt;strong&gt;rec&lt;/strong&gt; files rather than raw image files so creating those will be our next step. The &lt;strong&gt;rec&lt;/strong&gt; files are essentially just images compressed into the record file format. Their creation will be handled by the &lt;strong&gt;im2rec.py&lt;/strong&gt; file included with the MxNet framework, but we’ll use our own script to create the &lt;strong&gt;lst&lt;/strong&gt; files that serve to pair each image filepath with it’s encoded bird species class.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; bird_config &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; sklearn.preprocessing &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; LabelEncoder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; sklearn.model_selection &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; train_test_split&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; progressbar&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; pickle&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# read the contents of the labels file, then initialize the list of&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# image paths and labels&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] loading image paths and labels...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;rows &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;LABELS_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;).read()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;rows &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; rows.strip().split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;trainPaths &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;trainLabels &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# loop over the rows&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; row &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; rows:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # unpack the row, then update the image paths and labels list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    filename, species &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; row.split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    filename &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; filename[filename.rfind(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    trainPaths.append(os.sep.join([config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;IMAGES_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, filename]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    trainLabels.append(species)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# now that we have the total number of images in the dataset that&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# can be used for training, compute the number of images that&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# should be used for validation and testing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;numVal &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; int&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(trainPaths) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_VAL_IMAGES&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;numTest &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; int&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(trainPaths) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;NUM_TEST_IMAGES&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# our class labels are represented as strings so we need to encode&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# them&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] encoding labels...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;le &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; LabelEncoder().fit(trainLabels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;trainLabels &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; le.transform(trainLabels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# perform sampling from the training set to construct a a validation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# set&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] constructing validation data...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;split &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; train_test_split(trainPaths, trainLabels, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;test_size&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;numVal,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                         stratify&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;trainLabels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(trainPaths, valPaths, trainLabels, valLabels) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; split&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# perform stratified sampling from the training set to construct a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# a testing set&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] constructing testing data...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;split &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; train_test_split(trainPaths, trainLabels, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;test_size&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;numTest,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                         stratify&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;trainLabels)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(trainPaths, testPaths, trainLabels, testLabels) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; split&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# construct a list pairing the training, validation, and testing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# image paths along with their corresponding labels and output list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;datasets &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    (&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;train&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, trainPaths, trainLabels, config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TRAIN_MX_LIST&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    (&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;val&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, valPaths, valLabels, config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;VAL_MX_LIST&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    (&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, testPaths, testLabels, config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TEST_MX_LIST&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# loop over the dataset tuples&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (dType, paths, labels, outputPath) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; datasets:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # open the output file for writing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] building &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.format(outputPath))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    f &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(outputPath, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # initialize the progress bar&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    widgets &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;Building List: &quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, progressbar.Percentage(), &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;               progressbar.Bar(), &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, progressbar.ETA()]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    pbar &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; progressbar.ProgressBar(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;maxval&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(paths),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                                   widgets&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;widgets).start()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # loop over each of the individual images + labels&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (i, (path, label)) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; enumerate&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(paths, labels)):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;        # write the image index, label, and output path to file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        row &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.join([&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(i), &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(label), path])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        f.write(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;{}\n&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.format(row))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        pbar.update(i)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # close the output file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    pbar.finish()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    f.close()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# write the label encoder to file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[INFO] serializing label encoder...&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;f &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(config.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;LABEL_ENCODER_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;f.write(pickle.dumps(le))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;f.close()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Running our build dataset script will create the &lt;strong&gt;lst&lt;/strong&gt; files in the directory defined by the config file we created earlier. Now that we have those, we can run the im2rec script to generate the &lt;strong&gt;rec&lt;/strong&gt; files.&lt;/p&gt;
&lt;p&gt;To make things easy I grabbed the im2py script off of MxNet’s github and put it in my project directory:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /bird_ml/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://raw.githubusercontent.com/apache/incubator-mxnet/master/tools/im2rec.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To make generation of the &lt;strong&gt;rec&lt;/strong&gt; files easier, I wrote a small script to create and organize them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;build_rec_files.py&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;/bird_ml/venv/bin/python&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /bird_ml/im2rec.py&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    --resize&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 256&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --quality&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 100&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --encoding&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;.jpg&apos;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /ML/Birds/lists&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mv&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /ML/Birds/lists/&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;.idx&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /ML/Birds/rec&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mv&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /ML/Birds/lists/&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;.rec&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /ML/Birds/rec&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that we have our rec files, we’re ready to start training! I’ll handle that in the next post.&lt;/p&gt;
</content:encoded><category>bird</category><category>python</category><category>OpenCV</category><category>machine learning</category></item><item><title>Automatic Bird Identification: Part I</title><link>https://averyuslaner.com/blog/automatic-bird-identification-part-i/</link><guid isPermaLink="true">https://averyuslaner.com/blog/automatic-bird-identification-part-i/</guid><description>Making a bird feeder that automatically identifies its visitors.</description><pubDate>Thu, 07 May 2020 03:04:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;
&lt;p&gt;I have a bird feeder with a Raspberry Pi camera pointed at it. That raspberry pi creates a video feed of the bird feeder accessible on my local network. My local network has a Synology 918+ with a IP camera license. The Synology configured IP camera detects motion from birds (and wind unfortunately), and saves a short video of the motion events to disk.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Image unavailable: raspberry-pi-zero-bird-cam.jpg]&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-plan&quot;&gt;The Plan&lt;/h2&gt;
&lt;p&gt;At first I will manually watch each motion event video to organize the videos by bird species. I’ll do this by placing each video into a folder with the name of the bird species as the folder’s name. Then, using Python I can split the videos into individual images which I can use to train a machine learning model that automatically identifies the bird species that is visiting the bird feeder.&lt;/p&gt;
&lt;p&gt;I’m planning to base my machine learning model off of another machine learning problem described in a book containing example code. To minimize the amount of new code I have to write, I’ll organize the training images in the same way as the example code I’m following. So that is to say all images will be saved into the same directory while a csv file is used to describe their file locations and category labels. I’ll need to write the code to make that happen though.&lt;/p&gt;
&lt;h2 id=&quot;the-code&quot;&gt;The Code&lt;/h2&gt;
&lt;p&gt;The script below traverses the video files organized by species and saves each video frame to it’s own file. The &lt;strong&gt;dataset.csv&lt;/strong&gt; file referenced by the DATA_LOG variable keeps track of all of the file paths and their respective labels.&lt;/p&gt;
&lt;p&gt;At this point, there is a problem because significant portions of each video contain no birds when they either haven’t landed yet or have flown away. This means some frames are incorrectly labeled as a particular species when in fact they contain no birds at all. To address this, I’ll move any frames that don’t contain birds into a folder called “Empty feeder”. Later iterations of the below script will traverse this folder, so that these frames can be correct labeled as containing no birds so our future machine learning models can also learn to recognize images without birds in them.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; csv&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; cv2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; imutils.video &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; FileVideoStream&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATA_PATH&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;ML/Birds/DATA&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATA_LOG&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;bird_ml/dataset.csv&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; get_video_file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; root, dirs, files &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.walk(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;ML/Birds&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        try&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            dirs.remove(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATA_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        except&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; ValueError&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;            pass&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        for&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; files:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;            try&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                file_extension &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;            except&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; IndexError&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;            if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; file_extension &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;mp4&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                yield&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.path.join(root, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; split_and_label&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(video_file, file_number):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;[*] Processing&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, video_file)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    video_stream &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; FileVideoStream(video_file).start()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # Allow the buffer some time to fill&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    time.sleep(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    while&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; video_stream.more():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        frame &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; video_stream.read()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; frame &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; None&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;            break&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        else&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            write_path &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.path.join(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATA_PATH&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(file_number) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;.jpg&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;            print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;[*] Saving file number&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, file_number)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            cv2.imwrite(write_path, frame)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            file_number &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            label &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; video_file.split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;            with&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATA_LOG&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; dataset:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                fieldnames &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Image Filename&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Species&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                writer &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; csv.DictWriter(dataset, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;fieldnames)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                writer.writerow({&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Image Filename&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: write_path, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Species&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: label})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;            # Sleep again so we don&apos;t overtake the buffer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            time.sleep(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; file_number&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; get_next_filename&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    last_row &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; open&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATA_LOG&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;r&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;).readlines()[&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    file_path &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; last_row.split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;,&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    file_name &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; file_path.split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    file_number &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; file_name.split(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;.&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; int&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(file_number) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; main&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    next_file_num &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; get_next_filename()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; video_file &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; get_video_file():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        next_file_num &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; split_and_label(video_file, next_file_num)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;        # Delete the original video file so we don&apos;t duplicate training data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        os.remove(video_file)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; __name__&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    main()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; main&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; next_file_num &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; get_next_filename()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; video_file &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; get_video_file():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; next_file_num &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; split_and_label(video_file, next_file_num)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt; # Delete the original video file so we don&apos;t duplicate training data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.remove(video_file)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; __name__&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; main()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content:encoded><category>raspberry pi</category><category>python</category><category>OpenCV</category></item><item><title>Securing Django + Nginx With TLS</title><link>https://averyuslaner.com/blog/securing-django-nginx-tls/</link><guid isPermaLink="true">https://averyuslaner.com/blog/securing-django-nginx-tls/</guid><description>Encrypted good; insecure bad.</description><pubDate>Sun, 09 Feb 2020 00:25:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;installing-certbot&quot;&gt;Installing Certbot&lt;/h2&gt;
&lt;p&gt;We first need to install certbot from Let’s Encrypt since that will do most of the hard work for us.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; software-properties-common&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; add-apt-repository&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; universe&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; add-apt-repository&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ppa:certbot/certbot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; certbot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python-certbot-nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that certbot it installed, we can grab a certificate. We’ll have daphne consume it so we don’t need certbot to mess with our nginx file.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; certbot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; certonly&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The tool will prompt you for an email address and ask you to agree to a few things before it saves the certificate.&lt;/p&gt;
&lt;p&gt;At this point, I need to update my supervisord config file so Daphne can actually make use of it. That config should like something like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;[fcgi-program:asgi]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Set Django environment variables&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;photo_blog.settings.production&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&amp;lt;redacted&amp;gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# TCP socket used by Nginx backend upstream&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=tcp://localhost:8000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Directory where your site&apos;s project files are located&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/home/myusername/averyuslaner.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Each process needs to have a separate socket file, so we use process_num&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Make sure to update &quot;mysite.asgi&quot; to match your project name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/home/myusername/venv/bin/daphne -e ssl:443:&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;privateKey&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/etc/letsencrypt/live/averyuslaner.com/privkey.pem:&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;certKey&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/etc/letsencrypt/live/averyuslaner.com/fullchain.pem -u /run/daphne/daphnee%(process_num)d.sock --fd 0 --access-log - --proxy-headers mysite.asgi:application&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Number of processes to startup, roughly the number of CPUs you have&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;numprocs&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Give each process a unique name so they can be told apart&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;process_name&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=asgi%(process_num)d&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Automatically start and recover processes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;autostart&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;autorestart&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Choose where you want your log to go&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;stdout_logfile&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/var/log/asgi.log&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;redirect_stderr&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Daphne can’t handle TLS unless you have the correct packages installed for Twisted. To meet those requirements, we’ll pip install them:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Twisted[tls,http2]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we need to update supervisord:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; supervisorctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; reread&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; supervisorctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Boom, website secured.&lt;/p&gt;
</content:encoded><category>django</category><category>lets encrypt</category><category>nginx</category></item><item><title>Configuring MySQL for Django</title><link>https://averyuslaner.com/blog/configuring-mysql-django/</link><guid isPermaLink="true">https://averyuslaner.com/blog/configuring-mysql-django/</guid><description>How to setup MySQL for Django in Ubuntu 18.04</description><pubDate>Fri, 07 Feb 2020 16:42:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;installing-system-packages&quot;&gt;Installing System Packages&lt;/h2&gt;
&lt;p&gt;The first step is obviously to install MySQL itself, which is easiest to do using your systems package repository. In my case, I’m using Ubuntu 18.04 on a &lt;a href=&quot;https://m.do.co/c/5c2ac855bd07&quot;&gt;Digital Ocean droplet&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql-server&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libmysqlclient-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;securing-the-database&quot;&gt;Securing the Database&lt;/h2&gt;
&lt;p&gt;Now we can work on some initial setup of the new database server. Conveniently, MySQL provides a tool that walks you thru the basics of securing the installation. The tool will ask you to decide on a password for the MySQL root user, so before we get started I strongly suggest you get a password manager ready to create and store a strong password. If you don’t already have a password manager, I’ll recommend &lt;a href=&quot;http://bitwarden.com/&quot;&gt;Bitwarden&lt;/a&gt;, which is free and open-source.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql_secure_installation&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point, you’ll be guided thru a series of questions. For the greatest level of security, just answer ‘yes’ to all of the prompts. I personally declined installing the password checking plugin since I can just use my password manager to create and save long complicated passwords.&lt;/p&gt;
&lt;p&gt;The output of the tool will look like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Securing&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MySQL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; server&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; deployment.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Connecting&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MySQL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; using&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; blank&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; password.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;VALIDATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PASSWORD&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PLUGIN&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; can&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; be&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; used&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; test&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; passwords&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; improve&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; security.&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; It&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; checks&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; strength&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; of&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; password&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; allows&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; users&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; only&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; those&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; passwords&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; which&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; are&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;secure&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; enough.&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Would&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; you&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; like&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; setup&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; VALIDATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PASSWORD&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; plugin?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Press&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; y&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Yes,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; any&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; other&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; No:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Please&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; password&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; here.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; password:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Re-enter&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; new&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; password:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; default,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MySQL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; installation&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; has&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; an&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; anonymous&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; user,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;allowing&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; anyone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; log&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; into&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MySQL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; without&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; having&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; have&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; account&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; created&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; them.&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; This&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; is&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; intended&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; only&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;testing,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; and&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; make&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; installation&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; go&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bit&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; smoother.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;You&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; should&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; remove&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; them&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; before&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; moving&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; into&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; production&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;environment.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; anonymous&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; users?&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (Press &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Yes,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; any&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; other&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; No&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Success.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Normally,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; should&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; only&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; be&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; allowed&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; connect&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; from&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;&apos;localhost&apos;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; This&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ensures&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; that&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; someone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cannot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; guess&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; at&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; password&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; from&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; network.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Disallow&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; login&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; remotely?&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (Press &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Yes,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; any&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; other&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; No&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Success.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; default,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; MySQL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; comes&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; with&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; database&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; named&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;test&apos;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; that&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;anyone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; can&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; access.&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; This&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; is&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; also&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; intended&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; only&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; testing,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;and&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; should&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; be&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; removed&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; before&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; moving&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; into&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; production&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;environment.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; test&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; database&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; and&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; access&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; it?&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (Press &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Yes,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; any&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; other&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; No&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Dropping&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; test&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; database...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Success.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Removing&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; privileges&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; on&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; test&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; database...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Success.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Reloading&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; privilege&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tables&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; will&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ensure&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; that&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; all&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; changes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;made&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; so&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; far&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; will&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; take&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; effect&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; immediately.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Reload&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; privilege&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tables&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; now?&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (Press &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Yes,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; any&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; other&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; No&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Success.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;All&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; done!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have a little bit more work to do though because the root password we set isn’t actually being used. By default, the root user’s authentication is set to use the &lt;em&gt;auth_socket&lt;/em&gt; plugin, which only checks if the socket user name matches the MySQL user name. You can confirm this by connecting to MySQL and running the following query:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;SELECT&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; user,authentication_string,plugin,host&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; FROM&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql.user&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;+------------------+-------------------------------------------+-----------------------+-----------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;             |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; authentication_string&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                     |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; plugin&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; host&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;      |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;+------------------+-------------------------------------------+-----------------------+-----------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;             |&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                                           |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; auth_socket&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;           |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql.session&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql.sys&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; debian-sys-maint&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *EUFHL2894JFLJS819FIUSFKLJDFDFJFLSDFJFPOF&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;+------------------+-------------------------------------------+-----------------------+-----------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; rows&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (0.00 &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;sec&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We’ll want to change the plugin from auth_socket to mysql_native_password. To do so, execute the following command using the same password you came up with earlier:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;ALTER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; USER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;root&apos;@&apos;localhost&apos;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; IDENTIFIED&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; WITH&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; BY&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;yourpasswordhere&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can flush the privileges and confirm the change:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;FLUSH&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PRIVILEGES&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;SELECT&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; user,authentication_string,plugin,host&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; FROM&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql.user&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;+------------------+-------------------------------------------+-----------------------+-----------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;             |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; authentication_string&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                     |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; plugin&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; host&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;      |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;+------------------+-------------------------------------------+-----------------------+-----------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;             |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *IJKHL4567JFLJS093FIUSFKLJDFDFJFLSDFJFLMV&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql.session&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql.sys&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; debian-sys-maint&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; *EUFHL2894JFLJS819FIUSFKLJDFDFJFLSDFJFPOF&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql_native_password&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; localhost&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;+------------------+-------------------------------------------+-----------------------+-----------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; rows&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (0.00 &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;sec&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;configuring-the-database-for-django&quot;&gt;Configuring the Database For Django&lt;/h2&gt;
&lt;p&gt;Now that we have MySQL nice and secure, we can start getting it ready for our Django application. We’ll start by creating a new database and a user with access to that new database. Again, you’ll need to come up with a strong password for your database user.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; DATABASE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mydatabasename&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; CHARACTER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; SET&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; UTF8&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;CREATE&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; USER&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; myuser@localhost&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; IDENTIFIED&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; BY&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;youruserspasswordhere&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When we give our new user access to the database that Django will use and flush the privileges again:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;GRANT&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ALL&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PRIVILEGES&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ON&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; personalsite.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; TO&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; myuser@localhost&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;FLUSH&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; PRIVILEGES&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we need to feed MySQL timezone information to avoid issues with django datetimes. To do that, we’ll use the &lt;em&gt;mysql_tzinfo_to_sql&lt;/em&gt; tool. When prompted for a password, use the password you created for the MySQL root user.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql_tzinfo_to_sql&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /usr/share/zoneinfo&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; mysql&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -u&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; root&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Done with MySQL. Go ahead and exit so we can move on.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;configuring-django&quot;&gt;Configuring Django&lt;/h2&gt;
&lt;p&gt;If you already have a virtual environment setup to use with your Django application activate it now. Otherwise, you can create one using &lt;em&gt;virtualenv&lt;/em&gt;. You can download the tool using pip like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3-pip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip3&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; virtualenv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With &lt;em&gt;virtualenv&lt;/em&gt; installed, you can specify a python version and directory to create the virtual environment. In my case, I’ll be using Python 3.8 to create a virtual environment in a directory called ‘venv’ in my home directory. If you want to see how to install Python 3.8 from source for your virtual environment, check out my post on Setting Up Django with Nginx + Daphne.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;virtualenv&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3.8&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Active the new environment by sourcing it’s activation script:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/venv/bin/activate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don’t yet have a django project ready to go, you can get started by creating a new directory, installing &lt;em&gt;django&lt;/em&gt; inside of it, and starting a new project. Note the period (‘.’) at the end of the last command which specifies that you want to install django in the current directory.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/myprojectdirectory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/myprojectdirectory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; django&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;django-admin.py&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; startproject&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nameofmyproject&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can actually install &lt;em&gt;mysqlclient&lt;/em&gt; which will allow our python app to talk to the database:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysqlclient&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Before starting the Django server, you’ll want to make sure you have your database settings configured in Django. In a default django install, you can find these settings in &lt;em&gt;~/myprojectdirectory/nameofmyproject/settings.py&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Within this file, look for the &lt;em&gt;DATABASES&lt;/em&gt; environment variable. By default, it looks like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;    &apos;default&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;        &apos;ENGINE&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;django.db.backends.sqlite3&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;        &apos;NAME&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: os.path.join(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;BASE_DIR&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;db.sqlite3&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Instead of using sqlite3 though, we want to use MySQL. Modify the code to something like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;    &apos;default&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;        &apos;ENGINE&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;django.db.backends.mysql&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;        &apos;OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;            &apos;read_default_file&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;/home/myusername/mysql_django.cnf&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;            &apos;init_command&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;SET sql_mode=&apos;STRICT_TRANS_TABLES&apos;&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;            &apos;isolation_level&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;read committed&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above code instructs django to read our database credentials from a configuration file so we’ll need to create that. The &lt;em&gt;init_command&lt;/em&gt; and &lt;em&gt;isolation_level&lt;/em&gt; arguments also set some other database level settings that are recommended in the &lt;a href=&quot;https://docs.djangoproject.com/en/3.0/ref/databases/#mysql-notes&quot;&gt;Django docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Make sure you save your configuration file in the same location that you specified above:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;nano&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /home/myusername/mysql_django.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Within the file, add something like the following, substituting in the vales you used when configuring MySQL:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;[client]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; = mydatabasename&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; = myusername&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; = &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;mystrongpassword&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; = 127.0.0.1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; = 3306&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;default-character-set&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; = utf8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And with that done we can finally get django started! We just need to run a few django management commands to get our migrations in order. Make sure you’re in your django project directory where the &lt;em&gt;manage.py&lt;/em&gt; script lives.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; manage.py&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; makemigrations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; manage.py&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; migrate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hopefully this command successfully sets up of your tables in your newly created database. If you run into an error, be sure to double check your configuration file to make sure you gave Django all of the correct credentials to connect to the database. Once the migrations are done, we can finally run the server. Make sure you use the IP address of your own server so you can actually connect to it.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; manage.py&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; runserver&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 203.0.113.10:8000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above command, I’m assuming the remote server running the web app has an IP address of 203.0.113.10 and I’m serving the application thru port 8000. Now from my local computer I can connect to the running web application by typing &lt;a href=&quot;http://203.0.113.10:8000&quot;&gt;http://203.0.113.10:8000&lt;/a&gt; into my browser.&lt;/p&gt;
&lt;p&gt;If the runserver command seems to be working on your remote server but you still can’t connect to the web app from your local machine, you may need to make sure that port 8000 isn’t being blocked by a firewall on your remote machine.&lt;/p&gt;
&lt;p&gt;Now that you have MySQL working with Django, you’ll want to serve it with something other than the runserver command since it isn’t appropriate for use in a production environment. For help with that, check out my blog post on Setting Up Django with Nginx + Daphne.&lt;/p&gt;
</content:encoded><category>django</category><category>Ubuntu</category><category>mysql</category></item><item><title>Setting Up Django with Nginx + Daphne on Ubuntu 18.04</title><link>https://averyuslaner.com/blog/setting-django-nginx-daphne-ubuntu-1804/</link><guid isPermaLink="true">https://averyuslaner.com/blog/setting-django-nginx-daphne-ubuntu-1804/</guid><description>Serving a Django web application with Daphne and Nginx</description><pubDate>Thu, 06 Feb 2020 23:52:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;my-environment&quot;&gt;My Environment&lt;/h2&gt;
&lt;p&gt;I’ll be deploying a Django 3.0 web application on a &lt;a href=&quot;https://m.do.co/c/5c2ac855bd07&quot;&gt;Digital Ocean droplet&lt;/a&gt; running Ubuntu 18.04. The web app will be served by Daphne and Nginx.&lt;/p&gt;
&lt;h2 id=&quot;installing-things&quot;&gt;Installing Things&lt;/h2&gt;
&lt;h3 id=&quot;python&quot;&gt;Python&lt;/h3&gt;
&lt;p&gt;I’ll be running Django using Python 3.8.1 which isn’t currently available as a package on Ubuntu so I’ll be installing it from source. The files are available on &lt;a href=&quot;https://www.python.org/downloads/&quot;&gt;python.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You could use &lt;em&gt;wget&lt;/em&gt; to download the files straight from the remote machine, but I chose to just download it locally and transfer it to my remote home directory with &lt;em&gt;scp&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;scp&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Python-3.8.1.tar.xz&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; username@203.0.113.10:/home/username&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h4&gt;
&lt;p&gt;Before we install Python, we need to make sure we have a few packages installed:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libbz2-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libncursesw5-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libssl-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libsqlite3-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tk-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libgdbm-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libc6-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; zlib1g-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libffi-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we get go ahead with our Python install. I personally like to install third-party application in the /opt directory, so I’ll do that here.&lt;/p&gt;
&lt;p&gt;Move it over, configure, make, test, and install. I’m using altinstall so I we don’t overwrite our primary python installation because I don’t see any downsides to doing so and it seems less likely to result in unintended consequences.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mv&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/Python-3.8.1.tar.xz&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /opt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /opt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tar&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -xvf&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Python-3.8.1.tar.xz&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; rm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Python-3.8.1.tar.xz&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Python-3.8.1/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;./configure&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --enable-ipv6&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --enable-optimizations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; make&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; altinstall&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sweet, so now we have python3.8 installed. Calls to python3 should still be linked to the system default, which in my case is python 3.6. To use 3.8, you’ll actually need to call &lt;em&gt;python3.8&lt;/em&gt; explicitly.&lt;/p&gt;
&lt;p&gt;So let’s get a virtual environment setup that we can use to run our Django application. I’ll use &lt;em&gt;virtualenv&lt;/em&gt; which we can install via pip. I’ll install the python3 version on my system python to do it:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3-pip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip3&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; virtualenv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Back in our home directory we can use &lt;em&gt;virtualenv&lt;/em&gt; to create the environment in a new directory we’ll name ‘venv’.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;virtualenv&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3.8&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;django&quot;&gt;Django&lt;/h3&gt;
&lt;p&gt;Since I already have a &lt;a href=&quot;https://github.com/TechnoConserve/personal_website&quot;&gt;Django application&lt;/a&gt; ready to go, I’ll activate our new virtual environment and use the requirements file from the Django application to install everything the app needs.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/venv/bin/activate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/averyuslaner.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -r&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; requirements.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;My web app uses MySQL for it’s database so I need to install the following before I can successfully pip install &lt;em&gt;mysqlclient&lt;/em&gt;. If you’re interested in more details on how to use MySQL with Django, you can check out my other blog post on Setting up MySQL for Django.&lt;/p&gt;
&lt;p&gt;By the way, if you don’t have your own requirements file, the only things you need to pip install to follow along are &lt;em&gt;django 3.0+&lt;/em&gt; and &lt;em&gt;daphne&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Once you have at least those two things installed, we can test daphne’s ability to serve the app. It will make use of the &lt;em&gt;asgi.py&lt;/em&gt; file that lives in the same directory as the &lt;em&gt;settings.py&lt;/em&gt; file on a default install. If you’re upgrading django from version 2 or below, you’ll need to add it yourself.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;daphne&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -b&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 203.0.113.10&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 8000&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mydjangoproject.asgi:application&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above command binds the application to the given IP and port numbers respectively. You’ll want to replace the example address with the IP address of your own remote machine. If all goes well, your web application should now be accessible from your local machine by entering &lt;a href=&quot;http://203.0.113.10:8000&quot;&gt;http://203.0.113.10:8000&lt;/a&gt; into your browser.&lt;/p&gt;
&lt;h2 id=&quot;supervising-daphne&quot;&gt;Supervising Daphne&lt;/h2&gt;
&lt;p&gt;Launching daphne manually isn’t ideal so let’s manage it with &lt;a href=&quot;http://supervisord.org/&quot;&gt;&lt;em&gt;supervisord&lt;/em&gt;&lt;/a&gt;. We can start to attack this problem at along with configuring nginx so let’s install both now.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; supervisor&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we write a configuration file for daphne, which we save inside &lt;em&gt;/etc/supervisor/conf.d/.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nano&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/supervisor/conf.d/averyuslaner.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Within the file, add something like what I have below. Note that I’m supplying the absolute path to daphne that’s inside my virtual environment.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;[fcgi-program:asgi]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Set Django environment variables&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;mydjangoproject.settings.production&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;&amp;lt;redacted&amp;gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# TCP socket used by Nginx backend upstream&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=tcp://localhost:8000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Directory where your site&apos;s project files are located&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/home/myusername/averyuslaner.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Each process needs to have a separate socket file, so we use process_num&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Make sure to update &quot;mydjangoproject.asgi&quot; to match your project name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/home/&amp;lt;user&amp;gt;/venv/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers mydjangoproject.asgi:application&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Number of processes to startup, roughly the number of CPUs you have&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;numprocs&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Give each process a unique name so they can be told apart&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;process_name&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=asgi%(process_num)d&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Automatically start and recover processes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;autostart&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;autorestart&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Choose where you want your log to go&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;stdout_logfile&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=/var/log/asgi.log&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;redirect_stderr&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we tell supervisor to update so it can read the configuration file:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; supervisorctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; reread&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; supervisorctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;serving-from-nginx&quot;&gt;Serving From Nginx&lt;/h2&gt;
&lt;p&gt;Next, we create the configuration file for nginx which we’ll save in &lt;em&gt;/etc/nginx/sites-available/&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nano&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/nginx/sites-available/averyuslaner.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Within the file, add this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;upstream daphne-backend {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    server localhost:8000&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;server {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    listen 80 default_server&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    listen [::]:80 default_server&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    location / {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        try_files $uri @proxy_to_app&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    location @proxy_to_app {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_pass http://daphne-backend&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_http_version 1.1&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_set_header Upgrade $http_upgrade&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_set_header Connection &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;upgrade&quot;&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_redirect off&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_set_header Host $host&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_set_header X-Real-IP $remote_addr&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        proxy_set_header X-Forwarded-Host $server_name&lt;/span&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once that’s done, we simply symlink the file into nginx’s sites-enabled directory and reload nginx.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/nginx/sites-enabled&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ln&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -s&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ../sites-available/averyuslaner.com&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nginx&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That should do it! Your web application should now be accessible at your server’s IP address. If that isn’t the case, check your log files to see where the problem might be. Relevant log files can be found in the following places:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nginx - /var/log/nginx/error.log&lt;/li&gt;
&lt;li&gt;Supervisord - /var/log/supervisor/supervisord.log&lt;/li&gt;
&lt;li&gt;Daphne process - /var/log/asgi.log&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>daphne</category><category>supervisord</category><category>django</category><category>nginx</category><category>Ubuntu</category></item><item><title>Configuring Ubuntu 18.04 + CUDA 10.0 + NVIDIA GPU For Deep Learning With Tensorflow &amp; OpenCV Python Bindings</title><link>https://averyuslaner.com/blog/configuring-ubuntu-1804-cuda-nvidia-gpu-deep-learning-opencv-python-bindings/</link><guid isPermaLink="true">https://averyuslaner.com/blog/configuring-ubuntu-1804-cuda-nvidia-gpu-deep-learning-opencv-python-bindings/</guid><description>Configuring a development environment to perform deep learning using the python bindings of OpenCV.</description><pubDate>Wed, 24 Oct 2018 13:52:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;guides-exist-for-ubuntu-1604-less-so-for-1804&quot;&gt;Guides Exist for Ubuntu 16.04; Less so for 18.04&lt;/h2&gt;
&lt;p&gt;This guide will essentially adapt existing guides for 16.04 and address the areas where those guides need to be altered or worked around to achieve the desired results. This solution isn’t as well supported as 16.04 so if you’re just looking for an easy way to get started with machine learning, you should probably look elsewhere. Here we’re all about breaking things and figuring out how to fix them.&lt;/p&gt;
&lt;p&gt;This guide draws especially heavily from one written by Adrian Rosebrock over at &lt;a href=&quot;http://PyImageSearch.com&quot;&gt;PyImageSearch.com&lt;/a&gt;. And if you’re reading this post, you might also be interested in his latest book, &lt;a href=&quot;https://www.pyimagesearch.com/deep-learning-computer-vision-python-book/&quot;&gt;Deep Learning For Computer Vision With Python&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;connecting-to-your-development-machine&quot;&gt;Connecting To Your Development Machine&lt;/h2&gt;
&lt;p&gt;I’m going to assume you’ll be interacting with your development machine remotely over SSH. This is better than running everything locally anyway because running the X11 server that runs your Graphical User Interface (GUI) while you set up your development environment can eff things up.&lt;/p&gt;
&lt;p&gt;If you have no other choice but to run these commands locally, you can switch to another virtual console by pressing:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CTRL + ALT + F3&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;…logging in and then running:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lightdm&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; stop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;updating-your-environment&quot;&gt;Updating Your Environment&lt;/h2&gt;
&lt;p&gt;Make sure your package lists are up-to-date:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; upgrade&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;installing-necessary-packages&quot;&gt;Installing Necessary Packages&lt;/h2&gt;
&lt;p&gt;This is the first area where we start to run into differences between configuring 16.04 and 18.04.&lt;/p&gt;
&lt;p&gt;First, let’s install all of the packages that install painlessly for both systems:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build-essential&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cmake&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; git&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unzip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pkg-config&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libjpeg-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libtiff5-dev&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libavcodec-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libavformat-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libswscale-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libv4l-dev&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libxvidcore-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libx264-dev&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libgtk-3-dev&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libhdf5-serial-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; graphviz&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libopenblas-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libatlas-base-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; gfortran&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python-tk&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3-tk&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python-imaging-tk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The following packages require a bit more work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;libjasper-dev\&lt;/li&gt;
&lt;li&gt;libpng12-dev&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;libjasper-dev-for-ubuntu-1804&quot;&gt;libjasper-dev for Ubuntu 18.04&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;https://askubuntu.com/a/1079961/476088&quot;&gt;a handy SE answer&lt;/a&gt;, we can fix this issue pretty easily:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/Downloads&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; http://security.ubuntu.com/ubuntu/pool/main/j/jasper/libjasper-dev_1.900.1-debian1-2.4ubuntu1.2_amd64.deb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; http://security.ubuntu.com/ubuntu/pool/main/j/jasper/libjasper1_1.900.1-debian1-2.4ubuntu1.2_amd64.deb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ./libjasper-dev_1.900.1-debian1-2.4ubuntu1.2_amd64.deb&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ./libjasper1_1.900.1-debian1-2.4ubuntu1.2_amd64.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;libpng12-dev-for-ubuntu-1804&quot;&gt;libpng12-dev for Ubuntu 18.04&lt;/h2&gt;
&lt;p&gt;This package has since been dropped. Instead, we use libpng-dev which conveniently was already installed when we installed libgtk-3-dev.&lt;/p&gt;
&lt;h2 id=&quot;installing-python-27-and-python-3-header-files&quot;&gt;Installing Python 2.7 and Python 3 Header Files&lt;/h2&gt;
&lt;p&gt;We’ll be compiling OpenCV with python binding so we’ll need these development packages to do so:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python2.7-dev&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;preparing-nvidia-drivers&quot;&gt;Preparing NVIDIA Drivers&lt;/h2&gt;
&lt;p&gt;We’ll need to change out the default graphics drivers so we’ll need to install some packages in preparation for that change:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; linux-image-generic&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; linux-image-extra-virtual&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; linux-source&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; linux-headers-generic&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we need to disable the default Nouveau driver by creating a blacklist file. Open up the nano text editor with this command:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nano&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/modprobe.d/blacklist-nouveau.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To this file, add the following lines:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;blacklist nouveau&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;blacklist lbm-nouveau&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;options nouveau &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;modeset&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;=0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;alias nouveau off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;alias lbm-nouveau off&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can now close out the editor by hitting CTRL + X, being careful to select ‘Y’ when prompted to save your changes.&lt;/p&gt;
&lt;p&gt;Now we disable Nouveau in the Kernel Mode Settings (KMS):&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; options&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nouveau&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; modeset=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tee&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /etc/modprobe.d/nouveau-kms.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above command edits the file without us having to open a text editor. The first part of the command, &lt;strong&gt;echo&lt;/strong&gt;, returns everything after it, in this case &lt;strong&gt;options nouveau modeset=0&lt;/strong&gt;. The vertical pipe character &lt;strong&gt;|&lt;/strong&gt; in the middle, indicates that we want that output to be fed into the other part of our command, in this case &lt;strong&gt;tee&lt;/strong&gt;. We append that command with &lt;strong&gt;sudo&lt;/strong&gt; because we need admin writes to edit the file located at &lt;strong&gt;/etc/modprobe.d/nouveau-kms.conf&lt;/strong&gt;. The &lt;strong&gt;tee&lt;/strong&gt; command splits what is fed to it between the given file and the terminal output so we can see what it is doing. In this case, we’ve also included the &lt;strong&gt;-a&lt;/strong&gt; flag which instructs the &lt;strong&gt;tee&lt;/strong&gt; command to append the input to the file rather than just overwriting everything in the file.&lt;/p&gt;
&lt;p&gt;Now we update run the command that makes note of our previous changes so they will be respected at boot time:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update-initramfs&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -u&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now we can restart the machine:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; reboot&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;downloading-cuda-toolkit&quot;&gt;Downloading CUDA Toolkit&lt;/h2&gt;
&lt;p&gt;Now we download the CUDA Toolkit from the &lt;a href=&quot;https://developer.nvidia.com/cuda-toolkit&quot;&gt;NVIDIA website&lt;/a&gt;. Because we like the pain and frustration of the bleeding edge, we’ll be using CUDA Toolkit 10.0 so we’ll select Linux &amp;gt; x86_64 &amp;gt; Ubuntu &amp;gt; 18.04 &amp;gt; deb (network).&lt;/p&gt;
&lt;p&gt;If you’ve navigated to the website on a machine that isn’t the one you’re configuring, just copy the link address to the download file and use &lt;strong&gt;wget&lt;/strong&gt; on your Ubuntu machine:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we just install it:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dpkg&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -i&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cuda-repo-ubuntu1804_10.0.130-1_amd64.deb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-key&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; adv&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --fetch-keys&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cuda-10.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We need to update our path variable so the computer knows where CUDA lives.&lt;/p&gt;
&lt;p&gt;Note that I’m editing my &lt;strong&gt;~/.profile&lt;/strong&gt; file which only gets read when the user logs in. You could replace the &lt;strong&gt;~/.profile&lt;/strong&gt; part of the following command with &lt;strong&gt;~/.bashrc&lt;/strong&gt; which I imagine some people would recommend, but those people aren’t me.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;export PATH=/usr/local/cuda-10.0/bin${&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;}}&quot;&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/.profile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To refresh the PATH variable in your current session, you can either close and reopen a new terminal session or use the source command:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/.profile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can check to make sure &lt;strong&gt;/usr/local/cuda-10.0/bin&lt;/strong&gt; is included in your path variable by echoing it:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; $PATH&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After rebooting we can verify that things are working properly. Check that the NVIDIA Persistence Daemon is running:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; systemctl&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; status&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; nvidia-persistenced&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It should say something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;nvidia-persistenced.service - NVIDIA Persistence Daemon &lt;br&gt;
Loaded: loaded (/lib/systemd/system/nvidia-persistenced.service; static; vendor preset: enabled) &lt;br&gt;
Active: active (running)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now check that the NVIDA driver version:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /proc/driver/nvidia/version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You would expect something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NVRM version: NVIDIA UNIX x86_64 Kernel Module 410.48 Thu Sep 6 06:36:33 CDT 2018 &lt;br&gt;
GCC version: gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Check the version of CUDA Toolkit:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;nvcc&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -V&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It should say something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;nvcc: NVIDIA (R) Cuda compiler driver &lt;br&gt;
Copyright (c) 2005-2018 NVIDIA Corporation &lt;br&gt;
Built on Sat_Aug_25_21:08:01_CDT_2018 &lt;br&gt;
Cuda compilation tools, release 10.0, V10.0.130&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now let’s get the CUDA samples and make sure they run correctly. Change into whatever directory you’d like to download them to and run:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cuda-install-samples-10.0.sh&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There should now be a directory called &lt;strong&gt;NVIDIA_CUDA-10.0_Samples&lt;/strong&gt; in your current directory. Let’s &lt;strong&gt;cd&lt;/strong&gt; into it and compile the samples:&lt;/p&gt;
&lt;p&gt;Note that the &lt;strong&gt;make&lt;/strong&gt; command uses a single CPU core by default but will go much faster if you tell it to use more. You can find out how many cores your system has available by using the command:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;lscpu | grep -E ‘^Thread|^Core|^Socket|^CPU(’&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That will give you output like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CPU(s): 12 &lt;br&gt;
Thread(s) per core: 2 &lt;br&gt;
Core(s) per socket: 6 &lt;br&gt;
Socket(s): 1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So in my &lt;strong&gt;make&lt;/strong&gt; command I can say &lt;strong&gt;make -j6&lt;/strong&gt; to make things go much faster than if I had just executed &lt;strong&gt;make&lt;/strong&gt; without any additional arguments.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; NVIDIA_CUDA-10.0_Samples/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once that’s done, we’ll execute the &lt;strong&gt;deviceQuery&lt;/strong&gt; script to check if our GPU is working with CUDA. From the same directory you ran the &lt;strong&gt;make&lt;/strong&gt; command, you can run the script like this:&lt;/p&gt;
&lt;p&gt;Note the period (&lt;strong&gt;.&lt;/strong&gt;) at the beginning of the command.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;./bin/x86_64/linux/release/deviceQuery&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command gives you a bunch of info and at the bottom it should hopefully say:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result = PASS&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;installing-cudnn-cuda-deep-neural-network-library&quot;&gt;Installing cuDNN (CUDA Deep Neural Network library)&lt;/h2&gt;
&lt;p&gt;Downloading cuDNN requires the creation of an account on the &lt;a href=&quot;https://developer.nvidia.com&quot;&gt;developer.nvidia.com&lt;/a&gt; website so it’s probably easier to download the files on the machine you’re sshing from and then copy them over using &lt;strong&gt;scp&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The three downloads we’re looking for are &lt;a href=&quot;https://developer.nvidia.com/rdp/cudnn-download&quot;&gt;cuDNN v7.3.1 for CUDA 10.0&lt;/a&gt;. Specifically we’ll be installing the runtime and development libraries plus the code samples and user guide so look for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;cuDNN v7.3.1 Runtime Library for Ubuntu18.04 (Deb)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cuDNN v7.3.1 Developer Library for Ubuntu18.04 (Deb)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cuDNN v7.3.1 Code Samples and User Guide for Ubuntu18.04 (Deb)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you have all of those downloaded, you can copy them to your development machine. You’ll need to replace &lt;strong&gt;&amp;lt; user &amp;gt;&lt;/strong&gt; and &lt;strong&gt;&amp;lt; dev-machine-ip &amp;gt;&lt;/strong&gt; with their appropriate values. Make sure you run this command from the same directory you downloaded the files to.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;scp&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libcudnn7&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dev-machine-ip&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;:/home/&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/Downloads/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, back on the development machine, let’s install them. We copied them over to users &lt;strong&gt;Download&lt;/strong&gt; directory so you can look for the files there. When you find them, install them like so:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dpkg&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -i&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libcudnn7_7.3.1.20-1+cuda10.0_amd64.deb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dpkg&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -i&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libcudnn7-dev_7.3.1.20-1+cuda10.0_amd64.deb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dpkg&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -i&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; libcudnn7-doc_7.3.1.20-1+cuda10.0_amd64.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can verify the installation by running some sample code. First, we copy it over to our home directory:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -r&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /usr/src/cudnn_samples_v7/&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; $HOME&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can change into the directory and compile the samples. As before we can speed up the make command by giving it the number of CPU cores we have available (e.g. &lt;strong&gt;make -j4&lt;/strong&gt;).&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  $HOME&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;/cudnn_samples_v7/mnistCUDNN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; clean&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We then run the sample (again, note the period at the beginning):&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;./mnistCUDNN&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If all went well, you should see at the bottom of the output:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Test passed!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;setting-up-our-virtual-python-environments&quot;&gt;Setting Up Our Virtual Python Environments&lt;/h2&gt;
&lt;p&gt;Back in our home directory, let’s setup a virtual environment for our python code to run. This is standard practice since it separates our own python libraries from the system level ones and also helps us stay organized.&lt;/p&gt;
&lt;p&gt;There are quite a few ways to do this, so feel free to use whatever method you want or do what I do:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; python3-venv&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;python3&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -m&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; venv&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; venv/dl4cv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you followed my way, we created our virtual environment in a directory called &lt;strong&gt;dl4cv&lt;/strong&gt; which you could have named whatever you want. This directory itself is located in the &lt;strong&gt;venv&lt;/strong&gt; directory in your home directory.&lt;/p&gt;
&lt;p&gt;Now, whenever you want to work inside of your virtual environment, you’ll need to activate it:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; venv/dl4cv/bin/activate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When activated, you’ll notice that the name of your virtual environment appears in parentheses to the left side of your command prompt.&lt;/p&gt;
&lt;p&gt;Once inside our virtual python environment, we’ll be using the python package manager &lt;strong&gt;pip&lt;/strong&gt; to install new python packages. First, let’s upgrade it to the latest version:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --upgrade&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, let’s install the python package &lt;a href=&quot;http://www.numpy.org/&quot;&gt;NumPy&lt;/a&gt; which we’ll need to compile and install &lt;a href=&quot;https://docs.opencv.org/3.4.3/index.html&quot;&gt;OpenCV&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; numpy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We now need to download both opencv and opencv_contrib to our Downloads directory:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/Downloads&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -O&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; opencv.zip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://github.com/opencv/opencv/archive/3.4.3.zip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -O&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; opencv_contrib.zip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://github.com/opencv/opencv_contrib/archive/3.4.3.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unzip both of the archives we just downloaded:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;unzip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; opencv.zip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;unzip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; opencv_contrib.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we change directory into the &lt;strong&gt;~/opencv-3.4.3/&lt;/strong&gt; directory, create a new directory called &lt;strong&gt;build&lt;/strong&gt; and configure OpenCV inside of it:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/Downloads/opencv-3.4.3/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; CMAKE_BUILD_TYPE=RELEASE&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; CMAKE_INSTALL_PREFIX=/usr/local&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; WITH_CUDA=ON&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; INSTALL_PYTHON_EXAMPLES=ON&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; OPENCV_EXTRA_MODULES_PATH=~/Downloads/opencv_contrib-3.4.3/modules&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -D&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; BUILD_EXAMPLES=ON&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -DBUILD_opencv_cudacodec=OFF&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ..&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When it’s done make note of the output, focusing on the regions as highlighted in the image below.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Image unavailable: OpenCV Build Terminal Output]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You’ll want to make sure that both your Python and NumPy versions are the ones from your virtual environment.&lt;/p&gt;
&lt;p&gt;If for some reason they aren’t you can always delete the build folder and repeat the above steps, make sure you have the commands correct and that you have activated your virtual python environment before running the command.&lt;/p&gt;
&lt;p&gt;As an aside, I had originally tried to compile with CUDA support as well but it ends up not playing well at compile time so that’s why it’s disabled in this example.&lt;/p&gt;
&lt;p&gt;Now we are ready to compile. This command again runs faster if you specify more cores, but if you run into errors, try running &lt;strong&gt;make clean&lt;/strong&gt; and then rerunning &lt;strong&gt;make&lt;/strong&gt; without specifying additional cores.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -j4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we install and update our file links before returning to our home directory:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; make&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ldconfig&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To make our OpenCV bindings available to our virtual python environment, we need to symbolically link them, which is kind of like copying but without the copying part:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/venv/dl4cv/lib/python3.6/site-packages/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ln&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -s&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /usr/local/lib/python3.6/site-packages/cv2.cpython-36m-x86_64-linux-gnu.so&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cv2.so&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Time to test it out! Make sure you have your virtual python environment activated and just type &lt;strong&gt;python&lt;/strong&gt; and hit enter to enter the virtual environment.&lt;/p&gt;
&lt;p&gt;From there you can try importing the OpenCV library:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; cv2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;cv2.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;__version__&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No errors? Congrats!&lt;/p&gt;
&lt;p&gt;We’ll install a few more python packages before adding &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;Tensorflow&lt;/a&gt; support:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; scipy&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; matplotlib&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; pillow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; imutils&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; h5py&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; requests&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; progressbar2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; scikit-learn&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; scikit-image&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tensorflow with GPU support can be pip installed for earlier versions of CUDA + cuDNN but not for the latest versions that we’ve installed so we’ll need to build tensorflow from source ourselves.&lt;/p&gt;
&lt;p&gt;Let’s start by downloading the source into our &lt;strong&gt;Downloads/&lt;/strong&gt; folder:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/Downloads&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; clone&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://github.com/tensorflow/tensorflow.git&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tensorflow&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, we’re on the master branch of the source code which is more likely to have bugs and stability issues. Let’s switch to the latest release version:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; checkout&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; r1.11&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can test out the code branch with Bazel but we’ll need to install it. First the dependencies:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; apt-get&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; openjdk-8-jdk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we can install Bazel itself:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~/Downloads&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;wget&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; https://github.com/bazelbuild/bazel/releases/download/0.18.0/bazel_0.18.0-linux-x86_64.deb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;dpkg&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -i&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bazel_0.18.0-linux-x86_64.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;…and change back into our tensorflow directory to run the test (expect it to take awhile):&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;bazel&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; test&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -c&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; opt&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; //tensorflow/...&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -//tensorflow/compiler/...&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -//tensorflow/contrib/lite/...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You’ll see plenty of WARNING messages, but we just want to make sure things don’t completely go to shit. For me, my results were:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;INFO: Build completed, 23 tests FAILED, 27775 total actions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The documentation offers no clues as to whether 23 errors is good or bad, so I’ll just assume it’s totally fine.&lt;/p&gt;
&lt;p&gt;Now we run the configure script which essential surveys the user for which values to use to compile with. The things we care about are telling it to compile with the python executable in our virtual environment, enabling CUDA support, and telling it the correct versions of our tools. We’ll just leave everything else as their default values.&lt;/p&gt;
&lt;p&gt;So the only non-default answers we need to give are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Do you wish to build TensorFlow with CUDA support? [y/N]: &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 9.0]: &lt;strong&gt;10.0&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7.0]: &lt;strong&gt;7.3&lt;/strong&gt;\&lt;/li&gt;
&lt;li&gt;Please specify the NCCL version you want to use. If NCCL 2.2 is not installed, then you can use version 1.3 that can be fetched automatically but it may have worse performance with multiple GPUs. [Default is 2.2]: &lt;strong&gt;1.3&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now we make the package builder:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;bazel&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --config=opt&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --config=cuda&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; //tensorflow/tools/pip_package:build_pip_package&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;…build the package:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;./bazel-bin/tensorflow/tools/pip_package/build_pip_package&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /tmp/tensorflow_pkg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And install it using pip and change back to our home directory:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /tmp/tensorflow_pkg/tensorflow-1.11.0-cp36-cp36m-linux_x86_64.whl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ~&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can test by opening up another &lt;strong&gt;python&lt;/strong&gt; interactive shell and trying to import tensorflow:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; tensorflow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;tensorflow.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;__version__&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you don’t get any errors, you can move onto installing Keras:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; keras&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you open up another Python shell and &lt;strong&gt;import keras&lt;/strong&gt;, you should get a message saying:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using TensorFlow backend.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you do, you’re done! Go play with some deep learning models. Maybe &lt;a href=&quot;https://www.pyimagesearch.com/2017/12/11/image-classification-with-keras-and-deep-learning/&quot;&gt;start here&lt;/a&gt;?&lt;/p&gt;
</content:encoded><category>linux</category><category>hardware</category><category>python</category><category>machine learning</category><category>GPU</category><category>Ubuntu</category><category>OpenCV</category><category>Deep Learning</category><category>tensorflow</category></item><item><title>How to Politic: A Salt Lake County Democrats Guide to Partial Political Competence</title><link>https://averyuslaner.com/blog/how-politic-salt-lake-county-democrats-guide-partial-political-competence/</link><guid isPermaLink="true">https://averyuslaner.com/blog/how-politic-salt-lake-county-democrats-guide-partial-political-competence/</guid><description>I have no idea what I&apos;m doing so I made this guide to help both of us.</description><pubDate>Wed, 04 Apr 2018 01:26:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;caucus-night&quot;&gt;Caucus Night&lt;/h2&gt;
&lt;p&gt;A friend encouraged me to attend the Democratic Party’s Caucus Night. To be perfectly honest, I still don’t know if that event was organized by the State, County or National Democratic Party, or some combination thereof. Regardless, I consider myself a democrat and I wanted to get more involved in creating change in my local community so I decided to go.&lt;/p&gt;
&lt;p&gt;That same friend directed me to &lt;a href=&quot;https://vote.utah.gov/vote/menu/index&quot;&gt;vote.utah.gov&lt;/a&gt;. There you can enter your street address to figure out your precinct number and the location of your caucus.&lt;/p&gt;
&lt;h3 id=&quot;cool-but-what-the-fuck-is-a-caucus-anyway&quot;&gt;Cool, but what the fuck is a caucus anyway?&lt;/h3&gt;
&lt;p&gt;By definition, a caucus is “a meeting at which local members of a political party register their preference among candidates running for office or select delegates to attend a convention.” At this particular caucus, we were selecting delegates to attend the Salt Lake County Democratic Convention.&lt;/p&gt;
&lt;h3 id=&quot;attending-the-caucus&quot;&gt;Attending the caucus&lt;/h3&gt;
&lt;p&gt;Unfortunately, since most of the attendees are veteran political activists, there aren’t very clear directions as to where to go or what to do. I wish there had been a short posterboard explaining that I need to check in, fill out the form, and then go wait in the auditorium. Instead, I essentially just walked inside and put on my best “help me, I’m so confused” face until a volunteer approached me and asked if I had registered yet. I explained that I had not, and was directed to a table of computers labeled “ADA Registration.” I still have no idea what ADA stands for.&lt;/p&gt;
&lt;p&gt;I approached the nearest woman sitting behind a computer who looked up at me, apparently expecting something.&lt;/p&gt;
&lt;p&gt;“Umm, what do you need from me?” I asked, already feeling stupid.&lt;/p&gt;
&lt;p&gt;“I just need a government-issued ID that lists your current address,” she offered merrily.&lt;/p&gt;
&lt;p&gt;“Okay sure. The address on here is actually old, so I also brought the piece of mail if that works.”&lt;/p&gt;
&lt;p&gt;“No problem. Looks like you’re already registered to vote and the address matches so you’re good to go! Just fill this form out, and we’ll soon get started in the auditorium to my left here.”&lt;/p&gt;
&lt;p&gt;With the form in hand, I made my way to the nearest table, grabbed a pen and filled it out. The woman had also circled my precinct number on the top of the form since I would apparently need it later. The form requested basic contact info and offered me the ability to express interest in various event caucuses, which are essentially just more groups of people that share or are interested in specific topics.&lt;/p&gt;
&lt;p&gt;After bonding with a fellow democrat by nodding as she complained about how long everything was taking, we made our way into the auditorium to listen to people with supposed relevance to our political affiliation.&lt;/p&gt;
&lt;h3 id=&quot;speeches-and-instructions&quot;&gt;Speeches and Instructions&lt;/h3&gt;
&lt;p&gt;Some people whose names and titles I’ve already forgotten explained to the small crowd that we are the power that will turn the state blue. Later, I overheard a woman comment that she found the whole thing “uplifting,” and “inspiring.” Personally, I was hoping for something a little more educational in terms of how exactly this whole thing works. Luckily, they did get to that eventually.&lt;/p&gt;
&lt;p&gt;A bit later, the meeting transitioned to a brief explanation of what we would be voting on. Namely, local precinct leaders, some of whom would also act as delegates to vote at the upcoming &lt;a href=&quot;http://www.slcountydems.com/2018-convention/&quot;&gt;Salt Lake County Democratic Convention&lt;/a&gt;. They apologized for not having a projector available to explain how the forms worked but assured us that we would be able to figure it out on our own and if we had any questions people would be walking around to address them. Each precinct had its own meeting location and we were directed to meet there once the previous precinct Chair or other member of the precinct had gathered the relevant materials from up front.&lt;/p&gt;
&lt;p&gt;I decided to be optimistic and assume that the previous Chair of my precinct was in attendance and would gather the paperwork. I made my way to my precincts designated table. Thankfully, other precinct members had indeed shown up and soon joined me at the table. We quickly came to agreement that none of us wanted to serve as any elected official but we would if we had to. And we did have to.&lt;/p&gt;
&lt;p&gt;At this point I knew roughly that as a delegate, I would need to attend the aforementioned Democratic County Convention to vote there. With this is mind, I apprehensively volunteered myself to serve as a delegate. Later, my friend explained to me that this means I was also a State delegate. I’m still rather baffled that I could become an elected official for something I didn’t/don’t fully understand.&lt;/p&gt;
&lt;h2 id=&quot;what-now&quot;&gt;What now?&lt;/h2&gt;
&lt;p&gt;My first major responsibility is to attend the County Convention on April 14th. There I know I have to vote, but as of the time of writing, I don’t really know who is running, much less what they stand for. So that’s great.&lt;/p&gt;
&lt;p&gt;So far I’ve figured out my districts (House District 28 &amp;amp; Senate District 4) by going to &lt;a href=&quot;https://le.utah.gov/GIS/findDistrict.jsp&quot;&gt;le.utah.gov&lt;/a&gt; so that seems like a pretty good first start.&lt;/p&gt;
&lt;p&gt;I’ll figure out the rest later. Stay tuned.&lt;/p&gt;
</content:encoded><category>politics</category><category>utah</category><category>Salt Lake County</category><category>democrats</category></item><item><title>Docker-Compose in Production</title><link>https://averyuslaner.com/blog/docker-compose-production/</link><guid isPermaLink="true">https://averyuslaner.com/blog/docker-compose-production/</guid><description>Because just when I figured out Docker Cloud, they dropped support for it.</description><pubDate>Fri, 23 Mar 2018 18:04:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;production-is-like-development-but-with-more-stress-and-frustration&quot;&gt;Production is like development but with more stress and frustration&lt;/h2&gt;
&lt;p&gt;Just when I had my Docker Cloud deployment all figured out, Docker went ahead and ruined everything by announcing they were dropping support for it in May. So here I am trying to figure out how to use Docker Compose in production. Luckily, I already had a working implementation of Docker Compose for development. Unfortunately, docker didn’t want to make things too easy for me.&lt;/p&gt;
&lt;p&gt;I wish it was as easy as provisioning a new host with Docker Machine, targeting the remote host by configuring the DOCKER_HOST environment variable, and then firing off my &lt;strong&gt;docker-compose up&lt;/strong&gt; command. Sadly, that is not the case. While I can get everything running perfectly on my local host with docker-compose up, when I target the remote machine, my containers complain that their run scripts don’t exist:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ERROR:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cts_worker_1&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  Cannot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; worker:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; OCI&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; runtime&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; create&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; failed:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container_linux.go:348:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; starting&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; process&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; caused&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;exec: &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;./run_celery.sh&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;: stat ./run_celery.sh: no such file or directory&quot;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unknown&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ERROR:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cts_web_1&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  Cannot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; web:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; OCI&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; runtime&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; create&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; failed:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container_linux.go:348:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; starting&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; process&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; caused&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;exec: &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;./run_web.sh&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;: stat ./run_web.sh: no such file or directory&quot;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unknown&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ERROR:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; web&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  Cannot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; web:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; OCI&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; runtime&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; create&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; failed:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container_linux.go:348:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; starting&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; process&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; caused&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;exec: &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;./run_web.sh&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;: stat ./run_web.sh: no such file or directory&quot;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unknown&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ERROR:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; worker&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;  Cannot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; worker:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; OCI&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; runtime&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; create&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; failed:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container_linux.go:348:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; starting&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; container&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; process&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; caused&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;exec: &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;./run_celery.sh&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;: stat ./run_celery.sh: no such file or directory&quot;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unknown&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ERROR:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; Encountered&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; errors&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; while&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bringing&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; up&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; the&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; project.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It seems this is because the run scripts are added as relative volume mounts:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;dockerfile&quot; role=&quot;region&quot; aria-label=&quot;Code, dockerfile&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;web:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  volumes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;      - .:/code&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since the notation for this mounting is [host_path]:[container_path] and my DOCKER_HOST environment variable is set to the remote machine, docker is actually looking in the &lt;strong&gt;/root&lt;/strong&gt; folder of the remote docker machine I provisioned. I’d prefer if it didn’t work this way, but it does so I’ll have to make do.&lt;/p&gt;
&lt;p&gt;One potential solution is to use the relatively new &lt;strong&gt;docker-machine mount&lt;/strong&gt; command to sync my code to the remote machine. I however, couldn’t get this to work in a way that made sense to me. For one, the &lt;a href=&quot;https://docs.docker.com/machine/reference/mount/&quot;&gt;docs&lt;/a&gt; don’t provide much help. They also make it seem like the command is only designed to sync files from the machine to localhost rather than the other way around. Anyway, I tried executing the following in root directory of the source code I wanted synced to my remote machine:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker-machine&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mount&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [machine-name]:[machine-mount-point] &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fuse, presumably the underlying tool dealing with the mount, complained that the directory wasn’t empty, and invited me to use the “nonempty” option if I was feeling brave. My frustration was close enough to bravery so I tried it, and oddly, the option doesn’t even seem supported by docker machine. Out of curiosity, I also created a new empty folder and mounted that, which worked, but that doesn’t actually solve my issue. Maybe I could copy my code into that new folder, but then I’d have a duplicate local copy of everything which would be silly.&lt;/p&gt;
&lt;p&gt;I considered &lt;strong&gt;docker-machine scp&lt;/strong&gt; but quickly realized how inefficient it was for dealing with code changes.&lt;/p&gt;
&lt;p&gt;Then, after reading what seemed like hundreds of GitHub issues and SO questions, I realized that the solution was actually much more simple. I had been mislead from the very beginning by following the &lt;a href=&quot;https://docs.docker.com/compose/django/&quot;&gt;Docker docs for setting up a django project&lt;/a&gt;. I didn’t have any need to mount the code as a volume at all since my Dockerfile copied the code into the container already:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;dockerfile&quot; role=&quot;region&quot; aria-label=&quot;Code, dockerfile&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; python:3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; PYTHONUNBUFFERED 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;RUN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; apt-get update &amp;amp;&amp;amp; apt-get install -y \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    binutils \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    libproj-dev \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    gdal-bin \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    libgeoip1 \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    python-gdal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;RUN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mkdir /code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; /code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; requirements.txt /code/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;RUN&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; pip install -r requirements.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; . /code/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After deleting that relative bind mount volume, everything worked hunky dory.&lt;/p&gt;
</content:encoded><category>docker</category><category>docker-compose</category><category>production</category></item><item><title>Switching To Containerized Deployment</title><link>https://averyuslaner.com/blog/switching-containerized-deployment/</link><guid isPermaLink="true">https://averyuslaner.com/blog/switching-containerized-deployment/</guid><description>Deploying my docker containers with Docker Cloud.</description><pubDate>Fri, 02 Mar 2018 21:12:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Like so many of my projects, I’m coming back to this one after several months of not touching it so I need to reorient myself a bit and then continue stumbling forward until I end up with something that works. The end goal is to be able to deploy a series of docker containers that make up a web application using Docker Cloud.&lt;/p&gt;
&lt;p&gt;So far I have three docker files; one for Postgres, another that expands on Postgres to install PostGIS, and the third that incorporates these and all the other required services for my Django web application. I’ve also already created a private repository on Docker Cloud.&lt;/p&gt;
&lt;p&gt;Step one is to deploy a node in Docker Cloud.&lt;/p&gt;
&lt;h2 id=&quot;deploy-a-node&quot;&gt;Deploy a Node&lt;/h2&gt;
&lt;p&gt;The needs of my web application are light at the moment so I’ve disabled swarm mode in Docker Cloud. For the sake of cost, I’ll be sticking with a single server instance.&lt;/p&gt;
&lt;p&gt;I’ll be launching on Digital Ocean which I’ve linked to my Docker Cloud account. Digital Ocean recently increased the sizes of their droplets and those changes don’t yet seem to be reflected in the node creation options on Docker Cloud so I’m uncertain what size droplet I’ll actually end up with. I’m aiming for the $10/month size which should be 2 GB of RAM 50 GB of disk space and a single vCPU. On Docker Cloud I’m choosing what used to be the $10/mo option, listed as 1 GB of RAM, 30 GB of disk space, and a single vCPU. Hopefully when I create this, it will either create the upgraded version of the droplet or allow me resize it afterwards.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Image unavailable: Docker Cloud Node Creation Form]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As it turns out, the created droplet does reflect the options in Docker Cloud rather than the recent upgrade to droplet sizes on Digital Ocean. This is bad, because the node created by Docker Cloud still costs $10/month but with 1 less GB of RAM and 20 GB less disk space. So the first thing I’m going to do is power off the newly created droplet and resize it through the Digital Ocean web interface.&lt;/p&gt;
&lt;p&gt;Powering off the droplet involves it’s own problem solving of course since the Docker Cloud automated deployment doesn’t copy over any ssh keys you may have added to your Digital Ocean account. We have to do that ourselves and the process isn’t documented very clearly.&lt;/p&gt;
&lt;h2 id=&quot;connecting-to-the-node&quot;&gt;Connecting to the Node&lt;/h2&gt;
&lt;p&gt;I could just hard reset the droplet thru the Digital Ocean web interface but I’ll want to ssh to the node at some point so I may as well tackle this problem first. The Docker Cloud docs don’t go into much detail on &lt;a href=&quot;https://docs.docker.com/docker-cloud/infrastructure/ssh-into-a-node/&quot;&gt;this topic&lt;/a&gt;, but you apparently need to &lt;a href=&quot;https://hub.docker.com/r/dockercloud/authorizedkeys/&quot;&gt;create an application stack&lt;/a&gt; that will copy over your ssh key to all of your nodes.&lt;/p&gt;
&lt;p&gt;It should look like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;dockerfile&quot; role=&quot;region&quot; aria-label=&quot;Code, dockerfile&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;authorizedkeys:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  autodestroy: always&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  deployment_strategy: every_node&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  environment:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    - AUTHORIZED_KEYS=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDY....&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  image: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;dockercloud/authorizedkeys:latest&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  volumes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    - &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;/root:/user&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can get the value for &lt;strong&gt;AUTHORIZED_KEYS&lt;/strong&gt; by running the &lt;strong&gt;more&lt;/strong&gt; command on whichever public key you want to use as your key pair to connect to the containers. Make sure you include all of the gobbilty-gook except for the last part that includes your email or .local address.&lt;/p&gt;
&lt;p&gt;Interestingly, this granted me access to the node droplet, but after shutting it down, using the command &lt;strong&gt;shutdown now&lt;/strong&gt;, I can no longer connect. Digital Ocean reports that the droplet is still running so I’m not sure if the droplet never shutdown, or if Docker Cloud immediately restarted it after it went down. Attempting to restart the authorized keys stack file has no effect.&lt;/p&gt;
&lt;p&gt;So I’ll just go ahead and attempt a hard reset thru Digital Ocean to see what happens…&lt;/p&gt;
&lt;p&gt;…and it worked! I was able to resize the droplet to get an extra gig of RAM and 20 gigs of disk space so that’s pretty swell. After turning the droplet back on, I can also ssh into it as the root user so my public key is still there and functioning as it should.&lt;/p&gt;
&lt;h2 id=&quot;deploying-the-web-app&quot;&gt;Deploying the Web App&lt;/h2&gt;
&lt;p&gt;Now that we have our node configured properly, we need to add services to it. I’ll be using images from a private repository on Docker Hub. The repository is already setup, but is currently empty, so I’ll need to add my images to it first.&lt;/p&gt;
&lt;p&gt;First to login on the command line with my Docker Hub credentials:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; login&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --username=dockerhubusername&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I’m prompted for my password, after which I’m told I’ve successfully logged in. Now, I tag the image I want to push to the repository:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; tag&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cc0988358705&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dockerhubusername/repository-name:django&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And push the to the repository:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; push&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dockerhubusername/repository-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since I already have a &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file which I can been using for testing, I can copy that file and adapt for use as my &lt;strong&gt;docker-cloud.yml&lt;/strong&gt; file. The first change will be to point the &lt;strong&gt;image&lt;/strong&gt; keys in the file to the remote repository I pushed my images to. For my app, I need two from my private repository (django and PostGIS) and two from their own repositories (Redis and RabbitMQ).&lt;/p&gt;
&lt;p&gt;I can remove the reference to the volume containing my code since that will already exist in the image the service is pulling from. I also need to remove the &lt;strong&gt;build&lt;/strong&gt; and &lt;strong&gt;depends_on&lt;/strong&gt; config values since those aren’t supported.&lt;/p&gt;
&lt;p&gt;One thing I don’t like is that I have to hardcode my passwords into the Docker Cloud config file. Unfortunately, I couldn’t figure out a reliable workaround since the most obvious solutions were made much harder by the fact that unlike in Docker Compose config files, specifying an &lt;strong&gt;env_file&lt;/strong&gt; also is not supported by Docker Cloud.&lt;/p&gt;
&lt;p&gt;Other than that, the config file stays the same compared to the Compose config.&lt;/p&gt;
</content:encoded><category>docker</category><category>cloud</category></item><item><title>Product Review: FitBit Blaze</title><link>https://averyuslaner.com/blog/product-review-fitbit-blaze/</link><guid isPermaLink="true">https://averyuslaner.com/blog/product-review-fitbit-blaze/</guid><description>Smartwatches are worth it. The FitBit Blaze is not.</description><pubDate>Thu, 18 Jan 2018 19:03:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;are-smartwatches-even-worth-buying&quot;&gt;Are Smartwatches Even Worth Buying?&lt;/h2&gt;
&lt;p&gt;My experience with smartwatches began with the original kickstarter funded Pebble which I received in March of 2013. Since then, I have considered smartwatches to be a useful accessory that I prefer to have with me as much as possible.&lt;/p&gt;
&lt;p&gt;Here are a few reasons why:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Massively useful while driving&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While driving, I can monitor incoming texts, emails, and calls with a simple glance of my wrist. I essentially don’t even have to take my eyes of the road since my wrist it just below my windshield.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Greatly relieves the burden of two-factor authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I enable two-factor auth on every account that offers it. This can be annoying, and slow down normal web usage, but that cost is significantly reduced getting an auth code is as simple as glancing at my wrist.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Saves time and minimizes distractions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, things that would normally involve me pulling out my phone to investigate notifications are reduced to quick glances. I can quickly ignore spammy calls, emails, or other messages that would have otherwise required me to pull my phone out. And while I’m happy to concede that this time-savings it minimal, I’m definitely the sort of person who ends up distracted by something unimportant whenever I find myself thumbing listlessly through my phones apps. By minimizing the number of times I feel tempted to even pull the phone out, I’m sure I’m saving myself from droves of silly social media posts in the long run.&lt;/p&gt;
&lt;h2 id=&quot;fitbit-blaze-features&quot;&gt;FitBit Blaze Features&lt;/h2&gt;
&lt;p&gt;Those are the main benefits of smartwatches in general. So where does the FitBit Blaze fit in? Well it certainly has more features, but largely I don’t find them terribly appealing. I’ll go through them now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Heart Rate Monitor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This feature is cool. At first. Ultimately though, the data produced by this sensor isn’t useful to me 99% of the time. The scenario it is potentially useful is when I’m biking and I can use my heart rate as a metric to see how hard my body is working. But then again, can’t I just, you know, &lt;em&gt;feel&lt;/em&gt; how much effort I’m exerting?&lt;/p&gt;
&lt;p&gt;When selecting future smartwatch products to buy, I’ll consider a heart rate monitor to be an &lt;strong&gt;unnecessary feature&lt;/strong&gt; that I don’t want to pay for.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On-screen workouts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This feature is laughably bad which is why it is particularly tragic how much focus FitBit has placed on it. Looking at your watch for guidance on your workout is &lt;strong&gt;not&lt;/strong&gt; convenient. It’s really that simple. At least for me.&lt;/p&gt;
&lt;p&gt;Mayyybe the on-screen workouts would make more sense to you if you’re the sort of person whose workout clothes and/or activities prohibit you from bringing your phone with you. Otherwise, workout guidance is just better suited to being a phone application. Putting it on my watch just isn’t useful or convenient for me.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multi-sport tracking and connected GPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The one workout feature of the FitBit that I do like is for cycling. Much like while driving, it’s much easier for me to check my watch for notifications compared to my phone. And I also get the added benefit of being able to see things like my elapsed time, speed, distance, and pace. This is an area that a smartwatch can really shine and I wish the Blaze worked harder to make it great.&lt;/p&gt;
&lt;p&gt;The thing is, I actually greatly prefer my old Pebble watch when it came to tracking cycling workouts. It integrated with third-party apps, and best of all, it was painless to check during my rides.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Blaze trips over itself with its flashy color touchscreen and animations.&lt;/em&gt; Because of these, the screen can’t stay on all the time or the battery life would be abysmal. Instead, you’re forced to use things like gesture controls or to activate the screen using a button. The former is often awkward and error prone. I often find myself raising my wrist in a silly exaggerated movement just to try and wake my watch up so I can check the display. Clicking a button is the more reliable way to wake the screen up, but greatly diminishes the benefit of having a smartwatch in the first place.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Checking the display should be quick, easy, and intuitive. For the FitBit Blaze, this is not the case.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Guided breathing sessions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A useless gimmicky feature I don’t even care to go into detail about. Again, if you’re into this sort of thing, why not just use a phone application? There is no benefit to having this on your watch.&lt;/p&gt;
&lt;h2 id=&quot;conclusion--summary&quot;&gt;Conclusion &amp;amp; Summary&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;For its cost, the FitBit Blaze does not even come close to being worth the money.&lt;/strong&gt; In my opinion, the design team has gone off the rails by focusing on features that are much better suited to your smartphone and stand little to no benefit by being ported onto a watch interface. The greatest benefits of a smartwatch are sub-satisfactorily included on the Blaze and don’t seem to be the focus of software updates over the 14+ months I have owned and used the product.&lt;/p&gt;
&lt;p&gt;After FitBit acquired Pebble, I had hoped to see the FitBit Blaze absorb many of the features that made the Pebble great in my eyes. With the Pebble, I could create predefined text messages so I could send quick simple responses with the click of a button. I still can’t do that with my Blaze.&lt;/p&gt;
&lt;p&gt;With my Pebble, I could quickly and easily skip through songs playing on my phone, begin playing music through services like Pandora, and change volume. On my Blaze, the music menu is awkward to get to, often takes longer to connect than if I had just pulled out my phone, can’t control volume, and can’t launch other music services on my phone.&lt;/p&gt;
&lt;p&gt;On my Pebble, I could create my own applications and download other custom applications made by others in the developer community. For the Blaze, there is no app store so you can’t extend the functionality of your smartwatch. This is honestly the feature that I miss most about Pebble and probably the main feature I would look for in any future purchase.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;As an aside, I’d like to add that my first Blaze actually got stuck in a reboot loop after 11 months of gentle use. I can say the tech support for this problem was good and I received a replacement free of charge since it was still under warranty. That said, I was almost disappointed to receive a new one because I had been looking forward to buying a different product.&lt;/p&gt;
&lt;p&gt;I remain unimpressed with FitBit and their ability to produce quality smartwatches. In the future, I will be putting my money on a different company.&lt;/p&gt;
</content:encoded><category>smartwatch</category><category>hardware</category><category>review</category></item><item><title>Building a Server Monitor: Pyramid Setup</title><link>https://averyuslaner.com/blog/building-server-monitor-pyramid-setup/</link><guid isPermaLink="true">https://averyuslaner.com/blog/building-server-monitor-pyramid-setup/</guid><description>Because doing things manually is lame.</description><pubDate>Sat, 13 Jan 2018 21:53:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;building-a-server-monitor&quot;&gt;Building a Server Monitor&lt;/h2&gt;
&lt;p&gt;A few days ago I realized how nice it would be to have a web interface to manage my various servers. So today I’m going to start building one. I’ll also be using this as an excuse to try out the Python web framework &lt;a href=&quot;https://docs.pylonsproject.org&quot;&gt;Pyramid&lt;/a&gt; for the first time. As usual, this post will be less of a guide, and more of a record of my fumbling through the void that is the internet, trying to make things do what I want.&lt;/p&gt;
&lt;p&gt;First off, we’ll create the pyramid project. I’m using PyCharm as my IDE, it actually handles a lot of the initial project setup as far as my environment goes.&lt;/p&gt;
&lt;p&gt;According to the Pyramid docs, its helpful to start with a cookiecutter version of a project using a package of the same name, so I guess I’ll obey. I happen to be on my Windows box while starting this project, so I’ll be installing it using conda:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;conda&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; config&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; --add&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; channels&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; conda-forge&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;conda&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cookiecutter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we have a few options for which cookiecutter to use. The &lt;strong&gt;pyramid-cookiecutter-alchemy&lt;/strong&gt; project template sounds good to me since it uses persistent storage controlled by SQLAlchemy which I like a lot.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;cookiecutter&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; gh:Pylons/pyramid-cookiecutter-alchemy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command then asks what you want to call the project and repo. Annoyingly, I couldn’t call both things server_monitor because of directory conflicts with either my virtual environment, or my PyCharm project folder. Whatever it was, I just had to settle calling my repo serv_mon instead.&lt;/p&gt;
&lt;h2 id=&quot;oh&quot;&gt;Oh…&lt;/h2&gt;
&lt;p&gt;I now realize that I was essentially reimplementing the steps that PyCharm already took for me. So I just started a Pyramid project inside of a Pyramid project. Hurrumph.&lt;/p&gt;
&lt;p&gt;I’m just going to wipe the premade PyCharm files so I can follow along with the Pyramid docs. The silver lining is that now I can just repeat the steps above and actually name my project and repo server_monitor!&lt;/p&gt;
&lt;p&gt;Now I need to install the project into my virtual environment. For some reason I get some crazy nonsense when I try to install using PyCharm’s terminal:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Downloading&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; SQLAlchemy-1.2.0.tar.gz&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (5.5MB)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    33%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;██████████▊&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                     |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; 1.8MB&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 2.3MB/s&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; eta&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 0:00:02Exception:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Traceback&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (most &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;recent&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; call&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; last&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\basecommand.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 215,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    status&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; self.run&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;options,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; args&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\commands\install.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 335,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; run&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    wb.build(autobuilding&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;=True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\wheel.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 749,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    self.requirement_set.prepare_files(self.finder&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\req\req_set.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 380,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; prepare_files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    ignore_dependencies&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;self.ignore_dependencies&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\req\req_set.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 620,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; _prepare_file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    session&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;self.session,&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; hashes&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;hashes&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\download.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 821,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unpack_url&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    hashes&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;hashes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\download.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 659,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; unpack_http_url&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    hashes&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\download.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 882,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; _download_http_url&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    _download_url(resp,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; link,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; content_file,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; hashes&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\download.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 603,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; _download_url&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    hashes.check_against_chunks(downloaded_chunks&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\utils\hashes.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 46,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; check_against_chunks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; chunk &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chunks:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\download.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 571,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; written_chunks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; chunk &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chunks:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\utils\ui.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 141,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; iter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    self.next(n&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\_vendor\progress\__init__.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 73,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; next&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt;    self.update&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\_vendor\progress\bar.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 79,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    self.writeln(line&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\_vendor\progress\helpers.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 68,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; writeln&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;line,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; end=&apos;&apos;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; file=self.file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\_vendor\colorama\ansitowin32.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 141,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; write&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    self.write_and_convert(text&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\_vendor\colorama\ansitowin32.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 169,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; write_and_convert&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    self.write_plain_text(text,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cursor,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; len&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;C:\Users\Smith\Anaconda2\envs\server_monitor\lib\site-packages\pip\_vendor\colorama\ansitowin32.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 175,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; write_plain_text&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt;    self.wrapped.flush&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;OSError:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; raw&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; write&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;() &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;returned&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; invalid&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; length&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 180&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (should &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;have&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; been&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; between&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; and&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 90&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;    33%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;██████████▊&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;                     |&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; 1.8MB&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 2.3MB/s&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; eta&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 0:00:02&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I assume it has something to do with the reference to cursor, but I’m not actually going to bother trying to figure out for sure because the install works just fine in my normal command prompt:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; project_dir&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -e&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we install the testing dependencies because we’re good developers who test things:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -e&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;.[testing]&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now we can run our tests using:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pytest&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -q&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Which runs the two sample tests that were created by our cookiecutter template.&lt;/p&gt;
&lt;p&gt;We can also start our project using pserve and our development configuration:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;pserve&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; development.ini&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This launches the development web server. But when I navigate over to it in my browser, I’m told I need to do more stuff first:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot; role=&quot;region&quot; aria-label=&quot;Code, ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;Pyramid is having a problem using your SQL database.  The problem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;might be caused by one of the following things:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;1.  You may need to run the &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;initialize_server_monitor_db&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; script&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    to initialize your database tables.  Check your virtual&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    environment&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;s &quot;bin&quot; directory for this script and try to run it.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;2.  Your database server may not be running.  Check that the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;    database server referred to by the &quot;sqlalchemy.url&quot; setting in&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;    your &quot;development.ini&quot; file is running.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;After you fix the problem, please restart the Pyramid application to&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;try it again.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On Windows, this is a little annoying because the database initialization executable is in the directory of my virtual environment but I need to pass it the &lt;strong&gt;development.ini&lt;/strong&gt; file as an argument:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;C:\Users\Smith\Anaconda2\envs\server_monitor\Scripts\initialize_server_monitor_db.exe&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; development.ini&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cool, now we can actually start our server.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Image unavailable: Pyramid Project Initial Landing Page]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Next, I’ll actually write some code myself.&lt;/p&gt;
</content:encoded><category>server</category><category>python</category><category>pyramid</category><category>automation</category><category>monitor</category></item><item><title>Protecting Sensitive Information in Docker Compose</title><link>https://averyuslaner.com/blog/protecting-sensitive-information-docker-compose/</link><guid isPermaLink="true">https://averyuslaner.com/blog/protecting-sensitive-information-docker-compose/</guid><description>Protecting sensitive information when using docker-compose files in a public repository.</description><pubDate>Wed, 03 Jan 2018 18:06:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;hide-yo-passwords&quot;&gt;Hide Yo Passwords!&lt;/h2&gt;
&lt;p&gt;If you have multiple containers in a swarm service, this won’t be the path for you. If you do have a docker swarm service, check out &lt;a href=&quot;https://docs.docker.com/engine/swarm/secrets/&quot;&gt;docker secrets&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I however, don’t have a swarm, and I don’t see any benefit in converting my setup into a swarm of size one, as the docker secret docs offer as a suggestion. So instead, I’ll be using good ol’ environment variables. The problem however, is that I want to share as much of my code publicly as possible but without exposing any sensitive information. To this end, I’ll be using the handy env_file option in my docker-compose file.&lt;/p&gt;
&lt;p&gt;You can specify the file location like so:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;dockerfile&quot; role=&quot;region&quot; aria-label=&quot;Code, dockerfile&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;version: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;3&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;services:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;  # PostGIS database&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  db:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    env_file: /opt/db_secrets.env&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    image: my_postgis&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;  # Redis&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  redis:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    image: redis:3.2.11&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    hostname: redis&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;  # RabbitMQ&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  rabbit:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    hostname: rabbit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    image: rabbitmq:3.7.2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    env_file: /opt/rabbit_secrets.env&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;  # Django web server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;  web:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    build: .&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    env_file: /opt/django_secrets.env&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    command: python manage.py runserver 0.0.0.0:8000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    volumes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;      - .:/code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    ports:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;      - &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;8000:8000&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    depends_on:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;      - db&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I’ve opted to store my environment variable files in the /opt directory, far from my source control directory so I don’t accidently end up pushing anything I don’t intend to make public.&lt;/p&gt;
&lt;p&gt;Make sure to define the environment variables within those files using the following notation, with one credential per line:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;password&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;other_username&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;another_password&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, the only thing left to do is modify the file permissions for the sake of the docker container:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chown&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; root:docker&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; rabbit_secrets.env&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chmod&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 740&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /opt/rabbit_secrets.env&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now you’re ready to roll.&lt;/p&gt;
</content:encoded><category>docker</category><category>docker-compose</category><category>sensitive information</category></item><item><title>Import SQL file into Docker Compose Container</title><link>https://averyuslaner.com/blog/import-sql-file-docker-compose-container/</link><guid isPermaLink="true">https://averyuslaner.com/blog/import-sql-file-docker-compose-container/</guid><description>How to import a .sql dump file into a docker container created by docker-compose.</description><pubDate>Fri, 22 Dec 2017 23:30:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;get-in-there&quot;&gt;Get in there!&lt;/h2&gt;
&lt;p&gt;It took me a while to figure out how to properly import a .sql dump file into a docker container I had started with docker-compose. The recommended way was to import the data on creation of the container by adding the dump file to the /docker-entrypoint-initdb.d directory. I wanted to avoid this if possible because the dump file is a backup of a production database but the docker-compose file is shared in a public repository. I just didn’t like the idea of referencing the database file in a public repository; I’ve made the mistake of pushing sensitive info public repositories before and it is such a pain to clean up those mistakes afterwards. It seemed safer and more logical to do the import after the container had been initialized, especially since the data is purely for testing, and isn’t essential to the function of the application.&lt;/p&gt;
&lt;p&gt;Unfortunately, this wasn’t as easy as it seemed like it should be.&lt;/p&gt;
&lt;p&gt;Initially I tried something like this:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker-compose&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; exec&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -u&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgres&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service_name&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; psql&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_name&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /path/to/dump/backup_file.sql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But I would run into the following error:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;gTraceback&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (most &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;recent&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; call&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; last&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;bin/docker-compose&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 6,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;modul&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;compose/cli/main.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 71,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;compose/cli/main.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 124,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; perform_command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;compose/cli/main.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 467,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; exec_command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;site-packages/dockerpty/pty.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 338,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; start&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;  File&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;site-packages/dockerpty/io.py&quot;,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; line&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; 32,&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; set_blocking&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ValueError:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; descriptor&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cannot&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; be&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; negative&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; integer&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (-1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;Failed&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; execute&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; script&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This error is &lt;a href=&quot;https://github.com/docker/compose/issues/3352&quot;&gt;well discussed&lt;/a&gt;, and provides several solutions depending on what you’re trying to do. Several users seem only to need to pass the -T parameter to their docker-compose exec command. For me, the command seems to hang. By checking the logs, I can see that it does actually try to execute, but fails with many errors complaining how relations don’t exist and whatnot.&lt;/p&gt;
&lt;p&gt;The key to salvation is somewhat buried the comments of the issue discussion. It relies on docker exec, rather than docker-compose exec and keeps the stdin open with the -i flag. Or something like that. The important thing is that it worked.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; exec&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -u&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; postgres&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -i&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; $(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;docker-compose&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ps&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -q&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; service_name&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;psql&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; db_name&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /path/to/dump/backup_file.sql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content:encoded><category>docker</category><category>postgresql</category><category>docker-compose</category></item><item><title>Machine Learning Practice: Part II</title><link>https://averyuslaner.com/blog/machine-learning-practice-part-ii/</link><guid isPermaLink="true">https://averyuslaner.com/blog/machine-learning-practice-part-ii/</guid><description>Let&apos;s check the news.</description><pubDate>Mon, 27 Nov 2017 01:57:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;building-a-dataset&quot;&gt;Building a Dataset&lt;/h2&gt;
&lt;p&gt;We were introduced to a few basic concepts in part one of this series, but going forward it will probably be easier to start experimenting with data that is actually relevant to the problem that we want to solve. As refresher, that problem is scan news articles and determine if they are relevant to natural resource conservation.&lt;/p&gt;
&lt;p&gt;To start simple, we’ll grab two articles; one about some sort of ecological conservation topic, and another that has no relation to the topic. To do this, we’ll use the newpaper library (more specifically the newpaper3k library since I’m using Python 3):&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; newspaper &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Create the article objects&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;http://www.sltrib.com/news/environment/2017/11/24/restoring-utahs-damaged-landscapes-ephraim-center-provides-vital-seed-stocks-to-heal-public-lands/&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;http://www.sltrib.com/news/nation-world/2017/11/26/guns-were-black-friday-must-haves-going-by-the-fbis-record-203086-background-check-requests/&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that we have chosen our articles, we need to download and parse them before we do much with them:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Download and parse the articles&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_article.download()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_article.download()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_article.parse()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_article.parse()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point we can use some tools built into the newspaper to easily extract information that might be important to us. We’ll start by just taking a look at the summary data:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Use newspapers built-in natural language processing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_article.nlp()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_article.nlp()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Now we have should have access to some interesting info&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Conservation article summary:&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, conservation_article.summary)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;Regular article summary:&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, regular_article.summary)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While the summaries themselves aren’t perfectly sensible from a human-readable standpoint, they do manage to pull out some key ideas that clearly illustrate the differences between the two articles. In the summary of the conservation article we can also see some words and phrases that will likely be important for classifying conservation articles (e.g. ‘rehabilitation’, ‘reseeding’, ‘habitat restoration’).&lt;/p&gt;
&lt;p&gt;At this point it makes sense to start gathering some articles and manually labelling them so we can get a better sense of which words are more important for training a classifier. To do this, we’ll make some small changes and additions to the way we gather articles. For one, we’ll create two list to divide the articles that we gather:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; newspaper &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_articles &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_articles &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Conservation articles&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;http://www.sltrib.com/news/environment/2017/11/24/restoring-utahs-damaged-landscapes-ephraim-center-provides-vital-seed-stocks-to-heal-public-lands/&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_articles.append(conservation_article)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;con_art1 &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;https://www.nrcs.usda.gov/wps/portal/nrcs/detail/national/newsroom/features/?cid=nrcseprd1367450&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;conservation_articles.append(con_art1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Regular articles&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;http://www.sltrib.com/news/nation-world/2017/11/26/guns-were-black-friday-must-haves-going-by-the-fbis-record-203086-background-check-requests/&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_articles.append(regular_article)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;reg_art1 &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; Article(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;http://thehill.com/homenews/administration/362121-democrats-pull-out-of-white-house-meeting-with-trump&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;regular_articles.append(reg_art1)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will make it easy to label the articles by type in the form of tuples:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;labeled_articles &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;conservation&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, article) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; conservation_articles]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;labeled_articles &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;regular&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, article) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; regular_articles]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(labeled_articles)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now we can neatly organize the download and parsing of all of our articles at once:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; label, article &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; labeled_articles:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    article.download()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    article.parse()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We’ll want to keep adding to this list of articles, being careful to keep the two lists roughly the same length. While it would be easy to populate our list of regular articles by just grabbing whatever we can find from a random news source, we would end up with a highly imbalanced dataset. Training a classifier on such imbalanced data typically results in poor predictions since the classifier can just predict the majority class to achieve a high accuracy. We want to use a balanced number of labels so the classifier can focus in on the things that are actually informative to the problem; the words in the article.&lt;/p&gt;
</content:encoded><category>text processing</category><category>python</category></item><item><title>Machine Learning Practice: Part I</title><link>https://averyuslaner.com/blog/machine-learning-practice-part-i/</link><guid isPermaLink="true">https://averyuslaner.com/blog/machine-learning-practice-part-i/</guid><description>Bring on the learning. Machine style.</description><pubDate>Sat, 25 Nov 2017 23:17:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;I’ll mostly be following along with the online book &lt;em&gt;&lt;a href=&quot;http://www.nltk.org/book/&quot;&gt;Natural Language Processing with Python&lt;/a&gt;&lt;/em&gt; by Steven Bird, Ewan Klein, and Edward Loper while referring to &lt;em&gt;&lt;a href=&quot;http://amzn.to/2A8ClHC&quot;&gt;Machine Learning in Python&lt;/a&gt;&lt;/em&gt; by Michael Bowles, but I’ll be aiming to apply the lessons to problems that interest me personally. You can find the code associated with this blog series on &lt;a href=&quot;https://github.com/TechnoConserve/ml-practice&quot;&gt;my GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The ultimate goal of this machine learning practice is to produce a binary classifier for determining if a news article is related to natural resource conservation. I hope to use this classifier to learn more about current trends in the field of conservation that may also reveal interesting trends in how grant money is allocated across different study areas.&lt;/p&gt;
&lt;h2 id=&quot;examining-the-problem&quot;&gt;Examining the Problem&lt;/h2&gt;
&lt;p&gt;Ultimately I’ll be using text processing to determine the subject of the article. One of the challenges involved in text processing is dealing with the large number of attributes. Essentially, every word in an article could be considered it’s own attribute, and you could assign an even greater number of attributes to a machine learning problem if you also decide to include combinations of words and phrases.&lt;/p&gt;
&lt;p&gt;Generally speaking, when a machine learning problem has many attributes, you’ll need to feed the algorithm more training data in order to build a reliable model. This is a problem in its own right, since I don’t yet have a training dataset. Essentially, I’ll need to manually find articles I consider to be related to natural resource conservation and label them as such. The words used in these articles can then be extracted so the algorithm can begin to associate them the category of conservation.&lt;/p&gt;
&lt;p&gt;Some algorithms are better than others depending on the number of attributes and the size of the dataset you can supply it. Since we already know there will be lots of attributes and I likely won’t have the time to generate a huge list of articles manually labeled as conservation-related, there’s a good chance a penalized linear regression algorithm will be our best choice.&lt;/p&gt;
&lt;h2 id=&quot;setting-up&quot;&gt;Setting Up&lt;/h2&gt;
&lt;p&gt;I’ll be using python 3.5.3. For a full list of other requirements, check out the requirements.txt file on the &lt;a href=&quot;https://github.com/TechnoConserve/ml-practice&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First though, I’ll be using the NLTK library in a Jupyter notebook:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;pip install nltk&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;pip install jupyter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;using-an-example-dataset&quot;&gt;Using an Example Dataset&lt;/h2&gt;
&lt;p&gt;Before trying to create my own dataset of classified news articles, it probably makes more sense to use an existing example dataset so we can get a better idea of how to organize our own.&lt;/p&gt;
&lt;p&gt;To get some example data, you can use the examples from the nltk book. In your interpreter, simple import nltk and use the download_gui() function. I’ll only be downloading the “book” collection for now.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[Image unavailable: NLTK Book Examples Download GUI]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;These examples will give us a lot to work with but “text7” is probably the most relevant to our ultimate goal since it is an extract of the Wall Street Journal.&lt;/p&gt;
&lt;h3 id=&quot;exploring-the-data&quot;&gt;Exploring the Data&lt;/h3&gt;
&lt;p&gt;We can first get an idea of how much information we have by using the len() function on our text data:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; nltk.book &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; text7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(text7))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We find out that there are 100676 words and punctuation marks contained in the text7 object. Each of these items is known as a token, the majority of which won’t be very useful in determining the genre of the content. We can use some of the features of the nltk library to begin paring down the data into just the useful stuff.&lt;/p&gt;
&lt;p&gt;Logically, if we want to extract to subject of a body of text, we can probably eliminate things like punctuation and duplicate words. Such a process will also greatly reduce the amount of data we ultimately have to save and sort through when we create our own dataset. That said, the frequency of word occurrence could provide valuable information about the nature of the text. We can compromise by using something like this to try to extract the more meaningful words:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; nltk &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; FreqDist&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;fdist &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; FreqDist(text7)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Create a list of hopefully important words&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;focused_words &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; sorted&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(w &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; w &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; set&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(text7) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; len&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(w) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 5&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; and&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; fdist[w] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 7&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(focused_words)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we create a sorted list of words with more than 5 characters in length and occur in the text more than 7 times. Browsing through the list, we can see that we’ve successfully eliminated the majority of “filler” words in the English language and have been left mostly with words that are more meaningful.&lt;/p&gt;
</content:encoded><category>python</category><category>natural language processing</category><category>sklearn</category><category>machine learning</category><category>binary classification</category><category>penalized linear regression</category></item><item><title>Timelapse video from static images</title><link>https://averyuslaner.com/blog/timelapse-video-static-images/</link><guid isPermaLink="true">https://averyuslaner.com/blog/timelapse-video-static-images/</guid><description>How to make a video from a bunch of images.</description><pubDate>Thu, 02 Nov 2017 21:36:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;getting-things-in-order&quot;&gt;Getting things in order&lt;/h2&gt;
&lt;p&gt;For one of my nonprofit’s projects, I used a DSLR camera on a tripod to capture the transformation of a common garden green bean seed from germination to small seedling. If it interests you, you can find the code on GitHub &lt;a href=&quot;https://github.com/cts-admin/timelapse-dslr&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, an earlier iteration of the code I wrote to control the camera did not account for the fact that the script may need to restart at one point or another during the ~3 week period I was recording the timelapse. This created some issues with filenames, specifically images being overwritten by newer photographs or given duplicate names.&lt;/p&gt;
&lt;p&gt;This is problematic because the photos need to be sorted in order before they can stitched together into one cohesive video. I had hoped to use a file naming convention that would make this simple, but for the above reasons, I’ll need to resort to parsing the EXIF data to determine the correct chronological order of the photographs.&lt;/p&gt;
&lt;h3 id=&quot;sorting-files-using-exif-metadata&quot;&gt;Sorting files using EXIF metadata&lt;/h3&gt;
&lt;p&gt;Luckily writing a script to rename the files based on the original creation datetime of the image isn’t too difficult. First we establish where the images are located and where we want them to be saved. For me it was:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# The directory where our images are located&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PHOTO_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;/home/&amp;lt;user&amp;gt;/Documents/Work/CTS/timelapse/Images/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# The directory we want to save our renamed images&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PROCESSED_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;processed/&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We’ll to import a few packages for the processing:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; datetime &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; datetime&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PIL&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.Image&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PIL&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.ExifTags&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we need to iterate through the images in specified in the directory we designated above. We’ll also be sure to exclude any other directories that may be located there:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.listdir(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PHOTO_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # Make sure to skip directories-- we are only interested in image files&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    path &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.path.join(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PHOTO_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; os.path.isdir(path):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Processing &apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From here, it’s just a matter of reading the ‘DateTimeOriginal’ key in the EXIF data and using it as the new filename:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;img &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PIL&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.Image.open(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PHOTO_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; file&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    exif_date &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;        PIL&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.ExifTags.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TAGS&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[k]: v &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; k, v &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; img._getexif().items() &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; k &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PIL&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.ExifTags.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TAGS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        and&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PIL&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.ExifTags.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;TAGS&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;[k] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;DateTimeOriginal&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    image_time &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; datetime.strptime(exif_date[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;DateTimeOriginal&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;], &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;%Y:%m:&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; %H:%M:%S&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;    # Name the new file using the timestamp from the EXIF data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    new_filename &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; image_time.strftime(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;%m-&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;-%Y_%H-%M&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;.jpeg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    img.save(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PHOTO_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PROCESSED_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; new_filename, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;JPEG&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;    print&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Saveing as &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-f47067&quot;&gt;{}&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;.&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.format(new_filename, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;PHOTO_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; PROCESSED_DIRECTORY&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we now have a directory filled with our image files named by the time they were shot which makes them easy to sort in the correct order. This has the added benefit of eliminating any duplicate images that may have existed in the original directory.&lt;/p&gt;
&lt;h2 id=&quot;converting-images-to-video&quot;&gt;Converting images to video&lt;/h2&gt;
&lt;p&gt;For the video conversion, I followed this &lt;a href=&quot;https://www.raspberrypi.org/documentation/usage/camera/raspicam/timelapse.md&quot;&gt;handy guide&lt;/a&gt; from the &lt;a href=&quot;https://www.raspberrypi.org/about/&quot;&gt;Raspberry Pi Foundation&lt;/a&gt;. The default settings included in this guide work well for YouTube but if you’d like to tweak them for an alternative YouTube format, you may want to refer to their &lt;a href=&quot;https://support.google.com/youtube/answer/1722171?hl=en&quot;&gt;style guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From the directory with your processed images, making the video involves just two commands assuming you have the package mencoder already installed:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;.jpg&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; stills.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mencoder&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -nosound&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -ovc&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; lavc&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -lavcopts&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; vcodec=mpeg4:aspect=16/9:vbitrate=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;8000000&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -vf&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; scale=1920:1080&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -o&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; timelapse.avi&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -mf&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; type=jpeg:fps=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mf://@stills.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s it! If you want to check out the code in it’s entirety or propose any improvements of your own, you can check out the code on &lt;a href=&quot;https://github.com/cts-admin/timelapse-dslr&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</content:encoded><category>timelapse</category><category>python</category><category>image processing</category></item><item><title>Django + Wagtail Custom Users</title><link>https://averyuslaner.com/blog/django-wagtail-custom-users/</link><guid isPermaLink="true">https://averyuslaner.com/blog/django-wagtail-custom-users/</guid><description>Because I&apos;m willing to give myself a major headache for small gains.</description><pubDate>Wed, 13 Sep 2017 06:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;As I said in my last post, I’m aiming to add the ability for users to log in to the website using &lt;a href=&quot;https://github.com/ubernostrum/django-registration/tree/2.2&quot;&gt;django-registration&lt;/a&gt;. It should be pretty simple, especially considering I got it working just fine on my &lt;a href=&quot;https://conservationtechnologysolutions.com&quot;&gt;nonprofit’s website&lt;/a&gt;. Unfortunately, this website is essentially all about creating silly problems for myself so I can learn by fixing them. And thus, I have run into a problem that I did not encounter on my other domain:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot; role=&quot;region&quot; aria-label=&quot;Code&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;AttributeError at /accounts/register/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Manager isn&apos;t available; &apos;auth.User&apos; has been swapped for &apos;custom_user.CustomUser&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Argh!&lt;/p&gt;
&lt;p&gt;I had created a custom wagtail user model pretty much just because Wagtail showed me how to in their documentation. And now Django doesn’t know how to create users like normal.&lt;/p&gt;
&lt;p&gt;There are of course a number of ways to solve this. I will be using the one I can figure out first.&lt;/p&gt;
&lt;h2 id=&quot;the-struggle&quot;&gt;The Struggle&lt;/h2&gt;
&lt;p&gt;Google has led me to a &lt;a href=&quot;https://stackoverflow.com/a/17874111&quot;&gt;SO answer&lt;/a&gt; that makes it seem like an easy fix. We shall see.&lt;/p&gt;
&lt;p&gt;Essentially all I have to do is instruct Django to use my model instead of the one provided in django.contrib.auth:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; django.contrib.auth &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; get_user_model&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;User &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; get_user_model()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now I just have to figure out exactly where to place that code. And… after some more googling I found that the Django docs themselves describe how to &lt;a href=&quot;https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#custom-users-and-the-built-in-auth-forms&quot;&gt;address this issue&lt;/a&gt;. And this is why I love Django.&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; django.contrib.auth.forms &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; UserCreationForm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; myapp.models &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; CustomUser&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; CustomUserCreationForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;UserCreationForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    class&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; Meta&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;UserCreationForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;Meta&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        model &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; CustomUser&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        fields &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; UserCreationForm.Meta.fields &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;custom_field&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But since we’re using django-registration, we should defer to &lt;a href=&quot;http://django-registration.readthedocs.io/en/2.2/custom-user.html&quot;&gt;their docs&lt;/a&gt; first. The process looks similar to the official docs:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; registration.forms &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; RegistrationForm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; mycustomuserapp.models &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; MyCustomUser&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; MyCustomUserForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;RegistrationForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    class&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; Meta&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        model &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; MyCustomUser&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After making the appropriate changes in my custom user app’s forms.py file, I get the following error:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;fields&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;   attribute &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;or&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; the &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;exclude&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; attribute &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; prohibited&lt;/span&gt;&lt;span class=&quot;sl-b31d28 slfs-italic sd-ff938a sdfs-italic&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It instructs me to edit my custom user creation form. For now I add the most basic implementation by specifying the fields from the parent class:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;fields &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; RegistrationForm.Meta.fields&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now when attempting to create a new user using the registration form I get a timeout error with the following (&lt;em&gt;truncated&lt;/em&gt;) traceback:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot; role=&quot;region&quot; aria-label=&quot;Code&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Traceback:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;File &quot;/home/&amp;lt;user&amp;gt;/venv/averyuslaner.com/lib/python3.5/site-packages/registration/backends/hmac/views.py&quot; in create_inactive_user&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  55.         self.send_activation_email(new_user)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;File &quot;/home/&amp;lt;user&amp;gt;/venv/averyuslaner.com/lib/python3.5/site-packages/registration/backends/hmac/views.py&quot; in send_activation_email&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  98.         user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;File &quot;/home/&amp;lt;user&amp;gt;/venv/averyuslaner.com/lib/python3.5/site-packages/django/contrib/auth/models.py&quot; in email_user&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  366.         send_mail(subject, message, from_email, [self.email], **kwargs)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;File &quot;/home/&amp;lt;user&amp;gt;/venv/averyuslaner.com/lib/python3.5/site-packages/django/core/mail/__init__.py&quot; in send_mail&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  62.     return mail.send()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;File &quot;/home/&amp;lt;user&amp;gt;/venv/averyuslaner.com/lib/python3.5/site-packages/django/core/mail/message.py&quot; in send&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  348.         return self.get_connection(fail_silently).send_messages([self])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Exception Type: TimeoutError at /accounts/register/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Exception Value: [Errno 110] Connection timed out&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now it’s just a matter of configuring the connection back to the mail server which also happens to be the same server running this website. I just needed to remove the Digital Ocean firewall since I already had UFW configured to handle all the appropriate firewall rules.&lt;/p&gt;
&lt;p&gt;Since the error timed out while trying to send the activation email, the user was actually created and saved to the database. I’m just going to delete that user and try again from the beginning.&lt;/p&gt;
&lt;p&gt;I’m also going to start matching up the django-registration form to match my custom user model fields. So I need to add some name fields which is as simple as editing the fields attribute in my CustomUserForm:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;fields &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;first_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;last_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;] &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; RegistrationForm.Meta.fields&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sweet, and now we successfully get an activation email sent to the email address supplied when submitting the registration form.&lt;/p&gt;
&lt;p&gt;But we also get a new error when trying to access the activation link sent to our new user:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot; role=&quot;region&quot; aria-label=&quot;Code&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;django.urls.exceptions.NoReverseMatch: Reverse for &apos;login&apos; not found. &apos;login&apos; is not a valid view function or pattern name.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;[14/Sep/2017 12:04:24] &quot;GET /accounts/activate/complete/ HTTP/1.1&quot; 500 158304&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So I just need to throw in the default urls from django.contrib.auth:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;url(&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, include(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;django.contrib.auth.urls&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point everything seems to work properly but when we login, we get a 404 error because the default redirect page for a django login is /accounts/profile which doesn’t point anywhere yet. Were going to specify where that redirection should occur and create a template for it:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;# Django auth settings added to base settings file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;LOGIN_REDIRECT_URL&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;edit_profile&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The template is pretty basic:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;jinja&quot; role=&quot;region&quot; aria-label=&quot;Code, jinja&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;base.html&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; load&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; home_extras &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; block&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; title &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;Edit your profile&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endblock&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; block&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; heading_text &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;Edit Your Profile&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endblock&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; block&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; content &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            Use the form below to edit your profile.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            Use whatever name you&apos;d like to be identified with while on this website. If&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            you leave it blank, we&apos;ll identify you as &amp;lt;b&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;{{ &lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; }}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&amp;lt;/b&amp;gt;, your username.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;form method=&quot;POST&quot; action=&quot;.&quot; class=&quot;form-horizontal&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;            {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; csrf_token&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;            {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; error &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; form.non_field_errors &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;div class=&quot;form-group has-error text-danger&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                    {{ &lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;            {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endfor&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;            {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; for&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; field &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; form &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;div class=&quot;form-group has-error text-danger&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                    {{ &lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;div class=&quot;form-group&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                    {{ &lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;label_tag&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;                    {{ &lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;add_css&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;form-control&quot;&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt; }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;            {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endfor&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            &amp;lt;button class=&quot;btn btn-primary form-group&quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endblock&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we still need to create the view to serve it up:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt;@login_required&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; edit_profile&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(request):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    user &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; CustomUser.objects.get(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;request.user.username)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    form &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; ProfileForm(request.&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; or&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; None&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;user)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; form.is_valid():&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        form.save()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; redirect(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;user_profile&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, request.user.username)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; render(request, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&quot;accounts/edit_profile.html&quot;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, {&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;form&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: form})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And create the form referenced in the above view:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot; role=&quot;region&quot; aria-label=&quot;Code, python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; ProfileForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;forms&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;ModelForm&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    first_name &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; forms.CharField(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;        required&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;        widget&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;forms.TextInput(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;placeholder&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;First Name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    last_name &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; forms.CharField(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;        required&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;        widget&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;forms.TextInput(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;placeholder&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Last Name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    email &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; forms.EmailField(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;        required&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;        widget&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;forms.TextInput(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;placeholder&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;Email&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    class&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt; Meta&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        model &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; CustomUser&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        fields &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; [&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;first_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;last_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;email&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    def&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; __init__&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(self, &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;args, &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;kwargs):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;        # Instance is a CustomUser object&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        instance &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; kwargs.get(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;instance&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; instance:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            kwargs.setdefault(&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;initial&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;, {}).update({&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;first_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: instance.first_name,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;                                                     &apos;last_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: instance.last_name,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;                                                     &apos;email&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;: instance.email})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;        super&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;args, &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;kwargs)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;    def&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; save&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;(self, commit&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6a737d sd-768390&quot;&gt;        # Instance is a CustomUser object&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        instance &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; super&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;().save(&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;commit)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        instance.first_name &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.cleaned_data[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;first_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        instance.last_name &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.cleaned_data[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;last_name&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        instance.email &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;.cleaned_data[&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;email&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; commit:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            instance.save()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; instance&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Upon saving the edit form, our view redirects to the normal profile view which we also need to create under templates/accounts/user_profile.html:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;jinja&quot; role=&quot;region&quot; aria-label=&quot;Code, jinja&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; extends&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &quot;base.html&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; load&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; humanize &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; block&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; title &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; firstof&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; user_obj.profile.name user_obj.username &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endblock&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; block&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; heading_text &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;User Profile&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endblock&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; block&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; content &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;h3&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;            {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; firstof&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; user_obj.profile.name user_obj.username &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/h3&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            Hey internet person.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            You can edit your profile &amp;lt;a href=&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; url&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;edit_profile&apos;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&quot;&amp;gt;here&amp;lt;/a&amp;gt;. If you want. No pressure.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endblock&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; content &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cool, now we have everything working properly so we just need to make some improvements to the nav page. We need to hook up the login button to the actual login function:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;jinja&quot; role=&quot;region&quot; aria-label=&quot;Code, jinja&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; user.is_authenticated &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;ul class=&quot;nav navbar-nav navbar-right&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;li class=&quot;dropdown&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            &amp;lt;a href=&quot;#&quot; class=&quot;dropdown-toggle&quot; data-toggle=&quot;dropdown&quot;&amp;gt;My Account &amp;lt;b class=&quot;caret&quot;&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;ul class=&quot;dropdown-menu&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                    &amp;lt;li&amp;gt;&amp;lt;a href=&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; url&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;user_profile&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; user &lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&quot;&amp;gt;Profile&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                    &amp;lt;li&amp;gt;&amp;lt;a href=&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; url&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;logout&apos;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&quot;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;a class=&quot;navbar-text navbar-right&quot; href=&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; url&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;registration_register&apos;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&quot;&amp;gt;Register&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;form method=&quot;POST&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                    action=&quot;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; url&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;login&apos;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;?next=&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; if&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; request.path &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;/logout/&apos;&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;sl-e36209 sd-f69d50&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endif&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                    class=&quot;navbar-form navbar-right&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;        {%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; csrf_token&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;div class=&quot;form-group&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            &amp;lt;input type=&quot;text&quot; name=&quot;username&quot; placeholder=&quot;Username&quot; id=&quot;id_username&quot; class=&quot;form-control&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;div class=&quot;form-group&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;            &amp;lt;input type=&quot;password&quot; name=&quot;password&quot; placeholder=&quot;Password&quot; id=&quot;id_password&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;                class=&quot;form-control&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;        &amp;lt;button type=&quot;submit&quot; class=&quot;btn btn-success&quot;&amp;gt;Sign in&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;    &amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; endif&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-6cb6ff&quot;&gt; %}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And voilà! We now have a working registration process!&lt;/p&gt;
</content:encoded><category>user</category><category>django</category><category>authentication</category><category>custom</category><category>wagtail</category></item><item><title>Website updates</title><link>https://averyuslaner.com/blog/website-updates/</link><guid isPermaLink="true">https://averyuslaner.com/blog/website-updates/</guid><description>Because you can&apos;t have progress without a whole bunch of annoying things trying to stop you.</description><pubDate>Wed, 13 Sep 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;and-were-back&quot;&gt;And we’re back!&lt;/h2&gt;
&lt;p&gt;I’m finally coming back to my personal website so I can make it less bad. And more good.&lt;/p&gt;
&lt;p&gt;I’ve spent the better part of two days updating all of the packages on the VPS as well as those in the python development environment. It’s kind of just fun to update things. It makes me feel better.&lt;/p&gt;
&lt;h2 id=&quot;with-style&quot;&gt;With style&lt;/h2&gt;
&lt;p&gt;I refactored a bunch of the project code to better handle things like file permissions and environment variables. You can check it out on the &lt;a href=&quot;https://github.com/TechnoConserve/personal_website&quot;&gt;GitHub page&lt;/a&gt; if you’re curious. And of course in the process of doing so I briefly exposed ALL of this project’s sensitive information to the entire internet.&lt;/p&gt;
&lt;p&gt;For about 2 minutes.&lt;/p&gt;
&lt;p&gt;I actually checked the logs to see if anyone had managed to discover the directory traversal vulnerability I had unwittingly creating while learning the difference between “alias”, “root”, and “autoindex” in my nginx config files. Don’t worry, no one had. Looks like my website won’t be taking the place of Equifax in the headlines just yet.&lt;/p&gt;
&lt;p&gt;Anyway, as you might have noticed, I also made some stylistic changes to the front page already. Functionally, they are sterile. The little login form in the top nav bar doesn’t actually work at the time of writing, but I pushed it anyway because YOLO.&lt;/p&gt;
&lt;h2 id=&quot;registration&quot;&gt;Registration&lt;/h2&gt;
&lt;p&gt;I’ll be working on adding registration functionality to the website next. Yes that’s right, I’m announcing that I plan to start collecting sensitive user information in the same blog post in which I casually admitted to exposing the credentials of the database to the internet. Don’t worry though, I have it ALL under control!&lt;/p&gt;
</content:encoded><category>frustration</category><category>errors</category><category>config</category></item><item><title>MySQL: From remote to local</title><link>https://averyuslaner.com/blog/mysql-remote-local/</link><guid isPermaLink="true">https://averyuslaner.com/blog/mysql-remote-local/</guid><description>Securely backing up a remote mysql database to a local machine.</description><pubDate>Sun, 15 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ok so now that we have our &lt;a href=&quot;https://averyuslaner.com/blog/encrypting-backups/&quot;&gt;secure backup location&lt;/a&gt;, it’s time to actually grab everything from the database. The first command will allow us to securely communicate with the remote server over SSH. If we didn’t do this, all of the website traffic would be vulnerable to interception since it would be unencrypted in transit (with the exception of the user passwords which are stored encrypted already).&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;ssh&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -f&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -L3310:localhost:3306&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;redacte&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -N&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above command will forward traffic directed at local port 3310 to the remote machine’s port 3306 which is the default port for a mysql server. To make sure this works, you’ll want to make sure the port is actually open for communication on port 3306, preferably restricted to just the IP address of your local machine for better security. If you’re using uncomplicated firewall, you can achieve this with the following command (replacing the example address with your own IP address):&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; ufw&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; allow&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; from&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 198.51.100.11&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; any&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; port&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 3306&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now we’re ready to actually dump the database. Fill in your own credentials where appropriate:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysqldump&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -P&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 3310&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -h&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; 127.0.0.1&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -u&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mysql_user&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; database_name&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; table_name&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; backup_file.sql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can leave off the name of the table if you want to dump the entire database. This will generate all the SQL statements needed to recreate the database and write them out to the file backup_file.sql.&lt;/p&gt;
&lt;h2 id=&quot;import-the-sql-dump&quot;&gt;Import the SQL Dump&lt;/h2&gt;
&lt;p&gt;Now on my local machine, I want to import the dump into a new database I’ve created:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot; role=&quot;region&quot; aria-label=&quot;Code, sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; database&lt;/span&gt;&lt;span class=&quot;sl-6f42c1 sd-dcbdfb&quot;&gt; website_bak&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then I give my non-root user permissions to write to all of the tables in the new database:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot; role=&quot;region&quot; aria-label=&quot;Code, sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;grant&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; all privileges &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt; website_bak . &lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; to&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; &apos;user&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt;&apos;localhost&apos;&lt;/span&gt;&lt;span class=&quot;sl-24292e sd-adbac7&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can quit back out and run the command to import the dump file into the database:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;mysql&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -u&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; user&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -p&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; website_bak&lt;/span&gt;&lt;span class=&quot;sl-d73a49 sd-f47067&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /path/to/backup_file.sql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content:encoded><category>web development</category><category>mysqldump</category><category>mysql</category></item><item><title>Encrypting the backups</title><link>https://averyuslaner.com/blog/encrypting-backups/</link><guid isPermaLink="true">https://averyuslaner.com/blog/encrypting-backups/</guid><description>You gotta encrypt all the things.</description><pubDate>Sat, 14 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As of the time of writing, the website still looks crumby. But there has been progress! You just can’t enjoy it yet.&lt;/p&gt;
&lt;p&gt;Considering I implemented the strictest level of encryption on my website before I even built a way for users to submit data, I obviously care about security. In fact, I probably approach security in way that could be construed as paranoia, but that’s just because I think such an approach offers the greatest about of fun.&lt;/p&gt;
&lt;p&gt;Anyway, my latest addition to the website has been a custom user model which will eventually facilitate the ability for users to order prints of my photographs if they so choose. Unfortunately, this created some dependency issues when I attempted to apply the Django migrations to all the tables that had been built using the default wagtail user model. So rather than mess around editing the migration files for hours and probably just ruining things further, it probably makes more sense to just drop the database entirely and rebuild it from scratch using the custom user model. But wait! Then I’d lose all three of these masterfully crafted blog posts. Time for backups.&lt;/p&gt;
&lt;p&gt;My fancy new workstation has a separate 1 TB HDD that would be ideal for such a backup. But all that fancy-shmancy web encryption would be wasted if I backed up all the data to an unencrypted drive. Which brings us to the exciting world of:&lt;/p&gt;
&lt;h2 id=&quot;full-disk-encryption&quot;&gt;Full Disk Encryption!&lt;/h2&gt;
&lt;p&gt;Step one of course is to fire up gparted and delete the existing partitions. Then we create a new partition which uses up the whole drive, but we leave the filesystem unformatted. We’ll do that ourselves by following a guide such as &lt;a href=&quot;https://ncona.com/2016/07/encrypting-an-external-drive-using-luks/&quot;&gt;this&lt;/a&gt;. We also want to zero out the drive before the encryption part so you’ll probably want to confirm the location of the disk and partition with something like:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;fdisk&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And throw something like this at it, where you replace sda1 with whichever disk partition you happen to be targeting:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; dd&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; if=/dev/zero&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; of=/dev/sda1&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; bs=1M&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You’ll want to be extra careful when using a command like dd since a typo there could result in irreversible loss of data if you target the wrong disk or partition. So at this point if you haven’t ruined your computer by mistyping the above command and you’re zeroing out a large disk like my 1 TB HDD, you can go out and play with your friends because it will take about forever for the command to complete. Just be patient and don’t worry about how it seems to hang, dd just doesn’t output any info to describe its progress.&lt;/p&gt;
&lt;p&gt;If you’ve been patient enough to wait for forever, you’re now ready to actually start doing the encryption stuff, like so:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cryptsetup&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; luksFormat&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /dev/sda1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You’ll want to make sure you’re using latest version of cryptsetup before running this command, since we’re using all the defaults here which will offer plenty of security as long as your using version 1.6.0+. If you’re interested, you can read a bit more about the tool &lt;a href=&quot;https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Encryption_options_for_LUKS_mode&quot;&gt;here&lt;/a&gt;. Once you run the command, you’ll be prompted to supply a password that will be used to unlock the disk. The encryption won’t be worth much if you use a weak password, but you’ll also need to make sure you don’t lose it as there will be no way to recover the data on the disk if you misplace the password. As such, this might be a good time to start using a password manager like &lt;a href=&quot;https://keepersecurity.com/&quot;&gt;Keeper&lt;/a&gt; which makes it easy to create and use complicated passwords without having to worry about forgetting them later.&lt;/p&gt;
&lt;p&gt;Now we need to mount and unlock the drive:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; cryptsetup&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; luksOpen&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /dev/sda1&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; encrypted-hdd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This lets us give the drive a filesystem:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; mke2fs&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /dev/mapper/encrypted-hdd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And finally we want to transfer ownership of the drive to our unprivileged user so that user can actually write to the disk. It will look something like this, where the username in my case is myuser:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; chown&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -R&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; myuser&lt;/span&gt;&lt;span class=&quot;sl-032f62 sd-96d0ff&quot;&gt; /media/myuser/ae722e82-1476-4374-acd8-a8a18ef8ae7a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can check where your disk is mounted using:&lt;/p&gt;
&lt;div class=&quot;code-block&quot;&gt;&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark-dimmed&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot; role=&quot;region&quot; aria-label=&quot;Code, bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;sl-6f42c1 sd-f69d50&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;sl-005cc5 sd-6cb6ff&quot;&gt; -h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content:encoded><category>encryption</category></item><item><title>Setting up a new work environment</title><link>https://averyuslaner.com/blog/setting-new-work-environment/</link><guid isPermaLink="true">https://averyuslaner.com/blog/setting-new-work-environment/</guid><description>There&apos;s a lot of stuff to do behind the scenes when building a website from scratch. And it takes up a lot of time.</description><pubDate>Fri, 13 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As with most computer related things it seems, working on one problem always seems to expose a variety of new problems, some of which are blocking while others are just interesting optimizations. In the age of Squarespace and other such tools that allow one to erect aesthetically pleasing websites in a matter of minutes, part of the fun of this project is to tackle as many of the challenges I encounter head on. As such, I’ve spent the better part of my week working more on my new workstation than I have on the website itself.&lt;/p&gt;
&lt;p&gt;It turns out that buying new hardware doesn’t necessarily mean that everything will run flawlessly when you stubbornly insist your development environment must be run under linux. After about four separate clean install attempts of various Debian configurations, I finally gave up and turned to Ubuntu 16.04 LTS instead. For the past few years I have preferred to use Debian because I considered Ubuntu to be linux with training wheels. And perhaps it is, but I have to say it sure was nice to finish the install and not have to wrestle with the innards of my computer to try and figure out why my touchpad, wifi-adapter, and xserver all weren’t running properly despite having seemingly downloaded the latest drivers from the stable-branch repository. Under Ubuntu, everything has pretty much just worked without my intervention (save for my GTX 960M), so now I can actually focus on the website itself.&lt;/p&gt;
</content:encoded><category>linux</category><category>web development</category></item><item><title>Building the website</title><link>https://averyuslaner.com/blog/building-website/</link><guid isPermaLink="true">https://averyuslaner.com/blog/building-website/</guid><description>Outlining my plans for the new website.</description><pubDate>Mon, 02 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This website will serve to showcase my various projects and interests.&lt;/p&gt;
&lt;p&gt;Various topics and categories will be explored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programming&lt;/li&gt;
&lt;li&gt;Photography&lt;/li&gt;
&lt;li&gt;Miscellaneous projects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the foreseeable future, I will mainly be writing about programming in Python and various web-focused languages while I build out this website. The site is hosted by &lt;a href=&quot;https://m.do.co/c/5c2ac855bd07&quot;&gt;DigitalOcean&lt;/a&gt;* on an Ubuntu 16.04 x64 instance and powered by &lt;a href=&quot;https://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt; and &lt;a href=&quot;https://wagtail.io/&quot;&gt;Wagtail&lt;/a&gt;. It is served by the nginx web server. The source code can be found on GitHub &lt;a href=&quot;https://github.com/TechnoConserve/personal_website&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you’re reading this close to the date of publication, you can clearly see that my focus thus far has been on function rather than form. I have spent the majority of my time thus far laying the basic framework for the rest of the website. Behind the scenes, I have used &lt;a href=&quot;https://letsencrypt.org/&quot;&gt;LetsEncrypt&lt;/a&gt; to ensure a high level of security if you choose to exchange any information with the website. At the time of writing, this website receives an &lt;a href=&quot;https://www.ssllabs.com/ssltest/analyze.html?d=averyuslaner.com&quot;&gt;A+ rating from SSL Labs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;going-forward&quot;&gt;Going forward&lt;/h2&gt;
&lt;p&gt;Now that the groundwork has been laid, I will be focusing on making the website a little prettier. I’ll also begin building out the photography section of the website since I think this is the area that will largely dictate how things the rest of the pages will look, stylistically speaking.&lt;/p&gt;
</content:encoded><category>planning</category></item></channel></rss>