<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[noreasontopanic]]></title><description><![CDATA[(yet) another newsletter about software development and code]]></description><link>https://noreasontopanic.com</link><image><url>https://noreasontopanic.com/img/substack.png</url><title>noreasontopanic</title><link>https://noreasontopanic.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 16 Apr 2026 05:49:51 GMT</lastBuildDate><atom:link href="https://noreasontopanic.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Patrick DeVivo]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[noreasontopanic@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[noreasontopanic@substack.com]]></itunes:email><itunes:name><![CDATA[Patrick DeVivo]]></itunes:name></itunes:owner><itunes:author><![CDATA[Patrick DeVivo]]></itunes:author><googleplay:owner><![CDATA[noreasontopanic@substack.com]]></googleplay:owner><googleplay:email><![CDATA[noreasontopanic@substack.com]]></googleplay:email><googleplay:author><![CDATA[Patrick DeVivo]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Querying Billions of GitHub Events Using Modal and DuckDB (Part 1: Ingesting Data)]]></title><description><![CDATA[Using Modal.com and DuckDB to download and query billions of public GitHub events from gharchive.org.]]></description><link>https://noreasontopanic.com/p/querying-billions-of-github-events</link><guid isPermaLink="false">https://noreasontopanic.com/p/querying-billions-of-github-events</guid><dc:creator><![CDATA[Patrick DeVivo]]></dc:creator><pubDate>Fri, 29 Aug 2025 12:33:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!BpW5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wjy6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wjy6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 424w, https://substackcdn.com/image/fetch/$s_!wjy6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 848w, https://substackcdn.com/image/fetch/$s_!wjy6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 1272w, https://substackcdn.com/image/fetch/$s_!wjy6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wjy6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png" width="728" height="121.33333333333333" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:41735,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://noreasontopanic.substack.com/i/172110107?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wjy6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 424w, https://substackcdn.com/image/fetch/$s_!wjy6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 848w, https://substackcdn.com/image/fetch/$s_!wjy6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 1272w, https://substackcdn.com/image/fetch/$s_!wjy6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc27f6914-ed40-4420-bb12-78ef86d5fb3b_1200x200.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>There have been two technologies I&#8217;ve been really excited about recently - and will jump at any excuse to use them. One is <a href="https://duckdb.org/">DuckDB</a>, my new go-to for most local data processing, especially with the recent addition of a <a href="https://duckdb.org/2025/03/12/duckdb-ui.html">UI mode</a>. DuckDB makes it very convenient to query fairly large (multiple GB) datasets on disk - CSVs, JSON files, etc. without having to write much boilerplate code. It&#8217;s also great for querying small JSON, like the output from an API request (or many requests).</p><p>The second is <a href="https://modal.com/">Modal</a>, an infrastructure platform that <strong>truly</strong> feels like magic, which I&#8217;ll focus on more throughout this series.</p><p>This post and the following will demonstrate how to use <a href="https://modal.com/">Modal.com</a> and <a href="https://duckdb.org/">DuckDB</a> to ingest, process, and query huge amounts of public GitHub data (several terabytes of compressed JSON). It&#8217;s meant to serve as an example and introduction to these tools, and to show how well they work together!</p><p>This first post (Part 1) will cover how to use Modal&#8217;s highly concurrent, serverless infrastructure to download <em>lots </em>(50K+ files, 3.5 TB) of public GitHub data and store it on a <a href="https://modal.com/docs/guide/volumes">Modal Volume</a> - in about 15 minutes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://noreasontopanic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe to stay up to date &#127881;</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>The GH Archive</h1><p>Anyone who knows me, knows that I have a soft spot for <a href="https://www.mergestat.com/">querying git data</a> with SQL -  so when I came across the <a href="https://www.gharchive.org/">GH Archive</a> again, I couldn&#8217;t help wanting to poke around to see what kind of queries I could run.</p><p>You can read more on <a href="https://www.gharchive.org/">the website</a>, but the quick background is that it&#8217;s an <a href="https://github.com/igrigorik/gharchive.org">open-source project</a> that continuously archives public <a href="https://docs.github.com/en/rest/using-the-rest-api/github-event-types">GitHub events</a> (15+ types, such as git pushes, new issues, new PRs, stars, etc.), for <em><strong>all public GitHub repos</strong></em>, going back to 2011. That&#8217;s a lot of events!</p><p>The events are stored in gzip compressed JSON files and available for download at <code>data.gharchive.org</code>, partitioned by the hour - so each data file stores 1 hour of public GitHub event records. The URL format to access a data file looks like this:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!u_6Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!u_6Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 424w, https://substackcdn.com/image/fetch/$s_!u_6Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 848w, https://substackcdn.com/image/fetch/$s_!u_6Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 1272w, https://substackcdn.com/image/fetch/$s_!u_6Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!u_6Y!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png" width="1200" height="201.0989010989011" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:244,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:80942,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://noreasontopanic.substack.com/i/172110107?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!u_6Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 424w, https://substackcdn.com/image/fetch/$s_!u_6Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 848w, https://substackcdn.com/image/fetch/$s_!u_6Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 1272w, https://substackcdn.com/image/fetch/$s_!u_6Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96eca9b1-eece-444c-9af4-12766eedeed3_1920x322.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p><em>GH Archive data is also available to query <a href="https://www.gharchive.org/#bigquery">in BigQuery</a> - but that&#8217;s no fun, let&#8217;s roll our own setup!</em></p><h1>Downloading Lots of JSON</h1><p>It&#8217;s great that we can access these files, but how can we actually query and analyze their content?</p><p>DuckDB can query remote data sources over HTTP(s) using the <code>httpfs</code><a href="https://duckdb.org/docs/stable/core_extensions/httpfs/https.html"> extension</a>, and this is actually very cool. In fact, combined with the ability to decompress and handle line-delimited JSON on the fly, you could just run a simple query like so:</p><pre><code>SELECT * FROM 'https://data.gharchive.org/2015-01-01-15.json.gz';</code></pre><p>To treat that single hour of event data as a table. The file is &#8220;downloaded&#8221; as the query executes (it&#8217;s also decompressed and each line of JSON is mapped into a schema, inferred by sampling the JSON attributes). The output will look like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4S3W!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4S3W!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 424w, https://substackcdn.com/image/fetch/$s_!4S3W!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 848w, https://substackcdn.com/image/fetch/$s_!4S3W!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 1272w, https://substackcdn.com/image/fetch/$s_!4S3W!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4S3W!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png" width="1200" height="666.7582417582418" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:809,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:1256504,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://noreasontopanic.substack.com/i/172110107?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4S3W!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 424w, https://substackcdn.com/image/fetch/$s_!4S3W!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 848w, https://substackcdn.com/image/fetch/$s_!4S3W!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 1272w, https://substackcdn.com/image/fetch/$s_!4S3W!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4bf5ceb0-4a39-4d2f-a8d7-7c0836de694a_3420x1900.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>However, given that we want to execute queries across <em>a lot</em> of these files (let&#8217;s say over 1 year: <code>365 days * 24 hours = 8760 files</code>) we&#8217;re probably going to want to download these files ahead of time. Storing them on disk and pre-processing them will certainly lead to faster querying - we don&#8217;t want to be waiting for thousands of network requests as our queries execute! Not only would this be really slow, it wouldn&#8217;t be very reliable either.</p><p>I&#8217;ll skip ahead and show you where we end up, which is every <code>json.gz</code> file from 2020 to now (August, 2025) stored on disk (a Modal Volume), in a folder structure organized by year, month, then day, where each file is named from <code>{0-23}.json.gz</code>, indicating the hour of the day. You can see that it takes up quite a bit of space on a Modal Volume: ~3.5 TB total. You can also see the slow growth in data size by year (corresponding to the overall user/activity growth of GitHub).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j6sj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j6sj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 424w, https://substackcdn.com/image/fetch/$s_!j6sj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 848w, https://substackcdn.com/image/fetch/$s_!j6sj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 1272w, https://substackcdn.com/image/fetch/$s_!j6sj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j6sj!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png" width="1200" height="440.46242774566474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:508,&quot;width&quot;:1384,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:90346,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://noreasontopanic.substack.com/i/172110107?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!j6sj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 424w, https://substackcdn.com/image/fetch/$s_!j6sj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 848w, https://substackcdn.com/image/fetch/$s_!j6sj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 1272w, https://substackcdn.com/image/fetch/$s_!j6sj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c5806b7-3962-411a-a9aa-9e909324afa3_1384x508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Using <a href="https://modal.com/docs/reference/cli/shell">Modal&#8217;s debug shell</a> with an attached Volume to inspect the disk usage of all the GitHub events we&#8217;ve stored.</figcaption></figure></div><p>All of this data was downloaded in <strong>~15m</strong> using Modal&#8217;s highly concurrent infrastructure. The files are stored in a Modal Volume, a filesystem primitive which can be conveniently attached to other functions (and even <a href="https://modal.com/docs/guide/notebooks-modal">Modal Notebooks</a>!).</p><p>Here&#8217;s what the execution of the &#8220;parent&#8221; function (more on this in a moment) looks like, showing the timeline of the full download:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qe31!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qe31!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 424w, https://substackcdn.com/image/fetch/$s_!Qe31!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 848w, https://substackcdn.com/image/fetch/$s_!Qe31!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 1272w, https://substackcdn.com/image/fetch/$s_!Qe31!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qe31!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png" width="1200" height="523.3516483516484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:635,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:91060,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://noreasontopanic.substack.com/i/172110107?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Qe31!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 424w, https://substackcdn.com/image/fetch/$s_!Qe31!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 848w, https://substackcdn.com/image/fetch/$s_!Qe31!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 1272w, https://substackcdn.com/image/fetch/$s_!Qe31!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a6b7c58-6789-455f-b115-f9784cc7c30f_1620x706.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And here&#8217;s a screenshot of the Modal monitoring UI, showing resource utilization during the download run. Note the 300+ containers that were spun up and executed concurrently.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BpW5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BpW5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 424w, https://substackcdn.com/image/fetch/$s_!BpW5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 848w, https://substackcdn.com/image/fetch/$s_!BpW5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 1272w, https://substackcdn.com/image/fetch/$s_!BpW5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BpW5!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png" width="1200" height="328.02197802197804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:398,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:130368,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://noreasontopanic.substack.com/i/172110107?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BpW5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 424w, https://substackcdn.com/image/fetch/$s_!BpW5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 848w, https://substackcdn.com/image/fetch/$s_!BpW5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 1272w, https://substackcdn.com/image/fetch/$s_!BpW5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a79ec-7f67-4b5d-8b6c-9da39b8b8f52_2736x748.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Parallelizing Downloads</h2><p>Because GH Archive breaks out data into 1 hour chunks (1 file per 1 hour), we&#8217;re able to massively parallelize the overall download process - and this is where Modal can really shine.</p><p>Instead of spinning up a single big VM (or bare-metal server), or a Kubernetes cluster running a bunch of workers (and writing lots of YAML along the way&#8230;), we just decorate some Python code and instruct Modal to do a large fan-out for us, even handling retries with exponential back-off (important for dealing with network requests)!</p><p>This is where Modal really starts to feel like <em><strong>magic</strong> </em>- and it&#8217;s probably easier to show rather then tell, but here&#8217;s a basic overview before I show you the code:</p><ul><li><p>We define a function called <code>download_file</code> decorated with <code>@app.function</code>, indicating to Modal that it can be executed remotely. This function will handle the download of a <em>single</em> data file (1 hour of events). It will download the file into <code>/tmp</code> (attached disk), and then copy it into the Modal Volume, according to the recommendations <a href="https://modal.com/docs/guide/dataset-ingestion">here</a>. This is the function that will execute many times in parallel, across hundreds of containers (for different inputs of year/month/day/hour combinations).</p></li><li><p>A &#8220;parent&#8221; function called <code>download_range</code> is responsible for generating the inputs for the calls to <code>download_file</code> that represent the time range we want to download data for. This does some calendar math to produce the set of year/month/day/hour combinations. Then, it uses <strong><a href="https://modal.com/docs/guide/scale#starmap">.starmap(&#8230;)</a></strong> to have Modal execute <code>download_file</code> for all of those inputs in parallel!</p></li><li><p>Finally, a <code>main</code> function decorated with <code>@app.local_entrypoint()</code> calls <code>download_range.remote(date(2020, 1, 1))</code>, this tells Modal to start the download process for all files from Jan 1, 2020 until today.</p></li></ul><p>Here&#8217;s some code!</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist140495505\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot; data-color-mode=\&quot;light\&quot; data-light-theme=\&quot;light\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container\&quot;>\n  <div id=\&quot;file-download-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot;\n      class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;\n      style=\&quot;overflow: auto\&quot; tabindex=\&quot;0\&quot; role=\&quot;region\&quot;\n      aria-label=\&quot;download.py content, created by patrickdevivo on 03:14PM today.\&quot;\n    >\n\n        \n<div class=\&quot;js-check-hidden-unicode js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container\&quot; data-tab-size=\&quot;4\&quot; data-paste-markdown-skip data-tagsearch-path=\&quot;download.py\&quot;>\n        <tr>\n          <td id=\&quot;file-download-py-L1\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-download-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> <span class=pl-s1>modal</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L2\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-download-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>from</span> <span class=pl-s1>datetime</span> <span class=pl-k>import</span> <span class=pl-s1>date</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L3\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-download-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>from</span> .<span class=pl-s1>app</span> <span class=pl-k>import</span> <span class=pl-s1>app</span>, <span class=pl-s1>gharchive</span>, <span class=pl-c1>GHARCHIVE_DATA_PATH</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L4\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-download-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L5\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-download-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L6\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-download-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>app</span>.<span class=pl-c1>function</span>(</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L7\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-download-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>    <span class=pl-s1>volumes</span><span class=pl-c1>=</span>{<span class=pl-c1>GHARCHIVE_DATA_PATH</span>: <span class=pl-s1>gharchive</span>},</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L8\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-download-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>    <span class=pl-s1>timeout</span><span class=pl-c1>=</span><span class=pl-c1>36000</span>,</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L9\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-download-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>    <span class=pl-s1>retries</span><span class=pl-c1>=</span><span class=pl-s1>modal</span>.<span class=pl-c1>Retries</span>(</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L10\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-download-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>        <span class=pl-s1>max_retries</span><span class=pl-c1>=</span><span class=pl-c1>8</span>,</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L11\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-download-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>        <span class=pl-s1>backoff_coefficient</span><span class=pl-c1>=</span><span class=pl-c1>2</span>,</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L12\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-download-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>        <span class=pl-s1>initial_delay</span><span class=pl-c1>=</span><span class=pl-c1>1</span>,</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L13\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-download-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>        <span class=pl-s1>max_delay</span><span class=pl-c1>=</span><span class=pl-c1>30</span>,</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L14\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-download-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>    ),</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L15\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-download-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>    <span class=pl-s1>ephemeral_disk</span><span class=pl-c1>=</span><span class=pl-c1>800</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span>,</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L16\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-download-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>)</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L17\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-download-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>modal</span>.<span class=pl-c1>concurrent</span>(<span class=pl-s1>max_inputs</span><span class=pl-c1>=</span><span class=pl-c1>12</span>)</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L18\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-download-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>download_file</span>(<span class=pl-s1>year</span>: <span class=pl-smi>int</span>, <span class=pl-s1>month</span>: <span class=pl-smi>int</span>, <span class=pl-s1>day</span>: <span class=pl-smi>int</span>, <span class=pl-s1>hour</span>: <span class=pl-smi>int</span>) <span class=pl-c1>-&amp;gt;</span> <span class=pl-s1>tuple</span>[<span class=pl-smi>str</span>, <span class=pl-smi>float</span>, <span class=pl-smi>int</span>]:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L19\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-download-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>import</span> <span class=pl-s1>os</span>, <span class=pl-s1>time</span>, <span class=pl-s1>tempfile</span>, <span class=pl-s1>shutil</span>, <span class=pl-s1>pycurl</span>, <span class=pl-s1>random</span>, <span class=pl-s1>io</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L20\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-download-py-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L21\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-download-py-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Tiny jitter to avoid synchronized bursts (helps with WAF/rate shaping)</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L22\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-download-py-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>time</span>.<span class=pl-c1>sleep</span>(<span class=pl-s1>random</span>.<span class=pl-c1>uniform</span>(<span class=pl-c1>0.01</span>, <span class=pl-c1>0.05</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L23\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-download-py-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L24\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-download-py-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># URLs &amp;amp; paths</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L25\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-download-py-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>url</span> <span class=pl-c1>=</span> <span class=pl-s>f&amp;quot;https://data.gharchive.org/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>year</span><span class=pl-kos>}</span></span>-<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>month</span>:02d<span class=pl-kos>}</span></span>-<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>day</span>:02d<span class=pl-kos>}</span></span>-<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>hour</span><span class=pl-kos>}</span></span>.json.gz&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L26\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-download-py-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>vol_path</span> <span class=pl-c1>=</span> <span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-c1>GHARCHIVE_DATA_PATH</span><span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>year</span><span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>month</span>:02d<span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>day</span>:02d<span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>hour</span><span class=pl-kos>}</span></span>.json.gz&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L27\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-download-py-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L28\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-download-py-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Stage to a temporary file in /tmp which is on the attached SSD, as recommended in Modal docs: https://modal.com/docs/guide/dataset-ingestion</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L29\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-download-py-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>tmp_dir</span> <span class=pl-c1>=</span> <span class=pl-s>f&amp;quot;/tmp/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>year</span><span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>month</span>:02d<span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>day</span>:02d<span class=pl-kos>}</span></span>&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L30\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-download-py-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>os</span>.<span class=pl-c1>makedirs</span>(<span class=pl-s1>tmp_dir</span>, <span class=pl-s1>exist_ok</span><span class=pl-c1>=</span><span class=pl-c1>True</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L31\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-download-py-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>fd</span>, <span class=pl-s1>tmp_path</span> <span class=pl-c1>=</span> <span class=pl-s1>tempfile</span>.<span class=pl-c1>mkstemp</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L32\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-download-py-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>dir</span><span class=pl-c1>=</span><span class=pl-s1>tmp_dir</span>, <span class=pl-s1>prefix</span><span class=pl-c1>=</span><span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>year</span><span class=pl-kos>}</span></span>-<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>month</span>:02d<span class=pl-kos>}</span></span>-<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>day</span>:02d<span class=pl-kos>}</span></span>-<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>hour</span><span class=pl-kos>}</span></span>.json.gz.&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L33\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-download-py-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    )</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L34\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-download-py-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>os</span>.<span class=pl-c1>close</span>(<span class=pl-s1>fd</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L35\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-download-py-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L36\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-download-py-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Configure curl</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L37\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-download-py-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span> <span class=pl-c1>=</span> <span class=pl-s1>pycurl</span>.<span class=pl-c1>Curl</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L38\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-download-py-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>URL</span>, <span class=pl-s1>url</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L39\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-download-py-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>FOLLOWLOCATION</span>, <span class=pl-c1>1</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L40\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-download-py-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>HTTP_VERSION</span>, <span class=pl-s1>pycurl</span>.<span class=pl-c1>CURL_HTTP_VERSION_2TLS</span>)  <span class=pl-c># allow HTTP/2</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L41\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-download-py-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L42\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-download-py-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>c</span>.<span class=pl-c1>USERAGENT</span>, <span class=pl-s>&amp;quot;gharchive-downloader/1.0 (contact: patrick.devivo@gmail.com)&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L43\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-download-py-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    )  <span class=pl-c># may help with rate limiting</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L44\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-download-py-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>NOSIGNAL</span>, <span class=pl-c1>1</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L45\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-download-py-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>CONNECTTIMEOUT</span>, <span class=pl-c1>10</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L46\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-download-py-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L47\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-download-py-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>c</span>.<span class=pl-c1>TIMEOUT</span>, <span class=pl-c1>60</span> <span class=pl-c1>*</span> <span class=pl-c1>5</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L48\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-download-py-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    )  <span class=pl-c># total timeout - most downloads should occur within this</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L49\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-download-py-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>LOW_SPEED_LIMIT</span>, <span class=pl-c1>20_000</span>)  <span class=pl-c># bytes/sec</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L50\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-download-py-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>LOW_SPEED_TIME</span>, <span class=pl-c1>20</span>)  <span class=pl-c># if below limit for 20s -&amp;gt; timeout</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L51\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;51\&quot;></td>\n          <td id=\&quot;file-download-py-LC51\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L52\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;52\&quot;></td>\n          <td id=\&quot;file-download-py-LC52\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>hdr_buf</span> <span class=pl-c1>=</span> <span class=pl-s1>io</span>.<span class=pl-c1>BytesIO</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L53\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;53\&quot;></td>\n          <td id=\&quot;file-download-py-LC53\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>HEADERFUNCTION</span>, <span class=pl-s1>hdr_buf</span>.<span class=pl-c1>write</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L54\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;54\&quot;></td>\n          <td id=\&quot;file-download-py-LC54\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L55\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;55\&quot;></td>\n          <td id=\&quot;file-download-py-LC55\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Execute the download &#8594; /tmp, then fsync for durability</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L56\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;56\&quot;></td>\n          <td id=\&quot;file-download-py-LC56\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>with</span> <span class=pl-en>open</span>(<span class=pl-s1>tmp_path</span>, <span class=pl-s>&amp;quot;wb&amp;quot;</span>, <span class=pl-s1>buffering</span><span class=pl-c1>=</span><span class=pl-c1>1024</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span>) <span class=pl-k>as</span> <span class=pl-s1>f</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L57\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;57\&quot;></td>\n          <td id=\&quot;file-download-py-LC57\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>c</span>.<span class=pl-c1>setopt</span>(<span class=pl-s1>c</span>.<span class=pl-c1>WRITEDATA</span>, <span class=pl-s1>f</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L58\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;58\&quot;></td>\n          <td id=\&quot;file-download-py-LC58\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>c</span>.<span class=pl-c1>perform</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L59\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;59\&quot;></td>\n          <td id=\&quot;file-download-py-LC59\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>f</span>.<span class=pl-c1>flush</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L60\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;60\&quot;></td>\n          <td id=\&quot;file-download-py-LC60\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>os</span>.<span class=pl-c1>fsync</span>(<span class=pl-s1>f</span>.<span class=pl-c1>fileno</span>())</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L61\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;61\&quot;></td>\n          <td id=\&quot;file-download-py-LC61\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L62\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;62\&quot;></td>\n          <td id=\&quot;file-download-py-LC62\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Telemetry from curl</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L63\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;63\&quot;></td>\n          <td id=\&quot;file-download-py-LC63\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>status</span> <span class=pl-c1>=</span> <span class=pl-en>int</span>(<span class=pl-s1>c</span>.<span class=pl-c1>getinfo</span>(<span class=pl-s1>pycurl</span>.<span class=pl-c1>RESPONSE_CODE</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L64\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;64\&quot;></td>\n          <td id=\&quot;file-download-py-LC64\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>size_b</span> <span class=pl-c1>=</span> <span class=pl-en>int</span>(<span class=pl-s1>c</span>.<span class=pl-c1>getinfo</span>(<span class=pl-s1>pycurl</span>.<span class=pl-c1>SIZE_DOWNLOAD</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L65\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;65\&quot;></td>\n          <td id=\&quot;file-download-py-LC65\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>total_s</span> <span class=pl-c1>=</span> <span class=pl-en>float</span>(<span class=pl-s1>c</span>.<span class=pl-c1>getinfo</span>(<span class=pl-s1>pycurl</span>.<span class=pl-c1>TOTAL_TIME</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L66\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;66\&quot;></td>\n          <td id=\&quot;file-download-py-LC66\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>mbps</span> <span class=pl-c1>=</span> <span class=pl-en>float</span>(<span class=pl-s1>c</span>.<span class=pl-c1>getinfo</span>(<span class=pl-s1>pycurl</span>.<span class=pl-c1>SPEED_DOWNLOAD</span>)) <span class=pl-c1>/</span> (<span class=pl-c1>1024</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L67\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;67\&quot;></td>\n          <td id=\&quot;file-download-py-LC67\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>ttfb_s</span> <span class=pl-c1>=</span> <span class=pl-en>float</span>(<span class=pl-s1>c</span>.<span class=pl-c1>getinfo</span>(<span class=pl-s1>pycurl</span>.<span class=pl-c1>STARTTRANSFER_TIME</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L68\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;68\&quot;></td>\n          <td id=\&quot;file-download-py-LC68\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>headers_s</span> <span class=pl-c1>=</span> <span class=pl-s1>hdr_buf</span>.<span class=pl-c1>getvalue</span>().<span class=pl-c1>decode</span>(<span class=pl-s>&amp;quot;latin1&amp;quot;</span>, <span class=pl-s1>errors</span><span class=pl-c1>=</span><span class=pl-s>&amp;quot;replace&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L69\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;69\&quot;></td>\n          <td id=\&quot;file-download-py-LC69\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>c</span>.<span class=pl-c1>close</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L70\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;70\&quot;></td>\n          <td id=\&quot;file-download-py-LC70\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L71\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;71\&quot;></td>\n          <td id=\&quot;file-download-py-LC71\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Handle non-200s</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L72\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;72\&quot;></td>\n          <td id=\&quot;file-download-py-LC72\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>if</span> <span class=pl-s1>status</span> <span class=pl-c1>!=</span> <span class=pl-c1>200</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L73\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;73\&quot;></td>\n          <td id=\&quot;file-download-py-LC73\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c># Clean partial temp file</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L74\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;74\&quot;></td>\n          <td id=\&quot;file-download-py-LC74\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>try</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L75\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;75\&quot;></td>\n          <td id=\&quot;file-download-py-LC75\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>os</span>.<span class=pl-c1>remove</span>(<span class=pl-s1>tmp_path</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L76\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;76\&quot;></td>\n          <td id=\&quot;file-download-py-LC76\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>except</span> <span class=pl-v>FileNotFoundError</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L77\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;77\&quot;></td>\n          <td id=\&quot;file-download-py-LC77\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>pass</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L78\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;78\&quot;></td>\n          <td id=\&quot;file-download-py-LC78\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L79\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;79\&quot;></td>\n          <td id=\&quot;file-download-py-LC79\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c># Sometimes there&amp;#39;s missing hours, but raise on 404 anyways to retry and report</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L80\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;80\&quot;></td>\n          <td id=\&quot;file-download-py-LC80\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>if</span> <span class=pl-s1>status</span> <span class=pl-c1>==</span> <span class=pl-c1>404</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L81\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;81\&quot;></td>\n          <td id=\&quot;file-download-py-LC81\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>time</span>.<span class=pl-c1>sleep</span>(<span class=pl-s1>random</span>.<span class=pl-c1>uniform</span>(<span class=pl-c1>0.5</span>, <span class=pl-c1>2.0</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L82\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;82\&quot;></td>\n          <td id=\&quot;file-download-py-LC82\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>raise</span> <span class=pl-en>RuntimeError</span>(<span class=pl-s>f&amp;quot;HTTP 404 for <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>url</span><span class=pl-kos>}</span></span> (retryable)&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L83\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;83\&quot;></td>\n          <td id=\&quot;file-download-py-LC83\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L84\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;84\&quot;></td>\n          <td id=\&quot;file-download-py-LC84\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c># Transient / retry-worthy codes &#8594; raise so Modal retries</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L85\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;85\&quot;></td>\n          <td id=\&quot;file-download-py-LC85\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>retry_statuses</span> <span class=pl-c1>=</span> {<span class=pl-c1>403</span>, <span class=pl-c1>429</span>, <span class=pl-c1>500</span>, <span class=pl-c1>502</span>, <span class=pl-c1>503</span>, <span class=pl-c1>504</span>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L86\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;86\&quot;></td>\n          <td id=\&quot;file-download-py-LC86\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>if</span> <span class=pl-s1>status</span> <span class=pl-c1>in</span> <span class=pl-s1>retry_statuses</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L87\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;87\&quot;></td>\n          <td id=\&quot;file-download-py-LC87\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>first_hdr</span> <span class=pl-c1>=</span> <span class=pl-s1>headers_s</span>.<span class=pl-c1>splitlines</span>()[<span class=pl-c1>0</span>] <span class=pl-k>if</span> <span class=pl-s1>headers_s</span> <span class=pl-k>else</span> <span class=pl-s>f&amp;quot;HTTP <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>status</span><span class=pl-kos>}</span></span>&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L88\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;88\&quot;></td>\n          <td id=\&quot;file-download-py-LC88\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>raise</span> <span class=pl-en>RuntimeError</span>(<span class=pl-s>f&amp;quot;HTTP <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>status</span><span class=pl-kos>}</span></span> for <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>url</span><span class=pl-kos>}</span></span> (<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>first_hdr</span><span class=pl-kos>}</span></span>)&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L89\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;89\&quot;></td>\n          <td id=\&quot;file-download-py-LC89\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L90\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;90\&quot;></td>\n          <td id=\&quot;file-download-py-LC90\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c># Other client errors: surface as failures (Modal will retry)</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L91\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;91\&quot;></td>\n          <td id=\&quot;file-download-py-LC91\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>raise</span> <span class=pl-en>RuntimeError</span>(<span class=pl-s>f&amp;quot;HTTP <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>status</span><span class=pl-kos>}</span></span> for <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>url</span><span class=pl-kos>}</span></span>&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L92\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;92\&quot;></td>\n          <td id=\&quot;file-download-py-LC92\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L93\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;93\&quot;></td>\n          <td id=\&quot;file-download-py-LC93\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Publish into the Modal volume atomically</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L94\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;94\&quot;></td>\n          <td id=\&quot;file-download-py-LC94\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>vol_dir</span> <span class=pl-c1>=</span> <span class=pl-s1>os</span>.<span class=pl-c1>path</span>.<span class=pl-c1>dirname</span>(<span class=pl-s1>vol_path</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L95\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;95\&quot;></td>\n          <td id=\&quot;file-download-py-LC95\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>os</span>.<span class=pl-c1>makedirs</span>(<span class=pl-s1>vol_dir</span>, <span class=pl-s1>exist_ok</span><span class=pl-c1>=</span><span class=pl-c1>True</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L96\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;96\&quot;></td>\n          <td id=\&quot;file-download-py-LC96\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>tmp_dest</span> <span class=pl-c1>=</span> <span class=pl-s1>vol_path</span> <span class=pl-c1>+</span> <span class=pl-s>&amp;quot;.part&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L97\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;97\&quot;></td>\n          <td id=\&quot;file-download-py-LC97\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>with</span> (</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L98\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;98\&quot;></td>\n          <td id=\&quot;file-download-py-LC98\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-en>open</span>(<span class=pl-s1>tmp_path</span>, <span class=pl-s>&amp;quot;rb&amp;quot;</span>, <span class=pl-s1>buffering</span><span class=pl-c1>=</span><span class=pl-c1>1024</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span>) <span class=pl-k>as</span> <span class=pl-s1>rf</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L99\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;99\&quot;></td>\n          <td id=\&quot;file-download-py-LC99\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-en>open</span>(<span class=pl-s1>tmp_dest</span>, <span class=pl-s>&amp;quot;wb&amp;quot;</span>, <span class=pl-s1>buffering</span><span class=pl-c1>=</span><span class=pl-c1>1024</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span>) <span class=pl-k>as</span> <span class=pl-s1>wf</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L100\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;100\&quot;></td>\n          <td id=\&quot;file-download-py-LC100\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    ):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L101\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;101\&quot;></td>\n          <td id=\&quot;file-download-py-LC101\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>shutil</span>.<span class=pl-c1>copyfileobj</span>(<span class=pl-s1>rf</span>, <span class=pl-s1>wf</span>, <span class=pl-s1>length</span><span class=pl-c1>=</span><span class=pl-c1>8</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span> <span class=pl-c1>*</span> <span class=pl-c1>1024</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L102\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;102\&quot;></td>\n          <td id=\&quot;file-download-py-LC102\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>wf</span>.<span class=pl-c1>flush</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L103\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;103\&quot;></td>\n          <td id=\&quot;file-download-py-LC103\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>os</span>.<span class=pl-c1>fsync</span>(<span class=pl-s1>wf</span>.<span class=pl-c1>fileno</span>())</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L104\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;104\&quot;></td>\n          <td id=\&quot;file-download-py-LC104\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>os</span>.<span class=pl-c1>replace</span>(<span class=pl-s1>tmp_dest</span>, <span class=pl-s1>vol_path</span>)  <span class=pl-c># atomic within the same FS</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L105\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;105\&quot;></td>\n          <td id=\&quot;file-download-py-LC105\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>dfd</span> <span class=pl-c1>=</span> <span class=pl-s1>os</span>.<span class=pl-c1>open</span>(<span class=pl-s1>vol_dir</span>, <span class=pl-s1>os</span>.<span class=pl-c1>O_DIRECTORY</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L106\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;106\&quot;></td>\n          <td id=\&quot;file-download-py-LC106\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>try</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L107\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;107\&quot;></td>\n          <td id=\&quot;file-download-py-LC107\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>os</span>.<span class=pl-c1>fsync</span>(<span class=pl-s1>dfd</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L108\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;108\&quot;></td>\n          <td id=\&quot;file-download-py-LC108\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>finally</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L109\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;109\&quot;></td>\n          <td id=\&quot;file-download-py-LC109\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>os</span>.<span class=pl-c1>close</span>(<span class=pl-s1>dfd</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L110\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;110\&quot;></td>\n          <td id=\&quot;file-download-py-LC110\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L111\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;111\&quot;></td>\n          <td id=\&quot;file-download-py-LC111\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Clean local temp</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L112\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;112\&quot;></td>\n          <td id=\&quot;file-download-py-LC112\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>try</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L113\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;113\&quot;></td>\n          <td id=\&quot;file-download-py-LC113\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>os</span>.<span class=pl-c1>remove</span>(<span class=pl-s1>tmp_path</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L114\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;114\&quot;></td>\n          <td id=\&quot;file-download-py-LC114\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>except</span> <span class=pl-v>FileNotFoundError</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L115\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;115\&quot;></td>\n          <td id=\&quot;file-download-py-LC115\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>pass</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L116\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;116\&quot;></td>\n          <td id=\&quot;file-download-py-LC116\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L117\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;117\&quot;></td>\n          <td id=\&quot;file-download-py-LC117\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L118\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;118\&quot;></td>\n          <td id=\&quot;file-download-py-LC118\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>os</span>.<span class=pl-c1>path</span>.<span class=pl-c1>basename</span>(<span class=pl-s1>vol_path</span>)<span class=pl-kos>}</span></span> &#8212; <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>size_b</span> <span class=pl-c1>/</span> <span class=pl-c1>1_048_576</span>:.1f<span class=pl-kos>}</span></span> MB &amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L119\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;119\&quot;></td>\n          <td id=\&quot;file-download-py-LC119\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s>f&amp;quot;in <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>total_s</span>:.2f<span class=pl-kos>}</span></span>s @ <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>mbps</span>:.2f<span class=pl-kos>}</span></span> MB/s (TTFB <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>ttfb_s</span>:.2f<span class=pl-kos>}</span></span>s) &#8594; <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>vol_path</span><span class=pl-kos>}</span></span>&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L120\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;120\&quot;></td>\n          <td id=\&quot;file-download-py-LC120\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    )</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L121\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;121\&quot;></td>\n          <td id=\&quot;file-download-py-LC121\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L122\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;122\&quot;></td>\n          <td id=\&quot;file-download-py-LC122\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>vol_path</span>, <span class=pl-s1>total_s</span>, <span class=pl-s1>size_b</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L123\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;123\&quot;></td>\n          <td id=\&quot;file-download-py-LC123\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L124\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;124\&quot;></td>\n          <td id=\&quot;file-download-py-LC124\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L125\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;125\&quot;></td>\n          <td id=\&quot;file-download-py-LC125\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>app</span>.<span class=pl-c1>function</span>(<span class=pl-s1>timeout</span><span class=pl-c1>=</span><span class=pl-c1>36000</span>, <span class=pl-s1>volumes</span><span class=pl-c1>=</span>{<span class=pl-c1>GHARCHIVE_DATA_PATH</span>: <span class=pl-s1>gharchive</span>})</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L126\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;126\&quot;></td>\n          <td id=\&quot;file-download-py-LC126\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>download_range</span>(<span class=pl-s1>start</span>: <span class=pl-smi>date</span>, <span class=pl-s1>end</span>: <span class=pl-smi>date</span> <span class=pl-c1>=</span> <span class=pl-s1>date</span>.<span class=pl-c1>today</span>()):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L127\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;127\&quot;></td>\n          <td id=\&quot;file-download-py-LC127\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>from</span> <span class=pl-s1>datetime</span> <span class=pl-k>import</span> <span class=pl-s1>timedelta</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L128\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;128\&quot;></td>\n          <td id=\&quot;file-download-py-LC128\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>import</span> <span class=pl-s1>time</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L129\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;129\&quot;></td>\n          <td id=\&quot;file-download-py-LC129\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L130\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;130\&quot;></td>\n          <td id=\&quot;file-download-py-LC130\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c># Build hour-level inputs</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L131\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;131\&quot;></td>\n          <td id=\&quot;file-download-py-LC131\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>inputs</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L132\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;132\&quot;></td>\n          <td id=\&quot;file-download-py-LC132\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>delta</span> <span class=pl-c1>=</span> <span class=pl-s1>end</span> <span class=pl-c1>-</span> <span class=pl-s1>start</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L133\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;133\&quot;></td>\n          <td id=\&quot;file-download-py-LC133\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> <span class=pl-s1>d</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>delta</span>.<span class=pl-c1>days</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L134\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;134\&quot;></td>\n          <td id=\&quot;file-download-py-LC134\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>day</span> <span class=pl-c1>=</span> <span class=pl-s1>start</span> <span class=pl-c1>+</span> <span class=pl-en>timedelta</span>(<span class=pl-s1>days</span><span class=pl-c1>=</span><span class=pl-s1>d</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L135\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;135\&quot;></td>\n          <td id=\&quot;file-download-py-LC135\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>hour</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-c1>24</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L136\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;136\&quot;></td>\n          <td id=\&quot;file-download-py-LC136\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>inputs</span>.<span class=pl-c1>append</span>((<span class=pl-s1>day</span>.<span class=pl-c1>year</span>, <span class=pl-s1>day</span>.<span class=pl-c1>month</span>, <span class=pl-s1>day</span>.<span class=pl-c1>day</span>, <span class=pl-s1>hour</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L137\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;137\&quot;></td>\n          <td id=\&quot;file-download-py-LC137\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L138\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;138\&quot;></td>\n          <td id=\&quot;file-download-py-LC138\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L139\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;139\&quot;></td>\n          <td id=\&quot;file-download-py-LC139\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s>f&amp;quot;Downloading events from <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>start</span><span class=pl-kos>}</span></span> to <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>end</span><span class=pl-kos>}</span></span> &#8212; <span class=pl-s1><span class=pl-kos>{</span><span class=pl-en>len</span>(<span class=pl-s1>inputs</span>)<span class=pl-kos>}</span></span> files over <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>delta</span>.<span class=pl-c1>days</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span><span class=pl-kos>}</span></span> days&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L140\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;140\&quot;></td>\n          <td id=\&quot;file-download-py-LC140\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    )</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L141\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;141\&quot;></td>\n          <td id=\&quot;file-download-py-LC141\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L142\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;142\&quot;></td>\n          <td id=\&quot;file-download-py-LC142\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>t0</span> <span class=pl-c1>=</span> <span class=pl-s1>time</span>.<span class=pl-c1>time</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L143\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;143\&quot;></td>\n          <td id=\&quot;file-download-py-LC143\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>total_size</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L144\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;144\&quot;></td>\n          <td id=\&quot;file-download-py-LC144\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>ok</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L145\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;145\&quot;></td>\n          <td id=\&quot;file-download-py-LC145\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>failures</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L146\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;146\&quot;></td>\n          <td id=\&quot;file-download-py-LC146\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L147\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;147\&quot;></td>\n          <td id=\&quot;file-download-py-LC147\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> <span class=pl-s1>result</span> <span class=pl-c1>in</span> <span class=pl-s1>download_file</span>.<span class=pl-c1>starmap</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L148\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;148\&quot;></td>\n          <td id=\&quot;file-download-py-LC148\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>inputs</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L149\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;149\&quot;></td>\n          <td id=\&quot;file-download-py-LC149\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>return_exceptions</span><span class=pl-c1>=</span><span class=pl-c1>True</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L150\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;150\&quot;></td>\n          <td id=\&quot;file-download-py-LC150\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>wrap_returned_exceptions</span><span class=pl-c1>=</span><span class=pl-c1>False</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L151\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;151\&quot;></td>\n          <td id=\&quot;file-download-py-LC151\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>order_outputs</span><span class=pl-c1>=</span><span class=pl-c1>False</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L152\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;152\&quot;></td>\n          <td id=\&quot;file-download-py-LC152\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    ):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L153\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;153\&quot;></td>\n          <td id=\&quot;file-download-py-LC153\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>if</span> <span class=pl-en>isinstance</span>(<span class=pl-s1>result</span>, <span class=pl-v>Exception</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L154\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;154\&quot;></td>\n          <td id=\&quot;file-download-py-LC154\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>failures</span>.<span class=pl-c1>append</span>(<span class=pl-s1>result</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L155\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;155\&quot;></td>\n          <td id=\&quot;file-download-py-LC155\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>else</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L156\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;156\&quot;></td>\n          <td id=\&quot;file-download-py-LC156\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>_</span>, <span class=pl-s1>_</span>, <span class=pl-s1>sz</span> <span class=pl-c1>=</span> <span class=pl-s1>result</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L157\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;157\&quot;></td>\n          <td id=\&quot;file-download-py-LC157\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>total_size</span> <span class=pl-c1>+=</span> <span class=pl-s1>sz</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L158\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;158\&quot;></td>\n          <td id=\&quot;file-download-py-LC158\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>ok</span> <span class=pl-c1>+=</span> <span class=pl-c1>1</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L159\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;159\&quot;></td>\n          <td id=\&quot;file-download-py-LC159\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L160\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;160\&quot;></td>\n          <td id=\&quot;file-download-py-LC160\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>elapsed</span> <span class=pl-c1>=</span> <span class=pl-s1>time</span>.<span class=pl-c1>time</span>() <span class=pl-c1>-</span> <span class=pl-s1>t0</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L161\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;161\&quot;></td>\n          <td id=\&quot;file-download-py-LC161\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>total_gb</span> <span class=pl-c1>=</span> <span class=pl-s1>total_size</span> <span class=pl-c1>/</span> (<span class=pl-c1>1024</span><span class=pl-c1>**</span><span class=pl-c1>3</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L162\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;162\&quot;></td>\n          <td id=\&quot;file-download-py-LC162\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>agg_gbps</span> <span class=pl-c1>=</span> (<span class=pl-s1>total_gb</span> <span class=pl-c1>/</span> <span class=pl-s1>elapsed</span>) <span class=pl-k>if</span> <span class=pl-s1>elapsed</span> <span class=pl-c1>&amp;gt;</span> <span class=pl-c1>0</span> <span class=pl-k>else</span> <span class=pl-c1>0.0</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L163\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;163\&quot;></td>\n          <td id=\&quot;file-download-py-LC163\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L164\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;164\&quot;></td>\n          <td id=\&quot;file-download-py-LC164\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s>f&amp;quot;Done: <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>ok</span><span class=pl-kos>}</span></span>/<span class=pl-s1><span class=pl-kos>{</span><span class=pl-en>len</span>(<span class=pl-s1>inputs</span>)<span class=pl-kos>}</span></span> files in <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>elapsed</span>:.1f<span class=pl-kos>}</span></span>s &#8212; <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>total_gb</span>:.2f<span class=pl-kos>}</span></span> GB total, avg <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>agg_gbps</span>:.2f<span class=pl-kos>}</span></span> GB/s&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L165\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;165\&quot;></td>\n          <td id=\&quot;file-download-py-LC165\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    )</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L166\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;166\&quot;></td>\n          <td id=\&quot;file-download-py-LC166\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L167\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;167\&quot;></td>\n          <td id=\&quot;file-download-py-LC167\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>if</span> <span class=pl-s1>failures</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L168\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;168\&quot;></td>\n          <td id=\&quot;file-download-py-LC168\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-en>print</span>(<span class=pl-s>f&amp;quot;Encountered <span class=pl-s1><span class=pl-kos>{</span><span class=pl-en>len</span>(<span class=pl-s1>failures</span>)<span class=pl-kos>}</span></span> failures (Modal handled retries): &amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L169\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;169\&quot;></td>\n          <td id=\&quot;file-download-py-LC169\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>f</span> <span class=pl-c1>in</span> <span class=pl-s1>failures</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L170\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;170\&quot;></td>\n          <td id=\&quot;file-download-py-LC170\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-en>print</span>(<span class=pl-s>f&amp;quot;[FAIL] <span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>f</span>!s<span class=pl-kos>}</span></span>&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L171\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;171\&quot;></td>\n          <td id=\&quot;file-download-py-LC171\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L172\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;172\&quot;></td>\n          <td id=\&quot;file-download-py-LC172\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>gharchive</span>.<span class=pl-c1>commit</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L173\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;173\&quot;></td>\n          <td id=\&quot;file-download-py-LC173\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L174\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;174\&quot;></td>\n          <td id=\&quot;file-download-py-LC174\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L175\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;175\&quot;></td>\n          <td id=\&quot;file-download-py-LC175\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>app</span>.<span class=pl-c1>local_entrypoint</span>()</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L176\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;176\&quot;></td>\n          <td id=\&quot;file-download-py-LC176\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>main</span>():</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-download-py-L177\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;177\&quot;></td>\n          <td id=\&quot;file-download-py-LC177\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>download_range</span>.<span class=pl-c1>remote</span>(<span class=pl-en>date</span>(<span class=pl-c1>2020</span>, <span class=pl-c1>1</span>, <span class=pl-c1>1</span>))</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/patrickdevivo/9da8add9baf7e1c41be643d9381783be/raw/554450d524252e6e59189f0a7b1c9310b3e98a94/download.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/patrickdevivo/9da8add9baf7e1c41be643d9381783be#file-download-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          download.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-59543e005c9c.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-59543e005c9c.css"><div id="gist140495505" class="gist">
    <div class="gist-file" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-download-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  " style="overflow:auto">

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip="" data-tagsearch-path="download.py">
        <tbody><tr>
          <td id="file-download-py-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-download-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-s1">modal</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-download-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-k">from</span> <span class="pl-s1">datetime</span> <span class="pl-k">import</span> <span class="pl-s1">date</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-download-py-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-k">from</span> .<span class="pl-s1">app</span> <span class="pl-k">import</span> <span class="pl-s1">app</span>, <span class="pl-s1">gharchive</span>, <span class="pl-c1">GHARCHIVE_DATA_PATH</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-download-py-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-download-py-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-download-py-LC6" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-c1">function</span>(</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-download-py-LC7" class="blob-code blob-code-inner js-file-line"><span class="pl-en">    <span class="pl-s1">volumes</span><span class="pl-c1">=</span>{<span class="pl-c1">GHARCHIVE_DATA_PATH</span>: <span class="pl-s1">gharchive</span>},</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-download-py-LC8" class="blob-code blob-code-inner js-file-line"><span class="pl-en">    <span class="pl-s1">timeout</span><span class="pl-c1">=</span><span class="pl-c1">36000</span>,</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-download-py-LC9" class="blob-code blob-code-inner js-file-line"><span class="pl-en">    <span class="pl-s1">retries</span><span class="pl-c1">=</span><span class="pl-s1">modal</span>.<span class="pl-c1">Retries</span>(</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-download-py-LC10" class="blob-code blob-code-inner js-file-line"><span class="pl-en">        <span class="pl-s1">max_retries</span><span class="pl-c1">=</span><span class="pl-c1">8</span>,</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-download-py-LC11" class="blob-code blob-code-inner js-file-line"><span class="pl-en">        <span class="pl-s1">backoff_coefficient</span><span class="pl-c1">=</span><span class="pl-c1">2</span>,</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-download-py-LC12" class="blob-code blob-code-inner js-file-line"><span class="pl-en">        <span class="pl-s1">initial_delay</span><span class="pl-c1">=</span><span class="pl-c1">1</span>,</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-download-py-LC13" class="blob-code blob-code-inner js-file-line"><span class="pl-en">        <span class="pl-s1">max_delay</span><span class="pl-c1">=</span><span class="pl-c1">30</span>,</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-download-py-LC14" class="blob-code blob-code-inner js-file-line"><span class="pl-en">    ),</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-download-py-LC15" class="blob-code blob-code-inner js-file-line"><span class="pl-en">    <span class="pl-s1">ephemeral_disk</span><span class="pl-c1">=</span><span class="pl-c1">800</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span>,</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-download-py-LC16" class="blob-code blob-code-inner js-file-line"><span class="pl-en">)</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-download-py-LC17" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">modal</span>.<span class="pl-c1">concurrent</span>(<span class="pl-s1">max_inputs</span><span class="pl-c1">=</span><span class="pl-c1">12</span>)</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-download-py-LC18" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">download_file</span>(<span class="pl-s1">year</span>: <span class="pl-smi">int</span>, <span class="pl-s1">month</span>: <span class="pl-smi">int</span>, <span class="pl-s1">day</span>: <span class="pl-smi">int</span>, <span class="pl-s1">hour</span>: <span class="pl-smi">int</span>) <span class="pl-c1">-&gt;</span> <span class="pl-s1">tuple</span>[<span class="pl-smi">str</span>, <span class="pl-smi">float</span>, <span class="pl-smi">int</span>]:</td>
        </tr>
        <tr>
          <td id="file-download-py-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-download-py-LC19" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">import</span> <span class="pl-s1">os</span>, <span class="pl-s1">time</span>, <span class="pl-s1">tempfile</span>, <span class="pl-s1">shutil</span>, <span class="pl-s1">pycurl</span>, <span class="pl-s1">random</span>, <span class="pl-s1">io</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-download-py-LC20" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-download-py-LC21" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Tiny jitter to avoid synchronized bursts (helps with WAF/rate shaping)</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-download-py-LC22" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">time</span>.<span class="pl-c1">sleep</span>(<span class="pl-s1">random</span>.<span class="pl-c1">uniform</span>(<span class="pl-c1">0.01</span>, <span class="pl-c1">0.05</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-download-py-LC23" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-download-py-LC24" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># URLs &amp; paths</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-download-py-LC25" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">f"https://data.gharchive.org/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">year</span><span class="pl-kos">}</span></span>-<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">month</span>:02d<span class="pl-kos">}</span></span>-<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">day</span>:02d<span class="pl-kos">}</span></span>-<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">hour</span><span class="pl-kos">}</span></span>.json.gz"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-download-py-LC26" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">vol_path</span> <span class="pl-c1">=</span> <span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-c1">GHARCHIVE_DATA_PATH</span><span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">year</span><span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">month</span>:02d<span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">day</span>:02d<span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">hour</span><span class="pl-kos">}</span></span>.json.gz"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-download-py-LC27" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-download-py-LC28" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Stage to a temporary file in /tmp which is on the attached SSD, as recommended in Modal docs: https://modal.com/docs/guide/dataset-ingestion</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-download-py-LC29" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">tmp_dir</span> <span class="pl-c1">=</span> <span class="pl-s">f"/tmp/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">year</span><span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">month</span>:02d<span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">day</span>:02d<span class="pl-kos">}</span></span>"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-download-py-LC30" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">os</span>.<span class="pl-c1">makedirs</span>(<span class="pl-s1">tmp_dir</span>, <span class="pl-s1">exist_ok</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-download-py-LC31" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">fd</span>, <span class="pl-s1">tmp_path</span> <span class="pl-c1">=</span> <span class="pl-s1">tempfile</span>.<span class="pl-c1">mkstemp</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-download-py-LC32" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">dir</span><span class="pl-c1">=</span><span class="pl-s1">tmp_dir</span>, <span class="pl-s1">prefix</span><span class="pl-c1">=</span><span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">year</span><span class="pl-kos">}</span></span>-<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">month</span>:02d<span class="pl-kos">}</span></span>-<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">day</span>:02d<span class="pl-kos">}</span></span>-<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">hour</span><span class="pl-kos">}</span></span>.json.gz."</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-download-py-LC33" class="blob-code blob-code-inner js-file-line">    )</td>
        </tr>
        <tr>
          <td id="file-download-py-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-download-py-LC34" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">os</span>.<span class="pl-c1">close</span>(<span class="pl-s1">fd</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-download-py-LC35" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-download-py-LC36" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Configure curl</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-download-py-LC37" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span> <span class="pl-c1">=</span> <span class="pl-s1">pycurl</span>.<span class="pl-c1">Curl</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-download-py-LC38" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">URL</span>, <span class="pl-s1">url</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-download-py-LC39" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">FOLLOWLOCATION</span>, <span class="pl-c1">1</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-download-py-LC40" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">HTTP_VERSION</span>, <span class="pl-s1">pycurl</span>.<span class="pl-c1">CURL_HTTP_VERSION_2TLS</span>)  <span class="pl-c"># allow HTTP/2</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L41" class="blob-num js-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-download-py-LC41" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L42" class="blob-num js-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-download-py-LC42" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">c</span>.<span class="pl-c1">USERAGENT</span>, <span class="pl-s">"gharchive-downloader/1.0 (contact: patrick.devivo@gmail.com)"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L43" class="blob-num js-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-download-py-LC43" class="blob-code blob-code-inner js-file-line">    )  <span class="pl-c"># may help with rate limiting</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L44" class="blob-num js-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-download-py-LC44" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">NOSIGNAL</span>, <span class="pl-c1">1</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L45" class="blob-num js-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-download-py-LC45" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">CONNECTTIMEOUT</span>, <span class="pl-c1">10</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L46" class="blob-num js-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-download-py-LC46" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L47" class="blob-num js-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-download-py-LC47" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">c</span>.<span class="pl-c1">TIMEOUT</span>, <span class="pl-c1">60</span> <span class="pl-c1">*</span> <span class="pl-c1">5</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L48" class="blob-num js-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-download-py-LC48" class="blob-code blob-code-inner js-file-line">    )  <span class="pl-c"># total timeout - most downloads should occur within this</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L49" class="blob-num js-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-download-py-LC49" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">LOW_SPEED_LIMIT</span>, <span class="pl-c1">20_000</span>)  <span class="pl-c"># bytes/sec</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L50" class="blob-num js-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-download-py-LC50" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">LOW_SPEED_TIME</span>, <span class="pl-c1">20</span>)  <span class="pl-c"># if below limit for 20s -&gt; timeout</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L51" class="blob-num js-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-download-py-LC51" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L52" class="blob-num js-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-download-py-LC52" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">hdr_buf</span> <span class="pl-c1">=</span> <span class="pl-s1">io</span>.<span class="pl-c1">BytesIO</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L53" class="blob-num js-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-download-py-LC53" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">HEADERFUNCTION</span>, <span class="pl-s1">hdr_buf</span>.<span class="pl-c1">write</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L54" class="blob-num js-line-number js-blob-rnum" data-line-number="54"></td>
          <td id="file-download-py-LC54" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L55" class="blob-num js-line-number js-blob-rnum" data-line-number="55"></td>
          <td id="file-download-py-LC55" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Execute the download &#8594; /tmp, then fsync for durability</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L56" class="blob-num js-line-number js-blob-rnum" data-line-number="56"></td>
          <td id="file-download-py-LC56" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">with</span> <span class="pl-en">open</span>(<span class="pl-s1">tmp_path</span>, <span class="pl-s">"wb"</span>, <span class="pl-s1">buffering</span><span class="pl-c1">=</span><span class="pl-c1">1024</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span>) <span class="pl-k">as</span> <span class="pl-s1">f</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L57" class="blob-num js-line-number js-blob-rnum" data-line-number="57"></td>
          <td id="file-download-py-LC57" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">c</span>.<span class="pl-c1">setopt</span>(<span class="pl-s1">c</span>.<span class="pl-c1">WRITEDATA</span>, <span class="pl-s1">f</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L58" class="blob-num js-line-number js-blob-rnum" data-line-number="58"></td>
          <td id="file-download-py-LC58" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">c</span>.<span class="pl-c1">perform</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L59" class="blob-num js-line-number js-blob-rnum" data-line-number="59"></td>
          <td id="file-download-py-LC59" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">f</span>.<span class="pl-c1">flush</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L60" class="blob-num js-line-number js-blob-rnum" data-line-number="60"></td>
          <td id="file-download-py-LC60" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">os</span>.<span class="pl-c1">fsync</span>(<span class="pl-s1">f</span>.<span class="pl-c1">fileno</span>())</td>
        </tr>
        <tr>
          <td id="file-download-py-L61" class="blob-num js-line-number js-blob-rnum" data-line-number="61"></td>
          <td id="file-download-py-LC61" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L62" class="blob-num js-line-number js-blob-rnum" data-line-number="62"></td>
          <td id="file-download-py-LC62" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Telemetry from curl</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L63" class="blob-num js-line-number js-blob-rnum" data-line-number="63"></td>
          <td id="file-download-py-LC63" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">status</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-s1">c</span>.<span class="pl-c1">getinfo</span>(<span class="pl-s1">pycurl</span>.<span class="pl-c1">RESPONSE_CODE</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L64" class="blob-num js-line-number js-blob-rnum" data-line-number="64"></td>
          <td id="file-download-py-LC64" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">size_b</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-s1">c</span>.<span class="pl-c1">getinfo</span>(<span class="pl-s1">pycurl</span>.<span class="pl-c1">SIZE_DOWNLOAD</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L65" class="blob-num js-line-number js-blob-rnum" data-line-number="65"></td>
          <td id="file-download-py-LC65" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">total_s</span> <span class="pl-c1">=</span> <span class="pl-en">float</span>(<span class="pl-s1">c</span>.<span class="pl-c1">getinfo</span>(<span class="pl-s1">pycurl</span>.<span class="pl-c1">TOTAL_TIME</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L66" class="blob-num js-line-number js-blob-rnum" data-line-number="66"></td>
          <td id="file-download-py-LC66" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">mbps</span> <span class="pl-c1">=</span> <span class="pl-en">float</span>(<span class="pl-s1">c</span>.<span class="pl-c1">getinfo</span>(<span class="pl-s1">pycurl</span>.<span class="pl-c1">SPEED_DOWNLOAD</span>)) <span class="pl-c1">/</span> (<span class="pl-c1">1024</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L67" class="blob-num js-line-number js-blob-rnum" data-line-number="67"></td>
          <td id="file-download-py-LC67" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">ttfb_s</span> <span class="pl-c1">=</span> <span class="pl-en">float</span>(<span class="pl-s1">c</span>.<span class="pl-c1">getinfo</span>(<span class="pl-s1">pycurl</span>.<span class="pl-c1">STARTTRANSFER_TIME</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L68" class="blob-num js-line-number js-blob-rnum" data-line-number="68"></td>
          <td id="file-download-py-LC68" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">headers_s</span> <span class="pl-c1">=</span> <span class="pl-s1">hdr_buf</span>.<span class="pl-c1">getvalue</span>().<span class="pl-c1">decode</span>(<span class="pl-s">"latin1"</span>, <span class="pl-s1">errors</span><span class="pl-c1">=</span><span class="pl-s">"replace"</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L69" class="blob-num js-line-number js-blob-rnum" data-line-number="69"></td>
          <td id="file-download-py-LC69" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">c</span>.<span class="pl-c1">close</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L70" class="blob-num js-line-number js-blob-rnum" data-line-number="70"></td>
          <td id="file-download-py-LC70" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L71" class="blob-num js-line-number js-blob-rnum" data-line-number="71"></td>
          <td id="file-download-py-LC71" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Handle non-200s</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L72" class="blob-num js-line-number js-blob-rnum" data-line-number="72"></td>
          <td id="file-download-py-LC72" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">if</span> <span class="pl-s1">status</span> <span class="pl-c1">!=</span> <span class="pl-c1">200</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L73" class="blob-num js-line-number js-blob-rnum" data-line-number="73"></td>
          <td id="file-download-py-LC73" class="blob-code blob-code-inner js-file-line">        <span class="pl-c"># Clean partial temp file</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L74" class="blob-num js-line-number js-blob-rnum" data-line-number="74"></td>
          <td id="file-download-py-LC74" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">try</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L75" class="blob-num js-line-number js-blob-rnum" data-line-number="75"></td>
          <td id="file-download-py-LC75" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">os</span>.<span class="pl-c1">remove</span>(<span class="pl-s1">tmp_path</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L76" class="blob-num js-line-number js-blob-rnum" data-line-number="76"></td>
          <td id="file-download-py-LC76" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">except</span> <span class="pl-v">FileNotFoundError</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L77" class="blob-num js-line-number js-blob-rnum" data-line-number="77"></td>
          <td id="file-download-py-LC77" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">pass</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L78" class="blob-num js-line-number js-blob-rnum" data-line-number="78"></td>
          <td id="file-download-py-LC78" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L79" class="blob-num js-line-number js-blob-rnum" data-line-number="79"></td>
          <td id="file-download-py-LC79" class="blob-code blob-code-inner js-file-line">        <span class="pl-c"># Sometimes there's missing hours, but raise on 404 anyways to retry and report</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L80" class="blob-num js-line-number js-blob-rnum" data-line-number="80"></td>
          <td id="file-download-py-LC80" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">if</span> <span class="pl-s1">status</span> <span class="pl-c1">==</span> <span class="pl-c1">404</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L81" class="blob-num js-line-number js-blob-rnum" data-line-number="81"></td>
          <td id="file-download-py-LC81" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">time</span>.<span class="pl-c1">sleep</span>(<span class="pl-s1">random</span>.<span class="pl-c1">uniform</span>(<span class="pl-c1">0.5</span>, <span class="pl-c1">2.0</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L82" class="blob-num js-line-number js-blob-rnum" data-line-number="82"></td>
          <td id="file-download-py-LC82" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">raise</span> <span class="pl-en">RuntimeError</span>(<span class="pl-s">f"HTTP 404 for <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">url</span><span class="pl-kos">}</span></span> (retryable)"</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L83" class="blob-num js-line-number js-blob-rnum" data-line-number="83"></td>
          <td id="file-download-py-LC83" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L84" class="blob-num js-line-number js-blob-rnum" data-line-number="84"></td>
          <td id="file-download-py-LC84" class="blob-code blob-code-inner js-file-line">        <span class="pl-c"># Transient / retry-worthy codes &#8594; raise so Modal retries</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L85" class="blob-num js-line-number js-blob-rnum" data-line-number="85"></td>
          <td id="file-download-py-LC85" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">retry_statuses</span> <span class="pl-c1">=</span> {<span class="pl-c1">403</span>, <span class="pl-c1">429</span>, <span class="pl-c1">500</span>, <span class="pl-c1">502</span>, <span class="pl-c1">503</span>, <span class="pl-c1">504</span>}</td>
        </tr>
        <tr>
          <td id="file-download-py-L86" class="blob-num js-line-number js-blob-rnum" data-line-number="86"></td>
          <td id="file-download-py-LC86" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">if</span> <span class="pl-s1">status</span> <span class="pl-c1">in</span> <span class="pl-s1">retry_statuses</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L87" class="blob-num js-line-number js-blob-rnum" data-line-number="87"></td>
          <td id="file-download-py-LC87" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">first_hdr</span> <span class="pl-c1">=</span> <span class="pl-s1">headers_s</span>.<span class="pl-c1">splitlines</span>()[<span class="pl-c1">0</span>] <span class="pl-k">if</span> <span class="pl-s1">headers_s</span> <span class="pl-k">else</span> <span class="pl-s">f"HTTP <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">status</span><span class="pl-kos">}</span></span>"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L88" class="blob-num js-line-number js-blob-rnum" data-line-number="88"></td>
          <td id="file-download-py-LC88" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">raise</span> <span class="pl-en">RuntimeError</span>(<span class="pl-s">f"HTTP <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">status</span><span class="pl-kos">}</span></span> for <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">url</span><span class="pl-kos">}</span></span> (<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">first_hdr</span><span class="pl-kos">}</span></span>)"</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L89" class="blob-num js-line-number js-blob-rnum" data-line-number="89"></td>
          <td id="file-download-py-LC89" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L90" class="blob-num js-line-number js-blob-rnum" data-line-number="90"></td>
          <td id="file-download-py-LC90" class="blob-code blob-code-inner js-file-line">        <span class="pl-c"># Other client errors: surface as failures (Modal will retry)</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L91" class="blob-num js-line-number js-blob-rnum" data-line-number="91"></td>
          <td id="file-download-py-LC91" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">raise</span> <span class="pl-en">RuntimeError</span>(<span class="pl-s">f"HTTP <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">status</span><span class="pl-kos">}</span></span> for <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">url</span><span class="pl-kos">}</span></span>"</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L92" class="blob-num js-line-number js-blob-rnum" data-line-number="92"></td>
          <td id="file-download-py-LC92" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L93" class="blob-num js-line-number js-blob-rnum" data-line-number="93"></td>
          <td id="file-download-py-LC93" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Publish into the Modal volume atomically</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L94" class="blob-num js-line-number js-blob-rnum" data-line-number="94"></td>
          <td id="file-download-py-LC94" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">vol_dir</span> <span class="pl-c1">=</span> <span class="pl-s1">os</span>.<span class="pl-c1">path</span>.<span class="pl-c1">dirname</span>(<span class="pl-s1">vol_path</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L95" class="blob-num js-line-number js-blob-rnum" data-line-number="95"></td>
          <td id="file-download-py-LC95" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">os</span>.<span class="pl-c1">makedirs</span>(<span class="pl-s1">vol_dir</span>, <span class="pl-s1">exist_ok</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L96" class="blob-num js-line-number js-blob-rnum" data-line-number="96"></td>
          <td id="file-download-py-LC96" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">tmp_dest</span> <span class="pl-c1">=</span> <span class="pl-s1">vol_path</span> <span class="pl-c1">+</span> <span class="pl-s">".part"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L97" class="blob-num js-line-number js-blob-rnum" data-line-number="97"></td>
          <td id="file-download-py-LC97" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">with</span> (</td>
        </tr>
        <tr>
          <td id="file-download-py-L98" class="blob-num js-line-number js-blob-rnum" data-line-number="98"></td>
          <td id="file-download-py-LC98" class="blob-code blob-code-inner js-file-line">        <span class="pl-en">open</span>(<span class="pl-s1">tmp_path</span>, <span class="pl-s">"rb"</span>, <span class="pl-s1">buffering</span><span class="pl-c1">=</span><span class="pl-c1">1024</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span>) <span class="pl-k">as</span> <span class="pl-s1">rf</span>,</td>
        </tr>
        <tr>
          <td id="file-download-py-L99" class="blob-num js-line-number js-blob-rnum" data-line-number="99"></td>
          <td id="file-download-py-LC99" class="blob-code blob-code-inner js-file-line">        <span class="pl-en">open</span>(<span class="pl-s1">tmp_dest</span>, <span class="pl-s">"wb"</span>, <span class="pl-s1">buffering</span><span class="pl-c1">=</span><span class="pl-c1">1024</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span>) <span class="pl-k">as</span> <span class="pl-s1">wf</span>,</td>
        </tr>
        <tr>
          <td id="file-download-py-L100" class="blob-num js-line-number js-blob-rnum" data-line-number="100"></td>
          <td id="file-download-py-LC100" class="blob-code blob-code-inner js-file-line">    ):</td>
        </tr>
        <tr>
          <td id="file-download-py-L101" class="blob-num js-line-number js-blob-rnum" data-line-number="101"></td>
          <td id="file-download-py-LC101" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">shutil</span>.<span class="pl-c1">copyfileobj</span>(<span class="pl-s1">rf</span>, <span class="pl-s1">wf</span>, <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-c1">8</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span> <span class="pl-c1">*</span> <span class="pl-c1">1024</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L102" class="blob-num js-line-number js-blob-rnum" data-line-number="102"></td>
          <td id="file-download-py-LC102" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">wf</span>.<span class="pl-c1">flush</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L103" class="blob-num js-line-number js-blob-rnum" data-line-number="103"></td>
          <td id="file-download-py-LC103" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">os</span>.<span class="pl-c1">fsync</span>(<span class="pl-s1">wf</span>.<span class="pl-c1">fileno</span>())</td>
        </tr>
        <tr>
          <td id="file-download-py-L104" class="blob-num js-line-number js-blob-rnum" data-line-number="104"></td>
          <td id="file-download-py-LC104" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">os</span>.<span class="pl-c1">replace</span>(<span class="pl-s1">tmp_dest</span>, <span class="pl-s1">vol_path</span>)  <span class="pl-c"># atomic within the same FS</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L105" class="blob-num js-line-number js-blob-rnum" data-line-number="105"></td>
          <td id="file-download-py-LC105" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">dfd</span> <span class="pl-c1">=</span> <span class="pl-s1">os</span>.<span class="pl-c1">open</span>(<span class="pl-s1">vol_dir</span>, <span class="pl-s1">os</span>.<span class="pl-c1">O_DIRECTORY</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L106" class="blob-num js-line-number js-blob-rnum" data-line-number="106"></td>
          <td id="file-download-py-LC106" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">try</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L107" class="blob-num js-line-number js-blob-rnum" data-line-number="107"></td>
          <td id="file-download-py-LC107" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">os</span>.<span class="pl-c1">fsync</span>(<span class="pl-s1">dfd</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L108" class="blob-num js-line-number js-blob-rnum" data-line-number="108"></td>
          <td id="file-download-py-LC108" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">finally</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L109" class="blob-num js-line-number js-blob-rnum" data-line-number="109"></td>
          <td id="file-download-py-LC109" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">os</span>.<span class="pl-c1">close</span>(<span class="pl-s1">dfd</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L110" class="blob-num js-line-number js-blob-rnum" data-line-number="110"></td>
          <td id="file-download-py-LC110" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L111" class="blob-num js-line-number js-blob-rnum" data-line-number="111"></td>
          <td id="file-download-py-LC111" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Clean local temp</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L112" class="blob-num js-line-number js-blob-rnum" data-line-number="112"></td>
          <td id="file-download-py-LC112" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">try</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L113" class="blob-num js-line-number js-blob-rnum" data-line-number="113"></td>
          <td id="file-download-py-LC113" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">os</span>.<span class="pl-c1">remove</span>(<span class="pl-s1">tmp_path</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L114" class="blob-num js-line-number js-blob-rnum" data-line-number="114"></td>
          <td id="file-download-py-LC114" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">except</span> <span class="pl-v">FileNotFoundError</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L115" class="blob-num js-line-number js-blob-rnum" data-line-number="115"></td>
          <td id="file-download-py-LC115" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">pass</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L116" class="blob-num js-line-number js-blob-rnum" data-line-number="116"></td>
          <td id="file-download-py-LC116" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L117" class="blob-num js-line-number js-blob-rnum" data-line-number="117"></td>
          <td id="file-download-py-LC117" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L118" class="blob-num js-line-number js-blob-rnum" data-line-number="118"></td>
          <td id="file-download-py-LC118" class="blob-code blob-code-inner js-file-line">        <span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">os</span>.<span class="pl-c1">path</span>.<span class="pl-c1">basename</span>(<span class="pl-s1">vol_path</span>)<span class="pl-kos">}</span></span> &#8212; <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">size_b</span> <span class="pl-c1">/</span> <span class="pl-c1">1_048_576</span>:.1f<span class="pl-kos">}</span></span> MB "</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L119" class="blob-num js-line-number js-blob-rnum" data-line-number="119"></td>
          <td id="file-download-py-LC119" class="blob-code blob-code-inner js-file-line">        <span class="pl-s">f"in <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">total_s</span>:.2f<span class="pl-kos">}</span></span>s @ <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">mbps</span>:.2f<span class="pl-kos">}</span></span> MB/s (TTFB <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">ttfb_s</span>:.2f<span class="pl-kos">}</span></span>s) &#8594; <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">vol_path</span><span class="pl-kos">}</span></span>"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L120" class="blob-num js-line-number js-blob-rnum" data-line-number="120"></td>
          <td id="file-download-py-LC120" class="blob-code blob-code-inner js-file-line">    )</td>
        </tr>
        <tr>
          <td id="file-download-py-L121" class="blob-num js-line-number js-blob-rnum" data-line-number="121"></td>
          <td id="file-download-py-LC121" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L122" class="blob-num js-line-number js-blob-rnum" data-line-number="122"></td>
          <td id="file-download-py-LC122" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">vol_path</span>, <span class="pl-s1">total_s</span>, <span class="pl-s1">size_b</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L123" class="blob-num js-line-number js-blob-rnum" data-line-number="123"></td>
          <td id="file-download-py-LC123" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L124" class="blob-num js-line-number js-blob-rnum" data-line-number="124"></td>
          <td id="file-download-py-LC124" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L125" class="blob-num js-line-number js-blob-rnum" data-line-number="125"></td>
          <td id="file-download-py-LC125" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-c1">function</span>(<span class="pl-s1">timeout</span><span class="pl-c1">=</span><span class="pl-c1">36000</span>, <span class="pl-s1">volumes</span><span class="pl-c1">=</span>{<span class="pl-c1">GHARCHIVE_DATA_PATH</span>: <span class="pl-s1">gharchive</span>})</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L126" class="blob-num js-line-number js-blob-rnum" data-line-number="126"></td>
          <td id="file-download-py-LC126" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">download_range</span>(<span class="pl-s1">start</span>: <span class="pl-smi">date</span>, <span class="pl-s1">end</span>: <span class="pl-smi">date</span> <span class="pl-c1">=</span> <span class="pl-s1">date</span>.<span class="pl-c1">today</span>()):</td>
        </tr>
        <tr>
          <td id="file-download-py-L127" class="blob-num js-line-number js-blob-rnum" data-line-number="127"></td>
          <td id="file-download-py-LC127" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">from</span> <span class="pl-s1">datetime</span> <span class="pl-k">import</span> <span class="pl-s1">timedelta</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L128" class="blob-num js-line-number js-blob-rnum" data-line-number="128"></td>
          <td id="file-download-py-LC128" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">import</span> <span class="pl-s1">time</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L129" class="blob-num js-line-number js-blob-rnum" data-line-number="129"></td>
          <td id="file-download-py-LC129" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L130" class="blob-num js-line-number js-blob-rnum" data-line-number="130"></td>
          <td id="file-download-py-LC130" class="blob-code blob-code-inner js-file-line">    <span class="pl-c"># Build hour-level inputs</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L131" class="blob-num js-line-number js-blob-rnum" data-line-number="131"></td>
          <td id="file-download-py-LC131" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">inputs</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-download-py-L132" class="blob-num js-line-number js-blob-rnum" data-line-number="132"></td>
          <td id="file-download-py-LC132" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">delta</span> <span class="pl-c1">=</span> <span class="pl-s1">end</span> <span class="pl-c1">-</span> <span class="pl-s1">start</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L133" class="blob-num js-line-number js-blob-rnum" data-line-number="133"></td>
          <td id="file-download-py-LC133" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> <span class="pl-s1">d</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">delta</span>.<span class="pl-c1">days</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>):</td>
        </tr>
        <tr>
          <td id="file-download-py-L134" class="blob-num js-line-number js-blob-rnum" data-line-number="134"></td>
          <td id="file-download-py-LC134" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">day</span> <span class="pl-c1">=</span> <span class="pl-s1">start</span> <span class="pl-c1">+</span> <span class="pl-en">timedelta</span>(<span class="pl-s1">days</span><span class="pl-c1">=</span><span class="pl-s1">d</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L135" class="blob-num js-line-number js-blob-rnum" data-line-number="135"></td>
          <td id="file-download-py-LC135" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">hour</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">24</span>):</td>
        </tr>
        <tr>
          <td id="file-download-py-L136" class="blob-num js-line-number js-blob-rnum" data-line-number="136"></td>
          <td id="file-download-py-LC136" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">inputs</span>.<span class="pl-c1">append</span>((<span class="pl-s1">day</span>.<span class="pl-c1">year</span>, <span class="pl-s1">day</span>.<span class="pl-c1">month</span>, <span class="pl-s1">day</span>.<span class="pl-c1">day</span>, <span class="pl-s1">hour</span>))</td>
        </tr>
        <tr>
          <td id="file-download-py-L137" class="blob-num js-line-number js-blob-rnum" data-line-number="137"></td>
          <td id="file-download-py-LC137" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L138" class="blob-num js-line-number js-blob-rnum" data-line-number="138"></td>
          <td id="file-download-py-LC138" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L139" class="blob-num js-line-number js-blob-rnum" data-line-number="139"></td>
          <td id="file-download-py-LC139" class="blob-code blob-code-inner js-file-line">        <span class="pl-s">f"Downloading events from <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">start</span><span class="pl-kos">}</span></span> to <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">end</span><span class="pl-kos">}</span></span> &#8212; <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-en">len</span>(<span class="pl-s1">inputs</span>)<span class="pl-kos">}</span></span> files over <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">delta</span>.<span class="pl-c1">days</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span><span class="pl-kos">}</span></span> days"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L140" class="blob-num js-line-number js-blob-rnum" data-line-number="140"></td>
          <td id="file-download-py-LC140" class="blob-code blob-code-inner js-file-line">    )</td>
        </tr>
        <tr>
          <td id="file-download-py-L141" class="blob-num js-line-number js-blob-rnum" data-line-number="141"></td>
          <td id="file-download-py-LC141" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L142" class="blob-num js-line-number js-blob-rnum" data-line-number="142"></td>
          <td id="file-download-py-LC142" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">t0</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-c1">time</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L143" class="blob-num js-line-number js-blob-rnum" data-line-number="143"></td>
          <td id="file-download-py-LC143" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">total_size</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L144" class="blob-num js-line-number js-blob-rnum" data-line-number="144"></td>
          <td id="file-download-py-LC144" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">ok</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L145" class="blob-num js-line-number js-blob-rnum" data-line-number="145"></td>
          <td id="file-download-py-LC145" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">failures</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-download-py-L146" class="blob-num js-line-number js-blob-rnum" data-line-number="146"></td>
          <td id="file-download-py-LC146" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L147" class="blob-num js-line-number js-blob-rnum" data-line-number="147"></td>
          <td id="file-download-py-LC147" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> <span class="pl-s1">result</span> <span class="pl-c1">in</span> <span class="pl-s1">download_file</span>.<span class="pl-c1">starmap</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L148" class="blob-num js-line-number js-blob-rnum" data-line-number="148"></td>
          <td id="file-download-py-LC148" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">inputs</span>,</td>
        </tr>
        <tr>
          <td id="file-download-py-L149" class="blob-num js-line-number js-blob-rnum" data-line-number="149"></td>
          <td id="file-download-py-LC149" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">return_exceptions</span><span class="pl-c1">=</span><span class="pl-c1">True</span>,</td>
        </tr>
        <tr>
          <td id="file-download-py-L150" class="blob-num js-line-number js-blob-rnum" data-line-number="150"></td>
          <td id="file-download-py-LC150" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">wrap_returned_exceptions</span><span class="pl-c1">=</span><span class="pl-c1">False</span>,</td>
        </tr>
        <tr>
          <td id="file-download-py-L151" class="blob-num js-line-number js-blob-rnum" data-line-number="151"></td>
          <td id="file-download-py-LC151" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">order_outputs</span><span class="pl-c1">=</span><span class="pl-c1">False</span>,</td>
        </tr>
        <tr>
          <td id="file-download-py-L152" class="blob-num js-line-number js-blob-rnum" data-line-number="152"></td>
          <td id="file-download-py-LC152" class="blob-code blob-code-inner js-file-line">    ):</td>
        </tr>
        <tr>
          <td id="file-download-py-L153" class="blob-num js-line-number js-blob-rnum" data-line-number="153"></td>
          <td id="file-download-py-LC153" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">result</span>, <span class="pl-v">Exception</span>):</td>
        </tr>
        <tr>
          <td id="file-download-py-L154" class="blob-num js-line-number js-blob-rnum" data-line-number="154"></td>
          <td id="file-download-py-LC154" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">failures</span>.<span class="pl-c1">append</span>(<span class="pl-s1">result</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L155" class="blob-num js-line-number js-blob-rnum" data-line-number="155"></td>
          <td id="file-download-py-LC155" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">else</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L156" class="blob-num js-line-number js-blob-rnum" data-line-number="156"></td>
          <td id="file-download-py-LC156" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">_</span>, <span class="pl-s1">_</span>, <span class="pl-s1">sz</span> <span class="pl-c1">=</span> <span class="pl-s1">result</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L157" class="blob-num js-line-number js-blob-rnum" data-line-number="157"></td>
          <td id="file-download-py-LC157" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">total_size</span> <span class="pl-c1">+=</span> <span class="pl-s1">sz</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L158" class="blob-num js-line-number js-blob-rnum" data-line-number="158"></td>
          <td id="file-download-py-LC158" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">ok</span> <span class="pl-c1">+=</span> <span class="pl-c1">1</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L159" class="blob-num js-line-number js-blob-rnum" data-line-number="159"></td>
          <td id="file-download-py-LC159" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L160" class="blob-num js-line-number js-blob-rnum" data-line-number="160"></td>
          <td id="file-download-py-LC160" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">elapsed</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-c1">time</span>() <span class="pl-c1">-</span> <span class="pl-s1">t0</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L161" class="blob-num js-line-number js-blob-rnum" data-line-number="161"></td>
          <td id="file-download-py-LC161" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">total_gb</span> <span class="pl-c1">=</span> <span class="pl-s1">total_size</span> <span class="pl-c1">/</span> (<span class="pl-c1">1024</span><span class="pl-c1">**</span><span class="pl-c1">3</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L162" class="blob-num js-line-number js-blob-rnum" data-line-number="162"></td>
          <td id="file-download-py-LC162" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">agg_gbps</span> <span class="pl-c1">=</span> (<span class="pl-s1">total_gb</span> <span class="pl-c1">/</span> <span class="pl-s1">elapsed</span>) <span class="pl-k">if</span> <span class="pl-s1">elapsed</span> <span class="pl-c1">&gt;</span> <span class="pl-c1">0</span> <span class="pl-k">else</span> <span class="pl-c1">0.0</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L163" class="blob-num js-line-number js-blob-rnum" data-line-number="163"></td>
          <td id="file-download-py-LC163" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(</td>
        </tr>
        <tr>
          <td id="file-download-py-L164" class="blob-num js-line-number js-blob-rnum" data-line-number="164"></td>
          <td id="file-download-py-LC164" class="blob-code blob-code-inner js-file-line">        <span class="pl-s">f"Done: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">ok</span><span class="pl-kos">}</span></span>/<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-en">len</span>(<span class="pl-s1">inputs</span>)<span class="pl-kos">}</span></span> files in <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">elapsed</span>:.1f<span class="pl-kos">}</span></span>s &#8212; <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">total_gb</span>:.2f<span class="pl-kos">}</span></span> GB total, avg <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">agg_gbps</span>:.2f<span class="pl-kos">}</span></span> GB/s"</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L165" class="blob-num js-line-number js-blob-rnum" data-line-number="165"></td>
          <td id="file-download-py-LC165" class="blob-code blob-code-inner js-file-line">    )</td>
        </tr>
        <tr>
          <td id="file-download-py-L166" class="blob-num js-line-number js-blob-rnum" data-line-number="166"></td>
          <td id="file-download-py-LC166" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L167" class="blob-num js-line-number js-blob-rnum" data-line-number="167"></td>
          <td id="file-download-py-LC167" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">if</span> <span class="pl-s1">failures</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L168" class="blob-num js-line-number js-blob-rnum" data-line-number="168"></td>
          <td id="file-download-py-LC168" class="blob-code blob-code-inner js-file-line">        <span class="pl-en">print</span>(<span class="pl-s">f"Encountered <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-en">len</span>(<span class="pl-s1">failures</span>)<span class="pl-kos">}</span></span> failures (Modal handled retries): "</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L169" class="blob-num js-line-number js-blob-rnum" data-line-number="169"></td>
          <td id="file-download-py-LC169" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">f</span> <span class="pl-c1">in</span> <span class="pl-s1">failures</span>:</td>
        </tr>
        <tr>
          <td id="file-download-py-L170" class="blob-num js-line-number js-blob-rnum" data-line-number="170"></td>
          <td id="file-download-py-LC170" class="blob-code blob-code-inner js-file-line">            <span class="pl-en">print</span>(<span class="pl-s">f"[FAIL] <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">f</span>!s<span class="pl-kos">}</span></span>"</span>)</td>
        </tr>
        <tr>
          <td id="file-download-py-L171" class="blob-num js-line-number js-blob-rnum" data-line-number="171"></td>
          <td id="file-download-py-LC171" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L172" class="blob-num js-line-number js-blob-rnum" data-line-number="172"></td>
          <td id="file-download-py-LC172" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">gharchive</span>.<span class="pl-c1">commit</span>()</td>
        </tr>
        <tr>
          <td id="file-download-py-L173" class="blob-num js-line-number js-blob-rnum" data-line-number="173"></td>
          <td id="file-download-py-LC173" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L174" class="blob-num js-line-number js-blob-rnum" data-line-number="174"></td>
          <td id="file-download-py-LC174" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-download-py-L175" class="blob-num js-line-number js-blob-rnum" data-line-number="175"></td>
          <td id="file-download-py-LC175" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-c1">local_entrypoint</span>()</span></td>
        </tr>
        <tr>
          <td id="file-download-py-L176" class="blob-num js-line-number js-blob-rnum" data-line-number="176"></td>
          <td id="file-download-py-LC176" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">main</span>():</td>
        </tr>
        <tr>
          <td id="file-download-py-L177" class="blob-num js-line-number js-blob-rnum" data-line-number="177"></td>
          <td id="file-download-py-LC177" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">download_range</span>.<span class="pl-c1">remote</span>(<span class="pl-en">date</span>(<span class="pl-c1">2020</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>))</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/patrickdevivo/9da8add9baf7e1c41be643d9381783be/raw/554450d524252e6e59189f0a7b1c9310b3e98a94/download.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/patrickdevivo/9da8add9baf7e1c41be643d9381783be#file-download-py" class="Link--inTextBlock">
          download.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>You can see there&#8217;s actually quite a bit going on, even though it&#8217;s a single file with &lt;200 LOC:</p><ul><li><p>We&#8217;re using <code>pycurl</code>, Python bindings to cURL, which has been benchmarked to be faster than <code>requests</code></p><ul><li><p>We configure it to &#8220;fail fast&#8221; on flaky downloads, allowing Modal to retry with an exponential back-off. This was key to improving overall performance and reliability - sometimes a download will get &#8220;stuck&#8221; or a connection gets reset. So instead of waiting out a slow download stream, we just end it quickly and try again (up to 8 times).</p></li></ul></li><li><p>We handle and report 404s - it turns out there are some data files (hour chunks) missing from the GH Archive dataset. We retry these downloads, but if they are truly missing, we just report the 404s at the end of the run.</p></li><li><p>We track download speed, errors, total time, etc. and log as the downloads execute and as a summary at the end of the run.</p></li><li><p>We use <code>@modal.concurrent(max_inputs=12)</code> to allow for concurrency <em>within a container</em> - Modal will run our <code>download_file</code> call up to 12 times at once in a single container. This allows a single container to do more work, and is a useful knob for tuning performance trade-offs.</p></li></ul><p>Here&#8217;s what the output of this code looks like (just the log lines)</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;dff7116c-4eb4-4b3a-89e9-994a537045aa&quot;,&quot;duration&quot;:null}"></div><p>And that&#8217;s pretty much it! We&#8217;re now able to reliably and quickly download data from GH Archive across arbitrary date ranges. In a future post I&#8217;ll get this code organized and in a public repo, and show how it can be processed so that DuckDB can query it. Stay tuned!</p>]]></content:encoded></item><item><title><![CDATA[Query Source Code with Tree-sitter]]></title><description><![CDATA[TreeQuery is a new command-line tool for querying source code with Tree-sitter]]></description><link>https://noreasontopanic.com/p/querying-source-code-with-tree-sitter</link><guid isPermaLink="false">https://noreasontopanic.com/p/querying-source-code-with-tree-sitter</guid><dc:creator><![CDATA[Patrick DeVivo]]></dc:creator><pubDate>Fri, 02 Jul 2021 20:45:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gU3K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://tree-sitter.github.io/tree-sitter/">Tree-sitter</a> is a really cool project. It&#8217;s primarily designed for code syntax-highlighting use cases (in editors and IDEs), but it also exposes a <a href="https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax">Query API</a> for selecting portions of a parsed syntax tree, using an <a href="https://en.wikipedia.org/wiki/S-expression">S-Expression</a> based query syntax.</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gU3K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gU3K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 424w, https://substackcdn.com/image/fetch/$s_!gU3K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 848w, https://substackcdn.com/image/fetch/$s_!gU3K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 1272w, https://substackcdn.com/image/fetch/$s_!gU3K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gU3K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png" width="210" height="210" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:400,&quot;resizeWidth&quot;:210,&quot;bytes&quot;:115131,&quot;alt&quot;:&quot;Tree-sitter logo&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Tree-sitter logo" title="Tree-sitter logo" srcset="https://substackcdn.com/image/fetch/$s_!gU3K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 424w, https://substackcdn.com/image/fetch/$s_!gU3K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 848w, https://substackcdn.com/image/fetch/$s_!gU3K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 1272w, https://substackcdn.com/image/fetch/$s_!gU3K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F925aab91-7b22-44d0-b800-6db1d7a18d7d_400x400.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Tree-sitter is a parser generator tool and an incremental parsing library.</figcaption></figure></div><p></p><p><a href="https://github.com/askgitdev/treequery">TreeQuery</a> is a new CLI that makes it easier to run Tree-sitter queries against local source code files. It installs as <code>tq </code>and looks something like this:</p><pre><code><code>&gt; tq -q some_file.go "(function_declaration name: (identifier) @method_name)"

