# API Client for Python Examples

cytomine-uliege/Cytomine-python-client | Last release: v2.8.3

This section provides code snippets for common use cases with the Cytomine API Client for Python library. More examples are available on the Github repository (opens new window).

# Get images

This script fetches all images in a project with ID id_project, prints some basic metadata for each image in the project and downloads these images at download_path if provided.

import logging
import sys
from argparse import ArgumentParser
import os
from cytomine import Cytomine
from cytomine.models.image import ImageInstanceCollection
if __name__ == '__main__':
    parser = ArgumentParser(prog="Get images example")
    parser.add_argument('--host', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key', help="The Cytomine private key")
    parser.add_argument('--id_project', help="The project from which we want the images")
    parser.add_argument('--download_path', required=False, help="Where to store images")
    params, other = parser.parse_known_args(sys.argv[1:])
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key,
                  verbose=logging.INFO) as cytomine:
        # We want all image instances in a given project.
        # => Fetch the collection of image instances, filtered by the given project.
        image_instances = ImageInstanceCollection().fetch_with_filter("project", params.id_project)
        print(image_instances)
        for image in image_instances:
            # Every element in the collection is an ImageInstance object.
            # See ImageInstance class for all available properties (width, height, resolution, ...)
            print("Image ID: {} | Width: {} | Height: {} | Resolution: {} | Magnification: {} | Filename: {}".format(
                image.id, image.width, image.height, image.resolution, image.magnification, image.filename
            ))
            if params.download_path:
                # To download the original files that have been uploaded to Cytomine
                # Attributes of ImageInstance are parsed in the filename
                # Image is downloaded only if it does not exists locally or if override is True
                image.download(os.path.join(params.download_path, str(params.id_project), "{originalFilename}"),
                               override=False)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

This script is also available on Github (opens new window). To run it, the command should be like

python get_images.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --id_project 42 --download_path /tmp
1

# Get terms

This script fetches all terms in (the ontology of) a project with ID id_project and prints some basic metadata for each term in the project ontology.

import logging
import sys
from argparse import ArgumentParser
from cytomine import Cytomine
from cytomine.models import TermCollection
if __name__ == '__main__':
    parser = ArgumentParser(prog="List terms in project example")
    parser.add_argument('--host', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key', help="The Cytomine private key")
    parser.add_argument('--id_project', help="The project from which we want the terms")
    params, other = parser.parse_known_args(sys.argv[1:])
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key,
                  verbose=logging.INFO) as cytomine:
        terms = TermCollection().fetch_with_filter("project", params.id_project)
        for term in terms:
            print("Term ID: {} | Name: {} | Color: {}".format(term.id, term.name, term.color))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

This script is also available on Github (opens new window). To run it, the command should be like

python get_terms.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --id_project 42
1

# Get annotations

This script fetches all annotations in a project with ID id_project, prints some basic metadata for each annotation in the project and downloads a crop, a mask and an alpha-mask for each annotation at download_path if provided.

import logging
import sys
from argparse import ArgumentParser
import os
from shapely import wkt
from shapely.affinity import affine_transform
from cytomine import Cytomine
from cytomine.models import AnnotationCollection, ImageInstanceCollection
def get_by_id(haystack, needle):
    return next((item for item in haystack if item.id == needle), None)
