def test_does_not_spam_activation_url_if_already_active( self, m: rm.Mocker): scene = create_scene() scene.status = scenes.STATUS_ACTIVE m.get('/planet/activate/planetscope/test-scene-id', text='') scenes.activate(scene, 'test-planet-api-key', 'test-user-id') self.assertEqual(0, len(m.request_history))
def test_throws_when_catalog_throws(self, m: rm.Mocker): scene = create_scene() m.get('/planet/activate/planetscope/test-scene-id', status_code=500, text='oh noes') with self.assertRaises(scenes.CatalogError): scenes.activate(scene, 'test-planet-api-key', 'test-user-id')
def test_throws_when_not_permitted(self, m: rm.Mocker): scene = create_scene() m.get('/planet/activate/planetscope/test-scene-id', status_code=401, text='oopsie') with self.assertRaises(scenes.NotPermitted): scenes.activate(scene, 'test-planet-api-key', 'test-user-id')
def test_throws_when_scene_does_not_exist(self, m: rm.Mocker): scene = create_scene() m.get('/planet/activate/planetscope/test-scene-id', status_code=404, text='wat') with self.assertRaises(scenes.NotFound): scenes.activate(scene, 'test-planet-api-key', 'test-user-id')
def test_calls_correct_activation_url_for_rapideye(self, m: rm.Mocker): scene = create_scene() scene.id = 'rapideye:test-scene-id' m.get('/planet/activate/rapideye/test-scene-id', text='') scenes.activate(scene, 'test-planet-api-key', 'test-user-id') self.assertEqual( 'https://test-catalog-host.localdomain/planet/activate/rapideye/test-scene-id?PL_API_KEY=test-planet-api-key', m.request_history[0].url)
def test_returns_multispectral_url_if_activated(self, m: rm.Mocker): scene = create_scene() scene.status = scenes.STATUS_ACTIVE scene.geotiff_multispectral = 'test-geotiff-multispectral-url' m.get('/planet/activate/planetscope/test-scene-id', text='') url = scenes.activate(scene, 'test-planet-api-key', 'test-user-id') self.assertEqual('test-geotiff-multispectral-url', url)
def forward_to_geotiff(scene_id: str): planet_api_key = flask.request.args.get('planet_api_key') if not planet_api_key: return 'Missing `planet_api_key` parameter', 400 user = getattr(flask.request, 'user', None) user_id = user.user_id if user else None try: scene = _scenes.get(scene_id, planet_api_key) geotiff_url = _scenes.activate(scene, planet_api_key, user_id) except _scenes.NotFound: return 'Cannot download: Scene `{}` not found'.format(scene_id), 404 except (_scenes.CatalogError, _scenes.MalformedSceneID) as err: return 'Cannot download: {}'.format(err), 500 if geotiff_url: return flask.redirect(geotiff_url) return flask.render_template('download_scene.jinja2', scene_id=scene_id), 202
def test_throws_when_catalog_is_unreachable(self, _): scene = create_scene() with unittest.mock.patch('requests.get') as stub: stub.side_effect = ConnectionError() with self.assertRaises(scenes.CatalogError): scenes.activate(scene, 'test-planet-api-key', 'test-user-id')
def test_returns_nothing_if_activated(self, m: rm.Mocker): scene = create_scene() m.get('/planet/activate/planetscope/test-scene-id', text='') url = scenes.activate(scene, 'test-planet-api-key', 'test-user-id') self.assertIsNone(url)
def test_activates_if_inactive(self, m: rm.Mocker): scene = create_scene() m.get('/planet/activate/planetscope/test-scene-id', text='') scenes.activate(scene, 'test-planet-api-key', 'test-user-id') self.assertEqual(1, len(m.request_history))
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, )