<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Shubham's blog]]></title><description><![CDATA[Shubham's blog]]></description><link>https://shubhamp.in</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 02:17:55 GMT</lastBuildDate><atom:link href="https://shubhamp.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[You should be running your 1-1s, not your manager]]></title><description><![CDATA[Biweekly 1-1s with my manager have been one of the best avenues for retrospective, career planning and seeking advice since I started a full time role.
The initial 1-1s after joining Glints were highly productive, I received a lot of feedback, both o...]]></description><link>https://shubhamp.in/you-should-be-running-your-1-1s-not-your-manager</link><guid isPermaLink="true">https://shubhamp.in/you-should-be-running-your-1-1s-not-your-manager</guid><category><![CDATA[engineering]]></category><category><![CDATA[engineering-management]]></category><category><![CDATA[one-on-one ]]></category><category><![CDATA[Career]]></category><category><![CDATA[career advice]]></category><category><![CDATA[Career development ]]></category><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Tue, 01 Mar 2022 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/wrdvOKfgzRo/upload/5c9e0228fb0995dc6fe190e0db394cdc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Biweekly 1-1s with my manager have been one of the best avenues for retrospective, career planning and seeking advice since I started a full time role.</p>
<p>The initial 1-1s after joining Glints were highly productive, I received a lot of feedback, both on things I should continue doing and things I should stop doing. During that time, my manager ran my 1-1s. He asked great questions starting from how I was feeling in day to day work to how I thought I was moving along in my career with some good retrospective questions mixed in there.</p>
<p>But after 4-5 months, the 1-1s did feel not as productive as before. After completed a 1-1; within the next few days, I always found myself thinking of things I missed to discuss with my manager, things I needed advice on. I put all the onus of running an effective 1-1 on my manager with me being a little bit of passive actor in the 1-1s.</p>
<p>This continued for a few months, after which I tried to come up with a solution to overcome the problem of me missing discussion points in our 1-1. I started keeping a log of things to discuss with my manager on notion throughout the week, which helped cover all my points of discussion in the 1-1 session but boy did the 1-1 session started becoming too long at that point. Thankfully, my manager was accommodating of the extended time, but it isn't a good sign if every session ran over its intended time.</p>
<p>One more thing I noticed was that since I kept the log of the things I wanted to discuss in my private Notion, most of the points where I needed advice from my manager were new to him. While, I could get advice on most of the things I had written down in my agenda, for some of the things, my manager also needed time to think through since he's also human.</p>
<p>To solve these two problems, I started preparing agenda on our shared 1-1 document in advance for him to review. That was a game changer in our 1-1s moving forward. The agenda had 2 kind of points:</p>
<ul>
<li><p>Points tagged with [Update] at their beginning. These were things that were good for my manager to be aware of, to be in touch with what's happening at the ground.</p>
</li>
<li><p>Points tagged with [Discussion] at their beginning. These are points that I need to discuss for the improvement of the team, personal career planning or anything that I need to get advice or brainstorm on.</p>
</li>
</ul>
<p>Having my manager have a pre-read of the agenda helped with 2 things:</p>
<ul>
<li><p>The updates could be read ahead of time and that was time saved for the other important discussions</p>
</li>
<li><p>Having discussions listed down helped me prioritise and time-box each discussion to fit the designated session time</p>
</li>
<li><p>It gave my manager some time to think about the problems before having the 1-1 agenda with me</p>
</li>
<li><p>I stopped missing important things to discuss</p>
</li>
<li><p>One of the main points was that it reduced any blindspots from the manager side, while every manager might have good questions to sus out important points of discussion, it is unrealistic to expect that those questions will cover all the things that are important to you.</p>
</li>
<li><p>I've had two managers over my course at Glints, both amazing mentors and it felt like setting the agenda from my side helped me get the best value I can from the opportunity of having those mentors to give me advice.</p>
</li>
</ul>
<p>ABOVE ALL: My career development is my responsibility, setting my agenda every 1-1 has provided with a higher ownership of my own development, which would not be possible by being less active in my career development journey. I realised early on that someone setting my goals for me just doesn't work in terms of development.</p>
<p>While this requires significant pre-work from my side, the effort has been worth it in most of the cases. But having this pre-work means that I don't religiously set the agenda every time, but try to aim to do it 70% of the time which goes a long way.</p>
]]></content:encoded></item><item><title><![CDATA[How Glints uses Unleash for A/B testing]]></title><description><![CDATA[In the beginning of 2020, Glints was in need of an A/B testing platform for us to test out different variants of a feature and we settled on an open source solution - Unleash. We evaluated multiple platforms but decided to use unleash because of the ...]]></description><link>https://shubhamp.in/how-glints-uses-unleash-for-ab-testing</link><guid isPermaLink="true">https://shubhamp.in/how-glints-uses-unleash-for-ab-testing</guid><category><![CDATA[engineering]]></category><category><![CDATA[ab testing]]></category><category><![CDATA[  feature flags]]></category><category><![CDATA[Feature Management]]></category><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Sat, 25 Sep 2021 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710194807295/53f047c1-ea24-4b34-9e27-3280938abe91.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the beginning of 2020, Glints was in need of an A/B testing platform for us to test out different variants of a feature and we settled on an open source solution - <a target="_blank" href="https://docs.getunleash.io/">Unleash</a>. We evaluated multiple platforms but decided to use unleash because of the following reasons:</p>
<ul>
<li><p>A simple UI for non-tech people to control the experiments</p>
</li>
<li><p>Language agnostic with client libraries in multiple languages</p>
</li>
<li><p>Actively maintained project (we started with Unleash v3 and now we are using Unleash v4 with significant improvement in terms of features)</p>
</li>
</ul>
<h3 id="heading-what-is-unleash"><strong>What is Unleash?</strong></h3>
<p>Unleash is an open-source feature management platform. It provides a great overview of all feature toggles/flags across all your applications and services.</p>
<h3 id="heading-architecture-overview"><strong>Architecture overview:</strong></h3>
<p><img src="https://tech.glints.com/content/images/2021/09/Unleash-diagram--1-.png" alt /></p>
<p>This is what our architecture with unleash looks like. We have the unleash server which is responsible for storing all the feature toggles, their strategies and their history along with all the unleash user info.</p>
<p>We do not directly access unleash via our front end clients. That would expose unnecessary information about the feature toggles that the user doesn't need to know e.g. which features have been disabled for them. The API server acts as a proxy between the front end clients and the unleash server.</p>
<p>The Glints API server connects to the unleash server to get the data of existing feature toggles. Using this data, the proxy endpoint gives a list of feature flags that have been enabled for the user along with the variant if it exists when requested by the client. Absence of a feature flag from the list should be perceived that the feature flag has been disabled for that user.</p>
<p>The API endpoint would return the feature flags based on the <a target="_blank" href="https://unleash.github.io/docs/unleash_context"><em>unleash-context</em></a> provided by the front end client.</p>
<h3 id="heading-would-the-unleash-server-being-down-affect-my-application"><strong>Would the unleash server being down affect my application?</strong></h3>
<p>Not at all. This is one of the things that we love about Unleash.</p>
<p>All of the Unleash SDKs (<a target="_blank" href="https://github.com/Unleash/unleash-client-node">unleash-client-node</a> in our case) do something called local evaluation. That means that only the information about a feature toggle is stored on the unleash server, but assigning a user to a variant A or a variant B happens via the SDK. This means that if your unleash server is down, your feature flags would still keep on working on the last known state without any updates possible to the existing state.</p>
<h3 id="heading-does-unleash-come-with-built-in-tools-to-analyse-the-performance-of-each-variant-of-the-ab-test"><strong>Does unleash come with built in tools to analyse the performance of each variant of the A/B test?</strong></h3>
<p>No, we use <a target="_blank" href="https://amplitude.com/">Amplitude</a> at Glints to analyse how each of our variants in the tests are performing. We think its for the best since Unleash is a feature management platform and it does that 1 thing right instead of trying to dip its toes in multiple places.</p>
<p>Checkout <a target="_blank" href="https://docs.getunleash.io/">https://docs.getunleash.io/</a> to get started on Unleash!</p>
]]></content:encoded></item><item><title><![CDATA[An engineer's guide to asking better questions on Slack]]></title><description><![CDATA[Have you recently found yourself in conversations on Slack that feel days to resolve when similar conversations would be resolved relatively quickly in person. If yes, this article will help you make your asynchronous conversations more efficient.
[M...]]></description><link>https://shubhamp.in/an-engineers-guide-to-asking-better-questions-on-slack</link><guid isPermaLink="true">https://shubhamp.in/an-engineers-guide-to-asking-better-questions-on-slack</guid><category><![CDATA[engineering]]></category><category><![CDATA[slack]]></category><category><![CDATA[learning]]></category><category><![CDATA[questions]]></category><category><![CDATA[communication]]></category><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Mon, 28 Dec 2020 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710194606105/50467144-850e-497a-955e-22ffc2fd7919.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you recently found yourself in conversations on Slack that feel days to resolve when similar conversations would be resolved relatively quickly in person. If yes, this article will help you make your asynchronous conversations more efficient.</p>
<p>[Monday 4:00 pm] Michael, a backend engineer with very little knowledge of the frontend codebase gets stuck while trying to solve a frontend bug. In a normal working situation, Michael would go to John's desk, the frontend engineer in the team and clarify the doubt in person. But since the whole team has been working remote since the pandemic, he drops a message to John on Slack. He attaches a code block in the message and asks <code>Hi John, can you guide how can I make this code work successfully?</code>.</p>
<p>[Tuesday 09:00 am] John starts his morning routine of going through the previous day's slack mentions and notices the above message from Michael. Although John is the most experienced frontend engineer on the team, John has no clue how to respond to the question since he does not know what problem is Michael trying to solve. John drops a message to Michael asking for a link to the bug that John is trying to solve.</p>
<p>[Tuesday 03:00 pm] Michael is going through his slack notifs after lunch and notices John has asked for the bug link, so Michael messages that link to John.</p>
<p>[Wednesday 09:00 am] John notices the bug link from Michael in his mentions, he goes through the bug and thinks of an alternative solution to the one that Michael gave and drops a message to Michael with that solution.</p>
<p>[Wednesday 10:00 am] Michael has been more frequent to check his slack in anticipation of John's reply. He notices the alternative solution proposed by John, but turns out he has already tried that solution and it does not quite solve the problem due to a weird edge case. He gets back to John with the details of his previous attempt.</p>
<p>This back and forth keeps on going on till Friday when John finally realizes on how the bug can be solved from Michael's information. <strong>The conversation around the bug took them 4 days to resolve.</strong> If both of the engineers were working in person, would this conversation have taken them 4 days to solve with the questions asked same way line to line? The answer would be no, since all of John's question about the problem would have been answered immediately instead of waiting for hours. The conversation would have taken at most an hour to resolve instead of 4 days.</p>
<p>What's the problem here, is Michael just bad at asking questions? But that can't be, Michael has been asking questions the same way as he did before. The example here is a bit of an hyperbole on how expensive asynchronous communication can be sometimes if we follow the same rules as real time communication. <strong>Following are points to keep in mind when trying to ask questions asynchronously:</strong></p>
<ul>
<li><p><strong>Give the full Context. (Clearly state what you're trying to do)</strong>Instead of just trying to ask what's wrong with the code, Michael could have started his message with <code>Hey, I was trying to solve [bug_link_here], where the popup doesn't appear on condition x</code> . This message would give John more context on what's the problem in the first place. Additional thing to keep in mind when trying to give John context is to assume that John is completely clueless on the ideal behaviour of that part of the codebase, since John is not an all knowing deity.</p>
</li>
<li><p><strong>Outline your previous attempts to solve the problem.</strong>Michael had tried 2-3 solutions that didn't work before going to John for help. It would help John narrow down the problem if he was aware of those attempts and what Michael had already tried.</p>
</li>
<li><p><strong>Describe what's the problem that you're facing in your attempt.</strong>Just describing your attempts isn't enough, please describe what you've tried before.</p>
</li>
</ul>
<p>Aside from the points described above, please be specific in what you are trying to point i.e. use <code>this</code>, <code>that</code> and <code>it</code> as less as possible. E.g. if you're referencing a column, explicitly name that column, don't assume the person on the other side knows what you're talking about. If you're referencing a commit, give a hash of that commit or even better, drop a link to a specific line of code at a specific revision on GitLab/GitHub.</p>
<p>Although these points might help you frame your better questions, <strong>the best way to get better at asking questions would be to ask a co-worker of yours to help you create a feedback loop.</strong> You agree that whenever you ask that co-worker any question, that co-worker would point out the flaws in your questions immediately and help you give feedback then and there on how you could you have better framed the question to help your co-worker understand the problem in the first go.</p>
]]></content:encoded></item><item><title><![CDATA[Supporting Kebab-Case Attributes And Query Params In Flask-Rest Jsonapi]]></title><description><![CDATA[In the Open Event API Server Project, it was decided to dasherize all the attributes of the API.
What Was The Need For Dasherizing The Attributes In The API ?
All the attributes in our database models are seperated by underscores i.e first name would...]]></description><link>https://shubhamp.in/supporting-kebab-case-attributes-and-query-params-in-flask-rest-jsonapi</link><guid isPermaLink="true">https://shubhamp.in/supporting-kebab-case-attributes-and-query-params-in-flask-rest-jsonapi</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Python]]></category><category><![CDATA[Flask Framework]]></category><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Wed, 07 Jun 2017 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/somKa7kuAmQ/upload/68ff08b7fd74e5a93a74a3b3dbf813f3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the <a target="_blank" href="https://web.archive.org/web/20200225124931/https://github.com/fossasia/open-event-orga-server">Open Event API Server</a> Project, it was decided to dasherize all the attributes of the API.</p>
<h3 id="heading-what-was-the-need-for-dasherizing-the-attributes-in-the-api"><strong>What Was The Need For Dasherizing The Attributes In The API ?</strong></h3>
<p>All the attributes in our database models are seperated by underscores i.e <code>first name</code> would be stored as <code>first_name</code>. But most of the API client implementations support dasherized attributes by default. In order to attract third party client implementations in the future and making the API easy to setup for them was the primary reason behind this decision. Note: The dasherized version for <code>first_name</code> will be <code>first-name</code>. Also to quote the official json-api spec recommendation for the same:</p>
<blockquote>
<p><em>Member names SHOULD contain only the characters “a-z” (U+0061 to U+007A), “0-9” (U+0030 to U+0039), and the hyphen minus (U+002D HYPHEN-MINUS, “-“) as separator between multiple words.</em></p>
</blockquote>
<p><a target="_blank" href="https://web.archive.org/web/20200225124931/http://flask-rest-jsonapi.readthedocs.io/en/latest/">flask-rest-jsonapi</a> is the API framework used by the project. We were able to dasherize the API responses and requests by adding <code>inflect=dasherize</code> to each API schema, where <code>dasherize</code> iss the following function:</p>
<pre><code class="lang-plaintext">def dasherize(text):
    return text.replace('_', '-')
