<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gabriel Saldanha</title>
    <description>The latest articles on Forem by Gabriel Saldanha (@gcrsaldanha).</description>
    <link>https://forem.com/gcrsaldanha</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F374347%2Fcb1730f5-a17e-41a6-b2fc-f87c5de10891.jpg</url>
      <title>Forem: Gabriel Saldanha</title>
      <link>https://forem.com/gcrsaldanha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gcrsaldanha"/>
    <language>en</language>
    <item>
      <title>How to write concurrent code using Python's Future</title>
      <dc:creator>Gabriel Saldanha</dc:creator>
      <pubDate>Wed, 25 Nov 2020 11:43:11 +0000</pubDate>
      <link>https://forem.com/gcrsaldanha/how-to-write-concurrent-code-using-python-s-future-39ij</link>
      <guid>https://forem.com/gcrsaldanha/how-to-write-concurrent-code-using-python-s-future-39ij</guid>
      <description>&lt;h1&gt;
  
  
  Python futures (concurrency)
&lt;/h1&gt;

&lt;p&gt;tl;dr;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using concurrency to speed up things is quite simple in Python using the &lt;code&gt;concurrent.futures&lt;/code&gt; module. However, it's no silver bullet and one must know &lt;strong&gt;when&lt;/strong&gt; to use it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  All started with generators...
&lt;/h2&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/gcrsaldanha/using-python-generators-to-avoid-extra-service-calls-pl"&gt;previous post&lt;/a&gt; I mentioned how you could use Python generators as a way to avoid performing extra service calls, saving up some time and resources. Here is a summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Suppose you want to check if a given user_email is registered in 
# any of the following social media: Facebook, Github, or Twitter.
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_social_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# (expr for i in iterable) syntax denotes a generator comprehension
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple, huh? &lt;code&gt;any&lt;/code&gt; iterates and evaluates each &lt;code&gt;call(user_email)&lt;/code&gt; yield from the generator until one of them returns &lt;code&gt;True&lt;/code&gt;. This is known as &lt;em&gt;early return&lt;/em&gt; — you basically save up some time and resources by not performing unnecessary calls.&lt;/p&gt;

&lt;p&gt;Some folks gave nice feedback mentioning that I should make it &lt;strong&gt;concurrent&lt;/strong&gt;, i.e., I could make &lt;strong&gt;all the calls&lt;/strong&gt; concurrently and &lt;em&gt;early return&lt;/em&gt; as soon as any &lt;em&gt;call&lt;/em&gt; returned True. "That's a good idea", I thought. I'm glad there are smarter people than myself out there.&lt;/p&gt;

&lt;p&gt;If that's not clear &lt;em&gt;why&lt;/em&gt; I would want to do it: suppose &lt;code&gt;has_facebook_account&lt;/code&gt; takes too long to run (as usually happens with any I/O and network operations due to high latency) and &lt;code&gt;has_github_account&lt;/code&gt; is pretty fast (maybe it's cached, for example). I would &lt;strong&gt;always&lt;/strong&gt; need to wait for &lt;code&gt;has_facebook_account&lt;/code&gt; return &lt;strong&gt;before&lt;/strong&gt; calling &lt;code&gt;has_github_account&lt;/code&gt; since the generator's items would be evaluated &lt;strong&gt;orderly&lt;/strong&gt;. That does not sound fun.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make it concurrent!
&lt;/h2&gt;

&lt;p&gt;I am using &lt;a href="https://docs.python.org/3/library/concurrent.futures.html"&gt;Python's &lt;code&gt;concurrent.futures&lt;/code&gt; module&lt;/a&gt; (available since version 3.2). This module consists basically of two entities: the &lt;code&gt;Executor&lt;/code&gt; and the &lt;code&gt;Future&lt;/code&gt; object. You should read this documentation, it is really short and straight to the point.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Executor&lt;/code&gt; &lt;em&gt;abstract class&lt;/em&gt; is responsible for &lt;em&gt;scheduling&lt;/em&gt; a task (or &lt;em&gt;callable&lt;/em&gt;) to be executed &lt;em&gt;asynchronously&lt;/em&gt; (or &lt;em&gt;concurrently&lt;/em&gt;). Scheduling a task returns a &lt;code&gt;Future&lt;/code&gt; object, which is a reference to the task and represents its state — &lt;em&gt;pending, finished, or canceled&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you have ever worked with &lt;em&gt;JavaScript Promises&lt;/em&gt; before, &lt;code&gt;Future&lt;/code&gt; is very similar to a &lt;code&gt;Promise&lt;/code&gt;: you know its execution will &lt;em&gt;eventually&lt;/em&gt; be done, but you can not know when. The nice thing is: it is &lt;strong&gt;non-blocking code&lt;/strong&gt;, meaning the Python interpreter does not have to wait until the scheduled task's execution finishes before running the next line of code.&lt;/p&gt;

