<?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: Phantz</title>
    <description>The latest articles on Forem by Phantz (@totally_chase).</description>
    <link>https://forem.com/totally_chase</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%2F282278%2F03edce00-7486-4095-90cd-444b12819e4f.png</url>
      <title>Forem: Phantz</title>
      <link>https://forem.com/totally_chase</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/totally_chase"/>
    <language>en</language>
    <item>
      <title>Wanna have fun with Lazy Iterators in good ol' C?</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Fri, 14 May 2021 11:27:05 +0000</pubDate>
      <link>https://forem.com/totally_chase/wanna-have-fun-with-lazy-iterators-in-good-ol-c-m2o</link>
      <guid>https://forem.com/totally_chase/wanna-have-fun-with-lazy-iterators-in-good-ol-c-m2o</guid>
      <description>&lt;p&gt;I made a demonstration + explanation of implementing a lazy iterator interface in pure C99. As well as implementing strong lazy abstractions with the iterators!&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href="https://github.com/TotallyNotChase/c-iterators"&gt;on github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>c</category>
      <category>functional</category>
      <category>github</category>
    </item>
    <item>
      <title>How you can implement resumable tasks in celery</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Sun, 20 Dec 2020 12:45:07 +0000</pubDate>
      <link>https://forem.com/totally_chase/how-you-can-implement-resumable-tasks-in-celery-3nk5</link>
      <guid>https://forem.com/totally_chase/how-you-can-implement-resumable-tasks-in-celery-3nk5</guid>
      <description>&lt;h1&gt;
  
  
  Preface
&lt;/h1&gt;

&lt;p&gt;Celery is highly scalable task system for python. It allows you to send tasks to queues and execute them asynchronously over a worker. Celery tasks on their own are very useful, however a lot of times I've noticed the need to have to pause/cancel a task. Now celery &lt;em&gt;does&lt;/em&gt; allow you to shut down a task queue to cancel tasks. But I wanted something scalable, to pause, continue and cancel a task (without disrupting the queue) without any loss of data.&lt;/p&gt;

&lt;p&gt;So I decided to use the &lt;a href="https://en.wikipedia.org/wiki/Workflow_pattern"&gt;workflow pattern&lt;/a&gt;, aided with a &lt;a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/ControlBus.html"&gt;control bus&lt;/a&gt; to achieve this. Maybe this guide will help out someone else looking for pausable/resumable celery tasks as well!&lt;/p&gt;

&lt;p&gt;You can find the full demonstration to play around with, in &lt;a href="https://github.com/TotallyNotChase/resumable-celery-tasks"&gt;my github repo&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Guide
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://docs.celeryproject.org/en/stable/userguide/canvas.html"&gt;celery workflows&lt;/a&gt; - you can design your entire operation to be divided into a &lt;a href="https://docs.celeryproject.org/en/stable/userguide/canvas.html#chains"&gt;&lt;code&gt;chain&lt;/code&gt;&lt;/a&gt; of tasks. It doesn't necessarily have to be purely a chain, but it should follow the general concept of one task after another task (or task &lt;a href="https://docs.celeryproject.org/en/stable/userguide/canvas.html#groups"&gt;&lt;code&gt;group&lt;/code&gt;&lt;/a&gt;) finishes.&lt;/p&gt;

&lt;p&gt;Once you have a workflow like that, you can &lt;em&gt;finally define&lt;/em&gt; points to pause at throughout your workflow. At &lt;em&gt;each&lt;/em&gt; of these points, you can check whether or not the frontend user has &lt;strong&gt;requested the operation to pause&lt;/strong&gt; and continue accordingly. The concept is this:-&lt;/p&gt;

&lt;p&gt;A complex and time consuming operation O is split into 5 celery tasks - T1, T2, T3, T4, and T5 - each of these tasks (except the first one) depend on the return value of the previous task. &lt;/p&gt;

&lt;p&gt;Let's assume we define points to pause &lt;em&gt;after every single task&lt;/em&gt;, so the workflow looks like-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;T1 executes&lt;/li&gt;
&lt;li&gt;T1 completes, check if user has requested pause

&lt;ul&gt;
&lt;li&gt;If user has not requested pause - continue&lt;/li&gt;
&lt;li&gt;If user has requested pause, &lt;strong&gt;serialize&lt;/strong&gt; the &lt;em&gt;remaining workflow chain&lt;/em&gt; and store it somewhere to continue later&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and so on. Since there's a pause point after each task, that check is performed after every one of them (except the last one of course).&lt;/p&gt;

&lt;p&gt;But this is only theory, I struggled to find an implementation of this anywhere online so here's what I came up with-&lt;/p&gt;

&lt;h1&gt;
  
  
  Implementation
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;celery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;shared_task&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;celery.canvas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;


