title: How do I write async/synchyronous variants of one Python program?
body: <p>It's normal to develop a simple implementation first. So, for example, we might start with a  non-concurrent program, and then add concurrency. I'd like to be able to switch smoothly back and forth.</p>
  
  <p>For example, single-threaded (pseudocode):</p>
  
  <pre><code>   results=[]
     for url in urls:
        # This then calls other functions that call yet others
        # in a call hierarchy, down to a requests.request() call.
        get_result_and_store_in_database(url) 
  </code></pre>
  
  <p>Async (pseudocode):</p>
  
  <pre><code># The following calls other functions that call yet others
  # in a call hierarchy, down to an asyncio ClientSession().get() call.
  # It runs HTTP requests and store the results in a database.
  # The multiple URLs are processed concurrently.
  asyncio.run(get_results_in_parallel_and_store_in_db(urls))
  </code></pre>
  
  <p>With Python <code>async/await</code>, usually you wrap the run with <code>asyncio.run()</code> (compared to the loop you use in ordinary programs); then at the bottom of the  call hierarchy, you use an IO action like <code>aiohttp.ClientSession().get(url)</code> (compared to the ordinary <code>requests.request()</code>.)</p>
  
  <p><em>But</em>, in the async version, all functions in the call hierarchy between those two must be written as <code>async/await</code>. So, I need to write two copies of what is basically the same call-hierarchy, differing mostly in  whether they have the <code>async/await</code> keywords.</p>
  
  <p>That is a lot of code duplication.</p>
  
  <p>How can I make a switchably non-concurrent/async program?</p>