Skip to content
This repository was archived by the owner on Dec 10, 2019. It is now read-only.

Add convenience functions and example notebook for datasource CRUD #67

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions examples/Datasources.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Datasources"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from rasterfoundry.api import API\n",
"from rasterfoundry.models.datasource import Datasource\n",
"refresh_token = '<refresh_token>'\n",
"api = API(refresh_token=refresh_token)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## List datasources"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"api.get_datasources()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create datasource bands"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"band_one = Datasource.create_datasource_band('red', '0', 100.0)\n",
"band_two = Datasource.create_datasource_band('green', '1', 200.0)\n",
"band_three = Datasource.create_datasource_band('blue', '2', 300.0)\n",
"bands = [band_one, band_two, band_three]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Add a new datasource"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"new_datasource = Datasource.create(api, 'Test Datasource 1', bands)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get datasource by ID"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"new_datasource_back = api.get_datasource_by_id(new_datasource.id)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Update a datasource"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"new_datasource_back.name = new_datasource_back.name + ' updated'\n",
"datasource_dict = vars(new_datasource_back)['_Model__dict']\n",
"Datasource.update(api, new_datasource_back.id, datasource_dict)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Delete a datasource"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Datasource.delete(api, new_datasource_back.id)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
18 changes: 12 additions & 6 deletions rasterfoundry/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@

from .aws.s3 import str_to_file
from .exceptions import RefreshTokenException
from .models import Analysis, MapToken, Project, Export
from .models import Analysis, MapToken, Project, Export, Datasource
from .settings import RV_TEMP_URI

try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse


SPEC_PATH = os.getenv(
'RF_API_SPEC_PATH',
'https://raw.githubusercontent.com/raster-foundry/raster-foundry-api-spec/1.4.0/spec/spec.yml'
'https://raw.githubusercontent.com/raster-foundry/raster-foundry-api-spec/1.11.0/spec/spec.yml' # NOQA
)


Expand Down Expand Up @@ -167,8 +166,15 @@ def exports(self):
exports.append(Export(export, self))
return exports

def get_datasources(self, **kwargs):
return self.client.Datasources.get_datasources(**kwargs).result()
def get_datasources(self):
datasources = []
for datasource in self.client.Datasources.get_datasources().result().results:
datasources.append(Datasource(datasource, self))
return datasources

def get_datasource_by_id(self, datasource_id):
return self.client.Datasources.get_datasources_datasourceID(
datasourceID=datasource_id).result()

def get_scenes(self, **kwargs):
bbox = kwargs.get('bbox')
Expand Down Expand Up @@ -197,7 +203,7 @@ def get_project_config(self, project_ids, annotations_uris=None):
project_configs = []
for project_ind, project_id in enumerate(project_ids):
proj = Project(
self.client.Imagery.get_projects_uuid(uuid=project_id).result(),
self.client.Imagery.get_projects_projectID(projectID=project_id).result(),
self)

