Promises Tutorial by Irakli Nadareishvili
  • Introduction
  • Turning Callbacks Into Promises
  • Chain Parallel with Sequential
  • Conditions and Promises
  • Keeping Promise Chains Flat
  • Async and Await
  • Async/Await & Express, Mocha etc.
  • One More Thing (Go)...
  • One More Thing (Python)...
  • One More Thin (Nim)…
Powered by GitBook
On this page

Was this helpful?

One More Thing (Python)...

In our experience, few things enhance understanding of programming techniques than comparing similar implementations across languages. Now that we have seen how Go would do it, let's take a look at the implementation in Python. This one is especially interesting because Python (3.5+) added support to async/await, and it is quite similar to what we have in Node.

As a reminder, in this example we are:

  1. Looking up a list of authors for the Microservices Architecture book, using Google Books API

  2. Looking up, in parallel, the number of books each author has published. This means issuing several concurrent API calls to Google books API, all at the same time.

  3. Waiting until all parallel lookups from #2 finish, since they can take different length of time, and when all of them are finished - printing out the results in a nicely-formatted way.

Chain Parallel with Sequential

import aiohttp
import asyncio
import json
import uvloop # optional. @see https://github.com/MagicStack/uvloop

base_url = "https://www.googleapis.com/books/v1/volumes?q="

async def fetch(url):
  '''
  fetches contents of a URL asynchronously
  '''
  async with aiohttp.ClientSession() as session:
    async with session.get(url) as response:
      return await response.text()

async def book_authors(isbn):
  '''
  returns all authors of a book
  '''
  book_url = f"{base_url}isbn:{isbn}" # "Microservice Architecture"
  book_info = await fetch(book_url)
  json_response = json.loads(book_info)
  authors = json_response['items'][0]['volumeInfo']['authors']
  return authors

async def authorNumBooks(author_name):
  '''
  returns number of books published by an author
  '''
  author_url = f"{base_url}inauthor:{author_name}"
  print(f"Quering: {author_name}")
  author_info = await fetch(author_url)
  print(f"Fetched: {author_name}")
  author_info_json = json.loads(author_info)
  count = author_info_json['totalItems']
  return {"name" : author_name, "count": count}

async def msa_authors():
  authors = await book_authors(1491956224) # "Microservice Architecture"
  futures = [authorNumBooks(author) for author in authors]

  resolved_infos = await asyncio.gather(*futures)
  return resolved_infos

async def main():
    author_stat_results = await msa_authors()
    print("==== Author stats results: ====")
    pp = [f"  {item['name']} : {item['count']}" for item in author_stat_results]
    print('\n'.join(pp))

if __name__ == '__main__':
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) # optional: higher performance
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())


# @see: https://github.com/timofurrer/awesome-asyncio
PreviousOne More Thing (Go)...NextOne More Thin (Nim)…

Last updated 5 years ago

Was this helpful?

Side note: full source code of this example can be found at:

https://github.com/inadarei/python-async