&lt;p&gt;Thus, in our scenario, we could &lt;em&gt;schedule&lt;/em&gt; three tasks, one for querying each platform (Facebook, GitHub, and Twitter) for a user email address. This way, once any of these tasks &lt;em&gt;eventually&lt;/em&gt; returns a value, I can &lt;em&gt;early return&lt;/em&gt; if the value is &lt;code&gt;True&lt;/code&gt;, since all we want to know is if the user has an account in any of these platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talk is cheap. Show me the code.
&lt;/h2&gt;

&lt;p&gt;The example code below is easy to follow but I strongly suggest you read the commented lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;  &lt;span class="c1"&gt;# I will use it to simulate latency with time.sleep
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;as_completed&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 5 seconds! That is bad.
&lt;/span&gt;    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished facebook after 5 seconds!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 1 second. Phew!
&lt;/span&gt;    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished github after 1 second!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Well...
&lt;/span&gt;    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished twitter after 3 seconds!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="c1"&gt;# Main method that answers if a user has an account in any of the platforms
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_social_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# ThreadPoolExecutor is a subclass of Executor that uses threads.
&lt;/span&gt;    &lt;span class="c1"&gt;# max_workers is the max number of threads that will be used.
&lt;/span&gt;    &lt;span class="c1"&gt;# Since we are scheduling only 3 tasks, it does not make sense to have
&lt;/span&gt;    &lt;span class="c1"&gt;# more than 3 threads, otherwise we would be wasting resources.
&lt;/span&gt;    &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Schedule (submit) 3 tasks (one for each social account check)
&lt;/span&gt;    &lt;span class="c1"&gt;# .submit method returns a Future object
&lt;/span&gt;    &lt;span class="n"&gt;facebook_future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;twitter_future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;github_future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;future_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;facebook_future&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;github_future&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;twitter_future&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# as_completed receives an iterable of Future objects
&lt;/span&gt;    &lt;span class="c1"&gt;# and yields each future once it has been completed.
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;as_completed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;future_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# .result() returns the future object return value
&lt;/span&gt;        &lt;span class="n"&gt;future_return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;future_return_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;future_return_value&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# I can early return once any result is True
&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="n"&gt;user_email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user@email.com"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;has_social_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Finished github after 1 second!
User has social account.
&lt;span class="c"&gt;# The created threads will still run until completion&lt;/span&gt;
Finished twitter after 3 seconds!
Finished facebook after 5 seconds!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that even though &lt;code&gt;facebook_future&lt;/code&gt; takes longer than the other two scheduled tasks to finish, however, it does not &lt;strong&gt;block&lt;/strong&gt; the execution — it keeps working on its own thread. And although &lt;code&gt;github_future&lt;/code&gt; is the last scheduled task, it is the first to finish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Future&lt;/code&gt; is an object that represents a scheduled task that will &lt;strong&gt;eventually&lt;/strong&gt; finish.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Executor&lt;/code&gt; is the scheduler of tasks (once a task is scheduled, it returns a &lt;code&gt;Future&lt;/code&gt; object).

&lt;ul&gt;
&lt;li&gt;It can be a &lt;code&gt;ThreadPoolExecutor&lt;/code&gt; or a &lt;code&gt;ProcessPoolExecutor&lt;/code&gt; (using threads vs processes).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;One can use &lt;code&gt;executor.submit(callable)&lt;/code&gt; to schedule a task to be run asynchronously.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;as_completed&lt;/code&gt; receives an iterable of &lt;code&gt;Future&lt;/code&gt; objects and returns a generator where each yielded element is a &lt;strong&gt;finished&lt;/strong&gt; task.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When would I &lt;em&gt;not&lt;/em&gt; want to use concurrency then?
&lt;/h2&gt;

&lt;p&gt;As software engineers, our job is not only knowing &lt;strong&gt;how&lt;/strong&gt; to use a tool, but also &lt;strong&gt;when&lt;/strong&gt; to use it. Network operations (and I/O bound operations in general) are usually a good place to use concurrent code due to their latency. But there is always a trade-off...&lt;/p&gt;

