Sam Bosell
Ambient Data

Ambient Data

Weekly Notes 2021-W8

Weekly Notes 2021-W8

Sam Bosell's photo
Sam Bosell
·Feb 26, 2021·

5 min read

These logs are my work logs (anonymized) mixed in with a few thoughts and maybe some personal anecdotes. Like last week's notes had an introduction with a lesson I learned from boxing and will continue with the theme. Having spent a lot of time in the boxing gym I was able to spar a lot of people in the gym. When you know someone's strengths and weaknesses it is more an exercise than a competitive action but on one occasion I sparred a guy from another gym and learned a few things, one of which was having a coach in your corner is important. In business that can be a partner, mentor, or even a friend that is giving you objective advice that you respect. Family aside (wife, dad, brother, mom) as mine is great for advice, my business partner Creed has always been a great sounding board, ideas man, sometimes opposing view, and of course friend over the last 15 years. Like my awesome boxing coach Cesar, having someone in your corner can make a world of difference when dealing with the stresses of work, decisions, projects, or anything that might be weighing on one's mind.

Work logs

Building a gift card integration program to a square space site so that when a guest orders an e-card they'll get a nice email with a gift card number they can use in-store. ASPNET core application that receives webhooks, calls the SS api, creates a giftcard and issues an email. This will take most of the week.

Testing and making changes to an offline enabled PWA that allows field personnel to log inspection data in the field without an internet connection. Little did I realize that Apple devices only support this on Safari. Forget about Chrome and other browsers as they don't support service workers.

Updates to an existing large Energy Sector web application. I built a few Vue components to make data entry nicer and the users ask for more changes which is great and relatively easy now that it is all done in Vue (first version was jQuery since it predated angular/vue/etc).

Still waiting on Umbraco HQ to address this high impacting bug which I created December 8th, 2020 and has seen very little progress on it. I normally don't complain about open source software, but Umbraco is a for profit company that supports this software which is used to generate income for them.

Still working with Microsoft Support on some internal issues with our Azure account since we don't have access to some things in our Tenant that we should. They've been working on this for a month so it must be tricky but at least they are pushing the ball forward slowly.

Met with a colleague about the initial steps about putting together a pitch deck for a client for a new project which will add value and be a technically fun project to build out.

Personal Website logs

To continue with some of the changes I made to my personal website (not released yet), I redid the entire thing with Tailwind so no more templates. Also, I created a demo of the Azure Form Recognition Cognitive Service and Text Analytics.

The Form Recognition AI Service takes documents or images and converts them into structured data, much like OCR on steroids. For instance, if you have an invoice document (pdf probably mailed in) in your company and you want to extract that information in a standardized way, this service can help. The demo I am building is simple, the user uploads a store receipt and the system will return the information it can pull from it which is displayed on the page (vue). The server code is deceptively simple (10 lines of code) and uploads the file to a storage blob and then processes it. The blob is named with a GUID so you can bookmark the results without needing a database. I noticed that the underlying data model the SDK uses (ie RecognizedFormCollection) doesn't serialize well so I converted it to a dynamic JSON so I could add the image blob url to it (last couple lines). This is all trivial using Service Stack which has great support for Virtual File Systems (Azure in my case) and the ability to easily serialize and deserialize dynamic data.

public async Task<object> Any(DocumentScanUpload req) {
    var fileName = $"{Guid.NewGuid()}{Path.GetExtension(base.Request.Files[0].FileName)}";
    AzureVirtualFiles.WriteFile(fileName, base.Request.Files[0].InputStream);
    AzureBlobVirtualFile file = (AzureBlobVirtualFile) AzureVirtualFiles.GetFile(fileName);
    var waiter = Client.StartRecognizeReceiptsFromUri(file.Blob.Uri);
    Response<RecognizedFormCollection> operationResponse = await waiter.WaitForCompletionAsync();

    var opResult = operationResponse.GetRawResponse().ContentStream.ReadToEnd();
    var obj = JsonObject.Parse(opResult);
    obj.Add("ImageUrl", file.Blob.Uri.ToString());
    return obj.ToJson();


Here is a preview of the results:

Weekly Notes 2021-W8

The Text Analytic Service can be used to extract sentiment, opinion mining, key phrases and entities from textual information (feedback, etc). This endpoint is a little trickier because if you want to also extract Key Phrases and Entites along with the sentiment they are separate api calls. All the same, the code is simple. My example I am making 3 api calls and then amalgamating the results together, saving them to a blob and then returning the results to the front end.

[AddHeader(ContentType =MimeTypes.Json)]
public async Task<object> Any(TextAnalyticsRequest req)
        var fileId = Guid.NewGuid().ToString();

    var sentiment = TextClient.AnalyzeSentimentAsync(req.Text, options: new AnalyzeSentimentOptions(){ IncludeOpinionMining=true });
    var keywords =TextClient.ExtractKeyPhrasesAsync(req.Text);
    var entities = TextClient.RecognizeLinkedEntitiesAsync(req.Text);

    await Task.WhenAll(sentiment, keywords, entities);

    var text = sentiment.Result.GetRawResponse().ContentStream.ReadToEnd();
    var kText = keywords.Result.GetRawResponse().ContentStream.ReadToEnd();
    var eText= entities.Result.GetRawResponse().ContentStream.ReadToEnd();

    var obj = JsonObject.Parse(text);
    obj.Add("originalText", req.Text);
    obj.Add("keywords", kText );
    obj.Add("entities", eText);
    obj.Add("fileId", fileId);
    text = obj.ToJson();
    var filename = $"ta-{fileId}.json";
    AzureVirtualFiles.WriteFile (filename,text);
    return obj;

Here is a preview of the demo:

Weekly Notes 2021-W8

I have about ten ideas in total for labs of useful things that I built or have wanted to build over the last decade. I will add them as time permitting.

Share this