<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kodex</title>
    <description>The latest articles on DEV Community by Kodex (@kyledev008).</description>
    <link>https://dev.to/kyledev008</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1333977%2F83127e04-36c5-44d8-be77-27334dff9650.png</url>
      <title>DEV Community: Kodex</title>
      <link>https://dev.to/kyledev008</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kyledev008"/>
    <language>en</language>
    <item>
      <title>What I've Learned This Week #0</title>
      <dc:creator>Kodex</dc:creator>
      <pubDate>Thu, 25 Jul 2024 09:44:54 +0000</pubDate>
      <link>https://dev.to/kyledev008/what-ive-learned-this-week-0-57ek</link>
      <guid>https://dev.to/kyledev008/what-ive-learned-this-week-0-57ek</guid>
      <description>&lt;p&gt;I find myself each week learning one or more new things, at least from the perspective of my own personal experience. So, I thought sharing it here would be a good way to solidify some of that knowledge, keep a record of it, and to potentially help someone else learn something they didn't previously know.&lt;/p&gt;

&lt;p&gt;This week I learned that it's possible to write a python script that can take a list of database backup names, import a database into MySQL, then start up a Flask context, and run a report on the database as it stands, and then rinse and repeat.&lt;/p&gt;

&lt;p&gt;Maybe this sounds like a simple concept but trying to achieve this using a mostly standard approach proved to be deceptively challenging. I started off by simply writing a script that imported the backup, then ran the report on the imported data, and put that into a loop. But sadly, I was met with a terminal that hung on the 2nd loop iteration, and so I started to break down what might be happening.&lt;/p&gt;

&lt;p&gt;The first thought that came to mind was that the imports that I was making from the Flask app were causing the import to be blocked since the script hasn't terminated yet, so the lock holding the database connection with Flask was still active, but there was no error message to inform me that this was happening, and I assume this is by design, so I used my experience with Flask to rationalize that this was most likely the case.&lt;/p&gt;

&lt;p&gt;So, I went and searched for how to simply 'un-import' the modules I had imported from Flask and came across the &lt;code&gt;del&lt;/code&gt; keyword in python to get the job done and tried again... Only to be met with the same hanging terminal I had sat with previously. So, it was back to the drawing board.&lt;/p&gt;

&lt;p&gt;The next thought I had was that it might be that the modules have been removed, but the Flask app context is still running somewhere. To force the Flask app context to run and stop where I wanted it to, I tried an approach that I had used in a previous task some 2 years ago where I needed to use the Flask app context with send out emails asynchronously.&lt;/p&gt;

&lt;p&gt;I then tried importing the app from within the for loop, then using the &lt;code&gt;with app.app_context():&lt;/code&gt; command to force Flask to start and stop only within this specified context. I then ran the script and watched the terminal with bated breath as I waited the minute or so that it took for the database to import in the first loop, then it started with the 2nd as it had before, and then, success! The 2nd import worked, and I got the expected next step output indicating that the report had been completed, which I verified against the output file.&lt;/p&gt;

&lt;p&gt;I was pleased with my results as this was not something I had done before, so I was happy I could figure it out and get it working as expected.&lt;/p&gt;

&lt;p&gt;You might be wondering why I was trying to do this in the first place, and well, that's a good question. I was tasked with pulling a historical monthly report that required data that has not been saved anywhere other than in the database backups, and that couldn't be gathered from the current live database, so I only had backups to work with to pull this data. Which is what led me to learning about how to manage Flask context alongside database imports.&lt;/p&gt;

&lt;p&gt;For those that enjoy a bit of code reading, this is how I structured my script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="c1"&gt;# for running the database import command
&lt;/span&gt;
&lt;span class="n"&gt;backup_name_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;backup1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;backup2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;backup_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;backup_name_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# do all necessary changes or checks on the db name here
&lt;/span&gt;    &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mysql -u db_user_name --password=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SomePassword&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; db_name &amp;lt; &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/path/to/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.sql&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;
    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# import the app variable to allow for the context to be created