init
handleErr
someFunc
main</code></code></pre><p>(prints out all the function names in a go file).</p><p>I think this is pretty cool. We&#8217;re still exploring use-cases and getting a feel for what&#8217;s possible to query, go ahead and give it a try! It&#8217;s still rough around the edges and more language support will be added soon. See the <a href="https://github.com/askgitdev/treequery/issues">open issues</a> for a sense of the roadmap.</p><p>It will soon be integrated into <a href="https://github.com/askgitdev/askgit"><code>askgit</code></a>.</p>]]></content:encoded></item><item><title><![CDATA[What Comes After Serverless: How About Codeless?]]></title><description><![CDATA[Serverless lets you forget about servers; what if you could forget about the code too?]]></description><link>https://noreasontopanic.com/p/what-about-codeless</link><guid isPermaLink="false">https://noreasontopanic.com/p/what-about-codeless</guid><dc:creator><![CDATA[Patrick DeVivo]]></dc:creator><pubDate>Wed, 31 Mar 2021 22:05:05 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/e91f8057-9723-46bf-9617-70cec5e6a8ef_3840x5760.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Yes, this joke has been <a href="https://github.com/kelseyhightower/nocode">made before</a>, but I&#8217;m serious. In the same way that serverless lets backend developers &#8220;forget&#8221; about servers, what if &#8220;codeless&#8221; did the same, but for your application code.</p><p>In other words, <strong>what if API requests to your service included the code that the caller wants to be executed on the server?</strong></p><p>Your backend could essentially become a &#8220;runtime&#8221; for client-provided code. GraphQL APIs in some ways approach this - the backend is an &#8220;execution environment&#8221; for a (well defined and structured) GraphQL query. What if the &#8220;query language&#8221; became another programming language instead?</p><h3>Example</h3><p>A <a href="https://github.com/patrickdevivo/codeless">simple example</a> is fairly easy to implement in <a href="https://deno.land/">Deno</a>, which has built-in <a href="https://deno.land/manual/getting_started/permissions">sandboxing features</a>.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist108746540\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-main-ts\&quot; class=\&quot;file my-2\&quot;>\n    \n\n  <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-typescript  \&quot;>\n      \n<table class=\&quot;highlight tab-size js-file-line-container\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip>\n      <tr>\n        <td id=\&quot;file-main-ts-L1\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;1\&quot;></td>\n        <td id=\&quot;file-main-ts-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> <span class=pl-kos>{</span> <span class=pl-s1>listenAndServe</span> <span class=pl-kos>}</span> <span class=pl-k>from</span> <span class=pl-s>&amp;quot;https://deno.land/std@0.91.0/http/server.ts&amp;quot;</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L2\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;2\&quot;></td>\n        <td id=\&quot;file-main-ts-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> <span class=pl-kos>{</span> <span class=pl-smi>Status</span> <span class=pl-kos>}</span> <span class=pl-k>from</span> <span class=pl-s>&amp;quot;https://deno.land/std@0.91.0/http/http_status.ts&amp;quot;</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L3\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;3\&quot;></td>\n        <td id=\&quot;file-main-ts-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L4\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;4\&quot;></td>\n        <td id=\&quot;file-main-ts-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>const</span> <span class=pl-smi>HTTP_PORT</span> <span class=pl-c1>=</span> <span class=pl-c1>8080</span><span class=pl-kos>;</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L5\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;5\&quot;></td>\n        <td id=\&quot;file-main-ts-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>const</span> <span class=pl-s1>options</span> <span class=pl-c1>=</span> <span class=pl-kos>{</span> <span class=pl-c1>hostname</span>: <span class=pl-s>&amp;quot;0.0.0.0&amp;quot;</span><span class=pl-kos>,</span> <span class=pl-c1>port</span>: <span class=pl-smi>HTTP_PORT</span> <span class=pl-kos>}</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L6\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;6\&quot;></td>\n        <td id=\&quot;file-main-ts-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>console</span><span class=pl-kos>.</span><span class=pl-en>log</span><span class=pl-kos>(</span><span class=pl-s>`HTTP server running on localhost:<span class=pl-s1><span class=pl-kos>${</span><span class=pl-smi>HTTP_PORT</span><span class=pl-kos>}</span></span>`</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L7\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;7\&quot;></td>\n        <td id=\&quot;file-main-ts-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L8\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;8\&quot;></td>\n        <td id=\&quot;file-main-ts-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>listenAndServe</span><span class=pl-kos>(</span><span class=pl-s1>options</span><span class=pl-kos>,</span> <span class=pl-kos>(</span><span class=pl-s1>request</span><span class=pl-kos>)</span> <span class=pl-c1>=&amp;gt;</span> <span class=pl-kos>{</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L9\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;9\&quot;></td>\n        <td id=\&quot;file-main-ts-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>if</span> <span class=pl-kos>(</span><span class=pl-s1>request</span><span class=pl-kos>.</span><span class=pl-c1>method</span> <span class=pl-c1>!==</span> <span class=pl-s>&amp;quot;GET&amp;quot;</span><span class=pl-kos>)</span> <span class=pl-kos>{</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L10\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;10\&quot;></td>\n        <td id=\&quot;file-main-ts-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>request</span><span class=pl-kos>.</span><span class=pl-en>respond</span><span class=pl-kos>(</span><span class=pl-kos>{</span> <span class=pl-c1>status</span>: <span class=pl-smi>Status</span><span class=pl-kos>.</span><span class=pl-c1>MethodNotAllowed</span><span class=pl-kos>,</span> <span class=pl-c1>body</span>: <span class=pl-s>&amp;quot;must GET&amp;quot;</span> <span class=pl-kos>}</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L11\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;11\&quot;></td>\n        <td id=\&quot;file-main-ts-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L12\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;12\&quot;></td>\n        <td id=\&quot;file-main-ts-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-kos>}</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L13\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;13\&quot;></td>\n        <td id=\&quot;file-main-ts-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L14\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;14\&quot;></td>\n        <td id=\&quot;file-main-ts-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>const</span> <span class=pl-s1>start</span> <span class=pl-c1>=</span> <span class=pl-k>new</span> <span class=pl-smi>Date</span><span class=pl-kos>(</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L15\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;15\&quot;></td>\n        <td id=\&quot;file-main-ts-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>const</span> <span class=pl-s1>url</span> <span class=pl-c1>=</span> <span class=pl-s>`https://<span class=pl-s1><span class=pl-kos>${</span><span class=pl-s1>request</span><span class=pl-kos>.</span><span class=pl-c1>url</span><span class=pl-kos>.</span><span class=pl-en>substring</span><span class=pl-kos>(</span><span class=pl-c1>1</span><span class=pl-kos>)</span><span class=pl-kos>}</span></span>`</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L16\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;16\&quot;></td>\n        <td id=\&quot;file-main-ts-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>let</span> <span class=pl-s1>completed</span> <span class=pl-c1>=</span> <span class=pl-c1>false</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L17\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;17\&quot;></td>\n        <td id=\&quot;file-main-ts-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L18\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;18\&quot;></td>\n        <td id=\&quot;file-main-ts-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>const</span> <span class=pl-s1>p</span> <span class=pl-c1>=</span> <span class=pl-smi>Deno</span><span class=pl-kos>.</span><span class=pl-en>run</span><span class=pl-kos>(</span><span class=pl-kos>{</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L19\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;19\&quot;></td>\n        <td id=\&quot;file-main-ts-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c1>cmd</span>: <span class=pl-kos>[</span> <span class=pl-s>&amp;quot;deno&amp;quot;</span><span class=pl-kos>,</span> <span class=pl-s>&amp;quot;run&amp;quot;</span><span class=pl-kos>,</span> <span class=pl-s1>url</span> <span class=pl-kos>]</span><span class=pl-kos>,</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L20\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;20\&quot;></td>\n        <td id=\&quot;file-main-ts-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c1>stdout</span>: <span class=pl-s>&amp;quot;piped&amp;quot;</span><span class=pl-kos>,</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L21\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;21\&quot;></td>\n        <td id=\&quot;file-main-ts-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c1>stderr</span>: <span class=pl-s>&amp;quot;null&amp;quot;</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L22\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;22\&quot;></td>\n        <td id=\&quot;file-main-ts-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-kos>}</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L23\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;23\&quot;></td>\n        <td id=\&quot;file-main-ts-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L24\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;24\&quot;></td>\n        <td id=\&quot;file-main-ts-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// pipe the stdout of the process to the http response</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L25\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;25\&quot;></td>\n        <td id=\&quot;file-main-ts-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-s1>request</span><span class=pl-kos>.</span><span class=pl-en>respond</span><span class=pl-kos>(</span><span class=pl-kos>{</span> <span class=pl-c1>body</span>: <span class=pl-s1>p</span><span class=pl-kos>.</span><span class=pl-c1>stdout</span> <span class=pl-kos>}</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L26\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;26\&quot;></td>\n        <td id=\&quot;file-main-ts-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L27\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;27\&quot;></td>\n        <td id=\&quot;file-main-ts-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// whenever the process exits, mark it as done</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L28\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;28\&quot;></td>\n        <td id=\&quot;file-main-ts-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-s1>p</span><span class=pl-kos>.</span><span class=pl-en>status</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>.</span><span class=pl-en>finally</span><span class=pl-kos>(</span><span class=pl-kos>(</span><span class=pl-kos>)</span> <span class=pl-c1>=&amp;gt;</span> <span class=pl-kos>{</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L29\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;29\&quot;></td>\n        <td id=\&quot;file-main-ts-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>completed</span> <span class=pl-c1>=</span> <span class=pl-c1>true</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L30\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;30\&quot;></td>\n        <td id=\&quot;file-main-ts-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>let</span> <span class=pl-s1>elapsed</span> <span class=pl-c1>=</span> <span class=pl-kos>(</span><span class=pl-k>new</span> <span class=pl-smi>Date</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>)</span><span class=pl-kos>.</span><span class=pl-en>getTime</span><span class=pl-kos>(</span><span class=pl-kos>)</span> <span class=pl-c1>-</span> <span class=pl-s1>start</span><span class=pl-kos>.</span><span class=pl-en>getTime</span><span class=pl-kos>(</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L31\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;31\&quot;></td>\n        <td id=\&quot;file-main-ts-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>console</span><span class=pl-kos>.</span><span class=pl-en>log</span><span class=pl-kos>(</span><span class=pl-kos>{</span> url<span class=pl-kos>,</span> <span class=pl-c1>time</span>: <span class=pl-s>`<span class=pl-s1><span class=pl-kos>${</span><span class=pl-s1>elapsed</span><span class=pl-kos>}</span></span>ms`</span> <span class=pl-kos>}</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L32\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;32\&quot;></td>\n        <td id=\&quot;file-main-ts-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-kos>}</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L33\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;33\&quot;></td>\n        <td id=\&quot;file-main-ts-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L34\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;34\&quot;></td>\n        <td id=\&quot;file-main-ts-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// once the request is done (or canceled)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L35\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;35\&quot;></td>\n        <td id=\&quot;file-main-ts-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-smi>Deno</span><span class=pl-kos>.</span><span class=pl-en>readAll</span><span class=pl-kos>(</span><span class=pl-s1>request</span><span class=pl-kos>.</span><span class=pl-c1>r</span><span class=pl-kos>)</span><span class=pl-kos>.</span><span class=pl-en>then</span><span class=pl-kos>(</span><span class=pl-k>async</span> <span class=pl-kos>(</span><span class=pl-kos>)</span> <span class=pl-c1>=&amp;gt;</span> <span class=pl-kos>{</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L36\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;36\&quot;></td>\n        <td id=\&quot;file-main-ts-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// if the process hasn&amp;#39;t completed, end it</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L37\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;37\&quot;></td>\n        <td id=\&quot;file-main-ts-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>if</span> <span class=pl-kos>(</span><span class=pl-c1>!</span><span class=pl-s1>completed</span><span class=pl-kos>)</span> <span class=pl-s1>p</span><span class=pl-kos>.</span><span class=pl-en>kill</span><span class=pl-kos>(</span><span class=pl-c1>2</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L38\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;38\&quot;></td>\n        <td id=\&quot;file-main-ts-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-kos>}</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L39\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;39\&quot;></td>\n        <td id=\&quot;file-main-ts-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L40\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;40\&quot;></td>\n        <td id=\&quot;file-main-ts-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// don&amp;#39;t let requests run indefinitely</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L41\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;41\&quot;></td>\n        <td id=\&quot;file-main-ts-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-en>setTimeout</span><span class=pl-kos>(</span><span class=pl-kos>(</span><span class=pl-kos>)</span> <span class=pl-c1>=&amp;gt;</span> <span class=pl-kos>{</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L42\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;42\&quot;></td>\n        <td id=\&quot;file-main-ts-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>if</span> <span class=pl-kos>(</span><span class=pl-c1>!</span><span class=pl-s1>completed</span><span class=pl-kos>)</span> <span class=pl-s1>p</span><span class=pl-kos>.</span><span class=pl-en>kill</span><span class=pl-kos>(</span><span class=pl-c1>2</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L43\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;43\&quot;></td>\n        <td id=\&quot;file-main-ts-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-kos>}</span><span class=pl-kos>,</span> <span class=pl-c1>10</span><span class=pl-c1>*</span><span class=pl-c1>1000</span><span class=pl-kos>)</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-main-ts-L44\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;44\&quot;></td>\n        <td id=\&quot;file-main-ts-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-kos>}</span><span class=pl-kos>)</span><span class=pl-kos>;</span></td>\n      </tr>\n</table>\n\n\n  </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/patrickdevivo/b3d2a430ec9dec8020c46cf3eb0f11c4/raw/e1853733617bc6483626a46153fba1ea72845772/main.ts\&quot; style=\&quot;float:right\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/patrickdevivo/b3d2a430ec9dec8020c46cf3eb0f11c4#file-main-ts\&quot;>main.ts</a>\n        hosted with &amp;#10084; by <a href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-33b98015caf26cfcbee6ce1a5d1fc768.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-33b98015caf26cfcbee6ce1a5d1fc768.css"><div id="gist108746540" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-main-ts" class="file my-2">
    

  <div itemprop="text" class="Box-body p-0 blob-wrapper data type-typescript  ">
      