</code></pre>
<p><a target="_blank" href="https://web.archive.org/web/20200225124931/http://flask-rest-jsonapi.readthedocs.io/en/latest/">flask-rest-jsonapi</a> also provides powerful features like the following through query params:</p>
<ul>
<li><p><a target="_blank" href="https://web.archive.org/web/20200225124931/http://flask-rest-jsonapi.readthedocs.io/en/latest/sparse_fieldsets.html">Sparse fieldsets</a></p>
</li>
<li><p><a target="_blank" href="https://web.archive.org/web/20200225124931/http://flask-rest-jsonapi.readthedocs.io/en/latest/pagination.html">Sorting</a></p>
</li>
<li><p><a target="_blank" href="https://web.archive.org/web/20200225124931/http://flask-rest-jsonapi.readthedocs.io/en/latest/include_related_objects.html">Include related objects</a></p>
</li>
</ul>
<p>But we observed that the query params were not being dasherized which rendered the above awesome features useless :( . The reason for this was that <a target="_blank" href="https://web.archive.org/web/20200225124931/http://flask-rest-jsonapi.readthedocs.io/en/latest/">flask-rest-jsonapi</a> took the query params <code>as-is</code> and search for them in the API schema. As Python variable names cannot contain a dash, naming the attributes with a dash in the internal API schema was out of the question.</p>
<p>For adding dasherizing support to the query params, change in the <code>QueryStringManager</code> located at <code>querystring.py</code> of the framework root are required. A config variable named <code>DASHERIZE_API</code> was added to turn this feature on and off.</p>
<h3 id="heading-following-are-the-changes-required-for-dasherizing-query-params"><strong>Following Are The Changes Required For Dasherizing Query Params:</strong></h3>
<p>For Sparse Fieldsets in the <code>fields</code> function, replace the following line:</p>
<pre><code class="lang-plaintext">result[key] = [value]
</code></pre>
<p>with</p>
<pre><code class="lang-plaintext">if current_app.config['DASHERIZE_API'] is True:
    result[key] = [value.replace('-', '_')]
else:
    result[key] = [value]
</code></pre>
<p>For sorting, in the <code>sorting</code> function, replace the following line:</p>
<pre><code class="lang-plaintext">field = sort_field.replace('-', '')
</code></pre>
<p>with</p>
<pre><code class="lang-plaintext">if current_app.config['DASHERIZE_API'] is True:
    field = sort_field[0].replace('-', '') + sort_field[1:].replace('-', '_')
else:
    field = sort_field[0].replace('-', '') + sort_field[1:]
</code></pre>
<p>For Include related objects, in <code>include</code> function, replace the following line:</p>
<pre><code class="lang-plaintext">return include_param.split(',') if include_param else []
</code></pre>
<p>with</p>
<pre><code class="lang-plaintext">if include_param:
    param_results = []
    for param in include_param.split(','):
        if current_app.config['DASHERIZE_API'] is True:
            param = param.replace('-', '_')
        param_results.append(param)
    return param_results
return []
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Modifying Flask-Rest-Jsonapi Exception Handling To Enable Support For Sentry]]></title><description><![CDATA[In open-event-server Project, we had enabled sentry support in the project. So first of all,
What Is Sentry ?
Sentry provides open source error tracking that shows you every crash in your stack as it happens, with the details needed to prioritize, id...]]></description><link>https://shubhamp.in/modifying-flask-rest-jsonapi-exception-handling-to-enable-support-for-sentry</link><guid isPermaLink="true">https://shubhamp.in/modifying-flask-rest-jsonapi-exception-handling-to-enable-support-for-sentry</guid><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Wed, 07 Jun 2017 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710195971182/7a5c86d7-4915-4507-800b-d2fa5d59c8f0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In <a target="_blank" href="https://web.archive.org/web/20191230114041/https://github.com/fossasia/open-event-orga-server">open-event-server</a> Project, we had enabled <a target="_blank" href="https://web.archive.org/web/20191230114041/https://sentry.io/welcome/">sentry</a> support in the project. So first of all,</p>
<h3 id="heading-what-is-sentry"><strong>What Is Sentry ?</strong></h3>
<p>Sentry provides open source error tracking that shows you every crash in your stack as it happens, with the details needed to prioritize, identify, reproduce, and fix each issue.</p>
<p>We enabled the basic error tracking with the following two simple lines,</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> raven.contrib.flask <span class="hljs-keyword">import</span> Sentry
sentry = Sentry(app, dsn=<span class="hljs-string">'https://&lt;key&gt;:&lt;secret&gt;@sentry.io/&lt;project&gt;'</span>)
</code></pre>
<p>But after sometime, we noticed that we were not catching any app-related error in Sentry, while migration related errors were being caught. This meant that sentry was functioning properly in the app, but it was having some trouble in identifying uncaught exceptions.</p>
<p>After a lot of digging, it came to our knowledge that our api framework, <a target="_blank" href="https://web.archive.org/web/20191230114041/https://github.com/miLibris/flask-rest-jsonapi">flask-rest-jsonapi</a> caught all unknown exceptions while dispatching the request. After catching the exceptions, it gave a jsonapi error with status 500 in return. Following is the code responsible for that:</p>
<pre><code class="lang-python"><span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
            <span class="hljs-keyword">if</span> current_app.config[<span class="hljs-string">'DEBUG'</span>] <span class="hljs-keyword">is</span> <span class="hljs-literal">True</span>:
                <span class="hljs-keyword">raise</span> e
            exc = JsonApiException(<span class="hljs-string">''</span>, <span class="hljs-string">'Unknown error'</span>)
            <span class="hljs-keyword">return</span> make_response(json.dumps(jsonapi_errors([exc.to_dict()])),
                                 exc.status,
                                 headers)