&lt;/span&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;app_module&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;app_variable&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;app_variable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;app_context&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="c1"&gt;# do all Flask related imports here
&lt;/span&gt;        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;app_module&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;relevant_app_class_or_function&lt;/span&gt;

        &lt;span class="c1"&gt;# run all relevant code here to build up your data from the loaded backup
&lt;/span&gt;
        &lt;span class="c1"&gt;# remove the imported modules
&lt;/span&gt;        &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;relevant_app_class_or_function&lt;/span&gt;

    &lt;span class="c1"&gt;# remove the app variable after the context expires just to be safe
&lt;/span&gt;    &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;app_variable&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, that's how I was able to pull historical data from only database backups.&lt;/p&gt;

&lt;p&gt;This is highly specific, and I realize that, but this is also not a tutorial, it's purely an outlet for my personal learning experience, that I would like to share here in the hopes that it becomes either an interesting read or a helpful tip to someone, somewhere out there.&lt;/p&gt;

&lt;p&gt;If you've made it this far, I would like to say thank you for reading, and I hope you'll join me on my next post.&lt;/p&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>I Asked Copilot to Explain Threading in Python to a Dog</title>
      <dc:creator>Kodex</dc:creator>
      <pubDate>Thu, 18 Jul 2024 13:39:15 +0000</pubDate>
      <link>https://dev.to/kyledev008/i-asked-copilot-to-explain-threading-in-python-to-a-dog-5hmk</link>
      <guid>https://dev.to/kyledev008/i-asked-copilot-to-explain-threading-in-python-to-a-dog-5hmk</guid>
      <description>&lt;p&gt;So out of curiosity, I asked copilot this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can you explain the concept of threading in python to a dog?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And this is the response I got, which I was pleasantly surprised by:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ah, the age-old question: How does one explain threading to a dog? 🐶 Well, let’s give it a shot! Imagine you’re sitting in a sunny park, and there are multiple squirrels running around. Each squirrel represents a task that needs to be done. Now, threading is like having multiple doggy friends—each one chasing a different squirrel simultaneously. 🌳&lt;/p&gt;

&lt;p&gt;Okay, here goes:&lt;/p&gt;

&lt;p&gt;"Hey there, fluffy buddy! So, threading in Python is like having a bunch of tennis balls to fetch, but instead of fetching them one by one, you decide to chase after all of them at once. 🎾🎾🎾&lt;/p&gt;

&lt;p&gt;You see, when your human (who’s basically the Python interpreter) gives you a list of tasks (like “sit,” “stay,” or “roll over”), you can either do them one after the other (that’s called single-threading), or you can be a multitasking superstar and do several tasks at the same time (that’s threading!). Woof! 🐾&lt;/p&gt;

&lt;p&gt;Now, each tennis ball represents a little piece of work—maybe calculating some numbers, downloading files, or even barking at the mailman. When you use threads, you can juggle all these tasks without waiting for one to finish before starting the next. It’s like having extra paws! 🐾🐾&lt;/p&gt;

&lt;p&gt;But—and here’s the tricky part—even though it sounds fun, you need to be careful. If too many tennis balls are flying around, you might get tangled up or collide with other dogs (threads). And nobody wants a doggy pileup! 🙈&lt;/p&gt;

&lt;p&gt;So, Python provides a special doggy playground called the Global Interpreter Lock (GIL). It’s like a leash that ensures only one thread can play with the tennis balls at a time. But sometimes, if you really need to go full-speed, you can use special toys (like the multiprocessing module) to break free from the leash and play fetch without restrictions! 🏃‍♂️&lt;/p&gt;

&lt;p&gt;Remember, little buddy, threading can make your code faster and more efficient, but it also requires some smarts to avoid chaos. So, next time you see a squirrel—or a thread—go chase it with all your doggy enthusiasm! 🐿️🐕"&lt;/p&gt;

&lt;p&gt;And there you have it—a dog-friendly explanation of threading in Python! 🐾 If your dog happens to be a coding prodigy, maybe they’ll even start writing threaded programs. Who knows? 😄&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I found this pretty amusing, so I thought I'd share it here as a bit a comic relief for everyone else that didn't ask for it.&lt;/p&gt;

&lt;p&gt;You're welcome :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>dog</category>
      <category>threading</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
