Author Archive

#Speech to text recognition with #IBM #Watson in C#

If you’ve had experience with AWS Transcribe, you will notice that despite it’s excellent accuracy, it is unfortunately very slow, which can make things awkward if your application is time-sensitive.

One alternative was IBM Watson, which I personally found to be much faster than AWS Transcribe, by an order of magnitude, and it does support keyword matching, which is great if you are looking out for key phrases in audio. However, I did find it was less accurate than AWS transcribe.

You can get started with IBM Watson for free, without a credit card, and you can subscribe to the free version of the speech to text API (500 minutes free per month), which gives you enough to test with. This example assumes you already have an API key, and service URL, which you can get from the IBM website.

So, in this example, I am using a pre-recorded WAV file, which is included in my project (Build action set to copy always). The WAV file is a 8Hkz format, which is really low quality.

So, lets include the NUGET package by typing;

Install-Package IBM.Watson.SpeechToText.v1 

Then, we’ll write a bit of code to test this out – The project type is a .NET Core, Console app.

var bAudio = File.ReadAllBytes("Sample.wav");
var memAudio = new MemoryStream(bAudio);
const string apiKey = "xxxxxx";
var authenticator = new IamAuthenticator(apiKey);
var service = new SpeechToTextService(authenticator);
var results = service.Recognize( memAudio, model: "en-US_NarrowbandModel");

In terms of complexity, this is certainly easier than the equivalent code for AWS Transcribe, since you don’t need to upload to S3, poll on the results, then download from S3 again.

It’s pretty much the same price as AWS at $0.02 per minute, but has different pricing tiers, so it’s hard to compare like-for-like.

Categories: Uncategorized

Getting started with #DynamoDB in C#

DynamoDB is a good way to get started with NoSQL databases, and being hosted in AWS, means that you don’t have to worry about servers or backups.

Now, a few assumptions before starting. I’m assuming that you’ve set up a test table, with at least item, with primary key called id of type string. I’m also assuming your development machine has stored AWS credentials, (AWS configure), since they won’t be in the code.

So, step 1, we’ll install two NUGET packages;

Install-Package AWSSDK.DynamoDBv2 
Install-Package Newtonsoft.Json

Then, we'll set up a private static reference to our client as follows;
private static readonly AmazonDynamoDBClient Client = new AmazonDynamoDBClient();

The code supplied on Amazon for listing tables is designed to list any number of tables, however, this simplified version will read up to 100 tables. But here is a simplified version;

private static void ListMyTables()
 var response = Client.ListTablesAsync().Result;

Now, Imagine we want to read an item from the table, by id and return the data as JSON, we’d use;

private static string GetJsonById(string tableName, string id)
	var request = new QueryRequest
		TableName = tableName,
		KeyConditionExpression = "id = :v_Id",
		ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
			{":v_Id", new AttributeValue { S =  id }}}

	var response = Client.QueryAsync(request).Result;

	return JsonConvert.SerializeObject(response.Items, Formatting.Indented);

Where we pass the table name, and the id, and it returns as JSON.

And finally, let’s imagine we want to write to the table, with some JSON;

private static void CreateItemFromJson(string tableName, string jsonText)
	var item = Document.FromJson(jsonText);
	var table = Table.LoadTable(Client, tableName);
	var ignore =table.PutItemAsync(item).Result;

And that’s the basic read/write functionality of DynamoDB.

Categories: Uncategorized

#Twitter now added as a source to #AvatarAPI – Look up Twitter profiles by email address

AvatarAPI is a service that allows users to look up people’s real names, and profile images using only an email address.

Today, we’ve just added Twitter as a source to this, thanks to a RapidAPI API “” – As shown in the screenshot above, the input is an email address, and the profile data is returned. Including the name, location, profile picture – if set by the user.

That adds another 330 Million accounts toe the repertoire of AvatarAPI

Categories: Uncategorized

Remove the background from an Image using C#

Instead of manually processing images, and cutting out the subject from the background, you can use an API to do this, as long as the image is publicly accessible via a URL – Even temporarily accessible, you could upload to S3, then delete it again afterwards.

Here’s the code – in C#

var url = "";

var oReq = new { url = "" };

var strReq = JsonConvert.SerializeObject(oReq);

using var web = new WebClient();
web.Headers.Add("x-rapidapi-key", "xxxxxx");
var response = web.UploadData(url, "POST", Encoding.UTF8.GetBytes(strReq));
var b64Response = Convert.FromBase64String(Encoding.UTF8.GetString(response));
File.WriteAllBytes("result3.png", b64Response);

