Core ML is Apple’s framework for machine learning. With Core ML, everyone can use machine learning in their apps—as long as that app runs on an Apple platform, and Apple platforms only. Core ML cannot be used with Android, Windows, or on websites. This is very unfortunate because Core ML is such a great piece of technology.

It would be great if we could use Core ML with Python, for example. And as a programmer, you should know that if you want something bad enough, you can make it happen. And that’s what I’m going to show you in this post.

We’ll be building a REST API wrapper around a Core ML model using a new framework called Vapor. This API will be running on a remote server, accepting requests from every platform. This particular API will classify images, but any Core ML model should do.

Building an API around your Core ML model is not only beneficial when you want your model to work cross platform—even if your app only supports Apple devices, you might still want to consider using this approach over sending a copy of your Core ML model to each individual device.

First, your app size will decrease dramatically — Core ML models can be quite big. Second, you don’t need to update your app every time you improve your model — deploying new models can be done without Apple’s intervention.

I’ll start by introducing some web programming terminology you’ll need to know before writing a web app. Then we’ll write our own web app that uses Core ML in Vapor, because interfacing with Core ML is easiest with Swift, and because Swift is such a nice language to code with. Finally, we’ll also look at how to consume the API in Python.

The final project can be viewed on my GitHub. Don’t forget to leave a ⭐️ ;)

A quick introduction to web programming

In the world of web programming, there are clients and servers. Each application can have multiple clients, but there is only one server. Servers provide some kind of API and clients “consume” it over HTTP(S), the molecules of the internet.

REST is an architecture where clients ask the server for information, and the server returns that information, or in some cases an error. REST “requires” your API to be stateless — it should return the exact same answer when you ask it the exact same thing. Sounds like something we’d like a machine learning model to do.

Uploading data to a server is done using HTTP POST requests. A POST request can carry data in its body (yes, it’s called body). The server reads from the body and performs some type of action, like classifying an image.

The Client-Server model

Web applications consist of so-called routes. These make up the endpoints (URLs) of the API. In Vapor, each route has its own function, where you can write code to implement a feature the route represents.

A schematic of the internal server architecture we’re going to build is shown below. The the server will have a router that’s always listening for incoming requests. Once it accepts a request, it will look for an image in the request’s body. It will then forward that image to Core ML and wait for a result. Finally, it will send the result back to the client.

Schematic of the server architecture

In our case, the Vapor web application is the server. It will listen for clients, accept their requests, and return a result, encoded in JSON format. The client can be whatever device you want, as long as it has an internet connection.