</code></pre>
<p>We now had to let these exceptions go uncaught and that required us to modify the api framework. So we modified the api-framework’s exception handling as shown below</p>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> <span class="hljs-string">'API_PROPOGATE_UNCAUGHT_EXCEPTIONS'</span> <span class="hljs-keyword">in</span> current_app.config:
                <span class="hljs-keyword">if</span> current_app.config[<span class="hljs-string">'API_PROPOGATE_UNCAUGHT_EXCEPTIONS'</span>] <span class="hljs-keyword">is</span> <span class="hljs-literal">True</span>:
                    <span class="hljs-keyword">raise</span>
            <span class="hljs-keyword">if</span> current_app.config[<span class="hljs-string">'DEBUG'</span>] <span class="hljs-keyword">is</span> <span class="hljs-literal">True</span>:
                <span class="hljs-keyword">raise</span> e
            exc = JsonApiException({<span class="hljs-string">'pointer'</span>: <span class="hljs-string">''</span>}, <span class="hljs-string">'Unknown error'</span>)
            <span class="hljs-keyword">return</span> make_response(json.dumps(jsonapi_errors([exc.to_dict()])),
                                 exc.status,
                                 headers)
</code></pre>
<p>A config parameter named <code>API_PROPOGATE_UNCAUGHT_EXCEPTIONS</code> was added to the config to turn this feature on or off.</p>
<p>But with all this done, we were able to catch errors with sentry, but the json-api spec compliant error messages on an unknown error were not being returned due to this new change. So it was decided to handle these uncaught exceptions in the app itself. We used flask’s default error handlers to tackle this situation</p>
<pre><code class="lang-python"><span class="hljs-meta">@app.errorhandler(500)</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">internal_server_error</span>(<span class="hljs-params">error</span>):</span>
    exc = JsonApiException({<span class="hljs-string">'pointer'</span>: <span class="hljs-string">''</span>}, <span class="hljs-string">'Unknown error'</span>)
    <span class="hljs-keyword">return</span> make_response(json.dumps(jsonapi_errors([exc.to_dict()])), exc.status,
                         {<span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/vnd.api+json'</span>})
</code></pre>
<p>Thus, all uncaught exceptions were now returning a proper json-api spec compliant error response.</p>
<p>Related links:</p>
<ul>
<li><p>Flask error handlers: http://flask.pocoo.org/docs/0.12/patterns/errorpages/#error-handlers</p>
</li>
<li><p>Json-api spec: http://jsonapi.org/</p>
</li>
<li><p>Json-api errors: http://jsonapi.org/examples/#error-objects</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Event-Driven Programming In Flask With Blinker Signals]]></title><description><![CDATA[Setting Up Blinker:
The Open Event Project offers event managers a platform to organize all kinds of events including concerts, conferences, summits and regular meetups. In the server part of the project, the issue at hand was to perform multiple tas...]]></description><link>https://shubhamp.in/event-driven-programming-in-flask-with-blinker-signals</link><guid isPermaLink="true">https://shubhamp.in/event-driven-programming-in-flask-with-blinker-signals</guid><category><![CDATA[Flask Framework]]></category><category><![CDATA[Python]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Thu, 23 Mar 2017 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710195565416/c1a1db07-5c2e-48db-bbaf-34f214504549.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-setting-up-blinker"><strong>Setting Up Blinker:</strong></h2>
<p>The Open Event Project offers event managers a platform to organize all kinds of events including concerts, conferences, summits and regular meetups. In the server part of the project, the issue at hand was to perform multiple tasks in background(we use celery for this) whenever some changes occured wither in the event, or the speakers/sessions associated with the event.</p>
<p>The usual approach to this would be applying a function call after any relevant changes are made. But the statements making these changes were distributed all over the project at multiple places. It would be cumbersome to add 3-4 function calls(which are irrelevant to the function they are being executed) in so may places. Moreover, the code would get unstructured with this and it would be really hard to maintain this code over time.</p>
<p>That’s when signals came to our rescue. From Flask 0.6, there is integrated support for signalling in Flask, refer http://flask.pocoo.org/docs/latest/signals/ . The <a target="_blank" href="https://web.archive.org/web/20191230114103/https://github.com/jek/blinker">Blinker</a> library is used here to implement signals. If you’re coming from some other language, signals are analogous to events.</p>
<p>Given below is the code to create named signals in a custom namespace:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> blinker <span class="hljs-keyword">import</span> Namespace