if annotations_uris is None:
Expand Down
1 change: 1 addition & 0 deletions rasterfoundry/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from .upload import Upload # NOQA
from .analysis import Analysis # NOQA
from .export import Export # NOQA
from .datasource import Datasource # NOQA
4 changes: 2 additions & 2 deletions rasterfoundry/models/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ def get_center(self):
# fetch first one from api and use that project's coordinates
input = inputs.pop()
project = Project(
self.api.client.Imagery.get_projects_uuid(
uuid=input.get('projId')
self.api.client.Imagery.get_projects_projectID(
projectID=input.get('projId')
).result(),
self.api
)
Expand Down
82 changes: 82 additions & 0 deletions rasterfoundry/models/datasource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""A Datasource is a source of data a scene uses"""


class Datasource(object):
"""A Raster Foundry datasource"""

def __repr__(self):
return '<Datasource - {}>'.format(self.name)

def __init__(self, datasource, api):
"""Instantiate a new Datasource

Args:
datasource (Datasource): generated Datasource object from specification
api (API): api used to make requests on behalf of a datasource
"""
self._datasource = datasource
self.api = api

# A few things we care about
self.name = datasource.name
self.id = datasource.id

@classmethod
def create_datasource_band(cls, name, number, wavelength):
"""Create a datasource band

Args:
name (str): name of band, e.g. 'read', 'blue', 'infrared', etc.
number (str): band number
wavelength (str): wavelength

Returns:
dict: a band definition of a datasource band
"""
return dict(
name=name,
number=number,
wavelength=wavelength
)

@classmethod
def create(cls, api, name, bands, visibility='PRIVATE', extras={}):
"""Post an upload to Raster Foundry for processing

Args:
api (API): API to use for requests
name (str): name of datasource
bands (array): an array of create_datasource_band
visibility (str): datasource visibility, 'PRIVATE' by default
extras (dict): additional related information for a datasource, {} by default

Returns:
Datasource: created datasource object in Raster Foundry
"""
datasource_created = dict(
name=name,
bands=bands,
visibility=visibility,
extras=extras,
composites={
'natural': {
'label': 'Default',
'value': {
'redBand': 0,
'greenBand': 1,
'blueBand': 2
}
}
}
)
return api.client.Datasources.post_datasources(datasource=datasource_created).result()

@classmethod
def update(cls, api, datasource_id, datasource):
return api.client.Datasources.put_datasources_datasourceID(
datasourceID=datasource_id, datasource=datasource).result()

@classmethod
def delete(cls, api, datasource_id):
return api.client.Datasources.delete_datasources_datasourceID(
datasourceID=datasource_id).result()
9 changes: 5 additions & 4 deletions rasterfoundry/models/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def __init__(self, export, api):
@property
def files(self):
try:
fnames_res = self.api.client.Imagery.get_exports_uuid_files(uuid=self.id).result()
fnames_res = self.api.client.Imagery.get_exports_exportID_files(
exportID=self.id).result()
fnames = filter(
lambda name: name.upper() != 'RFUploadAccessTestFile'.upper(),
fnames_res)
Expand Down Expand Up @@ -74,11 +75,11 @@ def poll_export_status(cls,
'function will never return. You may have left off FAILED by accident. '
'If that is the case, you should include FAILED in until and try again.'
)
export = api.client.Imagery.get_exports_uuid(uuid=export_id).result()
export = api.client.Imagery.get_exports_exportID(exportID=export_id).result()
while export.exportStatus not in until:
time.sleep(delay)
export = api.client.Imagery.get_exports_uuid(
uuid=export_id).result()
export = api.client.Imagery.get_exports_exportID(
exportID=export_id).result()
return Export(export, api)

@classmethod
Expand Down
16 changes: 8 additions & 8 deletions rasterfoundry/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ def post_annotations(self, annotations_uri):
'confidence': properties['score']
}

self.api.client.Imagery.post_projects_uuid_annotations(
uuid=self.id, annotations=rf_annotations).future.result()
self.api.client.Imagery.post_projects_projectID_annotations(
projectID=self.id, annotations=rf_annotations).future.result()

def get_annotations(self):
def get_page(page):
return self.api.client.Imagery.get_projects_uuid_annotations(
uuid=self.id, page=page).result()
return self.api.client.Imagery.get_projects_projectID_annotations(
projectID=self.id, page=page).result()

return get_all_paginated(get_page, list_field='features')

Expand All @@ -214,15 +214,15 @@ def json_serial(obj):

def get_scenes(self):
def get_page(page):
return self.api.client.Imagery.get_projects_uuid_scenes(
uuid=self.id, page=page).result()
return self.api.client.Imagery.get_projects_projectID_scenes(
projectID=self.id, page=page).result()

return get_all_paginated(get_page)

def get_ordered_scene_ids(self):
def get_page(page):
return self.api.client.Imagery.get_projects_uuid_order(
uuid=self.id, page=page).result()
return self.api.client.Imagery.get_projects_projectID_order(
projectID=self.id, page=page).result()

# Need to reverse so that order is from bottom-most to top-most layer.
return list(reversed(get_all_paginated(get_page)))
Expand Down