<table class="highlight tab-size js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">
      <tbody><tr>
        <td id="file-main-ts-L1" class="blob-num js-line-number" data-line-number="1"></td>
        <td id="file-main-ts-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">listenAndServe</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"https://deno.land/std@0.91.0/http/server.ts"</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L2" class="blob-num js-line-number" data-line-number="2"></td>
        <td id="file-main-ts-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-smi">Status</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"https://deno.land/std@0.91.0/http/http_status.ts"</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L3" class="blob-num js-line-number" data-line-number="3"></td>
        <td id="file-main-ts-LC3" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L4" class="blob-num js-line-number" data-line-number="4"></td>
        <td id="file-main-ts-LC4" class="blob-code blob-code-inner js-file-line"><span class="pl-k">const</span> <span class="pl-smi">HTTP_PORT</span> <span class="pl-c1">=</span> <span class="pl-c1">8080</span><span class="pl-kos">;</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L5" class="blob-num js-line-number" data-line-number="5"></td>
        <td id="file-main-ts-LC5" class="blob-code blob-code-inner js-file-line"><span class="pl-k">const</span> <span class="pl-s1">options</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span> <span class="pl-c1">hostname</span>: <span class="pl-s">"0.0.0.0"</span><span class="pl-kos">,</span> <span class="pl-c1">port</span>: <span class="pl-smi">HTTP_PORT</span> <span class="pl-kos">}</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L6" class="blob-num js-line-number" data-line-number="6"></td>
        <td id="file-main-ts-LC6" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">`HTTP server running on localhost:<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-smi">HTTP_PORT</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L7" class="blob-num js-line-number" data-line-number="7"></td>
        <td id="file-main-ts-LC7" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L8" class="blob-num js-line-number" data-line-number="8"></td>
        <td id="file-main-ts-LC8" class="blob-code blob-code-inner js-file-line"><span class="pl-en">listenAndServe</span><span class="pl-kos">(</span><span class="pl-s1">options</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L9" class="blob-num js-line-number" data-line-number="9"></td>
        <td id="file-main-ts-LC9" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-c1">method</span> <span class="pl-c1">!==</span> <span class="pl-s">"GET"</span><span class="pl-kos">)</span> <span class="pl-kos">{</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L10" class="blob-num js-line-number" data-line-number="10"></td>
        <td id="file-main-ts-LC10" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-en">respond</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">status</span>: <span class="pl-smi">Status</span><span class="pl-kos">.</span><span class="pl-c1">MethodNotAllowed</span><span class="pl-kos">,</span> <span class="pl-c1">body</span>: <span class="pl-s">"must GET"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L11" class="blob-num js-line-number" data-line-number="11"></td>
        <td id="file-main-ts-LC11" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L12" class="blob-num js-line-number" data-line-number="12"></td>
        <td id="file-main-ts-LC12" class="blob-code blob-code-inner js-file-line">  <span class="pl-kos">}</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L13" class="blob-num js-line-number" data-line-number="13"></td>
        <td id="file-main-ts-LC13" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L14" class="blob-num js-line-number" data-line-number="14"></td>
        <td id="file-main-ts-LC14" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">const</span> <span class="pl-s1">start</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">Date</span><span class="pl-kos">(</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L15" class="blob-num js-line-number" data-line-number="15"></td>
        <td id="file-main-ts-LC15" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">const</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">`https://<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-c1">url</span><span class="pl-kos">.</span><span class="pl-en">substring</span><span class="pl-kos">(</span><span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">}</span></span>`</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L16" class="blob-num js-line-number" data-line-number="16"></td>
        <td id="file-main-ts-LC16" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">let</span> <span class="pl-s1">completed</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L17" class="blob-num js-line-number" data-line-number="17"></td>
        <td id="file-main-ts-LC17" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L18" class="blob-num js-line-number" data-line-number="18"></td>
        <td id="file-main-ts-LC18" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">const</span> <span class="pl-s1">p</span> <span class="pl-c1">=</span> <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-en">run</span><span class="pl-kos">(</span><span class="pl-kos">{</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L19" class="blob-num js-line-number" data-line-number="19"></td>
        <td id="file-main-ts-LC19" class="blob-code blob-code-inner js-file-line">    <span class="pl-c1">cmd</span>: <span class="pl-kos">[</span> <span class="pl-s">"deno"</span><span class="pl-kos">,</span> <span class="pl-s">"run"</span><span class="pl-kos">,</span> <span class="pl-s1">url</span> <span class="pl-kos">]</span><span class="pl-kos">,</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L20" class="blob-num js-line-number" data-line-number="20"></td>
        <td id="file-main-ts-LC20" class="blob-code blob-code-inner js-file-line">    <span class="pl-c1">stdout</span>: <span class="pl-s">"piped"</span><span class="pl-kos">,</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L21" class="blob-num js-line-number" data-line-number="21"></td>
        <td id="file-main-ts-LC21" class="blob-code blob-code-inner js-file-line">    <span class="pl-c1">stderr</span>: <span class="pl-s">"null"</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L22" class="blob-num js-line-number" data-line-number="22"></td>
        <td id="file-main-ts-LC22" class="blob-code blob-code-inner js-file-line">  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L23" class="blob-num js-line-number" data-line-number="23"></td>
        <td id="file-main-ts-LC23" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L24" class="blob-num js-line-number" data-line-number="24"></td>
        <td id="file-main-ts-LC24" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// pipe the stdout of the process to the http response</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L25" class="blob-num js-line-number" data-line-number="25"></td>
        <td id="file-main-ts-LC25" class="blob-code blob-code-inner js-file-line">  <span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-en">respond</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">body</span>: <span class="pl-s1">p</span><span class="pl-kos">.</span><span class="pl-c1">stdout</span> <span class="pl-kos">}</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L26" class="blob-num js-line-number" data-line-number="26"></td>
        <td id="file-main-ts-LC26" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L27" class="blob-num js-line-number" data-line-number="27"></td>
        <td id="file-main-ts-LC27" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// whenever the process exits, mark it as done</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L28" class="blob-num js-line-number" data-line-number="28"></td>
        <td id="file-main-ts-LC28" class="blob-code blob-code-inner js-file-line">  <span class="pl-s1">p</span><span class="pl-kos">.</span><span class="pl-en">status</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">finally</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L29" class="blob-num js-line-number" data-line-number="29"></td>
        <td id="file-main-ts-LC29" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">completed</span> <span class="pl-c1">=</span> <span class="pl-c1">true</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L30" class="blob-num js-line-number" data-line-number="30"></td>
        <td id="file-main-ts-LC30" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">let</span> <span class="pl-s1">elapsed</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-k">new</span> <span class="pl-smi">Date</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">getTime</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">-</span> <span class="pl-s1">start</span><span class="pl-kos">.</span><span class="pl-en">getTime</span><span class="pl-kos">(</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L31" class="blob-num js-line-number" data-line-number="31"></td>
        <td id="file-main-ts-LC31" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-kos">{</span> url<span class="pl-kos">,</span> <span class="pl-c1">time</span>: <span class="pl-s">`<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">elapsed</span><span class="pl-kos">}</span></span>ms`</span> <span class="pl-kos">}</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L32" class="blob-num js-line-number" data-line-number="32"></td>
        <td id="file-main-ts-LC32" class="blob-code blob-code-inner js-file-line">  <span class="pl-kos">}</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L33" class="blob-num js-line-number" data-line-number="33"></td>
        <td id="file-main-ts-LC33" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L34" class="blob-num js-line-number" data-line-number="34"></td>
        <td id="file-main-ts-LC34" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// once the request is done (or canceled)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L35" class="blob-num js-line-number" data-line-number="35"></td>
        <td id="file-main-ts-LC35" class="blob-code blob-code-inner js-file-line">  <span class="pl-smi">Deno</span><span class="pl-kos">.</span><span class="pl-en">readAll</span><span class="pl-kos">(</span><span class="pl-s1">request</span><span class="pl-kos">.</span><span class="pl-c1">r</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L36" class="blob-num js-line-number" data-line-number="36"></td>
        <td id="file-main-ts-LC36" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// if the process hasn't completed, end it</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L37" class="blob-num js-line-number" data-line-number="37"></td>
        <td id="file-main-ts-LC37" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">completed</span><span class="pl-kos">)</span> <span class="pl-s1">p</span><span class="pl-kos">.</span><span class="pl-en">kill</span><span class="pl-kos">(</span><span class="pl-c1">2</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L38" class="blob-num js-line-number" data-line-number="38"></td>
        <td id="file-main-ts-LC38" class="blob-code blob-code-inner js-file-line">  <span class="pl-kos">}</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L39" class="blob-num js-line-number" data-line-number="39"></td>
        <td id="file-main-ts-LC39" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-main-ts-L40" class="blob-num js-line-number" data-line-number="40"></td>
        <td id="file-main-ts-LC40" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// don't let requests run indefinitely</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L41" class="blob-num js-line-number" data-line-number="41"></td>
        <td id="file-main-ts-LC41" class="blob-code blob-code-inner js-file-line">  <span class="pl-en">setTimeout</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L42" class="blob-num js-line-number" data-line-number="42"></td>
        <td id="file-main-ts-LC42" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-s1">completed</span><span class="pl-kos">)</span> <span class="pl-s1">p</span><span class="pl-kos">.</span><span class="pl-en">kill</span><span class="pl-kos">(</span><span class="pl-c1">2</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L43" class="blob-num js-line-number" data-line-number="43"></td>
        <td id="file-main-ts-LC43" class="blob-code blob-code-inner js-file-line">  <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c1">10</span><span class="pl-c1">*</span><span class="pl-c1">1000</span><span class="pl-kos">)</span></td>
      </tr>
      <tr>
        <td id="file-main-ts-L44" class="blob-num js-line-number" data-line-number="44"></td>
        <td id="file-main-ts-LC44" class="blob-code blob-code-inner js-file-line"><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></td>
      </tr>
</tbody></table>


  </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/patrickdevivo/b3d2a430ec9dec8020c46cf3eb0f11c4/raw/e1853733617bc6483626a46153fba1ea72845772/main.ts" style="float:right">view raw</a>
        <a href="https://gist.github.com/patrickdevivo/b3d2a430ec9dec8020c46cf3eb0f11c4#file-main-ts">main.ts</a>
        hosted with &#10084; by <a href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p><em>This is just an example to illustrate the point, use at your own risk!</em></p><pre><code>deno run --allow-net --allow-run --unstable main.ts</code></pre><p>Will start an HTTP server that responds to <code>GET</code> requests, parses the path, and runs a Deno subprocess (<code>deno run</code> with no additional permissions) pointed at the remote code specified by the request path. In other words, you&#8217;ll be able to:</p><pre><code>&gt; curl localhost:8080/raw.githubusercontent.com/patrickdevivo/codeless/main/examples/hello_x.ts

hello, world!
hello, patrick!
hello, deno!
hello, reader!</code></pre><p>Where the path (with an <code>https://</code> preceding it) <a href="https://raw.githubusercontent.com/patrickdevivo/codeless/main/examples/hello_x.ts">resolves to a file</a> with the following contents (which is a Deno script):</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist108746612\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-hello_x-ts\&quot; class=\&quot;file my-2\&quot;>\n    \n\n  <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-typescript  \&quot;>\n      \n<table class=\&quot;highlight tab-size js-file-line-container\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip>\n      <tr>\n        <td id=\&quot;file-hello_x-ts-L1\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;1\&quot;></td>\n        <td id=\&quot;file-hello_x-ts-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>const</span> <span class=pl-s1>names</span> <span class=pl-c1>=</span> <span class=pl-kos>[</span><span class=pl-s>&amp;quot;world&amp;quot;</span><span class=pl-kos>,</span> <span class=pl-s>&amp;quot;patrick&amp;quot;</span><span class=pl-kos>,</span> <span class=pl-s>&amp;quot;deno&amp;quot;</span><span class=pl-kos>,</span> <span class=pl-s>&amp;quot;reader&amp;quot;</span><span class=pl-kos>]</span></td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-hello_x-ts-L2\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;2\&quot;></td>\n        <td id=\&quot;file-hello_x-ts-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n      </tr>\n      <tr>\n        <td id=\&quot;file-hello_x-ts-L3\&quot; class=\&quot;blob-num js-line-number\&quot; data-line-number=\&quot;3\&quot;></td>\n        <td id=\&quot;file-hello_x-ts-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>names</span><span class=pl-kos>.</span><span class=pl-en>forEach</span><span class=pl-kos>(</span><span class=pl-s1>n</span> <span class=pl-c1>=&amp;gt;</span> <span class=pl-smi>console</span><span class=pl-kos>.</span><span class=pl-en>log</span><span class=pl-kos>(</span><span class=pl-s>`hello, <span class=pl-s1><span class=pl-kos>${</span><span class=pl-s1>n</span><span class=pl-kos>}</span></span>!`</span><span class=pl-kos>)</span><span class=pl-kos>)</span></td>\n      </tr>\n</table>\n\n\n  </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/patrickdevivo/481081dd4c3a5486fd5783940de8b5bb/raw/e940f01537cbf3218cfa184f06039391f4412f1a/hello_x.ts\&quot; style=\&quot;float:right\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/patrickdevivo/481081dd4c3a5486fd5783940de8b5bb#file-hello_x-ts\&quot;>hello_x.ts</a>\n        hosted with &amp;#10084; by <a href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-33b98015caf26cfcbee6ce1a5d1fc768.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-33b98015caf26cfcbee6ce1a5d1fc768.css"><div id="gist108746612" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-hello_x-ts" class="file my-2">
    

  <div itemprop="text" class="Box-body p-0 blob-wrapper data type-typescript  ">
      
<table class="highlight tab-size js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">
      <tbody><tr>
        <td id="file-hello_x-ts-L1" class="blob-num js-line-number" data-line-number="1"></td>
        <td id="file-hello_x-ts-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">const</span> <span class="pl-s1">names</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-s">"world"</span><span class="pl-kos">,</span> <span class="pl-s">"patrick"</span><span class="pl-kos">,</span> <span class="pl-s">"deno"</span><span class="pl-kos">,</span> <span class="pl-s">"reader"</span><span class="pl-kos">]</span></td>
      </tr>
      <tr>
        <td id="file-hello_x-ts-L2" class="blob-num js-line-number" data-line-number="2"></td>
        <td id="file-hello_x-ts-LC2" class="blob-code blob-code-inner js-file-line">
</td>
      </tr>
      <tr>
        <td id="file-hello_x-ts-L3" class="blob-num js-line-number" data-line-number="3"></td>
        <td id="file-hello_x-ts-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">names</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-s1">n</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">`hello, <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">n</span><span class="pl-kos">}</span></span>!`</span><span class="pl-kos">)</span><span class="pl-kos">)</span></td>
      </tr>
</tbody></table>


  </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/patrickdevivo/481081dd4c3a5486fd5783940de8b5bb/raw/e940f01537cbf3218cfa184f06039391f4412f1a/hello_x.ts" style="float:right">view raw</a>
        <a href="https://gist.github.com/patrickdevivo/481081dd4c3a5486fd5783940de8b5bb#file-hello_x-ts">hello_x.ts</a>
        hosted with &#10084; by <a href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>If you don&#8217;t want to run locally, try:</p><pre><code>curl https://codeless-deno-ex-vgetngw32a-uc.a.run.app/raw.githubusercontent.com/patrickdevivo/codeless/main/examples/hello_x.ts</code></pre><p>Which will hit an instance of this service running in <a href="https://cloud.google.com/run">Google Cloud Run</a> (a container based serverless platform).</p><h2>Why&#8230;?</h2><p>Why not? As more tools make it <a href="https://wasmer.io/">easier and possible</a> to sandbox external code, maybe this isn&#8217;t such a weird (or dangerous) idea.</p><ol><li><p>You only need to update your API <em>runtime</em>, changes to backend business logic can be made in client implementations, which means that&#8230;</p></li><li><p>Clients can call very specific versions of code since the code-to-run is described with the request (pin to a git SHA, version tag, etc.)</p></li><li><p>Clients can arbitrarily shape the output to their need (only fetch the data they care about, one of the benefits of GraphQL)</p></li><li><p>No need to agree on explicit frontend &lt;&gt; backend API contracts (beyond the runtime) - frontends can incrementally change the behavior of their backend calls without synchronizing with the API maintainers</p></li></ol><h2>Additional Ideas</h2><ol><li><p>Be stricter about API resource consumption (could even be based on request status: auth vs unauthed, paying vs non-paying), timeout calls after N seconds, limit memory usage - treat more like a &#8220;cloud service&#8221;</p></li><li><p>Map HTTP headers to ENV variables (or some other place) in the execution environment for contextual information like API keys or auth tokens</p></li><li><p>Enable (permissioned) access to other backend services - like a database - to use directly in the sandboxed code</p></li><li><p>Support execution in different languages (WebAssemby?)</p></li></ol>]]></content:encoded></item><item><title><![CDATA[Listing Git Authors]]></title><description><![CDATA[How can I find (unique) contributors to a git repo? Here's a way using SQL...]]></description><link>https://noreasontopanic.com/p/listing-git-authors</link><guid isPermaLink="false">https://noreasontopanic.com/p/listing-git-authors</guid><dc:creator><![CDATA[Patrick DeVivo]]></dc:creator><pubDate>Fri, 03 Jul 2020 23:23:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jeid!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jeid!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jeid!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jeid!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jeid!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jeid!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jeid!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg" width="1456" height="965" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:965,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1248352,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jeid!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 424w, https://substackcdn.com/image/fetch/$s_!jeid!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 848w, https://substackcdn.com/image/fetch/$s_!jeid!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!jeid!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9030bfae-8be0-44d2-a92f-29436d8efeb8_3155x2091.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><p>How can I find (unique) contributors to a git repo?</p><p>The first answer <a href="https://stackoverflow.com/questions/12768502/how-do-i-log-unique-authors-in-git">on this StackOverflow question</a> offers:</p><pre><code>git log --format="%an" | sort -u</code></pre><p>Which is pretty cool. Simple and easy to understand. The <code>git log</code> command takes a <code>&#8212;format</code> flag which lets us supply a format string (where <code>%an</code> <a href="https://git-scm.com/docs/git-log#_pretty_formats">indicates</a> author name).</p><p>It returns just the author name for every commit in the current history, <code>sort -u</code> then de-duplicates (and sorts) by line (using the piped input).</p><p><strong>But here&#8217;s another way!</strong> And it&#8217;s a shameless plug for a project I&#8217;ve started called <a href="https://github.com/augmentable-dev/gitqlite">gitqlite</a>, which provides a SQL interface for ad-hoc querying of git information. </p><pre><code>gitqlite "SELECT DISTINCT author_name FROM commits"</code></pre><p>Returns a similar output. If alphabetical ordering matters, try:</p><pre><code>gitqlite "SELECT DISTINCT author_name FROM commits ORDER BY author_name"</code></pre><p>Or if you want a sorting by total # of commits:</p><pre><code>gitqlite "SELECT author_name, count(*) FROM commits GROUP BY author_name ORDER BY count(*) DESC"</code></pre><p>That&#8217;s just the beginning! I hope to collect more use cases as I continue working on <a href="https://github.com/augmentable-dev/gitqlite">gitqlite</a>. If you have ideas, please <a href="https://twitter.com/patrickdevivo">reach out</a>!</p>]]></content:encoded></item><item><title><![CDATA[Stop caring about your code]]></title><description><![CDATA[It's only the outcome that matters, not how you got there]]></description><link>https://noreasontopanic.com/p/stop-caring-about-your-code</link><guid isPermaLink="false">https://noreasontopanic.com/p/stop-caring-about-your-code</guid><dc:creator><![CDATA[Patrick DeVivo]]></dc:creator><pubDate>Fri, 19 Jun 2020 23:53:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!I4U-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The title of this post is extreme, and maybe clickbait-y, but I&#8217;ve come to agree with the sentiment. I think it&#8217;s made me a better developer.</p><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I4U-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I4U-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 424w, https://substackcdn.com/image/fetch/$s_!I4U-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 848w, https://substackcdn.com/image/fetch/$s_!I4U-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!I4U-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I4U-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1123930,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I4U-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 424w, https://substackcdn.com/image/fetch/$s_!I4U-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 848w, https://substackcdn.com/image/fetch/$s_!I4U-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!I4U-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9c90c4f0-d483-4208-91e0-7171d94337fe_5184x3456.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><p>A manager I know likes to describe software engineers on a spectrum, between &#8220;cowboy&#8221; and &#8220;astronaut.&#8221; Cowboys commit to master frequently, leaving a trail of bugs and <a href="https://www.tickgit.com/">TODOs</a>. Astronauts ruminate on open PRs for weeks and over-architect for every possible (unnecessary) scenario. Good developers are somewhere in the middle. I&#8217;d say the best are the ones who can play both roles, depending on the requirements at hand. </p><p>Sometimes you just need to cowboy &#129312; some code to spike an experiment, other times you need to astronaut &#129489;&#8205;&#128640; a foundational solution. The extremes are never the answer, but knowing which hat (helmet?) to wear and when is an invaluable skill.</p><p>I&#8217;d call myself astronaut-leaning, and learning to become more of a cowboy has made me a better developer, which is the sentiment of this post&#8217;s title.</p><p>Caring less about code doesn&#8217;t mean caring less about its outcome. In fact, putting the outcome <em>before</em> the implementation can really unlock you to think about the problems that &#8220;matter.&#8221; The value your software delivers, not the software itself.</p><p>It&#8217;s similar to the trap of building what you <em>think</em> your users care about vs what they actually want. No one cares about the abstractions or elegance of the code beneath your product, they care about the product.</p><p>Good abstractions, maintainability, elegance, reliability, the &#8220;behind the scenes&#8221; features of code astronauts like to overthink, can also be the outcome, if that&#8217;s what the problem calls for. They just don&#8217;t always need to be part of a particular solution.</p><p>Learning to care less about code can make you a better developer. It will make you more willing to throw code out to try new ideas, and less likely to get caught up in minutia (though, often it&#8217;s the minutia that makes our jobs fun!).</p>]]></content:encoded></item></channel></rss>