&lt;p&gt;In the example above we &lt;strong&gt;traded off performance for resource usage.&lt;/strong&gt; How so? When using &lt;strong&gt;generators&lt;/strong&gt;, only the &lt;strong&gt;worst-case scenario&lt;/strong&gt; would end up consuming 3 services — one call for each &lt;code&gt;has_&amp;lt;plataform&amp;gt;_account&lt;/code&gt;. That's because we could early return &lt;code&gt;True&lt;/code&gt; if any service returned &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our new example using concurrency, we are &lt;strong&gt;always&lt;/strong&gt; consuming the 3 service — since the calls are made &lt;em&gt;asynchronously&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;"Ah, but that still could save us lots of time!", you say. It depends on the &lt;strong&gt;services&lt;/strong&gt; you're consuming. In the example above I artificially made the &lt;code&gt;has_facebook_account&lt;/code&gt; &lt;strong&gt;&lt;em&gt;really slow —&lt;/em&gt;&lt;/strong&gt; 5 times slower than the fastest alternative. But, if all the services had a similar response time and if &lt;strong&gt;saving resources&lt;/strong&gt; was important (suppose that calling each service would trigger a &lt;strong&gt;really heavy query&lt;/strong&gt; in the database, for instance), using a &lt;em&gt;synchronous&lt;/em&gt; code could be a better approach.&lt;/p&gt;

&lt;p&gt;For the sake of data: &lt;a href="https://www.statista.com/statistics/264810/number-of-monthly-active-facebook-users-worldwide/#:~:text=How%20many%20users%20does%20Facebook,the%20biggest%20social%20network%20worldwide."&gt;Facebook has over &lt;strong&gt;2.7 billion monthly active users&lt;/strong&gt;&lt;/a&gt;, while &lt;a href="https://www.statista.com/statistics/282087/number-of-monthly-active-twitter-users/"&gt;Twitter has around &lt;strong&gt;330 million&lt;/strong&gt;&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/GitHub#:~:text=As%20of%20January%202020%2C%20GitHub,source%20code%20in%20the%20world."&gt;GitHub has merely &lt;strong&gt;40 million users&lt;/strong&gt;&lt;/a&gt;. So, it is highly likely that calling the &lt;code&gt;has_facebook_account&lt;/code&gt; first would be enough in a huge majority of scenarios since it would return &lt;code&gt;True&lt;/code&gt; with a much higher frequency than the other services, thus, saving lots of unnecessary calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Know how to write concurrent code, which is pretty easy with Python Futures. But more important: know &lt;strong&gt;when&lt;/strong&gt; to do so. There are cases where the performance increase does not pay off the resource usage.&lt;/p&gt;

&lt;p&gt;I strongly advise you to read the &lt;a href="https://docs.python.org/3/library/concurrent.futures.html"&gt;docs on &lt;code&gt;concurrent.futures&lt;/code&gt;&lt;/a&gt; and the &lt;a href="https://amzn.to/33fS84W"&gt;Chapter 17 on Luciano Ramalho's excellent Fluent Python book&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/gcrsaldanha/2d4709f604212e4ebbd9b5e2dc9b4a67"&gt;Ah, and here is the gist if you want it!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>concurrency</category>
      <category>asynchronous</category>
      <category>threads</category>
    </item>
    <item>
      <title>Persist data to the Ethereum blockchain using Python, Truffle and Ganache</title>
      <dc:creator>Gabriel Saldanha</dc:creator>
      <pubDate>Mon, 25 May 2020 11:25:42 +0000</pubDate>
      <link>https://forem.com/gcrsaldanha/persist-data-to-the-ethereum-blockchain-using-python-truffle-and-ganache-47lb</link>
      <guid>https://forem.com/gcrsaldanha/persist-data-to-the-ethereum-blockchain-using-python-truffle-and-ganache-47lb</guid>
      <description>&lt;p&gt;The &lt;a href="https://dev.to/gcrsaldanha/deploy-a-smart-contract-on-ethereum-with-python-truffle-and-web3py-5on"&gt;previous post&lt;/a&gt; demonstrated how to write a simple smart contract with Solidity and deploy it to the Ethereum Blockchain.&lt;br&gt;
This tutorial will show how to update the contract to save some data in the blockchain as well as how to inspect the blockchain to see our transactions.&lt;/p&gt;