Where the API Key can be found here:

Categories: Uncategorized

Extract a License Plate from an Image #ALPR

ALPR – Or Automatic License Plate Recognition is the process of extracting the textual elements of a License Plate from an image. For example, reading the text FL802FJ from the image shown above.

Here is an API on Rapid API that offers a simple API that reads the license plate from an image of a car when provided via a URL:

You make a HTTP POST request to the following endpoint:

With the JSON Body;


And the x-rapidapi-key set in the HTTP Headers.

Which results in the following:

    "processing_time": 147.311,
    "results": [
            "box": {
                "xmin": 896,
                "ymin": 307,
                "xmax": 1067,
                "ymax": 411
            "plate": "fl802fj",
            "region": {
                "code": "fr",
                "score": 0.621
            "score": 0.898,
            "candidates": [
                    "score": 0.898,
                    "plate": "fl802fj"
                    "score": 0.897,
                    "plate": "fl8o2fj"
                    "score": 0.777,
                    "plate": "flb02fj"
                    "score": 0.775,
                    "plate": "flbo2fj"
            "dscore": 0.729,
            "vehicle": {
                "score": 0.759,
                "type": "Sedan",
                "box": {
                    "xmin": 130,
                    "ymin": 3,
                    "xmax": 1148,
                    "ymax": 690
    "filename": "1214_OkT6R_93b5bdbc-09af-47c4-b1a7-14109ed988ae.jpg",
    "version": 1,
    "camera_id": null,
    "timestamp": "2021-11-25T12:14:00.429055Z"
Categories: Uncategorized

Saying goodbye to old websites

It’s probably hard to believe for certain people, but you do generally get attached to websites, something that you’ve created, and perhaps has paid you back a thousand fold, but some day, it no longer becomes relevant, and it’s time to say goodbye to it.

Some parting words for some of my websites that meant something to me ..

My very first domain, which I thought, at the time, was a cool mix between “Web” and “Entropy”. It made no sense to anyone else. But It was back in 2002, I was just out of University, and the £20 investment in a domain was a lot to me back then. It paid me back a hundred fold, once earning as much as $5,000 a month in advertisement (yes, it was spammy and ugly). But, it didn’t last long, and I guess about 2005 it slipped out of relevance, and was never revisited again.

My first really successful business, I remember it used to bring in 10,000 people a day, peaking on new-years-eve. It used to make a steady £10K a month, with sources from all over the world. Mostly the UK, but I remember selling as far afield as Serbia. One day, a google update killed my SEO position across the board, and the business was over, I think around 2010. It never recovered, and the whole concept of communicating via SMS is only for 2FA and grandmothers who never got a smartphone.

But, it’s time to say goodbye, adieu, and so long and thanks for all the fish.

Categories: Uncategorized

Using HTTP/2 from #AWS Lambda in .NET Core

If you need to make an outbound HTTP request using HTTP/2 instead of HTTP/1.1 then you will need to modify your HTTP request in C# to do so, since it is not the default. If you are working in a windows environment, then you may have used code such as the following to perform a HTTP/2 request;

public class Http2CustomHandler : WinHttpHandler
{ // PM> Install-Package System.Net.Http.WinHttpHandler - REQ .NET 4.6.2 +
	protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
		request.Version = new Version("2.0");
		return base.SendAsync(request, cancellationToken);

Which requires the System.Net.Http.WinHttpHandler NUGET package.

However, if you try to use this code in .NET core, and run it on a non-Windows platform, such as AWS Lambda, then you get an error such as;

System.PlatformNotSupportedException: WinHttpHandler is only supported on .NET Framework and .NET runtimes on Windows. It is not supported for Windows Store Applications (UWP) or Unix platforms.
at System.Net.Http.WinHttpHandler..ctor()

There is a workaround, in .NET Core 3 (Which is supported by AWS Lambda), where you can simply specify the HTTP Version in the HTTPRequest object

var initialRequest = new HttpRequestMessage(HttpMethod.Get, strUrl)
	Version = new Version(2, 0)

var homepage = httpClient.SendAsync(initialRequest ).Result.Content.ReadAsStringAsync().Result;

Much simpler!

Categories: Uncategorized

License Plate #API available in #Canada with

Canada has a population of 38 million, with a car ownership ratio of 87%, meaning an estimated 33 million cars drive on Canada’s streets, and we’ve just launched an API that will allow business users determine the Make, Model, VIN , Fuel, Transmission, and other technical details from the license plate of the vehicle.

This API can be used for many different scenarios such as;

  • Auto Insurance: Faster and externally verified customer onboarding. Less customer-drop off while entering their vehicle data. Customers are more likely to know their own license plate, than their own VIN number. Plus you can be sure that the customer is not entering misleading information about their vehicle.
  • Car parts: Less mis-ordered parts, and added confidence in the order process for consumers. Customers can get their vehicle details incorrect, or ask you to order parts that are not suitable for their vehicle. Instead of wasting time and money returning incorrect parts to suppliers, using a vehicle license plate lookup can help ensure you are buying the correct parts, first time round. It also helps boost consumer confidence in the order process, they know they are buying a part specifically for THEIR car, not just a part that hopefully will fit!
  • Second hand car sales: Make it easy for sellers to quickly add their vehicle to your sales portal. If you are tracking more visitors to your “sell your car” page, than actually list a car for sale, then you have a customer drop off. A few percentage points is always unavoidable, but if you’re loosing 10%, 20%, 50% of potential sellers because you are not capturing information from them in an engaging way?, use this API to engage with sellers, and be the first to list their vehicle for sale and earn your commission.

Go to to read more.

Car registration plates in Canada use the /CheckCanada  endpoint and return the following information:

  • Make / Model
  • VIN Number
  • Body / Trim
  • Transmission 
  • Fuel

Both a License plate and a State are required, where the state is a two letter code as follows;

British ColumbiaBC
New BrunswickNB
Newfoundland and LabradorNL
Nova ScotiaNS
Northwest TerritoriesNT
Prince Edward IslandPE

Sample Registration Number: 

CKST441 (ON)

Sample Json:


  “Description”: “Toyota C-HR”,

  “RegistrationYear”: “2020”,

  “CarMake”: {

    “CurrentTextValue”: “Toyota”


  “CarModel”: {

    “CurrentTextValue”: “C-HR”


  “MakeDescription”: {

    “CurrentTextValue”: “Toyota”


  “ModelDescription”: {

    “CurrentTextValue”: “C-HR”


  “ImageUrl”: “;,

  “Body”: “Sport Utility”,

  “Transmission”: “Automatic CVT”,

  “Drive”: “FWD”,

  “Trim”: “”,

  “VIN”: “JTNKHMBX8L1063053”,

  “Engine”: “2.0L L4 DOHC 16V”,

  “Fuel”: “Gasoline”


Categories: Uncategorized

#OpenSource list of disposable temporary email providers.

We’ve just compiled a list of 35,000 temporary email domains, with their associated MX-Records (Mail Exchange servers) and IP addresses associated with the MX-Records. This should allow users to not only block known temporary email address domains, but to discover future domains. It’s easier to register a new domain than to get a new IP address and Mail Exchanger.

You can download this file at GITHUB here;


A CSV of temporary email domains with their associated MX Records, in the format

DomainMX RecordIP

Where Domain is a domain name associated with a temporary email address such as the MX record is a Mail-exchange server associated with that domain, and the IP is the IP of the Mail-exchange server.

Blocking user registrations if temporary email addresses are used can be risky, you can end up blocking a legitimate user.

If you block emails using the domain listed in the domain column, then it is very likely the email is temporary, but fresh “disposable” domains will not be discovered.

If you block emails using a domain that uses the same mail exchanger as the mx-record listed in the “MX column” then this is highly risky, since many legitimate russian users use “”, (yandex being the russian equivalent of Google). However patterns of dispostable emails can be discovered and blocked on a case by case basis.

This is an open-source list and we do invite users to contribute by raising pull requests. Please give credit to our work, if you use it.

Categories: Uncategorized

Open Source multilingual #CookieBanner script for #Bootstrap

Under Article 5 Paragraph 3 of the EU ePrivacy Directive (Directive 2009/136/EC) and respective implementations of the Directive into national law of the EU member states, the setting of individual cookies on the user’s terminal equipment that are not strictly necessary for the functioning of the website is only allowed if the user has given his or her prior consent.

Which translated into normal-speak, is that you should ask your users to consent to cookies before you place them on your user’s browser.

While we develop this for our own website, we’ve open-sourced the work, to invite others to perfect, what we’re working on.

Please feel free to Fork, or submit a pull request at if you want to suggest changes or improvements.

Supports the following languages;

English, Czech, Danish, German, Greek, Spanish, Estonian, Finnish, French, Hebrew, Croatian, Hungarian, Islandic, Italian, Latvian, Norwegiam, Dutch, Portuguese, Russian, Slovak, Slovenian, and Ukrainian

With automatic browser-language detection.

Categories: Uncategorized
%d bloggers like this: