Image Tagger is REST API for tagging images with ImageNet-1K labels. It wraps around an EfficientNetB3-NoisyStudent model trained for ILSVRC dataset, exposing its functionality through a simple endpoint. The API was built using FastAPI python framework. It utilizes Tensorflow for executing deep learning models.
Currently, there is a running instance of the API on Google Cloud using the docker container. It can be accessed through: https://imagetagger-xuoak2q65a-lm.a.run.app/ (separate domain name too expensive 😛)
Image Tagger is available at PyPI and can be installed as following:
pip install image_tagger
In order to start the server use:
uvicorn image_tagger.main:app --host 0.0.0.0 --port 8000
Now the server should be up and running. If port 8000
is occupied
by something else on your machine, then try a different port.
Get the url of an image you like and perform a GET request to the API like:
GET localhost:8000/predictions?url=https://example.com/path/to/image.png
You will see a nice JSON response containing the label for your image. You can perform a GET request either by navigating to the above location with your browser, or by using a requests tool like Postman.
- Use your favorite browser and navigate to
localhost:8000/docs
.
You will see a nice documentation page for all the endpoints exposed by this API, along with the ability for interactively calling them.
- Navigate to
localhost:8000/redoc
.
You will see another version of the documentation. This one is for people who prefer the style of Redoc docs, instead of the Swagger UI based ones.
In order to use the API in a production environment, a docker container can be built using the following command:
docker build -t imagetagger .
Then, container can be run by executing the command below:
docker run -d -p 8000:8000 -e PORT=8000 imagetagger
As you may have noticed, in order to run the container, PORT
environmental variable should be passed to the container. It defines
the port the server will listen to and also makes the container
ready to be deployed in cloud services like Google Cloud.
Currently, two endpoints are exposed by the API. The one for performing predictions and the other for obtaining versioning info about the live API.
Returned labels can be filtered according to two parameters, top
and minconf
.
The first parameter controls the number of top-confidence labels to be
returned, sorted in descending order according to computed confidence. The
second one, limits the returned labels to the ones whose confidence score is
at least minconf
. These two parameters can be combined, applying the restrictions
of both, thus returning the most restrictive labels set.
By default, if top
and minconf
are omitted, only the label with the highest
confidence score is returned (the same as setting top=1
).
The image format can be any format supported be the Pillow library. For more info see: https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
Image retrieval is performed through a GET request on given url.
- url: The url of the image file. It can be any https or http url pointing to an image file. For example: 'https://example.com/path/to/image.jpg'
- top [optional]: The number of top ImageNet labels to be returned. The number of returned labels cannot exceed the number of available classes (top<=1000).
- minconf [optional]: The minimum confidence score a label should have in order to be
returned. It should be in the range
[0, 1]
.
Successful calls return a JSON containing the following attributes:
- url: The same url passed into the request.
- predictions: An array containing the predicted label objects in descending order.
Each object contains the following attributes:
- label: The predicted ImageNet-1K label.
- confidence: The confidence score of the label.
{
"url": "https://example.com/path/to/image.jpg",
"predictions": [
{"label": "dog", "confidence": 0.78},
{"label": "wolf", "confidence": 0.06},
{"label": "tiger", "confidence": 0.03},]
}
In case the url
points to a resource that is not a supported image format,
response code is set to 400
and the following JSON is returned:
{"error": {
"type": "InvalidImage",
"detail": "Url is not pointing to a valid image format."
}}
If the GET request on url
fails, then response code is set to 404
and the
following JSON is returned:
{"error": {
"type": "UnreachableURL",
"detail": "Url cannot be reached."
}}
When the parameters of the request are invalid, response code is set to 422
and
a JSON describing the cause of the error is returned. An example response is
presented below:
{"error": {
"type": "ValidationError",
"detail": [{"loc": ["query", "url"],
"message": "URL scheme not permitted",
"type": "value_error.url.scheme"}]
}}
The only part of the response that is changing for different validation errors
is the content of detail
attribute. It is an array containing all validation
errors detected. The detail object of each detected violation contains the
following attributes:
- loc: An array describing the location of the error. For example
["query", "url"]
means that the value of query parameterurl
is invalid. - message: An informal message describing the cause of the error.
- type: A formal identifier of the error.
This endpoint serves both as a placeholder for root path and as a way in order to retrieve versioning info.
Calls return a JSON containing the following attributes:
- description: A short textual description of the API.
- version: The version of the API in the format of semantic versioning (e.g. 1.0.0). For more info see: https://semver.org/
- revision: An integer indicating the current revision of the API. Each newer version of the API is guaranteed to have a greater revision number.
- author: API author's name.
- github_url: Link to the github repository containing the code of this API.
Except from the REST endpoints described above, Image Tagger also provides a live version of their documentation.
This project is licensed under Apache License 2.0. A copy of this license is contained in current
project under LICENSE
file. It applies to all files in this project whether or not it is stated in them.
Copyright 2022 | Dimitrios S. Karageorgiou