From zero to hero: contributing to open source

Do you ever get the feeling that you are always a consumer and never a contributor to a library? Would you like to get more involved in open source projects and don’t know how? This is the story on how I personally became involved and went from fixing a simple bug to becoming the main contributor of a Node.js library.

It all began a couple of months ago. Microsoft offers a set of APIs called “cognitive services” for doing cool things like detecting faces in an image, converting spoken audio to text, recommending items to users based on past purchases, and many more. I was updating the part of the Azure website that has demos on each of these services. I had no idea these services existed before then, but they seemed to be on the road to become increasingly popular.

And I was not wrong. StackOverflow soon had tags for the topic: first project-oxford (the original name of the project), then microsoft-cognitive, then azure-cognitive-services

One day I was casually browsing the site when I came across this question: someone was using an NPM module called cognitive-services which was a wrapper over Microsoft’s APIs, and was getting a 404 error when attempting to call a service.

I skimmed over the library and while it seemed to look useful, it definitely could use some work. I saw duplicate code and, what’s most important, no tests.

But back to the original StackOverflow question: since I knew a bit about the topic, I decided to help out. I cloned the library to my machine, tweaked a bit the user’s question and created a Mocha test.

const cognitiveServices = require('../index');
const assert = require('assert');

describe('OCR', () => {
it('should work', done => {
const computerVision = cognitiveServices.computerVision({
API_KEY: "YAY MY OWN KEY!"
});
const parameters = {
"language": "unk",
"detectOrientation": "true",
"content-type": "application/json"
};
const body = {
"url": "https://upload.wikimedia.org/wikipedia/commons/2/23/Space_Needle_2011-07-04.jpg"
};

computerVision.ocr({
parameters,
body
})
.then(response => {
assert(response !== undefined);
done();
})
.catch(err => {
done(err);
});
})
})

And then I just ran the test.

reproducing the bug

Yep, the bug was there. I looked over the Issues page of the library, and it turns out that someone had already figured out the problem (or most of it): Microsoft had deprecated some endpoints, but the code hadn’t been updated. So whenever the code said “ai.projectoxford.com”, it had to be replaced with “westus.api.cognitive.microsoft.com”.

old
The bug was revealed but not fixed!

“Well”, I thought, “this is an easy change. Just update the production endpoint”.

And that’s what I did. Except that the code still did not work. I added a console.log of the URI the module was talking to… But wait, why is part of the URI “undefined“?

undefined

Let’s get into debug mode. The library is using this little makeRequest function to actually do the HTTP call. So why is this uriTemplate variable used but not set anywhere?

uriTemplate.PNG
What’s this variable for?

Let’s dive in now. Every function this Node module exposes defines an “operation” object with useful data like the query parameters it accepts, the headers it accepts, and so on. But they don’t have a “uriTemplate” parameter, they have a “path” parameter. Let’s change that!

changing uriTemplate to path
Changing the “uriTemplate” to “path”

This should work now, right?

fixing things
No… still doesn’t work!

Nope. We have to dig deeper, but I sense that we are close. Let’s look at the code that verifies the parameters and does the request.

code meat

Is there something wrong here? Yes! makeRequest returns a Promise object, but are we doing anything with it? No, there is a return statement missing. Let’s fix that.

o return statement, where art thou

Hooray! The test now passes!

success!

At that point, I was happy. With these code changes I would be able to submit a pull request, get it merged, and then be able to reply to the person “Your question allowed me to contribute to open source and get something fixed!”

But then I glanced again at the “Open issues” page and realized… this project is filled with errors! 404 errors, syntax errors (!)…

issues

Well, that’s when I got excited. The problems seemed easily solvable and would require some moderate amount of work. This was the exact combination I was looking for, so I went ahead and created an enormous pull request.

PR

When that got merged, suprise! I was made a project contributor.

contributor

Now I felt even more excited. I could push fixes and refactors without having to wait for someone to code review them. I of course wouldn’t write any code without supporting tests, so I went ahead and created API keys of my own for all the services, and wrote integration tests using those keys. The end result was a bunch of commits which brought the code coverage to 80%.

And I was even more happy when I looked at the star history of the repository! There was a steady growth ever since I pushed my first commit: the project’s stargazers went from 45 to 66 in less than two months.

star history

Why was I happy? Simple: people were actually using the library! And also, I was actually able to detect a few bugs in the API itself and report them to the core team.

Isn’t this what coding is all about? Quick iterations of development and lots of feedback in between? That’s what makes coding exciting.

So, now that you have read my story, I invite you to contribute to open source! There surely is a library you use every day that you can contribute to. Remember that no contribution is too small: even updates to documentation can make a big impact.

If you are feeling adventurous, you can always go the extra mile. Go ahead and subscribe to the StackOverflow tags you feel know best, and answer the questions for those tags. Maybe one day you’ll become such an expert on the subject that you’ll be ranked as a top answerer for the tag!

Subscribing to StackOverflow questions

And if you still don’t know where to start… PRs are welcome at cognitive-services 🙂

From zero to hero: contributing to open source

One thought on “From zero to hero: contributing to open source

Leave a comment