if __name__ == '__main__':
    parser = ArgumentParser(prog="Get annotations example")
    parser.add_argument('--host', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key', help="The Cytomine private key")
    parser.add_argument('--id_project', help="The project from which we want the annotations")
    parser.add_argument('--download_path', required=False, 
                        help="Where to store annotation crops. Required if you want Cytomine generate annotation crops.")
    params, other = parser.parse_known_args(sys.argv[1:])
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key, verbose=logging.INFO) as cytomine:
        # We want all annotations in a given project.
        annotations = AnnotationCollection()
        annotations.project = params.id_project  # Add a filter: only annotations from this project
        # You could add other filters:
        # annotations.image = id_image => Add a filter: only annotations from this image
        # annotations.images = [id1, id2] => Add a filter: only annotations from these images
        # annotations.user = id_user => Add a filter: only annotations from this user
        # ...
        annotations.showWKT = True  # Ask to return WKT location (geometry) in the response
        annotations.showMeta = True  # Ask to return meta information (id, ...) in the response
        annotations.showGIS = True  # Ask to return GIS information (perimeter, area, ...) in the response
        # ...
        # => Fetch annotations from the server with the given filters.
        annotations.fetch()
        print(annotations)
        for annotation in annotations:
            print("ID: {} | Image: {} | Project: {} | Term: {} | User: {} | Area: {} | Perimeter: {} | WKT: {}".format(
                annotation.id,
                annotation.image,
                annotation.project,
                annotation.term,
                annotation.user,
                annotation.area,
                annotation.perimeter,
                annotation.location
            ))
            # Annotation location is the annotation geometry in WKT format.
            # See https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry
            # You can use Shapely library to read geometry in WKT format. See https://shapely.readthedocs.io/en/latest/
            # See 'shapely.wkt.loads(wkt)' function in Shapely library.
            geometry = wkt.loads(annotation.location)
            print("Geometry from Shapely: {}".format(geometry))
            # In Cytomine, geometries are referenced using a cartesian coordinate system !
            # See 'shapely.affinity.affine_transform(geom, matrix)' function in Shapely library if needed
            if params.download_path:
                # max_size is set to 512 (in pixels). Without max_size parameter, it downloads a dump of the same size as the annotation.
                # Dump a rectangular crop containing the annotation
                annotation.dump(dest_pattern=os.path.join(params.download_path, "{project}", "crop", "{id}.jpg"), max_size=512)
                # Dumps a rectangular mask containing the annotation
                annotation.dump(dest_pattern=os.path.join(params.download_path, "{project}", "mask", "{id}.jpg"), mask=True, max_size=512)
                # Dumps the annotation crop where pixels outside it are transparent.
                annotation.dump(dest_pattern=os.path.join(params.download_path, "{project}", "alpha", "{id}.png"), mask=True, alpha=True, max_size=512)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

This script is also available on Github (opens new window). To run it, the command should be like

python get_annotations.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --id_project 42 --download_path /tmp
1

# Add annotations

This script adds 2 annotations in an image with ID id_image_instance associated to a project with ID id_project. These annotations are a point and a bounding box. A property my_property with value 10 is associated to the bounding box. If id_term is provided, this term is associated to the annotations.

import logging
import sys
from argparse import ArgumentParser
from shapely.geometry import Point, box
from cytomine import Cytomine
from cytomine.models import Property, Annotation, AnnotationTerm, AnnotationCollection
if __name__ == '__main__':
    parser = ArgumentParser(prog="Add annotation example")
    parser.add_argument('--host', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key',help="The Cytomine private key")
    parser.add_argument('--id_project', help="The project from which we want the images")
    parser.add_argument('--id_image_instance', help="The image to which the annotation will be added")
    parser.add_argument('--id_term', required=False, help="The term to associate to the annotations (optional)")
    params, other = parser.parse_known_args(sys.argv[1:])
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key, verbose=logging.INFO) as cytomine:
        # We first add a point in (10,10) where (0,0) is bottom-left corner
        point = Point(10, 10)
        annotation_point = Annotation(location=point.wkt, id_image=params.id_image_instance).save()
        if params.id_term:
            AnnotationTerm(annotation_point.id, params.id_term).save()
        # Then, we add a rectangle as annotation
        rectangle = box(20, 20, 100, 100)
        annotation_rectangle = Annotation(location=rectangle.wkt, id_image=params.id_image_instance).save()
        if params.id_term:
            AnnotationTerm(annotation_rectangle.id, params.id_term).save()
        # We can also add a property (key-value pair) to an annotation
        Property(annotation_rectangle, key="my_property", value=10).save()
        # Print the list of annotations in the given image:
        annotations = AnnotationCollection()
        annotations.image = params.id_image_instance
        annotations.fetch()
        print(annotations)
        # We can also add multiple annotation in one request:
        annotations = AnnotationCollection()
        annotations.append(Annotation(location=point.wkt, id_image=params.id_image_instance, id_project=params.id_project))
        annotations.append(Annotation(location=rectangle.wkt, id_image=params.id_image_instance, id_project=params.id_project))
        annotations.save()
        # Print the list of annotations in the given image:
        annotations = AnnotationCollection()
        annotations.image = params.id_image_instance
        annotations.fetch()
        print(annotations)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

This script is also available on Github (opens new window). To run it, the command should be like

python add_annotation.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --id_project 42  --id_image 13209 --id_term 176
1

# Add properties

This script adds a property (key-value pair) to a Cytomine resource: a project, an image or an annotation.

