Exemplo n.º 1
0
def get_algorithm(service_id: str):
    try:
        algorithm = _algorithms.get(service_id)
    except _algorithms.NotFound:
        return 'Algorithm not found', 404
    return flask.jsonify({
        'algorithm': algorithm.serialize(),
    })
Exemplo n.º 2
0
 def test_throws_when_piazza_throws(self, mock: MagicMock):
     mock.side_effect = piazza.Unauthorized()
     with self.assertRaises(piazza.Unauthorized):
         algorithms.get('test-service-id')
Exemplo n.º 3
0
 def test_throws_if_with_invalid_max_cloud_cover(self, mock: MagicMock):
     service = create_service()
     service.metadata['metadata']['ImgReq-cloudCover'] = 'lolwut'
     mock.return_value = service
     with self.assertRaisesRegex(algorithms.ValidationError, 'not a number'):
         algorithms.get('test-service-id')
Exemplo n.º 4
0
 def test_throws_if_missing_version(self, mock: MagicMock):
     service = create_service()
     service.metadata.pop('version')
     mock.return_value = service
     with self.assertRaisesRegex(algorithms.ValidationError, 'missing `version`'):
         algorithms.get('test-service-id')
Exemplo n.º 5
0
 def test_throws_if_missing_max_cloud_cover(self, mock: MagicMock):
     service = create_service()
     service.metadata['metadata'].pop('ImgReq-cloudCover')
     mock.return_value = service
     with self.assertRaisesRegex(algorithms.ValidationError, 'missing `cloudCover`'):
         algorithms.get('test-service-id')
Exemplo n.º 6
0
 def test_throws_if_missing_interface(self, mock: MagicMock):
     service = create_service()
     service.metadata['metadata'].pop('Interface')
     mock.return_value = service
     with self.assertRaisesRegex(algorithms.ValidationError, 'missing `Interface`'):
         algorithms.get('test-service-id')
Exemplo n.º 7
0
 def test_extracts_correct_version(self, mock: MagicMock):
     mock.return_value = create_service()
     algo = algorithms.get('test-service-id')
     self.assertEqual('test-version', algo.version)
Exemplo n.º 8
0
 def test_extracts_correct_max_cloud_cover(self, mock: MagicMock):
     mock.return_value = create_service()
     algo = algorithms.get('test-service-id')
     self.assertEqual(42, algo.max_cloud_cover)
Exemplo n.º 9
0
 def test_extracts_correct_interface(self, mock: MagicMock):
     mock.return_value = create_service()
     algo = algorithms.get('test-service-id')
     self.assertEqual('test-interface', algo.interface)
Exemplo n.º 10
0
 def test_throws_when_service_not_found(self, mock: MagicMock):
     mock.side_effect = piazza.ServerError(404)
     with self.assertRaises(algorithms.NotFound):
         algorithms.get('test-service-id')
Exemplo n.º 11
0
 def test_returns_an_algorithm(self, mock: MagicMock):
     mock.return_value = create_service()
     self.assertIsInstance(algorithms.get('test-service-id'), algorithms.Algorithm)
Exemplo n.º 12
0
 def test_requests_algorithms_from_piazza(self, mock: MagicMock):
     mock.return_value = create_service()
     algorithms.get('test-service-id')
     self.assertEqual(('test-service-id',), mock.call_args[0])
Exemplo n.º 13
0
def create(user_id: str, scene_id: str, service_id: str, job_name: str,
           planet_api_key: str) -> Job:
    log = logging.getLogger(__name__)
    log.info('Job service create', action='service job create', actor=user_id)

    # Fetch prerequisites
    try:
        algorithm = algorithms.get(service_id)
        scene = scenes.get(scene_id, planet_api_key)
        scenes.activate(scene, planet_api_key, user_id)
    except (algorithms.NotFound, algorithms.ValidationError,
            scenes.MalformedSceneID, scenes.CatalogError, scenes.NotFound,
            scenes.NotPermitted, scenes.ValidationError) as err:
        log.error('Preprocessing error: %s', err)
        raise PreprocessingError(err)

    # Determine GeoTIFF URLs.
    if scene.platform in ('rapideye', 'planetscope'):
        geotiff_filenames = ['multispectral.TIF']
        geotiff_urls = [scenes.create_download_url(scene.id, planet_api_key)]
    elif scene.platform == 'landsat':
        geotiff_filenames = ['coastal.TIF', 'swir1.TIF']
        geotiff_urls = [scene.geotiff_coastal, scene.geotiff_swir1]
    else:
        raise PreprocessingError(message='Unexpected platform')

    # Dispatch to Piazza
    try:
        log.info('Dispatching <scene:%s> to <algo:%s>', scene_id,
                 algorithm.name)
        cli_cmd = _create_algorithm_cli_cmd(algorithm.interface,
                                            geotiff_filenames, scene.platform)
        job_id = piazza.execute(
            algorithm.service_id, {
                'body': {
                    'content':
                    json.dumps({
                        'cmd': cli_cmd,
                        'inExtFiles': geotiff_urls,
                        'inExtNames': geotiff_filenames,
                        'outGeoJson': ['shoreline.geojson'],
                        'userID': user_id,
                    }),
                    'type':
                    'body',
                    'mimeType':
                    'application/json',
                },
            })
    except piazza.Error as err:
        log.error('Could not execute via Piazza: %s', err)
        raise

    # Record the data
    log.debug('Saving job record <%s>', job_id)
    conn = db.get_connection()
    transaction = conn.begin()
    try:
        db.jobs.insert_job(
            conn,
            algorithm_id=algorithm.service_id,
            algorithm_name=algorithm.name,
            algorithm_version=algorithm.version,
            job_id=job_id,
            name=job_name,
            scene_id=scene_id,
            status=piazza.STATUS_PENDING,
            user_id=user_id,
            tide=scene.tide,
            tide_min_24h=scene.tide_min,
            tide_max_24h=scene.tide_max,
        )
        db.jobs.insert_job_user(
            conn,
            job_id=job_id,
            user_id=user_id,
        )
        transaction.commit()
    except db.DatabaseError as err:
        transaction.rollback()
        log.error('Could not save job to database')
        db.print_diagnostics(err)
        raise
    finally:
        conn.close()

    return Job(
        algorithm_name=algorithm.name,
        algorithm_version=algorithm.version,
        created_by=user_id,
        created_on=datetime.utcnow(),
        geometry=scene.geometry,
        job_id=job_id,
        name=job_name,
        scene_time_of_collect=scene.capture_date,
        scene_sensor_name=scene.sensor_name,
        scene_id=scene_id,
        status=piazza.STATUS_PENDING,
        tide=scene.tide,
        tide_min_24h=scene.tide_min,
        tide_max_24h=scene.tide_max,
    )