&lt;p&gt;We'll work on the same files from the previous tutorial, &lt;a href="https://github.com/gcrsaldanha/hello-eth/tree/v1.0"&gt;which can be found here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If not in the mood of going along with the tutorial, the finished code is &lt;a href="https://github.com/gcrsaldanha/hello-eth/tree/v2.0"&gt;available here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  TOC
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Updating our contract&lt;/li&gt;
&lt;li&gt;Executing a transaction&lt;/li&gt;
&lt;li&gt;Inspecting the blockchain with Ganache&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  1. Project setup &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;HelloWorld.sol&lt;/code&gt; and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt; pragma solidity &amp;gt;= 0.5.0;

 contract HelloWorld {
&lt;span class="gi"&gt;+    string public payload;
+
+    function setPayload(string memory content) public {
+        payload = content;
+    }
+
&lt;/span&gt;     function sayHello() public pure returns (string memory) {
         return 'Hello World!';
     }
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we did before, spin up &lt;code&gt;truffle&lt;/code&gt; local blockchain with &lt;code&gt;truffle develop&lt;/code&gt; CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;truffle develop
Truffle Develop started at http://127.0.0.1:9545/

Accounts:
&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt; 0x55660bb0918f9aade4db7b7ef7f71639750c2262
...
Private Keys:
&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt; ead0d6b318832f278b9a2ee1a6a6ab0156ab439d898394b6887d023bc929159c
...
&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, we need to &lt;strong&gt;update&lt;/strong&gt; our contract, what under Truffle's Suite is performed with the &lt;strong&gt;migrate&lt;/strong&gt; command. Write &lt;code&gt;migrate&lt;/code&gt; within Truffle's console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;Compiling your contracts...
&lt;span class="o"&gt;===========================&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling ./contracts/HelloWorld.sol
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Compiling ./contracts/Migrations.sol
...
2_deploy_contracts.js
&lt;span class="o"&gt;=====================&lt;/span&gt;

   Replacing &lt;span class="s1"&gt;'HelloWorld'&lt;/span&gt;
   &lt;span class="nt"&gt;----------------------&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; transaction &lt;span class="nb"&gt;hash&lt;/span&gt;:    0x6f55fc4a165225c6911d6e0acda8b4ec75b0962370eab66ab94aefd0e0cfd084
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Blocks: 0            Seconds: 0
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; contract address:    0x85534E0ec31b63d635CcBa1fb6b953a9C47a9022
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The contract is now updated with a public method &lt;code&gt;setPayload&lt;/code&gt; deployed at &lt;code&gt;0x85534E0ec31b63d635CcBa1fb6b953a9C47a9022&lt;/code&gt; (contract address). Write this address somewhere else, we will need it soon.&lt;br&gt;
We can verify that the contract was properly updated by fetching the contract instance and checking for &lt;code&gt;setPayload&lt;/code&gt; method existence, as well as the value of &lt;code&gt;payload&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# We're still inside Truffle's console&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;let &lt;/span&gt;instance &lt;span class="o"&gt;=&lt;/span&gt; await HelloWorld.deployed&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; instance.setPayload
&lt;span class="o"&gt;[&lt;/span&gt;Function] &lt;span class="o"&gt;{&lt;/span&gt;
  call: &lt;span class="o"&gt;[&lt;/span&gt;Function],
  sendTransaction: &lt;span class="o"&gt;[&lt;/span&gt;Function],
  estimateGas: &lt;span class="o"&gt;[&lt;/span&gt;Function],
  request: &lt;span class="o"&gt;[&lt;/span&gt;Function]
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; instance.payload.call&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="s1"&gt;''&lt;/span&gt;  &lt;span class="c"&gt;# Empty, as expected!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Executing a transaction &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;When we &lt;code&gt;call&lt;/code&gt; a function that only  returns a value, such as &lt;code&gt;sayHello&lt;/code&gt;, the blockchain state is not altered. Since now we want to save a value to the blockchain, its state must be altered and it is done via a &lt;code&gt;transaction&lt;/code&gt; execution.&lt;br&gt;
We want to execute this transaction from our &lt;code&gt;Python&lt;/code&gt; script, the same we used for calling the &lt;code&gt;sayHello&lt;/code&gt; method in the previous post.&lt;br&gt;
Add the following to the bottom of &lt;code&gt;app.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# executes setPayload function
&lt;/span&gt;&lt;span class="n"&gt;tx_hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'abc'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;transact&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# waits for the specified transaction (tx_hash) to be confirmed
# (included in a mined block)
&lt;/span&gt;&lt;span class="n"&gt;tx_receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;waitForTransactionReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'tx_hash: {}'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx_hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Also, update the &lt;code&gt;deployed_contract_address&lt;/code&gt; in &lt;code&gt;app.py&lt;/code&gt; with the new contract address (output from &lt;code&gt;migrate&lt;/code&gt;). If you don't remember it, go back to the Truffle console and call &lt;code&gt;instance.address&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On another terminal session, execute our Python script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;python app.py
Hello World!
tx_hash: 0x2b7bf989fd0fc692d0ef976b3293c39958ab7de64a08a3f66c0d758b871ad8e6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Not fun, right? How do we know that the data was persisted? Go back to the Truffle console and call &lt;code&gt;payload&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; instance.payload.call&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="s1"&gt;'abc'&lt;/span&gt;  &lt;span class="c"&gt;# cool! It changed!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This means that our transaction was &lt;strong&gt;mined&lt;/strong&gt;, thus being added to a block that was successfully added to the blockchain.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Inspecting the blockchain with Ganache&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;There are various ways for inspecting the blockchain. For example, using the Truffle console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fetch blockchain's latest mined block&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; block &lt;span class="o"&gt;=&lt;/span&gt; await web3.eth.getBlock&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"latest"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; block
&lt;span class="o"&gt;{&lt;/span&gt;
  number: 6,  &lt;span class="c"&gt;# YMMV&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;...&lt;span class="o"&gt;)&lt;/span&gt;
  transactions: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'0x2b7bf989fd0fc692d0ef976b3293c39958ab7de64a08a3f66c0d758b871ad8e6'&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;transactions&lt;/code&gt; lists all the transactions that were added to this block. In this case, there is one transaction that should match &lt;code&gt;tx_hash&lt;/code&gt; that was printed when we ran &lt;code&gt;app.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To make our lives easier, there is a GUI tool for inspecting the blockchain and its transactions: &lt;a href="https://www.trufflesuite.com/ganache"&gt;Ganache&lt;/a&gt;. As per their website:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quickly fire up a personal Ethereum blockchain which you can use to run tests, execute commands, and inspect state while controlling how the chain operates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After successfully installing and opening it, you should see the following image:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DeEm6jkz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ifjel8i76vgwo3whrzzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DeEm6jkz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ifjel8i76vgwo3whrzzw.png" alt="Ganache initial screen"&gt;&lt;/a&gt;&lt;br&gt;
Select "Quickstart" and you'll be welcomed with a screen listing some accounts and its respective addresses (very similar to how &lt;code&gt;truffle develop&lt;/code&gt; works). There will be also a &lt;code&gt;RPC Server&lt;/code&gt; address, such as &lt;code&gt;http://127.0.0.1:8545&lt;/code&gt;, write that down. Click "Save" (top-right corner) so this Ganache workspace is persisted.&lt;/p&gt;

&lt;p&gt;When quick-starting Ganache, it created another local blockchain for us. We can now tell &lt;code&gt;truffle&lt;/code&gt; to use Ganache's blockchain (which has a nice UI). To do so, open &lt;code&gt;truffle-config.js&lt;/code&gt; and replace it with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// host and port should match the RPC Server address&lt;/span&gt;
      &lt;span class="c1"&gt;// as seen in Ganache&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8545&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go to the Contracts tab, and select &lt;code&gt;Link Truffle Projects&lt;/code&gt;. Click &lt;code&gt;Add Project&lt;/code&gt; then select the &lt;code&gt;truffle-config.js&lt;/code&gt; file from &lt;code&gt;hello-eth/&lt;/code&gt; root project folder. Click &lt;code&gt;Save and Restart&lt;/code&gt; at the upper-right corner.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GlS-B622--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ceksfiejbzmcf9a04ry1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GlS-B622--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ceksfiejbzmcf9a04ry1.png" alt="Add Project screen of Ganache"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you go to the Contracts tab now, you should see two contracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HelloWorld: Not Deployed&lt;/li&gt;
&lt;li&gt;Migrations: Not Deployed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open another terminal session, go to the project root level (where &lt;code&gt;truffle-config.js&lt;/code&gt; is located), and type &lt;code&gt;truffle migrate&lt;/code&gt;. It will deploy our contracts to Ganache's blockchain. Copy the &lt;code&gt;HelloWorld&lt;/code&gt; contract address and update the &lt;code&gt;deployed_contract_address&lt;/code&gt; in &lt;code&gt;app.py&lt;/code&gt; with its new value, as well as the variable &lt;code&gt;blockchain_address&lt;/code&gt; with &lt;code&gt;http://127.0.0.1:8545&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- blockchain_address = 'http://127.0.0.1:9545'  # truffle blockchain
&lt;/span&gt;&lt;span class="gi"&gt;+ blockchain_address = 'http://127.0.0.1:8545'  # ganache blockchain
&lt;/span&gt;&lt;span class="gd"&gt;- deployed_contract_address = '0x85534E0ec31b63d635CcBa1fb6b953a9C47a9022'
&lt;/span&gt;&lt;span class="gi"&gt;+ deployed_contract_address = '0x433D7E91B659CB4f1bbBb8dacd2B1cBBa7F82F1A'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Under Contracts tab now, both contracts (&lt;code&gt;HelloWorld&lt;/code&gt; and &lt;code&gt;Migrations&lt;/code&gt;) should have an address. It means they're deployed! woohoo!&lt;br&gt;
Now, run &lt;code&gt;app.py&lt;/code&gt; again to execute a new transaction on our newest blockchain and then click on &lt;code&gt;HelloWorld&lt;/code&gt; contract:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t1waZZ3x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rybnj2vyjbwa6ahzb55z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t1waZZ3x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rybnj2vyjbwa6ahzb55z.png" alt="HelloWorld contract showing transactions"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Notice the &lt;code&gt;TX HASH&lt;/code&gt;, it should be the same as printed when you ran &lt;code&gt;app.py&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And if you click on the transaction itself:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wie8wj7d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r7rp44rvlagcmftw7hy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wie8wj7d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r7rp44rvlagcmftw7hy5.png" alt="Showing transaction information"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;You can see both the function that was called and the inputs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;app.py&lt;/code&gt; a few more times, change &lt;code&gt;abc&lt;/code&gt; (in &lt;code&gt;tx_hash = contract.functions.setPayload('abc').transact()&lt;/code&gt;) to something else, then inspect your contract again. It's YOUR blockchain now, act up to it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a method that changes the blockchain state;&lt;/li&gt;
&lt;li&gt;Use Truffle CLI to interact with a deployed smart contract;&lt;/li&gt;
&lt;li&gt;Use Ganache app both as the blockchain provider as well as its inspector;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If something is not clear or if there are any suggestions, please leave a comment below!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Deploy a Smart Contract on Ethereum with Python, Truffle and web3py</title>
      <dc:creator>Gabriel Saldanha</dc:creator>
      <pubDate>Tue, 12 May 2020 13:10:13 +0000</pubDate>
      <link>https://forem.com/gcrsaldanha/deploy-a-smart-contract-on-ethereum-with-python-truffle-and-web3py-5on</link>
      <guid>https://forem.com/gcrsaldanha/deploy-a-smart-contract-on-ethereum-with-python-truffle-and-web3py-5on</guid>
      <description>&lt;p&gt;In this tutorial, we'll write a simple smart contract, deploy it to a personal Ethereum blockchain, and call the contract from a Python script.&lt;/p&gt;

&lt;p&gt;What you need to have installed before we proceed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python3 v3.5.3 or later, I had some issues using version 3.8 then switched to 3.5.3;&lt;/li&gt;
&lt;li&gt;NodeJS v8.9.4 or later (for installing &lt;code&gt;truffle&lt;/code&gt;);&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full project code is available at &lt;a href="https://github.com/gcrsaldanha/hello-eth/tree/v1.0"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TOC
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Project Setup&lt;/li&gt;
&lt;li&gt;Writing the smart contract&lt;/li&gt;
&lt;li&gt;Deploying smart contract to the blockchain&lt;/li&gt;
&lt;li&gt;Calling the deployed contract&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Project setup &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;First, let's create a folder for the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;hello-eth
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;hello-eth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;hello-eth&lt;/code&gt; folder, install &lt;code&gt;truffle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;truffle
...
&lt;span class="c"&gt;# You should something like this once the installation process is finished&lt;/span&gt;
+ truffle@5.1.25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use the &lt;code&gt;truffle&lt;/code&gt; CLI tool to initialize an empty smart contract project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./node_modules/.bin/truffle init
&lt;span class="c"&gt;# if truffle was installed globally (npm install -g truffle): $ truffle init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will create the following project structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;contracts/&lt;/code&gt;: Directory for Solidity contracts source code (&lt;code&gt;.sol&lt;/code&gt; files).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;migrations/&lt;/code&gt;: Directory for contracts migration files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test/&lt;/code&gt;: Directory for test files. Won't be covered in this tutorial.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;truffle.js&lt;/code&gt;: Truffle configuration file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;contracts/&lt;/code&gt; and &lt;code&gt;migrations/&lt;/code&gt; folders will already contain a &lt;code&gt;Migration&lt;/code&gt; contract and its deploy script (&lt;code&gt;1_initial_migration.js&lt;/code&gt;). This contract is used by truffle to keep track of the migrations of our contracts. It won't be covered in this tutorial, so don't worry about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Writing the smart contract &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Yes, I'll use the &lt;code&gt;Hello World&lt;/code&gt; example. Create a file called &lt;code&gt;HelloWorld.sol&lt;/code&gt; inside &lt;code&gt;contracts/&lt;/code&gt; folder and add the following content to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="nc"&gt;HelloWorld&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayHello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="nf"&gt;returns&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;Hello&lt;/span&gt; &lt;span class="nc"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the project root folder, use &lt;code&gt;truffle&lt;/code&gt; to compile the contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./node_modules/.bin/truffle compile  &lt;span class="c"&gt;# or just truffle compile if installed globally...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will output the compiled contract &lt;code&gt;HelloWorld.sol&lt;/code&gt; as &lt;code&gt;HelloWorld.json&lt;/code&gt; inside &lt;code&gt;build/contracts/&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;We now have a compiled contract and are ready to deploy it to our running to the (local) blockchain.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Deploying smart contract to the blockchain &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;To deploy our smart contract to the blockchain we first need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a migration script;&lt;/li&gt;
&lt;li&gt;a blockchain to deploy the contract to;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the migration script, create a file named &lt;code&gt;2_deploy_contract.js&lt;/code&gt; inside &lt;code&gt;migrations/&lt;/code&gt; folder and add the following content to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HelloWorld&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HelloWorld&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Truffle suite contains a personal blockchain that we can use for testing purposes. Open your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;truffle develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see an output similar to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Truffle Develop started at http://127.0.0.1:9545/

Accounts:
&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt; 0xdfb772fba7631b5bfde93cc3e2b0e488d1a17b2a
...
&lt;span class="o"&gt;(&lt;/span&gt;9&lt;span class="o"&gt;)&lt;/span&gt; 0x974779d6a98264043e8bb1c8b0cf93d9c7141a29

Private Keys:
...

truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now &lt;code&gt;migrate&lt;/code&gt; our contract, which calls each migration in &lt;code&gt;migrations/&lt;/code&gt; (in order), deploying the contracts to the blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;truffle&lt;span class="o"&gt;(&lt;/span&gt;develop&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; migrate
Starting migrations...
...
2_deploy_contracts.js
&lt;span class="o"&gt;=====================&lt;/span&gt;

   Deploying &lt;span class="s1"&gt;'HelloWorld'&lt;/span&gt;
   &lt;span class="nt"&gt;----------------------&lt;/span&gt;
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; transaction &lt;span class="nb"&gt;hash&lt;/span&gt;:    0xddc3dd045a7b6f70063303ff534d07e93c1dcb7a0a6c15e42fe281c7d2ab53e8
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Blocks: 0            Seconds: 0
   &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; contract address:    0xb7afC8dB8EEf302cd30553B39cEa0599093FDE3C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;contract address&lt;/code&gt; is the address on the Ethereum network that hosts this contract instance.&lt;br&gt;
Sweet! We now have a Smart Contract deployed on our personal Ethereum blockchain. Next step is call it from a Python script.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Calling the deployed contract &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Under the project root folder (&lt;code&gt;hello-eth/&lt;/code&gt;) create a file named &lt;code&gt;app.py&lt;/code&gt; with the following content (pay attention to the comments explaining the script):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;web3&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPProvider&lt;/span&gt;

&lt;span class="c1"&gt;# truffle development blockchain address
&lt;/span&gt;&lt;span class="n"&gt;blockchain_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'http://127.0.0.1:9545'&lt;/span&gt;
&lt;span class="c1"&gt;# Client instance to interact with the blockchain
&lt;/span&gt;&lt;span class="n"&gt;web3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockchain_address&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# Set the default account (so we don't need to set the "from" for every transaction call)
&lt;/span&gt;&lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Path to the compiled contract JSON file
&lt;/span&gt;&lt;span class="n"&gt;compiled_contract_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'build/contracts/HelloWorld.json'&lt;/span&gt;
&lt;span class="c1"&gt;# Deployed contract address (see `migrate` command output: `contract address`)
&lt;/span&gt;&lt;span class="n"&gt;deployed_contract_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'0xb7afC8dB8EEf302cd30553B39cEa0599093FDE3C'&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compiled_contract_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;contract_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# load contract info as JSON
&lt;/span&gt;    &lt;span class="n"&gt;contract_abi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contract_json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'abi'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# fetch contract's abi - necessary to call its functions
&lt;/span&gt;
&lt;span class="c1"&gt;# Fetch deployed contract reference
&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;deployed_contract_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;contract_abi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Call contract function (this is not persisted to the blockchain)
&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, execute the following commands in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip3 &lt;span class="nb"&gt;install &lt;/span&gt;web3
&lt;span class="nv"&gt;$ &lt;/span&gt;python3 app.py
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Hello World!'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a simple Smart Contract in Solidity;&lt;/li&gt;
&lt;li&gt;Create a personal Ethereum Blockchain for tests and development;&lt;/li&gt;
&lt;li&gt;Deploy a contract to the blockchain using &lt;code&gt;truffle&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Call the contract function from a Python application.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I will write two follow-up posts in the next few days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how to persist data to the blockchain via a Web API using Flask;&lt;/li&gt;
&lt;li&gt;how to use Ganache as the personal blockchain provider (which has a nice GUI to inspect transactions);&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd like to be notified when that comes up, make sure to follow me on Dev.to.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Using Python Generators to avoid extra service calls</title>
      <dc:creator>Gabriel Saldanha</dc:creator>
      <pubDate>Tue, 28 Apr 2020 14:45:21 +0000</pubDate>
      <link>https://forem.com/gcrsaldanha/using-python-generators-to-avoid-extra-service-calls-pl</link>
      <guid>https://forem.com/gcrsaldanha/using-python-generators-to-avoid-extra-service-calls-pl</guid>
      <description>&lt;p&gt;This is my first post on &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;, and actually my first public post on the Internet that is not a tweet. Feedbacks are very welcome! :)&lt;/p&gt;




&lt;p&gt;I've been using Python Generators for a while now, having to deal with large &lt;code&gt;Django Querysets&lt;/code&gt;, reading large Excel files, and being able to save memory by using generators became part of my day to day work. However, these days I faced a different problem where I wanted to avoid making extra calls to services and solved it with generators. This is what this post is about.&lt;/p&gt;

&lt;p&gt;Suppose you want to check if a given &lt;code&gt;user_email&lt;/code&gt; is registered in &lt;strong&gt;any&lt;/strong&gt; of the following social media: Facebook, Github, or Twitter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'calling Facebook service'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'calling Github service'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'calling Twitter service'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_social_media_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Checking social media apps...'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Python's `any` receives an Iterable
&lt;/span&gt;    &lt;span class="c1"&gt;# and returns True when the first truthy clause is found.
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="n"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;# This is False
&lt;/span&gt;        &lt;span class="n"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;# This is True
&lt;/span&gt;        &lt;span class="n"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;# This is True
&lt;/span&gt;    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Done!'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What is wrong with the approach above? Well, if you run it locally you will see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; has_social_media_account&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fake@email.com'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
Checking social media apps...
calling Facebook service  &lt;span class="c"&gt;# This is False, keep going...&lt;/span&gt;
calling Github service  &lt;span class="c"&gt;# This is True! I can stop now...&lt;/span&gt;
calling Twitter service  &lt;span class="c"&gt;# Oh no!&lt;/span&gt;
Done!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The problem is that a &lt;code&gt;list&lt;/code&gt; is evaluated as soon as it is created (opposite to &lt;em&gt;lazy evaluation&lt;/em&gt;). Thus, if it's a list of method calls, all the calls will be performed.&lt;/p&gt;

&lt;p&gt;At the moment, I thought the problem was that I was actually &lt;em&gt;calling&lt;/em&gt; the methods when initializing the list. So maybe keeping only the methods references and using a &lt;em&gt;list comprehension&lt;/em&gt; would do the trick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_social_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Refs
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Well, it did not work as I wanted either. As I said before, &lt;code&gt;a list is fully evaluated upon its creation&lt;/code&gt;. In the example above, it will first make sure to call all methods so the list is &lt;em&gt;fully built&lt;/em&gt;, having all of its elements evaluated - which in turn means having all methods being called. The list comprehension is not aware of its context either, i.e., it does not know that it is being used as an argument to &lt;code&gt;any(...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How did I solve it? By using generator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_social_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;has_facebook_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;has_github_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;has_twitter_account&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Note the ( ) instead of [ ]
&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;has_social_account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'fake@email.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="n"&gt;Facebook&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;  &lt;span class="c1"&gt;# This is False, keep going...
&lt;/span&gt;&lt;span class="n"&gt;calling&lt;/span&gt; &lt;span class="n"&gt;Github&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;  &lt;span class="c1"&gt;# Aw yeah!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;(call(user_email) for call in calls)&lt;/code&gt; evaluates to a &lt;code&gt;generator&lt;/code&gt; (not a fully built list), which is then used by &lt;code&gt;any&lt;/code&gt;. &lt;code&gt;any(...)&lt;/code&gt; will &lt;em&gt;iterate&lt;/em&gt; over the generator elements evaluating &lt;strong&gt;one at a time&lt;/strong&gt;. This way, no extra calls are being made for once &lt;code&gt;any&lt;/code&gt; evaluates the second element (&lt;code&gt;has_github_account(user_email) -&amp;gt; True&lt;/code&gt;), the &lt;code&gt;any&lt;/code&gt; function is evaluated itself, returning &lt;code&gt;True&lt;/code&gt; and not calling the third service method (&lt;code&gt;has_twitter_account&lt;/code&gt;). &lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/gcrsaldanha/dfdf007cc015a4a36ccddef88def617a"&gt;Here is the Gist if you're interested&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please let me know in the comments below if something is not clear and/or if you'd like to have a more in-depth article on Python Generators.&lt;/p&gt;

</description>
      <category>python</category>
      <category>generators</category>
      <category>beginners</category>
      <category>tips</category>
    </item>
  </channel>
</rss>