import logging
import sys
from argparse import ArgumentParser
from cytomine import Cytomine
from cytomine.models import Property, Project, Annotation, ImageInstance
if __name__ == '__main__':
    parser = ArgumentParser(prog="Add properties example")
    parser.add_argument('--host', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key', help="The Cytomine private key")
    parser.add_argument('--key', help="the property key")
    parser.add_argument('--value', help="the property value")
    parser.add_argument('--id_project', required=False, help="The project to which the property will be added (optional)")
    parser.add_argument('--id_image_instance',, required=False, help="The image to which the property will be added (optional)")
    parser.add_argument('--id_annotation', required=False, help="The annotation to which the property will be added (optional)")
    params, other = parser.parse_known_args(sys.argv[1:])
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key, verbose=logging.INFO) as cytomine:
        if params.id_project:
            project = Project().fetch(params.id_project)
            prop = Property(project, key=params.key, value=params.value).save()
            print(prop)
        if params.id_image_instance:
            image = ImageInstance().fetch(params.id_image_instance)
            prop = Property(image, key=params.key, value=params.value).save()
            print(prop)
        if params.id_annotation:
            annot = Annotation().fetch(params.id_annotation)
            prop = Property(annot, key=params.key, value=params.value).save()
            print(prop)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

This script is also available on Github (opens new window). To run it, the command should be like

python add_property.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --id_project 42  --key "PROJECT_STATUS" --value "PENDING"
1

# Calibrate image

This script shows how to calibrate an image. It updates the resolution and/or magnification of an abstract image (image at storage level) based on the ID of one of its instances in a project. All future instances of the image will thus be affected. Every instance of this image can still have custom calibration and/or magnification values if set from the graphical interface.

import logging
from argparse import ArgumentParser
from cytomine import Cytomine
from cytomine.models import ImageInstance, AbstractImage
if __name__ == '__main__':
    parser = ArgumentParser(prog="Set calibration of an image (note that all instances of the image will be affected)")
    parser.add_argument('--host', default='localhost-core', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key', help="The Cytomine private key")
    parser.add_argument('--id_image', help="The identifier of the image instance to calibrate")
    parser.add_argument('--resolution', required=False, help="The resolution to set, in µm/px (optional)")
    parser.add_argument('--magnification', required=False, help="The magnification to set (optional)")
    params, _ = parser.parse_known_args()
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key, verbose=logging.INFO) as cytomine:
        image_instance = ImageInstance().fetch(params.id_image) # Fetch the image instance
        abstract_image = AbstractImage().fetch(image_instance.baseImage) # Retrieve the abstract image
        modification = False
        if params.resolution is not None:
            abstract_image.resolution = params.resolution
            modification = True
        if params.magnification is not None:
            abstract_image.magnification = params.magnification
            modification = True
        if not modification:
            logging.error("You should set either resolution or magnification")
        else:
            abstract_image.update()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

This script is also available on Github (opens new window). To run it, the command should be like

python calibrate_image.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --id_image 10372 --resolution 0.499 --magnification 20
1

to set a resolution of 0.499µm/px and 20x magnification to the abstract image related to image instance of id 10372.

# Upload image

This script shows how to use the Python client library to upload an image to Cytomine. The image located at filepath on your computer is uploaded to your storage and optionally linked with the project having id_project ID.

import logging
import sys
from argparse import ArgumentParser
import os
from cytomine import Cytomine
from cytomine.models import StorageCollection, Project, UploadedFile
if __name__ == '__main__':
    parser = ArgumentParser(prog="Upload image example")
    parser.add_argument('--host', help="The Cytomine host")
    parser.add_argument('--public_key', help="The Cytomine public key")
    parser.add_argument('--private_key', help="The Cytomine private key")
    parser.add_argument('--id_project', required=False, help="The project where to add the uploaded image")
    parser.add_argument('--filepath', help="The filepath (on your file system) of the file you want to upload")
    params, other = parser.parse_known_args(sys.argv[1:])
    with Cytomine(host=params.host, public_key=params.public_key, private_key=params.private_key,
                  verbose=logging.INFO) as cytomine:
        # Check that the file exists on your file system
        if not os.path.exists(params.filepath):
            raise ValueError("The file you want to upload does not exist")
        # Check that the given project exists
        if params.id_project:
            project = Project().fetch(params.id_project)
            if not project:
                raise ValueError("Project not found")
        # To upload the image, we need to know the ID of your Cytomine storage.
        storages = StorageCollection().fetch()
        my_storage = next(filter(lambda storage: storage.user == cytomine.current_user.id, storages))
        if not my_storage:
            raise ValueError("Storage not found")
        uploaded_file = cytomine.upload_image(upload_host=params.upload_host,
                                              filename=params.filepath,
                                              id_storage=my_storage.id,
                                              id_project=params.id_project)
        print(uploaded_file)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

This script is also available on Github (opens new window). To run it, the command should be like

python upload_image.py --host https://mycytomine.com --public_key AAA --private_key ZZZ --filepath /data/my-image.svs
1
Last Updated: 4/30/2021, 4:38:20 PM