Repository: Picterra/picterra-python

Issue:
Create a detector

Discussion:

Patch:
diff --git a/README.md b/README.md
index 11d6fdd..e2ea5fb 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,24 @@ result_id = pic.run_detector(detector, raster)
 pic.download_result_to_file(result_id, 'result.geojson')
 ```
 
+### Training API (beta)
+
+**Please note the above endpoints are still in beta and thus may be subject to change**
+
+#### Create a detector and add rasters to it
+
+```python
+from picterra import APIClient
+
+pic = APIClient()
+detector = pic.create_detector('my_car_counting_detector', 'count')
+raster1 = pic.upload_raster('<filename1>', 'training_raster_1')
+raster2 = pic.upload_raster('<filename2>', 'training_raster_2')
+pic.add_raster_to_detector(raster1, detector)
+pic.add_raster_to_detector(raster2, detector)
+
+
+```
 
 ### Getting results back in pixel coordinates
 
diff --git a/src/picterra/client.py b/src/picterra/client.py
index 84f034d..46a582f 100644
--- a/src/picterra/client.py
+++ b/src/picterra/client.py
@@ -175,6 +175,60 @@ class APIClient():
                 return False
         _poll_at_interval(_is_ready, poll_interval)
 
+    def add_raster_to_detector(self, raster_id: str, detector_id: str) -> str:
+        """
+        Associate a raster to a detector
+
+        This a **beta** function, subject to change.
+
+        Args:
+            detector_id (str): The id of the detector
+            raster_id (str): The id of the raster
+
+        Raises:
+            APIError: There was an error uploading the file to cloud storage
+        """
+        resp = self.sess.post(
+            self._api_url('detectors/%s/training_rasters/' % detector_id),
+            data={
+                'raster_id': raster_id
+            }
+        )
+        if not resp.status_code == 201:
+            raise APIError(resp.text)
+
+    def create_detector(self, name: str = '', type: str = 'count') -> str:
+        """
+        Associate a raster to a detector
+
+        This a **beta** function, subject to change.
+
+        Args:
+            name: Name of the detector
+            type: The type of the detector (on of 'count', 'segmentation')
+
+        Returns:
+            detector_id (str): The id of the detector
+
+        Raises:
+            APIError: There was an error while creating the detector
+        """
+        type = type.lower()
+        valid_types = ('count', 'segmentation')
+        if type not in valid_types:
+            raise ValueError(
+                'Invalid type "%s", choose one of %s.' % (type, ', '.join(valid_types)))
+        body_data = {'type': type}
+        if name:
+            body_data['name'] = name
+        resp = self.sess.post(
+            self._api_url('detectors/'),
+            data=body_data
+        )
+        if not resp.status_code == 201:
+            raise APIError(resp.text)
+        return resp.json()['id']
+
     def run_detector(self, detector_id, raster_id):
         """
         Runs a detector on a raster


Test patch:
diff --git a/tests/test_client.py b/tests/test_client.py
index 2e36824..135bbea 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -33,6 +33,10 @@ def add_mock_rasters_list_response():
     responses.add(responses.GET, api_url('rasters/'), json=data, status=200)
 
 
+def add_mock_detector_creation_response():
+    responses.add(responses.POST, api_url('detectors/'), json={'id': 'foobar'}, status=201)
+
+
 def add_mock_raster_upload_responses():
     raster_id = 42
     # Upload initiation
@@ -179,6 +183,14 @@ def test_list_rasters():
     assert rasters[1]['name'] == 'raster2'
 
 
+@responses.activate
+def test_detector_creation():
+    client = _client()
+    add_mock_detector_creation_response()
+    detector = client.create_detector()
+    assert detector == 'foobar'
+
+
 @responses.activate
 def test_set_raster_detection_areas_from_file():
     add_mock_detection_areas_upload_responses(1)