event_signals = Namespace()
speakers_modified = event_signals.signal(<span class="hljs-string">'event_json_modified'</span>)
</code></pre>
<p>If you want to emit a signal, you can do so by calling the send() method:</p>
<pre><code class="lang-python">speakers_modified.send(current_app._get_current_object(), event_id=event.id, speaker_id=speaker.id)
</code></pre>
<p>From the user guide itself: Try to always pick a good sender. If you have a class that is emitting a signal, pass self as sender. If you are emitting a signal from a random function, you can pass current_app._get_current_object() as sender.</p>
<p>To subscribe to a signal, <a target="_blank" href="https://web.archive.org/web/20191230114103/https://github.com/jek/blinker">blinker</a> provides neat decorator based signal subscriptions.</p>
<pre><code class="lang-python"><span class="hljs-meta">@speakers_modified.connect</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">name_of_signal_handler</span>(<span class="hljs-params">app, **kwargs</span>):</span>
</code></pre>
<h2 id="heading-some-design-decisions"><strong>Some Design Decisions:</strong></h2>
<p>When sending the signal, the signal may be sending lots of information, which your signal may or may not want. e.g when you have multiple subscribers listening to the same signal. Some of the information sent by the signal may not be of use to your specific function. Thus we decided to enforce the pattern below to ensure flexibility throughout the project.</p>
<pre><code class="lang-python"><span class="hljs-meta">@speakers_modified.connect</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">new_handler</span>(<span class="hljs-params">app, **kwargs</span>):</span>
<span class="hljs-comment"># do whatever you want to do with kwargs['event_id']</span>
</code></pre>
<p>In this case, the function <code>new_handler</code> needs to perform some task solely based on the event_id. If the function was of the form <code>def new_handler(app, event_id)</code>, an error would be raised by the app. A big plus of this approach, if you want to send some more info with the signal, for the sake of example, if you also want to send speaker_name along with the signal, this pattern ensures that no error is raised by any of the subscribers defined before this change was made.</p>
<h2 id="heading-when-to-use-signals-and-when-not"><strong>When To Use Signals And When Not ?</strong></h2>
<p>The call to send a signal will of course be lying in another function itself. The signal and the function should be independent of each other. If the task done by any of the signal subscribers, even remotely affects your current function, a signal shouldn’t be used, use a fucntion call instead.</p>
<p>That’s all for now. Have some fun signaling ;) .</p>
]]></content:encoded></item><item><title><![CDATA[My Journey Through Fossasia’s Codeheat Contest]]></title><description><![CDATA[Better late than never. Academics have been pretty hectic lately and I finally got some time to pen down my experience through fossasia’s Codeheat (In the heat of code) Contest.
There was always something that fascinated me about the web.I started ou...]]></description><link>https://shubhamp.in/my-journey-through-fossasias-codeheat-contest</link><guid isPermaLink="true">https://shubhamp.in/my-journey-through-fossasias-codeheat-contest</guid><dc:creator><![CDATA[Shubham Padia]]></dc:creator><pubDate>Fri, 17 Feb 2017 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1710195750156/3f2892b2-dea7-455f-b13f-501dd7df920f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Better late than never. Academics have been pretty hectic lately and I finally got some time to pen down my experience through <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a>’s <a target="_blank" href="https://web.archive.org/web/20191230114133/http://codeheat.org/">Codeheat</a> (In the heat of code) Contest.</p>
<p>There was always something that fascinated me about the web.I started out with web development in the first year of my undergrad and over the summer I thought it was time to apply these skills on some real projects. So I was looking for an open source organisation to contribute and sharpen my skills, and that’s when I came across <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a>. The community was so welcoming and wonderful and the <a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/fossasia/open-event">Open Event project</a> (<a target="_blank" href="https://web.archive.org/web/20191230114133/https://eventyay.com/">eventyay</a>) just caught my eye.</p>
<p>So let me tell you a little bit more about <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a>’s Open Event Project. Open Event project is a fully-fledged event management system along with its own website generator and android app generator. You can find more about the project <a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/fossasia/open-event">here</a>.</p>
<p>I started out with the <a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/fossasia/open-event-webapp/">Webapp repo</a> of the Open Event project of <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a> in September last year and actively contributed to it over the next two months(and learned a lot !!). I also started contributing to the Open Event Orga Server in the meantime. Thats when I heard about the <a target="_blank" href="https://web.archive.org/web/20191230114133/http://codeheat.org/">Codeheat</a> contest. Code Heat or aptly said ‘In The Heat Of Code’ is a coding contest with a focus on three projects:</p>
<ul>
<li><p><a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/fossasia/open-event-orga-server/">The Open Event Orga Server</a></p>
</li>
<li><p><a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/fossasia/?utf8=%E2%9C%93&amp;q=susi&amp;type=&amp;language=">AskSusi Project</a></p>
</li>
<li><p><a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/fossasia/loklak_search">Loklak Project</a></p>
</li>
</ul>
<p>I continued contributing to the server project whenever I got some free time. Meanwhile I also mentored in Google Code In for <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a>(What a lovely experience it was, but thats a topic for a whole another blog post). Then came the End semester Winter break in december(Yay!! to some free time). And thus began a coding streak and I tried to contribute to the project, solving issues, adding features as much as I can. I got to learn some exciting new things and practices as I continued solving issues. The project became a whole lot active during this period and it certainly was a lot of fun contributing to the project. The maintainers of the project <a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/SaptakS">Saptak Sengupta</a>, <a target="_blank" href="https://web.archive.org/web/20191230114133/https://github.com/niranjan94">Niranjan Rajendran</a> and Org admin <a target="_blank" href="https://web.archive.org/web/20191230114133/https://twitter.com/mariobehling">Mario Behling</a> were also very helpful and provided useful insights when solving the issues.</p>
<p>Time sure does move fast. I continued contributing to the project and in no time it was february. It was pretty late at night and I was just scrolling along my twitter feed when I noticed a tweet from <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a> announcing the winners of the <a target="_blank" href="https://web.archive.org/web/20191230114133/http://codeheat.org/">Codeheat</a> contest. Boy was I nervous !! I immediately clicked on the link and found out that I was among the grand prize winners. And all those nervousness was gone suddenly and I felt really happy and excited.</p>
<p>So I’m now planning to attend the <a target="_blank" href="https://web.archive.org/web/20191230114133/http://2017.fossasia.org/">fossasia summit</a> (which is awwesommeee !!) in Singapore and hoping to meet new people, learn about new technologies and expand my horizons in the world of open source. I’m also looking forward to contribute more towards making this project a great success. Thanks <a target="_blank" href="https://web.archive.org/web/20191230114133/https://twitter.com/hpdang">Hong Phuc Dang</a>, <a target="_blank" href="https://web.archive.org/web/20191230114133/https://twitter.com/mariobehling">Mario Behling</a> and <a target="_blank" href="https://web.archive.org/web/20191230114133/http://fossasia.org/">fossasia</a> for this wonderful opprtunity.</p>
]]></content:encoded></item></channel></rss>