&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;shared_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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;pause_or_continue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Task to use for deciding whether to pause the operation chain
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;retval&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Pause requested, call given callback with retval and remaining chain
&lt;/span&gt;        &lt;span class="c1"&gt;# chain should be reversed as the order of execution follows from end to start
&lt;/span&gt;        &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;retval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;[::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Pausing"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Continue to the next task in chain
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;retval&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tappable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Make a operation workflow chain pause-able/resume-able by inserting
    the pause_or_continue task for every nth task in given chain

    ch: chain
        The workflow chain

    clause: Signature
        Signature of a task that takes one argument - return value of
        last executed task in workflow (if any - othewise `None` is passsed)
        - and returns a boolean, indicating whether or not the operation should continue

        Should return True if operation should continue normally, or be paused

    callback: Signature
        Signature of a task that takes 2 arguments - return value of
        last executed task in workflow (if any - othewise `None` is passsed) and
        remaining chain of the operation workflow as a json dict object
        No return value is expected

        This task will be called when `clause` returns `True` (i.e task is pausing)
        The return value and the remaining chain can be handled accordingly by this task

    nth: Int
        Check `clause` after every nth task in the chain
        Default value is 1, i.e check `clause` after every task
        Hence, by default, user given `clause` is called and checked
        after every task

    NOTE: The passed in chain is mutated in place
    Returns the mutated chain
    """&lt;/span&gt;
    &lt;span class="n"&gt;newch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&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;n&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;nth&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nth&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;newch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pause_or_continue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clause&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;newch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newch&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;ch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*The implementation can also be seen in &lt;a href="https://github.com/TotallyNotChase/resumable-celery-tasks/blob/master/app/tappable.py"&gt;&lt;code&gt;tappable.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation - &lt;code&gt;pause_or_continue&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Here &lt;code&gt;pause_or_continue&lt;/code&gt; is the aforementioned &lt;em&gt;pause point&lt;/em&gt;. It's a task that will be called at specific intervals (intervals as in task intervals, not as in time intervals). This task then calls a user provided function (actually a task) - &lt;code&gt;clause&lt;/code&gt; - to check whether or not the task should continue.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;clause&lt;/code&gt; function (actually a task) returns &lt;code&gt;True&lt;/code&gt;, the user provided &lt;code&gt;callback&lt;/code&gt; function is called, the latest return value (if any - &lt;code&gt;None&lt;/code&gt; otherwise) is passed onto this callback, as well as the &lt;strong&gt;remaining chain of tasks&lt;/strong&gt;. The &lt;code&gt;callback&lt;/code&gt; does what it needs to do and &lt;code&gt;pause_or_continue&lt;/code&gt; sets &lt;code&gt;self.request.chain&lt;/code&gt; to &lt;code&gt;None&lt;/code&gt;, which tells celery "The task chain is now empty - everything is finished".&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;clause&lt;/code&gt; function (actually a task) returns &lt;code&gt;False&lt;/code&gt;, the return value from the previous task (if any - &lt;code&gt;None&lt;/code&gt; otherwise) is returned back for the next task to receive - and the chain goes on. Hence the workflow continues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why are &lt;code&gt;clause&lt;/code&gt; and &lt;code&gt;callback&lt;/code&gt; task signatures and not regular functions?
&lt;/h3&gt;

&lt;p&gt;Both &lt;code&gt;clause&lt;/code&gt; and &lt;code&gt;callback&lt;/code&gt; are being called &lt;em&gt;directly&lt;/em&gt; - without &lt;code&gt;delay&lt;/code&gt; or &lt;code&gt;apply_async&lt;/code&gt;. It is executed in the current process, in the current context. So it behaves exactly like a normal function, then why use &lt;a href="https://docs.celeryproject.org/en/stable/userguide/canvas.html#signatures"&gt;&lt;code&gt;signatures&lt;/code&gt;&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;The answer is serialization. You can't conveniently pass a regular function object to a celery task. But you &lt;em&gt;can&lt;/em&gt; pass a task signature. That's exactly what I'm doing here. Both &lt;code&gt;clause&lt;/code&gt; and &lt;code&gt;callback&lt;/code&gt; should be a &lt;strong&gt;regular&lt;/strong&gt; &lt;code&gt;signature&lt;/code&gt; object of a celery task.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is &lt;code&gt;self.request.chain&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;self.request.chain&lt;/code&gt; stores a list of dicts (representing jsons as the celery task serializer is json by default) - each of them representing a task signature. Each task from this list is executed in reverse order. Which is why, the list is reversed before passing to the user provided &lt;code&gt;callback&lt;/code&gt; function (actually a task) - the user probably expects the order of tasks to be left to right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick note&lt;/strong&gt;: Irrelevant to this discussion, but if you're using the &lt;code&gt;link&lt;/code&gt; parameter from &lt;code&gt;apply_async&lt;/code&gt; to construct a chain instead of the &lt;code&gt;chain&lt;/code&gt; primitive itself. &lt;code&gt;self.request.callback&lt;/code&gt; is the property to be modified (i.e set to &lt;code&gt;None&lt;/code&gt; to remove callback and stop chain) instead of &lt;code&gt;self.request.chain&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation - &lt;code&gt;tappable&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tappable&lt;/code&gt; is just a basic function that takes a chain (which is the only workflow primitive covered here, for brevity) and inserts &lt;code&gt;pause_or_continue&lt;/code&gt; after every &lt;code&gt;nth&lt;/code&gt; task. You can insert them wherever you want really, it is upto you to define pause points in your operation. This is just an example!&lt;/p&gt;

&lt;p&gt;For each &lt;code&gt;chain&lt;/code&gt; object, the actual signatures of tasks (in order, going from left to right) is stored in the &lt;code&gt;.tasks&lt;/code&gt; property. It's a &lt;em&gt;tuple&lt;/em&gt; of task signatures. So all we have to do, is take this tuple, convert into a list, insert the pause points and convert back to a tuple to assign to the chain. Then return the modified chain object.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;clause&lt;/code&gt; and &lt;code&gt;callback&lt;/code&gt; is also attached to the &lt;code&gt;pause_or_continue&lt;/code&gt; signature. Normal celery stuff.&lt;/p&gt;

&lt;p&gt;That covers the primary concept, but to showcase a real project using this pattern (and also to showcase the resuming part of a paused task), here's a small demo of all the necessary resources&lt;/p&gt;

&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;p&gt;This example usage assumes the concept of a basic web server with a database. Whenever an operation (i.e workflow chain) is started, it's &lt;em&gt;assigned an id&lt;/em&gt; and stored into the database. The schema of that table looks like-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create operations table&lt;/span&gt;
&lt;span class="c1"&gt;-- Keeps track of operations and the users that started them&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;operations&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;requester_id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;completion&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;workflow_store&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;result&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requester_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;The only field that needs to be known about right now, is &lt;code&gt;completion&lt;/code&gt;. It just stores the status of the operation-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the operation starts and a db entry is created, this is set to &lt;code&gt;IN PROGRESS&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When a user requests pause, the route controller (i.e view) modifies this to &lt;code&gt;REQUESTING PAUSE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When the operation actually gets paused and &lt;code&gt;callback&lt;/code&gt; (from &lt;code&gt;tappable&lt;/code&gt;, inside &lt;code&gt;pause_or_continue&lt;/code&gt;) is called, the &lt;code&gt;callback&lt;/code&gt; should modify this to &lt;code&gt;PAUSED&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;When the task is completed, this should be modified to &lt;code&gt;COMPLETED&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  An example of &lt;code&gt;clause&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;celery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;task&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;should_pause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# This is the `clause` to be used for `tappable`
&lt;/span&gt;    &lt;span class="c1"&gt;# i.e it lets celery know whether to pause or continue
&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Check the database to see if user has requested pause on the operation
&lt;/span&gt;    &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"SELECT * FROM operations WHERE id = ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;fetchone&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;operation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"completion"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"REQUESTING PAUSE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the task to call at the pause points, to determine whether or not to pause. It's a function that takes 2 parameters.....well sort of. The first one is mandatory, &lt;code&gt;tappable&lt;/code&gt; &lt;em&gt;requires&lt;/em&gt; the &lt;code&gt;clause&lt;/code&gt; to have one (and exactly one) argument - so it can pass the previous task's return value to it (even if that return value is &lt;code&gt;None&lt;/code&gt;). In this example, the return value isn't required to be used - so we can just ignore it.&lt;/p&gt;

&lt;p&gt;The second parameter is an operation id. See, all this &lt;code&gt;clause&lt;/code&gt; does - is check a database for the operation (the workflow) entry and see if it has the status &lt;code&gt;REQUESTING PAUSE&lt;/code&gt;. To do that, it needs to know the operation id. But &lt;code&gt;clause&lt;/code&gt; should be a task with one argument, what gives?&lt;/p&gt;

&lt;p&gt;Well, good thing signatures can be partial. When the task is first started and a &lt;code&gt;tappable&lt;/code&gt; chain is created. The operation id &lt;em&gt;is known&lt;/em&gt; and hence we can do &lt;code&gt;should_pause.s(operation_id)&lt;/code&gt; to get the signature of a task that takes &lt;strong&gt;one&lt;/strong&gt; parameter, that being the return value of the previous task. That qualifies as a &lt;code&gt;clause&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  An example of &lt;code&gt;callback&lt;/code&gt;
&lt;/h2&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;os&lt;/span&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;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;celery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;task&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;save_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# This is the `callback` to be used for `tappable`
&lt;/span&gt;    &lt;span class="c1"&gt;# i.e this is called when an operation is pausing
&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Prepare directories to store the workflow
&lt;/span&gt;    &lt;span class="n"&gt;operation_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"OPERATIONS"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;workflow_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"workflow.json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_dir&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;makedirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&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;# Store the remaining workflow chain, serialized into json
&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;workflow_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&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;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chains&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Store the result from the last task and the workflow json path
&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"""
        UPDATE operations
        SET completion = ?,
            workflow_store = ?,
            result = ?
        WHERE id = ?
        """&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PAUSED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workflow_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;retval&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the task to be called when the task &lt;em&gt;is being paused&lt;/em&gt;. Remember, this should take the last executed task's return value and the remaining list of signatures (in order, from left to right). There's an extra param - &lt;code&gt;operation_id&lt;/code&gt; - once again. The explanation for this is the same as the one for &lt;code&gt;clause&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This function stores the remaining chain in a json file (since it's a list of dicts). Remember, you can use a different serializer - I'm using json since it's the default task serializer used by celery.&lt;/p&gt;

&lt;p&gt;After storing the remaining chain, it updates the &lt;code&gt;completion&lt;/code&gt; status to &lt;code&gt;PAUSED&lt;/code&gt; and also logs the path to the json file into the db.&lt;/p&gt;

&lt;p&gt;Now, let's see these in action-&lt;/p&gt;

&lt;h2&gt;
  
  
  An example of starting the workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-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;start_operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;operation_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;operation_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"INSERT INTO operations (requester_id, completion) VALUES (?, ?)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"IN PROGRESS"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;lastrowid&lt;/span&gt;
    &lt;span class="c1"&gt;# Convert a regular workflow chain to a tappable one
&lt;/span&gt;    &lt;span class="n"&gt;tappable_workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tappable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;T3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;T4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;T5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="n"&gt;should_pause&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;save_state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Start the chain (i.e send task to celery to run asynchronously)
&lt;/span&gt;    &lt;span class="n"&gt;tappable_workflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;operation_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;operation_kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&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;operation_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A function that takes in a user id and starts an operation workflow. This is more or less an impractical dummy function modeled around a view/route controller. But I think it gets the general idea through.&lt;/p&gt;

&lt;p&gt;Assume &lt;code&gt;T[1-4]&lt;/code&gt; are all unit tasks of the operation, each taking the previous task's return as an argument. Just an example of a regular celery chain, feel free to go wild with your chains.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;T5&lt;/code&gt; is a task that saves the final result (result from &lt;code&gt;T4&lt;/code&gt;) to the database. So along with the return value from &lt;code&gt;T4&lt;/code&gt; it needs the &lt;code&gt;operation_id&lt;/code&gt;. Which is passed into the signature.&lt;/p&gt;

&lt;h2&gt;
  
  
  An example of pausing the workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-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;pause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"SELECT * FROM operations WHERE id = ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;fetchone&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;operation&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"completion"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"IN PROGRESS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Pause only if the operation is in progress
&lt;/span&gt;        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"""
            UPDATE operations
            SET completion = ?
            WHERE id = ?
            """&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"REQUESTING PAUSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'success'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'invalid id'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This employs the previously mentioned concept of modifying the db entry to change &lt;code&gt;completion&lt;/code&gt; to &lt;code&gt;REQUESTING PAUSE&lt;/code&gt;. Once this is committed, the next time &lt;code&gt;pause_or_continue&lt;/code&gt; calls &lt;code&gt;should_pause&lt;/code&gt;, it'll know that the user has requested the operation to pause and it'll do so accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  An example of resuming the workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-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;resume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"SELECT * FROM operations WHERE id = ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;fetchone&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;operation&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"completion"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"PAUSED"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Resume only if the operation is paused
&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;operation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"workflow_store"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Load the remaining workflow from the json
&lt;/span&gt;            &lt;span class="n"&gt;workflow_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="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Load the chain from the json (i.e deserialize)
&lt;/span&gt;        &lt;span class="n"&gt;workflow_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&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;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;serialized_ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Start the chain and feed in the last executed task result
&lt;/span&gt;        &lt;span class="n"&gt;workflow_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"""
            UPDATE operations
            SET completion = ?
            WHERE id = ?
            """&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IN PROGRESS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'success'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'invalid id'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recall that, when the operation is paused - the remaining workflow is stored in a json. Since we are currently restricting the workflow to a &lt;code&gt;chain&lt;/code&gt; object. We know this json is a list of signatures that should be turned into a &lt;code&gt;chain&lt;/code&gt;. So, we deserialize it accordingly and send it to the celery worker.&lt;/p&gt;

&lt;p&gt;Note that, this remaining workflow still has the &lt;code&gt;pause_or_continue&lt;/code&gt; tasks as they were originally - so this workflow itself, is once again pause-able/resume-able. When it pauses, the &lt;code&gt;workflow.json&lt;/code&gt; will simply be updated.&lt;/p&gt;

&lt;p&gt;And that's it! You can check out a more complex example in the repo itself. The tasks are in &lt;a href="https://github.com/TotallyNotChase/resumable-celery-tasks/blob/master/app/tasks.py"&gt;&lt;code&gt;tasks.py&lt;/code&gt;&lt;/a&gt;, these tasks are managed by the flask routes in &lt;a href="https://github.com/TotallyNotChase/resumable-celery-tasks/blob/master/app/operations.py"&gt;&lt;code&gt;operations.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A guide to testing flask applications using unittest!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Mon, 02 Nov 2020 14:14:08 +0000</pubDate>
      <link>https://forem.com/totally_chase/a-guide-to-testing-flask-applications-using-unittest-2k4n</link>
      <guid>https://forem.com/totally_chase/a-guide-to-testing-flask-applications-using-unittest-2k4n</guid>
      <description>&lt;p&gt;Flask is a backend web framework for python. One that is beloved by many python developers! But to make a great flask webapp, testing is important. I noticed the lack of a good library to integrate with the stdlib &lt;code&gt;unittest&lt;/code&gt; for testing flask apps. So I made one myself!&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://github.com/TotallyNotChase/flask-unittest"&gt;&lt;code&gt;flask-unittest&lt;/code&gt;&lt;/a&gt; on github!&lt;/p&gt;

&lt;p&gt;This tutorial will demonstrate how to test flask applications using the &lt;code&gt;FlaskClient&lt;/code&gt; object, i.e in an API centric way, &lt;em&gt;and&lt;/em&gt; also demonstrate how to test flask applications live, using a headless browser!&lt;/p&gt;

&lt;p&gt;If you're looking to use a &lt;code&gt;FlaskClient&lt;/code&gt; to test your app, I recommend you to read through &lt;a href="https://flask.palletsprojects.com/en/1.1.x/testing/"&gt;the official testing guide&lt;/a&gt;. It's super simple and should only take 5 minutes to read through!&lt;/p&gt;

&lt;h1&gt;
  
  
  Test using a &lt;code&gt;FlaskClient&lt;/code&gt; object
&lt;/h1&gt;

&lt;p&gt;The library provides us with the testcase &lt;code&gt;ClientTestCase&lt;/code&gt;, which creates a &lt;code&gt;FlaskClient&lt;/code&gt; object from a &lt;code&gt;Flask&lt;/code&gt; object for &lt;em&gt;each test method&lt;/em&gt;, that you can use to test your app. It also provides direct access to flask globals like &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, and &lt;code&gt;session&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Let's see how you could use &lt;code&gt;ClientTestCase&lt;/code&gt;&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;flask_unittest&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask_app&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_app&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flast_unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientTestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Assign the flask app object
&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_app&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;test_foo_with_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Use the client here
&lt;/span&gt;        &lt;span class="c1"&gt;# Example request to a route returning "hello world" (on a hypothetical app)
&lt;/span&gt;        &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertInResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'hello world!'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a flask app in a module named &lt;code&gt;flask_app&lt;/code&gt;, which has a function to create and return the &lt;code&gt;Flask&lt;/code&gt; app object. Just need to assign the returned object to &lt;code&gt;app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember, you don't &lt;em&gt;need&lt;/em&gt; a function to create and return the app. As long as you have a correctly configured app object, you can simply assign it!&lt;/p&gt;

&lt;p&gt;Now, we define a test method &lt;code&gt;test_foo_with_client&lt;/code&gt; with 2 parameters. The mandatory &lt;code&gt;self&lt;/code&gt; and a parameter named &lt;code&gt;client&lt;/code&gt;. For each test method, &lt;code&gt;ClientTestCase&lt;/code&gt; will create a &lt;code&gt;FlaskClient&lt;/code&gt; by using &lt;a href="https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.test_client"&gt;&lt;code&gt;.test_client&lt;/code&gt;&lt;/a&gt; and pass it to the test method.&lt;/p&gt;

&lt;p&gt;Now you can freely use this to make API calls to your app! In our example, we make a request to &lt;code&gt;/hello&lt;/code&gt;, which is a simple route returning &lt;code&gt;hello world!&lt;/code&gt; as a response. You can now use &lt;code&gt;assertInResponse&lt;/code&gt;, which is a utility method provided by &lt;code&gt;flask-unittest&lt;/code&gt;, to check if &lt;code&gt;hello world!&lt;/code&gt; actually exists in the response! (Note: you can also just use &lt;code&gt;assert 'hello world!' in rv.data&lt;/code&gt; for the same effect)&lt;/p&gt;

&lt;p&gt;Inside this test method, you also have access to flask globals like &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, and &lt;code&gt;session&lt;/code&gt;.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_foo_with_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/hello?q=paramfoo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'q'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;'paramFoo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Assertion succeeds
&lt;/span&gt;    &lt;span class="c1"&gt;# Do a POST request with valid credentials to login
&lt;/span&gt;    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;# Our flask app sets userId in session on a successful login
&lt;/span&gt;    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'userId'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Assertion succeeds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is obviously very useful for testing!&lt;/p&gt;

&lt;p&gt;You can also use the &lt;code&gt;setUp&lt;/code&gt; method to login to your webapp, and the session will persist in the actual test method! Because &lt;code&gt;setUp&lt;/code&gt;, &lt;code&gt;tearDown&lt;/code&gt; and the test method are ran together in a set - using the same &lt;code&gt;FlaskClient&lt;/code&gt;. The next test method along with its &lt;code&gt;setUp&lt;/code&gt; and &lt;code&gt;tearDown&lt;/code&gt; methods, however, will use a brand new &lt;code&gt;FlaskClient&lt;/code&gt; - and hence a new &lt;code&gt;session&lt;/code&gt;.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Login here
&lt;/span&gt;    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'b'&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;test_foo_with_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Check if the session is logged in
&lt;/span&gt;    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'userId'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Assertion succeeds
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Logout here, though there isn't really a need - since session is cleared for the next test method
&lt;/span&gt;    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/logout'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are also multiple utility methods for common assertions!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;assertStatus&lt;/code&gt; - Assert the status code of a response returned from a &lt;code&gt;client&lt;/code&gt; API call.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertResponseEqual&lt;/code&gt; - Assert the response &lt;code&gt;.data&lt;/code&gt; is equal to the given string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertJsonEqual&lt;/code&gt; - Assert the response &lt;code&gt;.json&lt;/code&gt; is equal to the given dict&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertInResponse&lt;/code&gt; - Assert given string/bytestring exists in response &lt;code&gt;.data&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertLocationHeader&lt;/code&gt; - Assert the location header in response is equal to the given string. Useful for redirect requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out a full example of using this testcase &lt;a href="https://github.com/TotallyNotChase/flask-unittest/blob/master/tests/flask_client_test.py"&gt;in the repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would you like the Flask app to be built per test method too? Instead of having it as a constant property of the class? Check out &lt;a href="https://github.com/TotallyNotChase/flask-unittest#test-using-both-flask-and-flaskclient"&gt;&lt;code&gt;AppClientTestCase&lt;/code&gt;&lt;/a&gt; (or even &lt;a href="https://github.com/TotallyNotChase/flask-unittest#test-using-flask"&gt;&lt;code&gt;AppTestCase&lt;/code&gt;&lt;/a&gt; if you don't need the functionality of the &lt;code&gt;FlaskClient&lt;/code&gt;)&lt;/p&gt;

&lt;h1&gt;
  
  
  Test a live flask server using &lt;code&gt;selenium&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;What if you want to just run a regular flask server live and use a headless browser like &lt;code&gt;selenium&lt;/code&gt; to test it out? &lt;code&gt;LiveTestCase&lt;/code&gt; and &lt;code&gt;LiveTestSuite&lt;/code&gt; is for you!&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;flask_unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;selenium.webdriver&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ChromeOptions&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;selenium.webdriver.common.by&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;By&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;selenium.webdriver.support.ui&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WebDriverWait&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;selenium.webdriver.support&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;expected_conditions&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;EC&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask_app&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_app&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flask_unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LiveTestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;std_wait&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;WebDriverWait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;classmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUpClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Initiate the selenium webdriver
&lt;/span&gt;        &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChromeOptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'--headless'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;std_wait&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebDriverWait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&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="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;classmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tearDownClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Quit the webdriver
&lt;/span&gt;        &lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quit&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;test_foo_with_driver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Use self.driver here
&lt;/span&gt;        &lt;span class="c1"&gt;# You also have access to self.server_url and self.app
&lt;/span&gt;        &lt;span class="c1"&gt;# Example of using selenium to go to index page and try to find some elements (on a hypothetical app)
&lt;/span&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;std_wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;presence_of_element_located&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LINK_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Register'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;std_wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;until&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;presence_of_element_located&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;By&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LINK_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Log In'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty simple, we instantiate the driver in &lt;code&gt;setUpClass&lt;/code&gt;, use it as we would normally in the test methods and quit it in &lt;code&gt;tearDownClass&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You'll have access to the flask app as well as the url the app is running on (localhost + port) in the testcase. (only in the instance methods though)&lt;/p&gt;

&lt;p&gt;The real juice of this is actually in &lt;code&gt;LiveTestSuite&lt;/code&gt;. Unlike the previous testcases, which can be run using the regular &lt;code&gt;unittest&lt;/code&gt; testsuite, or simply doing &lt;code&gt;unittest.main()&lt;/code&gt; - &lt;code&gt;LiveTestCase&lt;/code&gt; &lt;strong&gt;requires&lt;/strong&gt; you to use &lt;code&gt;LiveTestSuite&lt;/code&gt;&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;# Pass the flask app to suite
&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flask_unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LiveTestSuite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;# Add the testcase
&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;makeSuite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TestFoo&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# Run the suite
&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextTestRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verbosity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have to pass the flask app object to &lt;code&gt;LiveTestSuite&lt;/code&gt;, so it can spawn it using &lt;code&gt;.run&lt;/code&gt; - this same &lt;code&gt;app&lt;/code&gt; object will be available in the testcase.&lt;/p&gt;

&lt;p&gt;The flask server will be spawned as a daemon thread once the suite starts running and it runs for the duration of the program.&lt;/p&gt;

&lt;p&gt;Check out a full example of using this testcase &lt;a href="https://github.com/TotallyNotChase/flask-unittest/blob/master/tests/flask_live_test.py"&gt;in the repo&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;For more examples, including a full emulation of the &lt;a href="https://flask.palletsprojects.com/en/1.1.x/testing/"&gt;official flask testing example&lt;/a&gt;, check out the &lt;a href="https://github.com/TotallyNotChase/flask-unittest"&gt;repo&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>python</category>
      <category>showdev</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Pushing Native Messaging to the limits! - C vs Rust</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Thu, 04 Jun 2020 14:51:12 +0000</pubDate>
      <link>https://forem.com/totally_chase/pushing-native-messaging-to-the-limits-c-vs-rust-4nad</link>
      <guid>https://forem.com/totally_chase/pushing-native-messaging-to-the-limits-c-vs-rust-4nad</guid>
      <description>&lt;p&gt;I recently stumbled upon &lt;a href="https://stackoverflow.com/questions/25169384/what-is-native-messaging-between-applications-and-how-does-it-work" rel="noopener noreferrer"&gt;Native Messaging&lt;/a&gt;, which is basically the way for a browser extension (chrome or firefox) to communicate with a native application. A friend was implementing this feature in his rust app and I decided to help out, which also was enough of a motivation for me to finally start learning Rust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Native Messaging - Illustrated
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.prod.mdn.mozit.cloud%2Fattachments%2F2016%2F08%2F31%2F13833%2F81ec4685b1f9f8745e12d96fdb5b33a8%2Fnative-messaging.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.prod.mdn.mozit.cloud%2Fattachments%2F2016%2F08%2F31%2F13833%2F81ec4685b1f9f8745e12d96fdb5b33a8%2Fnative-messaging.png" alt="MDN"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Courtesy of MDN&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries used for Native Messaging
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/TotallyNotChase/lib-native-messaging/tree/master" rel="noopener noreferrer"&gt;For C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;made by yours truly - shameless plug&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No but seriously, I didn't find another library for native messaging in C on github, though there were 2 for Rust.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/neon64/chrome-native-messaging" rel="noopener noreferrer"&gt;For Rust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The story (also performance is love)
&lt;/h2&gt;

&lt;p&gt;I already had a pretty decent base built up on the low level and after reading the very well documented &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging" rel="noopener noreferrer"&gt;MDN&lt;/a&gt; and &lt;a href="https://developer.chrome.com/extensions/nativeMessaging" rel="noopener noreferrer"&gt;Google&lt;/a&gt; docs, and with major help from &lt;a href="https://github.com/neon64/chrome-native-messaging" rel="noopener noreferrer"&gt;this crate's code&lt;/a&gt; I had these functions-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;read_input&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="py"&gt;.read_u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NativeEndian&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&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="n"&gt;length&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="nf"&gt;.read_exact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;json_val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;write_output&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Chrome won't accept a message larger than 1MB&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message was too large"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="py"&gt;.write_u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;NativeEndian&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="nf"&gt;.flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&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;Which facilitated reading and writing the messages respectively. And it all worked like a charm!&lt;/p&gt;

&lt;p&gt;Now I'm really obsessed with performance, probably a bit more than I should be, though I &lt;em&gt;usually&lt;/em&gt; don't prefer performance over resource efficiency and safety. So I had to dig further.&lt;/p&gt;

&lt;p&gt;I decided to write this in C and also make the Rust code just a bit better for performance and also make both codebases as fair as possible. They both had to do exactly the same thing. Nothing more, nothing less.&lt;/p&gt;

&lt;p&gt;So I removed the &lt;code&gt;serde_json&lt;/code&gt; completely and just worked with strings instead, the user can parse themselves. So instead of-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;json_val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_utf8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;why&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;why&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same for the output too, I just removed &lt;code&gt;let msg = serde_json::to_string(value)?;&lt;/code&gt; completely and changed the parameter to &lt;code&gt;&amp;amp;str&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Not much difference syntactically but definitely a great boost to performance! The &lt;code&gt;C&lt;/code&gt; code also did the same thing, here's how that looked like-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;read_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&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="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while reading file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while reading file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&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;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while allocating memory for value"&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;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while reading file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while reading file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&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;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&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;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="nf"&gt;write_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Message too large"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&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="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while reading file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while reading file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&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="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while writing file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while writing file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&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="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fflush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&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;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&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;Yeah I know, a lot of error handling. But! It's time to benchmark! So how do they fare?&lt;/p&gt;

&lt;p&gt;Hold up! Not quite yet! Let's check the profile I used for optimization on the rust side&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[profile.release]&lt;/span&gt;
&lt;span class="py"&gt;opt-level&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="py"&gt;debug&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;debug-assertions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;overflow-checks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;lto&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;panic&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'abort'&lt;/span&gt;
&lt;span class="py"&gt;incremental&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;rpath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks quite juicy for the benchmark right? I'd say so!&lt;/p&gt;

&lt;p&gt;What about C? Well, I didn't have a &lt;code&gt;gcc&lt;/code&gt; + Native Messaging setup handy so I had to use &lt;code&gt;clang&lt;/code&gt;.....on windows, long story. This was kind of a disadvantage. All I could do was &lt;code&gt;-Ofast&lt;/code&gt;. That's it.&lt;/p&gt;

&lt;p&gt;Yes, I know. Not very fair on the optimization side. But I did some testing on the non optimized versions of both, and C was absolutely wiping the floor so I figured - "whatever"&lt;/p&gt;

&lt;p&gt;Also the benchmark was all done on the javascript side and the following is the &lt;strong&gt;connectionless&lt;/strong&gt; version. So each time a message is sent, the extension invokes the executable, waits for it to read &lt;em&gt;and&lt;/em&gt; send a response. This is how it looked like-&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;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;browserAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClicked&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sending: ping&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendNativeMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pingpong&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ping&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;onResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Received: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Took: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ms`&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;Alright benchmark time, here's what rust looked like-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717433620914241636%2Frustbench.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717433620914241636%2Frustbench.png" alt="Rust"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's C-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717433640425881640%2Fcbench.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717433640425881640%2Fcbench.png" alt="C"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Close, very close! But C still seems to win just a bit over. Impressive results nevertheless, how about some more optimization?&lt;/p&gt;

&lt;p&gt;That question lead to many, many code revisions - a lot of rust programmers helped me out so much to optimize the code. So after many, many revisions. This is how the rust code looked like-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;read_input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;instream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;instream&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&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="nn"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_ne_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&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;usize&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;instream&lt;/span&gt;&lt;span class="nf"&gt;.read_exact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;write_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;outstream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.len&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;len&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message was too large, length: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;outstream&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="nf"&gt;.to_ne_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;outstream&lt;/span&gt;&lt;span class="nf"&gt;.write_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;outstream&lt;/span&gt;&lt;span class="nf"&gt;.flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&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;Got rid of all dependencies and instead of converting to &lt;code&gt;String&lt;/code&gt;, returned the raw bytes. Also make &lt;code&gt;stdin&lt;/code&gt; and &lt;code&gt;stdout&lt;/code&gt; constants as those are always the streams used for Native Messaging anyway.&lt;/p&gt;

&lt;p&gt;The C code also changed accordingly, though not as many revisions-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;uint8_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;read_input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&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="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while reading file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while reading file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&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;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;uint8_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while allocating memory for value"&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;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while reading file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while reading file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&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;NULL&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="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="nf"&gt;write_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;uint8_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Message too large"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&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="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while reading file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while reading file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Unexpectedly encountered EOF while writing file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ferror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"An error occured while writing file, err code: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;clearerr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fflush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&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;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&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;And thus, it was benchmark time again! The final iteration!&lt;/p&gt;

&lt;p&gt;Here's Rust-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717439306544971859%2Frustbench.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717439306544971859%2Frustbench.png" alt="Rust"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's C-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717439312647553054%2Fcbench.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.discordapp.com%2Fattachments%2F716700841196650536%2F717439312647553054%2Fcbench.png" alt="C"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, would you look at that...not much difference from the last time. Well, I sure as hell was disappointed.&lt;/p&gt;

&lt;p&gt;Just as I was about to call it a &lt;del&gt;day&lt;/del&gt; benchmark, someone suggested I should use &lt;strong&gt;connectionful&lt;/strong&gt; messaging, because rust executable invokations take a long time, far longer than C due to panics and a whole lot of other setup. I decided, "sure I could try that!"&lt;/p&gt;

&lt;p&gt;So I switched my js code to this-&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;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connectNative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pingpong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&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;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Received: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, took: &lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; μs`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onDisconnect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Disconnected&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="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;browserAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClicked&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sending: ping&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ping&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And also changed my native app to use an infinite loop - to keep listening for input&lt;/p&gt;

&lt;p&gt;This actually brought the accuracy down to microseconds! So I had to change the timer to that instead, how astonishing!&lt;/p&gt;

&lt;p&gt;And thus, here be the final results-&lt;/p&gt;

&lt;p&gt;Rust-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frunxumlluflr8aa1o79m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frunxumlluflr8aa1o79m.png" alt="Rust"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;C-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn5th3ad91llz1wtzjros.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn5th3ad91llz1wtzjros.png" alt="C"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Incredible! Now that's a feat. Averaging these 2 results, with 1 anomaly from each result discarded (1k+ microseconds for C and 600+ microseconds for Rust), we can see that C beats Rust by just 20-30 microseconds!&lt;/p&gt;

&lt;p&gt;And thus, &lt;strong&gt;C is the winner!&lt;/strong&gt; Though Rust put up a very admirable fight.&lt;/p&gt;

&lt;p&gt;If you'd like to test out the code yourself, and I insist you do as my benchmarking really isn't very sophisticated, you can find the code in my gists-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/TotallyNotChase/8c9e79ed967ae911869aec82545b21ae" rel="noopener noreferrer"&gt;C gist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/TotallyNotChase/c747c55d4a965954f49a7fa5c3f344e0" rel="noopener noreferrer"&gt;Rust gist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This has been very fun! And a super nice start to my rust journey! I think this was a pretty practical demonstration of stdin and stdout IO speeds for Rust vs C. I hope to continue these benchmarks in the future, hopefully focusing on other practical topics.&lt;/p&gt;

&lt;p&gt;Once again, if you're looking forward to implementing Native Messaging in your C application, please check out &lt;a href="https://github.com/TotallyNotChase/lib-native-messaging/tree/master" rel="noopener noreferrer"&gt;libnativemsg&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>c</category>
      <category>webperf</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My Image/GIF glitching python library is now on pypi!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Sat, 22 Feb 2020 16:26:42 +0000</pubDate>
      <link>https://forem.com/totally_chase/my-image-gif-glitching-python-library-is-now-on-pypi-20ke</link>
      <guid>https://forem.com/totally_chase/my-image-gif-glitching-python-library-is-now-on-pypi-20ke</guid>
      <description>&lt;p&gt;After getting some requests, I finally put &lt;code&gt;glitch-this&lt;/code&gt; on &lt;a href="https://pypi.org/project/glitch-this/"&gt;pypi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iSzgN1pZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rcrhudb3uyw7v660mjsm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iSzgN1pZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rcrhudb3uyw7v660mjsm.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not interested in the library? Check out the commandline script &lt;a href="https://github.com/TotallyNotChase/glitch-this"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>python</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I made a commandline python script to glitchify images and make GIFs!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Fri, 21 Feb 2020 16:03:56 +0000</pubDate>
      <link>https://forem.com/totally_chase/i-made-a-commandline-python-script-to-glitchify-images-and-make-gifs-ck9</link>
      <guid>https://forem.com/totally_chase/i-made-a-commandline-python-script-to-glitchify-images-and-make-gifs-ck9</guid>
      <description>&lt;p&gt;Make glitched GIFs and images from the comfort of your commandline!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XcPpeMrj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lsdg9p7gs2hw2jeoglip.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XcPpeMrj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lsdg9p7gs2hw2jeoglip.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href="https://github.com/TotallyNotChase/glitch-this"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;README&lt;/code&gt; contains the full quickstart guide.&lt;/p&gt;

&lt;p&gt;Please consider starring, if you like it!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Looking for contributors with python 3 tensorflow experience for a cool chatbot!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Mon, 17 Feb 2020 05:19:01 +0000</pubDate>
      <link>https://forem.com/totally_chase/looking-for-contributors-with-python-3-tensorflow-experience-for-a-cool-chatbot-35l7</link>
      <guid>https://forem.com/totally_chase/looking-for-contributors-with-python-3-tensorflow-experience-for-a-cool-chatbot-35l7</guid>
      <description>&lt;h2&gt;
  
  
  What the project is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Facebook-Messenger-bot&lt;/strong&gt; is a chatbot you can train to talk like you! Check the repo &lt;a href="https://github.com/adeshpande3/Facebook-Messenger-Bot"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  What we need help with
&lt;/h2&gt;

&lt;p&gt;We're looking for someone experienced with &lt;strong&gt;python 3&lt;/strong&gt; &lt;code&gt;tensorflow&lt;/code&gt; and the &lt;code&gt;seq2seq&lt;/code&gt; model. We need to upgrade our codebase to &lt;code&gt;python3&lt;/code&gt; but since we used &lt;code&gt;legacy_seq2seq&lt;/code&gt; in our &lt;strong&gt;python 2&lt;/strong&gt; code, we're having trouble replacing it with a &lt;strong&gt;python 3&lt;/strong&gt; equivalent. More details on the issue &lt;a href="https://github.com/adeshpande3/Facebook-Messenger-Bot/issues/55"&gt;here!&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I wrote a lightning fast prime number generator in C!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Thu, 06 Feb 2020 05:22:37 +0000</pubDate>
      <link>https://forem.com/totally_chase/i-wrote-a-lightning-fast-prime-number-generator-in-c-4j1n</link>
      <guid>https://forem.com/totally_chase/i-wrote-a-lightning-fast-prime-number-generator-in-c-4j1n</guid>
      <description>&lt;p&gt;I recently found out about &lt;a href="https://github.com/kimwalisch/primesieve/wiki/Segmented-sieve-of-Eratosthenes"&gt;this&lt;/a&gt; improved and cache optimized version of the segmented sieve of eratosthenes algorithm. Now, me being super interested in primes, I wanted to make it &lt;em&gt;even faster&lt;/em&gt;. So I wrote it in &lt;code&gt;C&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href="https://github.com/TotallyNotChase/cFastSieve"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cool Algorithm: Calculating any index of a Cartesian Product!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Sun, 02 Feb 2020 05:54:53 +0000</pubDate>
      <link>https://forem.com/totally_chase/cool-algorithm-calculating-any-index-of-a-cartesian-product-1g8i</link>
      <guid>https://forem.com/totally_chase/cool-algorithm-calculating-any-index-of-a-cartesian-product-1g8i</guid>
      <description>&lt;p&gt;Ever tried generating the cartesian product of 42 large sets/sequences just to get the 236th index of the product?&lt;/p&gt;

&lt;p&gt;Trick Question: You don't have enough memory for that! (probably)&lt;/p&gt;

&lt;p&gt;Thankfully, there's an algorithm to get any index you desire, real freakin' fast!&lt;/p&gt;

&lt;p&gt;Sometimes, you just need to compute very large cartesian products just so you can use a handful of the indexes from the result. The problem is that generating the whole thing is slow, and often times, too much for your memory to even handle.&lt;/p&gt;

&lt;p&gt;That's what prompted me to come up with this algorithm, apparently this is &lt;em&gt;really&lt;/em&gt; hard to find on the internet (at least I couldn't find it). So I went ahead and asked some other folks about it and they too confirmed that, although many people know of this algorithm, it's nowhere to be found on the internet. So I'm making a post here for people to hopefully be able to find later :)&lt;/p&gt;

&lt;h2&gt;
  
  
  What does it do?
&lt;/h2&gt;

&lt;p&gt;Suppose we have 3 sequences - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A : &lt;code&gt;{1, 2, 3}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;B : &lt;code&gt;{2, 6, 7, 9}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;C : &lt;code&gt;{1, 7}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simply call &lt;code&gt;get_tuple_by_index&lt;/code&gt; and pass in the list/array of sequences (i.e &lt;code&gt;[A, B, C]&lt;/code&gt; or &lt;code&gt;{A, B, C}&lt;/code&gt;) and the index of the result you want.&lt;br&gt;
For &lt;code&gt;C&lt;/code&gt; (the programming language), you'd also need to pass in the &lt;strong&gt;number of sequences&lt;/strong&gt; (&lt;code&gt;3&lt;/code&gt; in this case) and an &lt;strong&gt;array containing the lengths of each sequences&lt;/strong&gt; (&lt;code&gt;{3, 4, 2}&lt;/code&gt; in this case).&lt;/p&gt;

&lt;p&gt;For example, if we'd call &lt;code&gt;get_tuple_by_index&lt;/code&gt; with the &lt;strong&gt;6th index&lt;/strong&gt; (starting from 0) of the cartesian product &lt;code&gt;A x B x C&lt;/code&gt;, we'd get &lt;code&gt;(1, 9, 1)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;For this demonstration, we'll be using the sequences mentioned above as examples&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;list&lt;/code&gt;/&lt;code&gt;array&lt;/code&gt; of sequences, that we'd like the cartesian product to, in this case &lt;code&gt;[A, B, C]&lt;/code&gt; or &lt;code&gt;{A, B, C}&lt;/code&gt; is reverse iterated through.&lt;/li&gt;
&lt;li&gt;In each iteration, the &lt;code&gt;result tuple&lt;/code&gt; is filled up from backwards.&lt;/li&gt;
&lt;li&gt;In each iteration, the &lt;code&gt;current element&lt;/code&gt; of the &lt;code&gt;result tuple&lt;/code&gt; will be the &lt;code&gt;index % length_of_current_set&lt;/code&gt;th index of the current set.&lt;/li&gt;
&lt;li&gt;Additionally, in each iteration, the &lt;code&gt;index&lt;/code&gt; is set to &lt;code&gt;index // length_of_current_set&lt;/code&gt; where &lt;code&gt;//&lt;/code&gt; signifies &lt;strong&gt;integer division&lt;/strong&gt;
So, in this case, in the first iteration, for &lt;code&gt;index = 6&lt;/code&gt;, the &lt;code&gt;current element&lt;/code&gt; will be &lt;code&gt;C[6 % 2]&lt;/code&gt; or &lt;code&gt;C[0]&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.
That will now be added as the &lt;strong&gt;last element&lt;/strong&gt; of &lt;code&gt;result tuple&lt;/code&gt;. It'll now look like -&amp;gt; &lt;code&gt;(1)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;index&lt;/code&gt; is now set to &lt;code&gt;6 // 2&lt;/code&gt; or &lt;code&gt;3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the second iteration, the &lt;code&gt;current element&lt;/code&gt; will be &lt;code&gt;B[3 % 4]&lt;/code&gt; or &lt;code&gt;B[3]&lt;/code&gt; or &lt;code&gt;9&lt;/code&gt;.&lt;br&gt;
  That will now be added as the &lt;strong&gt;second to last element&lt;/strong&gt; of &lt;code&gt;result tuple&lt;/code&gt;. It'll now look like -&amp;gt; &lt;code&gt;(9, 1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index&lt;/code&gt; is now set to &lt;code&gt;3 // 4&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the third iteration, the &lt;code&gt;current element&lt;/code&gt; will be &lt;code&gt;A[0 % 3]&lt;/code&gt; or &lt;code&gt;A[0]&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;br&gt;
  That will now be added as the &lt;strong&gt;third to last element&lt;/strong&gt; (or first element in this case) of &lt;code&gt;result tuple&lt;/code&gt;. It'll now look like -&amp;gt; &lt;code&gt;(1, 9, 1)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;Pretty cool! Here's some psuedocode to demonstrate the algorithm-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getNthTuple(sets, pos):
    tuple = ()
    for i in [(|sets|-1)..0]:
        set = sets[i]
        elem = set[pos mod |set|]
        tuple = (elem, tuple)
        pos = pos // |set|
    return tuple
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd like to see examples in real programming languages, you can find the &lt;code&gt;java&lt;/code&gt;, &lt;code&gt;python&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; versions &lt;a href="https://github.com/TotallyNotChase/Fast-Cartesian-Product"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How is the human brain so good at matching delimiters?</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Sun, 19 Jan 2020 10:15:00 +0000</pubDate>
      <link>https://forem.com/totally_chase/how-is-the-human-brain-so-good-at-matching-delimiters-1o51</link>
      <guid>https://forem.com/totally_chase/how-is-the-human-brain-so-good-at-matching-delimiters-1o51</guid>
      <description>&lt;p&gt;Just to be clear, by delimiters I mean mathematical delimiters - parentheses, braces, and brackets. Also this post will be discussing code from a &lt;code&gt;java class&lt;/code&gt; I wrote to be used as a library. You can check the repo &lt;a href="https://github.com/TotallyNotChase/Smart-Delimiter-Predictor"&gt;here&lt;/a&gt;. Alright, with that out of the way, let's go!&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 1 - Auto-complete
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A few months ago I needed to have an &lt;strong&gt;auto-complete&lt;/strong&gt; delimiters function in one of my programs. I never really thought about how to do it because it's really not something that just occurs. I mean like, have you ever manually went &lt;em&gt;step by step&lt;/em&gt; thinking how to match that &lt;strong&gt;one open brace&lt;/strong&gt; that you didn't close in your program yet? No, you just know instinctively. Your brain is just incredibly good at &lt;strong&gt;detecting&lt;/strong&gt; and &lt;strong&gt;matching&lt;/strong&gt; &lt;em&gt;patterns&lt;/em&gt;. But a program doesn't have &lt;code&gt;instincts&lt;/code&gt;. So, what's the algorithm behind this pattern matching? How does the brain do it, step by step?&lt;/p&gt;

&lt;p&gt;Before I start the explanation, I &lt;strong&gt;highly recommend&lt;/strong&gt; you check out the &lt;a href="https://github.com/TotallyNotChase/Smart-Delimiter-Predictor/blob/master/deprecated/src/com/github/chase/smartdelimiter/SmartDelimiterPredictor.java"&gt;code&lt;/a&gt; on github and follow along! Feel free to import the &lt;code&gt;class&lt;/code&gt; if you ever need it in the future :)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Algorithm
&lt;/h2&gt;

&lt;p&gt;Well, just check the number of opening delimiters (i.e &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;{&lt;/code&gt; and &lt;code&gt;[&lt;/code&gt;) in an expression and put that number of closing delimiters at the end! So if you were given &lt;code&gt;log(sin(2^(5&lt;/code&gt; you'd just put &lt;strong&gt;3&lt;/strong&gt; closing parentheses in the end, right?&lt;/p&gt;

&lt;p&gt;Not so fast. What if the expression is &lt;code&gt;log(sin(2^(5)&lt;/code&gt;? You can't put 3 closing delimiters now, you have to put &lt;strong&gt;2&lt;/strong&gt;, because 1 is &lt;em&gt;already closed&lt;/em&gt;. So we can't just count the appearance of opening delimiters, we also have to 1) &lt;em&gt;count the number of closing delimiters&lt;/em&gt;, 2) &lt;em&gt;Grab the difference between the 2&lt;/em&gt; and then 3) &lt;em&gt;append accordingly&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's all well and good, but we're not done yet. What about mixed delimiters? Like so &lt;code&gt;log[sin(2^{&lt;/code&gt;. Now we can finally discuss the &lt;strong&gt;fun&lt;/strong&gt; part, step by step how your brain does (probably) it. &lt;/p&gt;

&lt;p&gt;Simply put, your brain just scans the expression &lt;strong&gt;backwards&lt;/strong&gt; &lt;em&gt;really fast&lt;/em&gt;. If it sees an opening delimiter, it &lt;em&gt;immediately&lt;/em&gt; appends the corresponding closing delimiter to the expression. Now add the above paragraph about checking the number of appearance to the mix and no matter what expression you feed in, it'll always output a &lt;em&gt;perfectly matched output expression&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;You can implement this whole thing in a &lt;code&gt;switch&lt;/code&gt; statement that checks each unit expression (i.e &lt;code&gt;log&lt;/code&gt;, &lt;code&gt;sin&lt;/code&gt;, &lt;code&gt;cos&lt;/code&gt;, &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;{&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;....) like so in &lt;code&gt;Java&lt;/code&gt;-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Inside the Switch statement
case "(":
    ++openingParentheses;
    if (openingParentheses &amp;gt; closingParentheses) {
        resultstr.append(")");
        closingParentheses++;
    }
    break;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you just have to put the whole &lt;code&gt;switch&lt;/code&gt; statement in a &lt;code&gt;reverse iterator&lt;/code&gt; loop!&lt;/p&gt;

&lt;p&gt;Here it is in action!&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gfafx69B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rgeqb9fmdlr69wspdpbo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gfafx69B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rgeqb9fmdlr69wspdpbo.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;note that although the frontend shows only parentheses, the backend uses different delimiters for different functions, so it still uses the exact same algorithm&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Part 2 - Function associated with given closing delimiter
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Once I was done with the auto-complete, I needed to know exactly which function is associated with which delimiter. Suppose you were given this expression &lt;code&gt;log10[sin(23^{56*cos(loge[2])})]&lt;/code&gt; and you were told to find out which function does the &lt;strong&gt;second to last parenthesis&lt;/strong&gt; belongs to. In this case, that belongs to &lt;code&gt;cos&lt;/code&gt;. But what's the algorithm behind it?&lt;/p&gt;
&lt;h2&gt;
  
  
  The Algorithm
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Again, I recommend opening the &lt;a href="https://github.com/TotallyNotChase/Smart-Delimiter-Predictor/blob/master/deprecated/src/com/github/chase/smartdelimiter/SmartDelimiterPredictor.java"&gt;source code&lt;/a&gt; if you haven't already&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once again, we &lt;em&gt;reverse iterate&lt;/em&gt; the expression, this time we also need a user provided &lt;strong&gt;index&lt;/strong&gt; and the expression must be an &lt;strong&gt;array&lt;/strong&gt;, to separate each unit expression. The expression &lt;code&gt;log10[sin(23^{56*cos(loge[2])})]&lt;/code&gt;, if turned into a &lt;code&gt;String&lt;/code&gt; array, it'd be-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"log10", "[", "sin", "(", "23", "^", "{", "56", "*", "cos", "(", "loge", "[", "2", "]", ")", "}", ")", "]"}        
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, we start reverse iterating from the given index, but skip the index itself. So, the index of the &lt;strong&gt;second to last parenthesis&lt;/strong&gt; in this array is &lt;code&gt;15&lt;/code&gt;. So we'll start reverse iterating from &lt;code&gt;14&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, the reverse iteration must go on &lt;strong&gt;until the number of appearances of opening delimiters is &lt;em&gt;greater than&lt;/em&gt;(not equal to) the number of appearances of closing delimiters&lt;/strong&gt;. The moment the loop stops, wallah!, you magically have the index of the corresponding function, in this case, &lt;code&gt;cos&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Well, not magically, but you know what I mean.&lt;/p&gt;

&lt;p&gt;If we wanted to implement this for parentheses (&lt;code&gt;(&lt;/code&gt;). We'd do it like so;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while (openParentheses &amp;lt;= closeParentheses) {
    switch (expression[i]) {
    case ")":
        closeParentheses++;
        break;
    case "(":
        openParentheses++;
        break;
    }
    i--;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting &lt;code&gt;i&lt;/code&gt; is the index of the function.&lt;/p&gt;

&lt;p&gt;Here it is in action!&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RqlMZWiX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jz5j9ragmt70m62ajvnd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RqlMZWiX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jz5j9ragmt70m62ajvnd.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;notice that whenever I remove a closing delimiter using backspace, the program is able to tell which function region I just entered&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That's it! That's how your brain does it (probably). I found it really fascinating at first and when I figured out the algorithm, it felt really nice. I figured I'd share with everyone!&lt;/p&gt;

&lt;p&gt;Once again, if you need to use it in any of your &lt;code&gt;java&lt;/code&gt; programs, I personally used it in &lt;code&gt;Android&lt;/code&gt; dev stuff, you can just grab the &lt;code&gt;.jar&lt;/code&gt; file from the &lt;a href="https://github.com/TotallyNotChase/Smart-Delimiter-Predictor"&gt;repo&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Python: Using JWT in cookies with a flask app and restful API!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Sat, 11 Jan 2020 12:36:06 +0000</pubDate>
      <link>https://forem.com/totally_chase/python-using-jwt-in-cookies-with-a-flask-app-and-restful-api-2p75</link>
      <guid>https://forem.com/totally_chase/python-using-jwt-in-cookies-with-a-flask-app-and-restful-api-2p75</guid>
      <description>&lt;p&gt;This guide aims to provide an in-depth tutorial on how to set up &lt;strong&gt;&lt;code&gt;flask-jwt-extended&lt;/code&gt;&lt;/strong&gt; using cookies. There's a LOT of docs online but they are mostly using authentication headers and a frontend framework like react. I wanted to share my experience with using &lt;strong&gt;jwt through just the backend&lt;/strong&gt; (e.g returning redirects instead of json objs). This will also outline some of the guidelines about &lt;em&gt;token freshness&lt;/em&gt;, &lt;em&gt;access/refresh token expiry&lt;/em&gt; and &lt;em&gt;refreshing expired tokens&lt;/em&gt; (through the backend!!).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: Usually the backend only returns a &lt;code&gt;jsonify&lt;/code&gt;-ed dict with the tokens (when using headers) or simply a status report (when using cookies). Once the frontend framework receives the tokens/status report, it redirects to the desired url. We're just achieving all that &lt;strong&gt;without&lt;/strong&gt; the frontend.&lt;/p&gt;

&lt;p&gt;I'll be assuming you know what &lt;a href="https://en.wikipedia.org/wiki/JSON_Web_Token"&gt;&lt;code&gt;JWT&lt;/code&gt;&lt;/a&gt; is and are aware of the python package &lt;code&gt;flask-jwt-extended&lt;/code&gt;. You don't need to know how to use the package, I'll show how to do that in the guide :)&lt;br&gt;
You'll also need to know the basics of &lt;a href="https://flask-doc.readthedocs.io/en/latest/"&gt;flask&lt;/a&gt; and &lt;a href="https://flask-restful.readthedocs.io/en/latest/"&gt;flask-restful&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Need a working example? Here's a &lt;a href="https://gist.github.com/TotallyNotChase/fe0d66318e7f6b56fd2bc0b8972a483c"&gt;gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, time to make the flask app itself!&lt;/p&gt;
&lt;h2&gt;
  
  
  Initializing our app
&lt;/h2&gt;

&lt;p&gt;First let's see what imports we'll be needing. All of these will be explained as we go on, so don't worry too much about them. Just know that &lt;em&gt;these&lt;/em&gt; are the functions we are using later if you get confused and ask "wait what does that function do and where did it come from?"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask, redirect, make_response, render_template
from flask_restful import Api
from flask_jwt_extended import (JWTManager, jwt_required, 
                                jwt_refresh_token_required, 
                                jwt_optional, fresh_jwt_required, 
                                get_raw_jwt, get_jwt_identity,
                                create_access_token, create_refresh_token, 
                                set_access_cookies, set_refresh_cookies, 
                                unset_jwt_cookies,unset_access_cookies)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the purposes of this guide, we're declaring all functions in the same file &lt;code&gt;__init__.py&lt;/code&gt;. NEVER DO THIS, always separate your JWT handlers on a different file. &lt;/p&gt;

&lt;p&gt;let's make a &lt;code&gt;__init__.py&lt;/code&gt; and initialize all the required stuff&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app = Flask(__name__)
app.config['BASE_URL'] = 'http://127.0.0.1:5000'  #Running on localhost
app.config['JWT_SECRET_KEY'] = 'super-secret'  # Change this!
app.config['JWT_TOKEN_LOCATION'] = ['cookies']
app.config['JWT_COOKIE_CSRF_PROTECT'] = True
app.config['JWT_CSRF_CHECK_FORM'] = True
jwt = JWTManager(app) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't worry too much about the imports yet, in the above snipper we are only really concerned about &lt;code&gt;Flask&lt;/code&gt;, &lt;code&gt;redirect&lt;/code&gt;, &lt;code&gt;make_response&lt;/code&gt;, and &lt;code&gt;JWTManager&lt;/code&gt;. All we're doing here is creating a &lt;code&gt;Flask&lt;/code&gt; app instance and then setting up the &lt;code&gt;JWTManager&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As for the configs:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need a &lt;code&gt;JWT_SECRET_KEY&lt;/code&gt; for the JWT encryption. Try to go for a completely random string of alphanumeric characters. You can generate them using &lt;a href="https://www.grc.com/passwords.htm"&gt;this&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We &lt;strong&gt;have&lt;/strong&gt; to set &lt;code&gt;JWT_TOKEN_LOCATION&lt;/code&gt; to &lt;code&gt;['cookies']&lt;/code&gt; if we want to use cookies as our preferred token storage. The default is always auth header. &lt;/li&gt;
&lt;li&gt;We also set &lt;code&gt;JWT_COOKIE_CSRF_PROTECT&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; for cookie security, this is &lt;code&gt;True&lt;/code&gt; by default so you don't have to do this.&lt;/li&gt;
&lt;li&gt;Lastly, we set &lt;code&gt;JWT_CSRF_CHECK_FORM&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt;. This will come in handy when we have to pass tokens to &lt;strong&gt;api resources&lt;/strong&gt;. Don't worry about it much yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting cookies and returning redirects
&lt;/h2&gt;

&lt;p&gt;Let's make a function to &lt;em&gt;create&lt;/em&gt; and &lt;em&gt;assign&lt;/em&gt; one access token and one refresh token to the cookies. Remember, the tokens are &lt;strong&gt;always&lt;/strong&gt; assigned to a &lt;code&gt;flask response&lt;/code&gt; object which must then be returned.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;response&lt;/code&gt; object can be anything from a &lt;code&gt;jsonify&lt;/code&gt;-ed dict to a &lt;code&gt;redirect&lt;/code&gt;. There's a LOT of docs on returning &lt;code&gt;jsonify&lt;/code&gt;-ed dicts so I'll be showing how to return a &lt;code&gt;redirect&lt;/code&gt; instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def assign_access_refresh_tokens(user_id, url):
    access_token = create_access_token(identity=str(user_id))
    refresh_token = create_refresh_token(identity=str(user_id))
    resp = make_response(redirect(url, 302))
    set_access_cookies(resp, access_token)
    set_refresh_cookies(resp, refresh_token)
    return resp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We take in the &lt;code&gt;url&lt;/code&gt; to redirect to as an argument. We also take a &lt;strong&gt;unique identifer&lt;/strong&gt; (&lt;code&gt;user_id&lt;/code&gt;), which is essential to create a token&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt; : &lt;code&gt;create_access_token(identity)&lt;/code&gt; and &lt;code&gt;create_refresh_token(identity)&lt;/code&gt; will create and return an access and refresh token based on the identity provided. Remember the identity should be unique for each user. We then have to make a flask &lt;code&gt;response&lt;/code&gt; object that will redirect us to the desired url. We need to attach the cookies to this &lt;code&gt;response&lt;/code&gt; object.&lt;br&gt;
&lt;code&gt;make_response(redirect(url, 302))&lt;/code&gt; will create and return a response object that redirects to &lt;code&gt;url&lt;/code&gt; with code 302.&lt;br&gt;
Now we just need to assign the access and refresh tokens. We do that using &lt;code&gt;set_access_cookies(response, access_token)&lt;/code&gt; and &lt;code&gt;set_refresh_cookies(response, refresh_token)&lt;/code&gt;.&lt;br&gt;
Finally we return the &lt;code&gt;response&lt;/code&gt; object that now has the cookies attached. This will redirect the user to the give url and the user session now has the desired tokens, Awesome!&lt;/p&gt;

&lt;p&gt;Read more about &lt;a href="https://flask-jwt-extended.readthedocs.io/en/stable/api/#utilities"&gt;jwt functions&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;So, that's how you assign tokens, how do you un-assign them? You'd ideally need to revoke those tokens if a user logs out so let's see how to do that!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def unset_jwt():
    resp = make_response(redirect(app.config['BASE_URL'] + '/', 302))
    unset_jwt_cookies(resp)
    return resp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt; : yep, it's that easy. You just use &lt;code&gt;unset_jwt_cookies&lt;/code&gt; with a &lt;code&gt;response&lt;/code&gt; object and return that response. Now the user session no longer has access OR refresh tokens. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; : This removes &lt;strong&gt;both&lt;/strong&gt; access and refresh tokens. To remove only one of them, use &lt;code&gt;unset_access_cookies(response)&lt;/code&gt; or &lt;code&gt;unset_refresh_cookies(response)&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Now we have to use &lt;strong&gt;jwt decorator functions&lt;/strong&gt; to handle operations when the user doesn't have tokens/ has invalid tokens/ expired tokens. Let's do that!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@jwt.unauthorized_loader
def unauthorized_callback(callback):
    # No auth header
    return redirect(app.config['BASE_URL'] + '/signup', 302)

@jwt.invalid_token_loader
def invalid_token_callback(callback):
    # Invalid Fresh/Non-Fresh Access token in auth header
    resp = make_response(redirect(app.config['BASE_URL'] + '/signup'))
    unset_jwt_cookies(resp)
    return resp, 302

@jwt.expired_token_loader
def expired_token_callback(callback):
    # Expired auth header
    resp = make_response(redirect(app.config['BASE_URL'] + '/token/refresh'))
    unset_access_cookies(resp)
    return resp, 302
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt; : Let's discuss what each decorator does first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@jwt.unauthorized_loader&lt;/code&gt; is called when the user has &lt;strong&gt;no access tokens&lt;/strong&gt; in their request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@jwt.invalid_token_loader&lt;/code&gt; is called when the user has an &lt;strong&gt;invalid access token&lt;/strong&gt; in their request. This happens when someone tries to access an endpoint using &lt;em&gt;forged tokens&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@jwt.expired_token_loader&lt;/code&gt; is called when the user has an &lt;strong&gt;expired but otherwise valid&lt;/strong&gt; access token in their request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read more about &lt;a href="https://flask-jwt-extended.readthedocs.io/en/stable/api/#module-flask_jwt_extended"&gt;jwt loaders&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Now you may have noticed, tokens expire and when it does we unset said token and redirect the user to &lt;code&gt;http://127.0.0.1:5000/token/refresh&lt;/code&gt;. What does this url do? Well, it refreshes the expired token &lt;em&gt;if&lt;/em&gt; the user has a valid refresh token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route('/token/refresh', methods=['GET'])
@jwt_refresh_token_required
def refresh():
    # Refreshing expired Access token
    user_id = get_jwt_identity()
    access_token = create_access_token(identity=str(user_id))
    resp = make_response(redirect(app.config['BASE_URL'] + '/', 302))
    set_access_cookies(resp, access_token)
    return resp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt; : This function checks whether the user has a valid refresh token first using &lt;code&gt;@jwt_refresh_token_required&lt;/code&gt;, if they do, it'll extract the &lt;code&gt;identity&lt;/code&gt; given to the token during it's creation using &lt;code&gt;get_jwt_identity()&lt;/code&gt; and use it to create another access token. We then assign and return it just like before!&lt;/p&gt;

&lt;p&gt;Ok! That's all the jwt handlers, but before we put them to the test. Let's discuss on an important aspect of access token security - token freshness. &lt;/p&gt;

&lt;h2&gt;
  
  
  Token Freshness
&lt;/h2&gt;

&lt;p&gt;From the docs&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Fresh pattern] is useful for allowing fresh tokens to do some critical things (such as update an email address or complete an online purchase), but to deny those features to non-fresh tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's think of a situation, as long the refresh token is valid and non-expired, we can keep generating access tokens, right? If an &lt;strong&gt;access token&lt;/strong&gt; goes into the wrong hands, the attacker will only have a short period of time to use them as expire quite fast (15 mins by default). But what if the attacker gets their hands on a &lt;strong&gt;refresh token&lt;/strong&gt;, which usually have a longer expiry (1 day by default)?&lt;/p&gt;

&lt;p&gt;This is why we use the fresh/non-fresh pattern. When creating access tokens using &lt;code&gt;create_access_token&lt;/code&gt; we can set &lt;code&gt;fresh = True&lt;/code&gt; to create a fresh access token. By default when an access token is created without a fresh value supplied, it will be &lt;strong&gt;non-fresh&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We can create a fresh access token by &lt;code&gt;create_access_token(identity = id, fresh = True)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we can &lt;em&gt;only&lt;/em&gt; let refresh tokens create &lt;strong&gt;non-fresh&lt;/strong&gt; access tokens. non-fresh tokens &lt;strong&gt;cannot&lt;/strong&gt; access endpoints protected with &lt;code&gt;@fresh_jwt_required&lt;/code&gt;, only &lt;code&gt;@jwt_required&lt;/code&gt;. Fresh tokens &lt;strong&gt;can&lt;/strong&gt; access endpoints protected with both &lt;code&gt;@fresh_jwt_required&lt;/code&gt; and &lt;code&gt;@jwt_required&lt;/code&gt;. Make sure fresh tokens are &lt;strong&gt;only&lt;/strong&gt; created when the user &lt;em&gt;actually logs in using their password&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flask-jwt-extended.readthedocs.io/en/stable/token_freshness/"&gt;Read&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Now we can finally put the jwt handlers to the test! To use these handlers we have to decorate our functions using &lt;strong&gt;jwt required decorators&lt;/strong&gt;. Here's an overview on them!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jwt_required&lt;/code&gt; will block access to everyone unless they have a &lt;em&gt;valid, non-expired non-fresh or fresh access token&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fresh_jwt_required&lt;/code&gt; will block access to everyone unless they have a &lt;em&gt;valid, non-expired fresh access token&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jwt_optional&lt;/code&gt; won't block access but it'll still allow the jwt to be used inside the function &lt;em&gt;if&lt;/em&gt; it is present. Otherwise &lt;code&gt;get_jwt_identity()&lt;/code&gt; will return &lt;code&gt;None&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@jwt_refresh_token_required&lt;/code&gt; will block access to everyone unless they have a &lt;em&gt;valid non-expired refresh token&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read more about &lt;a href="https://flask-jwt-extended.readthedocs.io/en/stable/api/#protected-endpoint-decorators"&gt;jwt endpoint decorators&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Let us first assign the tokens first, we'll ideally want to assign them when the user signs up or logs in. Like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route('/login', methods=['POST'])
def login():
    // Verify username and password //
    return assign_access_refresh_tokens(username , app.config['BASE_URL'] + '/')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great now we have tokens in the session! Let's declare some functions using the decorators!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route('/account')
@fresh_jwt_required
def account():
     username = get_jwt_identity()
    // very important account settings //

@app.route('/service', methods=['GET'])
@jwt_required
def services():
    username = get_jwt_identity()
    // Not important stuff but still needs to be logged in //

@app.route('/')
@jwt_optional
def index():
    username = get_jwt_identity()   # None if not logged in
    // Accessible to everyone but maybe different to logged in users //
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first endpoint, &lt;code&gt;account&lt;/code&gt; can only be accessed by a fresh jwt. Someone who recently logged in will be able to access this as long as their fresh jwt does not expire. When it &lt;em&gt;does&lt;/em&gt; expire, the refresh token won't create a fresh jwt and hence to access this, the user will have to log in again.&lt;/p&gt;

&lt;p&gt;The second endpoint, &lt;code&gt;services&lt;/code&gt; can be accessed by either a fresh or non-fresh jwt. A logged in user can access this for the entirety of their refresh token lifetime without logging in again.&lt;/p&gt;

&lt;p&gt;The third endpoint, &lt;code&gt;index&lt;/code&gt; can be accessed by anyone. However it may offer a different look/functionality if the user &lt;em&gt;is&lt;/em&gt; logged in, i.e &lt;code&gt;get_jwt_identity&lt;/code&gt; is not &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the user is done looking around they'd wanna logout, we need to unset their cookies if they do so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route('/logout')
@jwt_required
def logout():
    # Revoke Fresh/Non-fresh Access and Refresh tokens
    return unset_jwt(), 302
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! Now let's learn how to pass the tokens correctly into api resources&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing JWT to RESTful API resources
&lt;/h2&gt;

&lt;p&gt;Let's assume we have a Class in another module like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask_restful import Resource
from flask_jwt_extended import fresh_jwt_required, get_jwt_identity
class AccountSettings(Resource):
    @fresh_jwt_required
    def post(self):
        username = get_jwt_identity()
        // important setting change commits //
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we add this to our api in &lt;code&gt;__init__.py&lt;/code&gt; using &lt;code&gt;api.add_resource(AccountSettings, '/account/change_settings')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So now whenever the url &lt;code&gt;http://127.0.0.1:5000/account/change_settings&lt;/code&gt; receives a &lt;code&gt;POST&lt;/code&gt;, it'll execute the &lt;code&gt;post&lt;/code&gt; function in &lt;code&gt;AccountSettings&lt;/code&gt;. However a &lt;code&gt;POST&lt;/code&gt; function &lt;em&gt;in an api resource` **cannot&lt;/em&gt;* access the CSRF token in our JWT cookies directly. Without that token, the jwt is useless. The reason this happens, along with it's solution is written in the docs-&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Typically JWT is used with API servers using JSON payloads, often via AJAX. However you may have an endpoint that receives POST requests directly from an HTML form. Without AJAX, you can’t set the CSRF headers to pass your token to the server. In this scenario you can send the token in a hidden form field. To accomplish this, first configure JWT to check the form for CSRF tokens. Now it’s not necessary to send the csrf in a separate cookie, you can render it directly into your HTML template.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All we have to do is turn the &lt;code&gt;JWT_CSRF_CHECK_FORM&lt;/code&gt; option on (which we already did earlier) and put the token in a hidden input field. You can do this by putting &lt;code&gt;&amp;lt;input hidden name="csrf_token" value="&lt;/code&gt;{{ csrf_token }}&lt;code&gt;"&amp;gt;&lt;/code&gt; &lt;strong&gt;INSIDE&lt;/strong&gt; your form that will &lt;code&gt;POST&lt;/code&gt; to the api resource. Now you can use &lt;code&gt;render_template&lt;/code&gt; to pass the &lt;code&gt;csrf_token&lt;/code&gt; to the template.&lt;/p&gt;

&lt;p&gt;Get the &lt;code&gt;csrf_token&lt;/code&gt; using &lt;code&gt;csrf_token = (get_raw_jwt() or {}).get("csrf")&lt;/code&gt; and pass it to the DOM like so &lt;br&gt;
&lt;code&gt;return render_template("account.html", csrf_token=csrf_token), 200&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; : You can only extract the &lt;code&gt;csrf_token&lt;/code&gt; (for access tokens) in endpoints decorated with &lt;code&gt;@fresh_jwt_required&lt;/code&gt; or &lt;code&gt;@jwt_required&lt;/code&gt;. &lt;code&gt;@jwt_optional&lt;/code&gt; will also work however, if there is no JWT present, it'll return &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; : You only have to do this on RESTful API resources that use &lt;code&gt;POST&lt;/code&gt; methods. &lt;code&gt;GET&lt;/code&gt;  method can access the csrf protected jwt just fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Error handling in API resources
&lt;/h2&gt;

&lt;p&gt;You may notice the jwt loaders (e.g &lt;code&gt;@jwt.unauthorized_loader&lt;/code&gt;, &lt;code&gt;@jwt.invalid_token_loader&lt;/code&gt;) not getting hit when the API resource URLs are directly accessed. This is because of flask's default exception handling behaviour, to fix this, simply set &lt;code&gt;PROPAGATE_EXCEPTIONS&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;app.config['PROPAGATE_EXCEPTIONS'] = True&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Advices, Standards and Discussions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expiry : The default expiry for access and refresh tokens is 15 minutes and 1 day respectively. You can change this using &lt;code&gt;app.config['JWT_ACCESS_TOKEN_EXPIRES']&lt;/code&gt; or &lt;code&gt;app.config['JWT_REFRESH_TOKEN_EXPIRES']&lt;/code&gt; and assigning a &lt;code&gt;datetime.timedelta()&lt;/code&gt; value. It is recommended to keep the access token duration low as it can simply be refreshed.&lt;/li&gt;
&lt;li&gt;Cookie path : It's always nice to &lt;strong&gt;only&lt;/strong&gt; send the tokens to the routes where they are needed, instead of sending them to every route by default. If I wanted to send the access tokens to only &lt;code&gt;/accounts&lt;/code&gt; and &lt;code&gt;/services&lt;/code&gt; I'd use
&lt;code&gt;app.config['JWT_ACCESS_COOKIE_PATH'] = ['/account', '/services']&lt;/code&gt;. As you can see it's simply a list of the urls you want the access tokens to be accessible from.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for refresh tokens, I always send them &lt;strong&gt;only&lt;/strong&gt; to the refresh url.&lt;br&gt;
&lt;code&gt;app.config['JWT_REFRESH_COOKIE_PATH'] = '/token/refresh'&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify jwt identity : Even if &lt;code&gt;get_jwt_identity&lt;/code&gt; returns an actual id, check whether the id exists in your database before assuming them to be an user outright.&lt;/li&gt;
&lt;li&gt;Fresh/Non-Fresh pattern : Make sure the important routes are protected using fresh tokens and never let fresh tokens be refreshed using refresh tokens. They should only be created when the user actually uses their password/2FA to log in.&lt;/li&gt;
&lt;li&gt;Change up the tokens on password change : It's a good idea to recreate both access and refresh tokens if a user changes their password.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And That's it! I hope this guide helps you in your JWT adventures!&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>Porting C structs into Python, because speed!</title>
      <dc:creator>Phantz</dc:creator>
      <pubDate>Wed, 01 Jan 2020 14:15:10 +0000</pubDate>
      <link>https://forem.com/totally_chase/porting-c-structs-into-python-because-speed-2aio</link>
      <guid>https://forem.com/totally_chase/porting-c-structs-into-python-because-speed-2aio</guid>
      <description>&lt;h1&gt;
  
  
  Why use C with Python?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt; is a really fun and friendly language, it offers so many cool features, has a great supportive community and has modules of pretty much everything you can think of. Programs that &lt;em&gt;would&lt;/em&gt; be written in 10-20 lines in other languages, can sometimes be written in just a single line in Python.&lt;/p&gt;

&lt;p&gt;But all that comes at a major cost, &lt;strong&gt;Performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's no coincident that so many libraries/frameworks and even compilers for python exist that focus on improving python's performance. &lt;a href="https://pypy.org/" rel="noopener noreferrer"&gt;PyPy&lt;/a&gt;, &lt;a href="http://numba.pydata.org/" rel="noopener noreferrer"&gt;Numba&lt;/a&gt; being only a few of them. Performance is &lt;em&gt;crucial&lt;/em&gt; for pushing the limits of a program. Luckily python has an inbuilt module called &lt;a href="https://docs.python.org/3/library/ctypes.html" rel="noopener noreferrer"&gt;&lt;code&gt;ctypes&lt;/code&gt;&lt;/a&gt;, which allows us to port/wrap C code with python. This is incredibly useful in any advanced tasks as, by nature, C is &lt;em&gt;very&lt;/em&gt; fast.&lt;/p&gt;

&lt;p&gt;Now, &lt;code&gt;ctypes&lt;/code&gt; is a &lt;em&gt;vast and advanced&lt;/em&gt; topic of python. So I'll only be covering one of the more useful features, using &lt;code&gt;C structs&lt;/code&gt; in Python. I'll be using a C program to &lt;strong&gt;calculate the Cartesian product of a large order&lt;/strong&gt; and port it to python!&lt;/p&gt;

&lt;h1&gt;
  
  
  Sounds cool, but how?
&lt;/h1&gt;

&lt;p&gt;Ok so first, we're gonna need some C code. You'll be able to find a lot examples using basic C programs but I want to give a practical example. &lt;em&gt;Infact, I actually used this very program as I was learning &lt;code&gt;ctypes&lt;/code&gt;&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Ideally, you'll want to use a C program that performs tasks that'd otherwise be extremely &lt;strong&gt;slow&lt;/strong&gt; or downright &lt;strong&gt;impossible&lt;/strong&gt; in python. &lt;code&gt;Cartesian product&lt;/code&gt; is one such example. The cartesian product using &lt;a href="https://docs.python.org/2/library/itertools.html" rel="noopener noreferrer"&gt;&lt;code&gt;itertools&lt;/code&gt;&lt;/a&gt; that would take you &lt;em&gt;multiple seconds&lt;/em&gt; in Python will only take you a few hundred &lt;em&gt;milliseconds&lt;/em&gt; in C.&lt;/p&gt;

&lt;p&gt;So, let's represent this piece of code &lt;code&gt;ls = list(itertools.product(range(0, 256), repeat = 3))&lt;/code&gt; in C.&lt;/p&gt;

&lt;h2&gt;
  
  
  The C code!
&lt;/h2&gt;

&lt;p&gt;First we need to figure out what kind of datatype we would want. Ofcourse the above python code returns a &lt;strong&gt;list of tuples of integers ranging from 0 - 255&lt;/strong&gt;. Now we could use multi-dimension arrays but I think the most efficient way of representing this in C is by using &lt;code&gt;struct&lt;/code&gt;. So let's declare a &lt;code&gt;struct&lt;/code&gt; containing 3 &lt;code&gt;int&lt;/code&gt; values, each corresponding to Red, Green, and Blue. Let's name it &lt;strong&gt;PixelTuple&lt;/strong&gt;, because this was originally intended to represent pixel values.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

struct PixelTuple
{
    int red;
    int green;
    int blue;
};


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;(optional)&lt;/code&gt; We might as well name it something easier to type...&lt;br&gt;
&lt;code&gt;typedef struct PixelTuple pxtup&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we can allocate an array of &lt;code&gt;struct PixelTuple&lt;/code&gt; variables in our main function. A Cartesian product of &lt;strong&gt;3 sets&lt;/strong&gt; of &lt;strong&gt;length 256&lt;/strong&gt; yields a total number of &lt;strong&gt;256^3&lt;/strong&gt; elements. So the array will contain that number of &lt;code&gt;struct PixelTuple&lt;/code&gt; type variables. Now such a large variable should be stored in the &lt;strong&gt;data segment&lt;/strong&gt; of your system memory. To do that, you can either make the array &lt;code&gt;global&lt;/code&gt; or declare the array with the &lt;code&gt;static&lt;/code&gt; keyword. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I highly recommend reading up on C's &lt;a href="https://www.geeksforgeeks.org/memory-layout-of-c-program/" rel="noopener noreferrer"&gt;memory layout&lt;/a&gt; as well as &lt;a href="https://www.geeksforgeeks.org/static-variables-in-c/" rel="noopener noreferrer"&gt;static variables&lt;/a&gt; to get a clear idea. But TL;DR: the &lt;code&gt;static&lt;/code&gt; keyword allocates memory for a variable in the &lt;code&gt;data segment&lt;/code&gt; which allows for larger variables to be stored. They are also &lt;em&gt;kept in memory as long as the program runs&lt;/em&gt; as opposed to other variables which are &lt;em&gt;destroyed outside of the scope/function&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So let's declare our array in &lt;code&gt;main()&lt;/code&gt;:&lt;br&gt;
&lt;code&gt;static pxtup pxarray[256*256*256];&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we will need some other variables, specifically &lt;em&gt;one array of integers from 0 to 255 (&lt;code&gt;valuearray&lt;/code&gt;)&lt;/em&gt;, &lt;strong&gt;3 variables (&lt;code&gt;i&lt;/code&gt;, &lt;code&gt;j&lt;/code&gt;, and &lt;code&gt;k&lt;/code&gt;)&lt;/strong&gt; to &lt;em&gt;iterate through the 0 to 255 3 times&lt;/em&gt;, &lt;strong&gt;1 variable (&lt;code&gt;pxindex&lt;/code&gt;)&lt;/strong&gt; to &lt;em&gt;keep track of the index of the &lt;code&gt;pxarray&lt;/code&gt; variable&lt;/em&gt; and &lt;strong&gt;a FILE pointer variable&lt;/strong&gt; to &lt;em&gt;open the file where we'll store the struct array in the end&lt;/em&gt;. Let's declare these first too:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

int i, j, k, l, pxindex = 0;
FILE* pxF;
for (i = 0; i &amp;lt; 256; i++)
{
    valuearray[i] = i;
}



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

&lt;/div&gt;

&lt;p&gt;Now we need to write a function to actually calculate the Cartesian Product itself, let's do that!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

for (i = 0; i &amp;lt; 256; i++)
{
    for (j = 0; j &amp;lt; 256; j++)
    {
        for (k = 0; k &amp;lt; 256; k++)
        {
            pxarray[pxindex].red = valuearray[i];
            pxarray[pxindex].green = valuearray[j];
            pxarray[pxindex++].blue = valuearray[k];
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;So yeah... all that code could &lt;em&gt;literally&lt;/em&gt; be represented by a single line in python. But! on the bright side, this code is &lt;strong&gt;significantly&lt;/strong&gt; faster than the python code. In my opinion, speed is what &lt;em&gt;really&lt;/em&gt; matters. &lt;/p&gt;

&lt;p&gt;Now we have to save our &lt;code&gt;pxarray&lt;/code&gt; in a file so python can read from it later. Let's use our previously declared &lt;code&gt;pxF&lt;/code&gt; pointer to create a &lt;code&gt;.bin&lt;/code&gt; file, then we can simply use &lt;code&gt;fwrite(const void * ptr, size_t size, size_t count, FILE * stream)&lt;/code&gt; to write the struct array inside.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

pxF = fopen("PixelTuples.bin", "wb");
if (allcF == NULL)
{
    printf("File cannot be created\n");
    return;
}
fwrite(&amp;amp;pxarray, sizeof(pxtup), 256*256*256, pxF);
fclose(pxF);


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

&lt;/div&gt;

&lt;p&gt;The first &lt;code&gt;size_t&lt;/code&gt; argument in &lt;code&gt;fwrite()&lt;/code&gt; i.e &lt;code&gt;size_t size&lt;/code&gt; should be the size of the &lt;strong&gt;data type&lt;/strong&gt; and the next &lt;code&gt;size_t&lt;/code&gt; argument i.e &lt;code&gt;size_t count&lt;/code&gt; should be the number of datatypes present in the first argument i.e &lt;code&gt;const void * ptr&lt;/code&gt;. Obviously, there are exactly &lt;strong&gt;256^3&lt;/strong&gt; number of &lt;code&gt;pxtup&lt;/code&gt; or &lt;code&gt;struct PixelTuple&lt;/code&gt; elements in &lt;code&gt;pxarray&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To recap, here's the &lt;a href="https://gist.github.com/TotallyNotChase/df5910accaf700c60801633c821cc26d" rel="noopener noreferrer"&gt;full code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There we go! The &lt;code&gt;.bin&lt;/code&gt; file is ready to be used by Python! But before we move on, I'd just like to mention that if you'd like to import this &lt;code&gt;.bin&lt;/code&gt; file back to a C struct array, you can simply open the &lt;strong&gt;File (PixelTuples.bin)&lt;/strong&gt; in &lt;code&gt;rb&lt;/code&gt; mode and use &lt;code&gt;fread(const void * ptr, size_t size, size_t count, FILE * stream)&lt;/code&gt;, which works much like &lt;code&gt;fwrite()&lt;/code&gt;. So to read the data into the variable &lt;code&gt;pxarray_read&lt;/code&gt; of size &lt;strong&gt;256^3&lt;/strong&gt; you'd use:&lt;br&gt;
&lt;code&gt;fread(&amp;amp;pxarray_read, sizeof(pxtup), 256*256*256, pxF);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ok! Now for &lt;code&gt;ctypes&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Python code!
&lt;/h2&gt;

&lt;p&gt;The python code is actually pretty small and straightforward, as always...&lt;/p&gt;

&lt;p&gt;First we have to make sure Python knows the structure/arrangement of the &lt;code&gt;C struct&lt;/code&gt; we are porting, to do that, we make a &lt;code&gt;Python class&lt;/code&gt; and pass the &lt;code&gt;Structure&lt;/code&gt; parameter for &lt;code&gt;ctypes&lt;/code&gt; into it. Then we have to declare the &lt;code&gt;__fields__&lt;/code&gt;. Since our &lt;code&gt;C struct&lt;/code&gt; had 3 &lt;code&gt;int&lt;/code&gt; values we will refer to these with &lt;code&gt;c_int&lt;/code&gt; in python. I name them 'red', 'green', and 'blue' but it doesn't really matter what you name them. Just make sure the datatypes are correct and there are exactly the same number of variables in &lt;code&gt;__fields__&lt;/code&gt; list as there were in our actual &lt;code&gt;C struct&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from ctypes import *

class pxtup(Structure):
    _fields_ = [('red', c_int),
                ('green', c_int),
                ('blue', c_int)]


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

&lt;/div&gt;

&lt;p&gt;Now all we have to do is open the &lt;code&gt;.bin&lt;/code&gt; file we saved earlier, open it in &lt;code&gt;rb&lt;/code&gt; mode and keep importing all the struct variables that are of the same size as &lt;code&gt;pxtup()&lt;/code&gt; until we reach EOF.&lt;/p&gt;

&lt;p&gt;We use the python function &lt;code&gt;file.readinto()&lt;/code&gt; to read the file stream and append all the structures into a list. The end result is a &lt;strong&gt;list of tuples of 3 integers&lt;/strong&gt;, exactly what we wanted!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

with open('allc.bin', 'rb') as file:
    result = []
    allc = pxtup()
    while file.readinto(allc) == sizeof(allc):
        result.append((allc.red, allc.green, allc.blue))



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

&lt;/div&gt;

&lt;p&gt;This is what the result will look like-&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjl6yp28qwwwl2l9yva15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjl6yp28qwwwl2l9yva15.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aaand that's it! That's how you port your &lt;code&gt;C struct&lt;/code&gt;s into Python. With performance improvements and efficiency guaranteed! I hope you learned something from this guide, thanks for reading!&lt;/p&gt;

&lt;p&gt;Special thanks to the &lt;a href="https://github.com/M4cs/pixcryption" rel="noopener noreferrer"&gt;pixcryption&lt;/a&gt; project on GitHub to motivate me to find a way to improve Cartesian Product performance which eventually led me to learn about &lt;code&gt;ctypes&lt;/code&gt;!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
