Commit 6d7c6d98 authored by Spencer Sutton's avatar Spencer Sutton
Browse files

Resetting to ado

parent 0bec959e
build
dist
osdu_api.egg-info
__pycache__
\ No newline at end of file
Apache 2.0
\ No newline at end of file
A package to interface with OSDU microservices
To install locally:
- Make sure you have setuptools and wheel installed `python3 -m pip install --user --upgrade setuptools wheel`
- Run `python setup.py sdist bdist_wheel`
- Make sure osdu-api isn't already installed `pip uninstall osdu-api`
- Run `python -m pip install <YOUR PATH TO PACKAGE>/dist/osdu_api-0.0.1-py3-none-any.whl` make sure to substitute your machine's path in that command
Example import after installing:
`from osdu_api.storage.record_client import RecordClient`
You can find examples of how to use this sdk under the examples folder in this package
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys, os
import importlib
import yaml # MIT license
import requests
from osdu_api.model.shared.http_method import HttpMethod
'''
Base client that is meant to be extended by service specific clients
'''
class BaseClient:
'''
Base client gets initialized with configuration values and a bearer token
based on provider-specific logic
'''
def __init__(self):
self._parse_config()
self.bearer_token = self._get_bearer_token()
'''
The path to the logic to get a valid bearer token is dynamically injected based on
what provider and entitlements module name is provided in the configuration yaml
'''
def _get_bearer_token(self):
entitlements_client = importlib.import_module('osdu_api.provider.%s.%s' % (self.provider, self.entitlements_module_name))
return entitlements_client.get_bearer_token()
'''
Parses a yaml filed named osdu_api.yaml. All config values listed below are meant to
be required except URLs to specific services which may or may not be used depending
on the specific script
'''
def _parse_config(self):
config_file_location = os.path.join(sys.path[0], 'osdu_api.yaml')
with open(config_file_location, 'r') as config_file:
config = yaml.load(config_file)
self.data_partition_id = self._parse_config_value(config, 'data_partition_id', True)
self.storage_url = self._parse_config_value(config, 'storage_url', False)
self.search_url = self._parse_config_value(config, 'search_url', False)
self.provider = self._parse_config_value(config, 'provider', True)
self.entitlements_module_name = self._parse_config_value(config, 'entitlements_module_name', True)
'''
Used during parsing of the yaml config file. Will raise an exception if a required config
value is missing
'''
def _parse_config_value(self, config, config_name, is_required):
config_value = ''
try:
config_value = config[config_name]
except TypeError:
if(is_required):
raise Exception('Config value %s missing and is required' % config_name)
else:
print('Config value %s missing' % config_name)
return config_value
'''
Makes a request using python's built in requests library. Takes additional headers if
necessary
'''
def make_request(self, method: HttpMethod, url: str, data = '', add_headers = {}, params = {}):
headers = {
'content-type': 'application/json',
'data-partition-id': self.data_partition_id,
'Authorization': self.bearer_token
}
if (len(add_headers) > 0):
for key, value in add_headers:
headers[key] = value
response = object
if (method == HttpMethod.GET):
response = requests.get(url=url, params=params, headers=headers)
elif (method == HttpMethod.POST):
response = requests.post(url=url, params=params, data=data, headers=headers)
elif (method == HttpMethod.PUT):
response = requests.put(url=url, params=params, data=data, headers=headers)
return response
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from typing import List
from osdu_api.client.base_client import BaseClient
from osdu_api.model.shared.http_method import HttpMethod
from osdu_api.model.search.query_response import QueryResponse
from osdu_api.model.search.query_request import QueryRequest
'''
Holds the logic for interfacing with Search's query api
'''
class SearchClient(BaseClient):
'''
Used to hit search's api endpoint "queryRecords"
'''
def query_records_from_dict(self, query_request: dict):
query_request_data = json.dumps(query_request)
response = self.make_request(method=HttpMethod.POST, url=self.search_url, data=query_request_data)
response_content = json.loads(response.content)
query_response = QueryResponse(response_content['results'], response_content['aggregations'])
return query_response
'''
Used to hit search's api endpoint "queryRecords" by serializing a model into json
'''
def query_records(self, query_request: QueryRequest):
query_data = query_request.convert_to_dict()
return self.query_records_from_dict(query_data)
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from typing import List
from osdu_api.client.base_client import BaseClient
from osdu_api.model.storage.record import Record
from osdu_api.model.shared.http_method import HttpMethod
'''
Holds the logic for interfacing with Storage's record api
'''
class RecordClient(BaseClient):
'''
Calls storage's api endpoint createOrUpdateRecords taking a list of record objects and constructing
the body of the request
Returns the response object for the call
Example of code to new up a record:
acl = Acl(['data.test1@opendes.testing.com'], ['data.test1@opendes.testing.com'])
legal = Legal(['opendes-storage-1579034803194'], ['US'], LegalCompliance.compliant)
ancestry = RecordAncestry([])
id = 'opendes:welldb:123456'
kind = 'opendes:welldb:wellbore:1.0.0'
meta = [{}]
version = 0
data = {'id': 'test'}
record = Record(id, version, kind, acl, legal, data, ancestry, meta)
'''
def create_update_records(self, records: List[Record]):
records_data = [record.convert_to_dict() for record in records]
return self.create_update_records_from_dict(records_data)
'''
Calls storage's api endpoint createOrUpdateRecords taking individual attributes and constructing
the body of the request
Returns the response object for the call
Example of records_data:
[
{
"acl": {
"owners":[
"data.test1@opendes.testing.com"
],
"viewers":[
"data.test1@opendes.testing.com"
]
},
"ancestry":{
"parents":[]
},
"data":{"id":"test"},
"id":"opendes:welldb:123456",
"kind":"opendes:welldb:wellbore:1.0.0",
"legal":{
"legaltags":["opendes-storage-1579034803194"],
"otherRelevantDataCountries":["US"],
"status":"compliant"
},
"meta":[
{}
],
"version":0
}
]
'''
def create_update_records_from_dict(self, records: dict):
records_data = json.dumps(records)
response = self.make_request(method=HttpMethod.PUT, url=self.storage_url, data=records_data)
return response
'''
Calls storage's api endpoint getLatestRecordVersion taking the required attributes
Returns the content for the response object
'''
def get_latest_record(self, recordId: str, attributes: List[str] = []):
request_params = {'attribute': attributes}
response = self.make_request(method=HttpMethod.GET, params=request_params, url=(self.storage_url + '/%s' % (recordId)))
response_content = json.loads(response.content)
return Record.from_dict(response_content)
'''
Calls storage's api endpoint getSpecificRecordVersion taking the required attributes
Returns the content for the response object
'''
def get_specific_record(self, recordId: str, version: str, attributes: List[str] = []):
request_params = {'attribute': attributes}
response = self.make_request(method=HttpMethod.GET, params=request_params, url=(self.storage_url + '/%s/%s' % (recordId, version)))
response_content = json.loads(response.content)
return Record.from_dict(response_content)
'''
Calls storage's api endpoint getRecordVersions taking the one required parameter record id
Returns the content for the response object for the call containing the list of versions.
Find the versions in the response.content attribute
'''
def get_record_versions(self, recordId: str):
response = self.make_request(method=HttpMethod.GET, url=(self.storage_url + '/versions/%s' % (recordId)))
response_content = json.loads(response.content.decode("utf-8"))
return response_content['versions']
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from osdu_api.client.storage.record_client import RecordClient
client = RecordClient()
response = client.create_update_records_from_dict(
[
{
"acl": {
"owners":[
"data.test1@opendes.testing.com"
],
"viewers":[
"data.test1@opendes.testing.com"
]
},
"ancestry":{
"parents":[]
},
"data":{"id":"test"},
"id":"opendes:welldb:123456",
"kind":"opendes:welldb:wellbore:1.0.0",
"legal":{
"legaltags":["opendes-storage-1579034803194"],
"otherRelevantDataCountries":["US"],
"status":"compliant"
},
"meta":[
{}
],
"version":0
}
])
if (response.ok != True):
raise Exception('Request failed')
print(response)
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from osdu_api.storage.record_client import RecordClient
from osdu_api.model.acl import Acl
from osdu_api.model.legal import Legal
from osdu_api.model.record_ancestry import RecordAncestry
from osdu_api.model.legal_compliance import LegalCompliance
from osdu_api.model.record import Record
# new up record client
client = RecordClient()
# new up record
acl = Acl(['data.test1@opendes.testing.com'], ['data.test1@opendes.testing.com'])
legal = Legal(['opendes-storage-1579034803194'], ['US'], LegalCompliance.compliant)
ancestry = RecordAncestry([])
id = 'opendes:welldb:123456'
kind = 'opendes:welldb:wellbore:1.0.0'
meta = [{}]
version = 0
data = {'id': 'test'}
record = Record(id, version, kind, acl, legal, data, ancestry, meta)
# call create or update
response = client.create_update_records([record])
# print response
print(response)
\ No newline at end of file
This diff is collapsed.
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from osdu_api.storage.record_client import RecordClient
recordId = 'opendes:doc:01219719b1844d86acd6bcd5ef9e3a7a'
client = RecordClient()
record = client.get_latest_record(recordId)
version = client.get_record_versions(recordId)[0]
response = client.get_specific_record(recordId, version)
print(response.content)
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
storage_url: http://localhost:8081/api/storage/v2/records
search_url: http://localhost:8085/api/search/v2/query
data_partition_id: opendes
# dynamically injects what provider-specific logic to use
provider: aws
entitlements_module_name: entitlements_client
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from osdu_api.client.search.search_client import SearchClient
from osdu_api.model.search.query_request import QueryRequest
client = SearchClient()
# response = client.query_records_from_dict({
# 'kind': 'opendes:osdu:well:*',
# 'limit': 30,
# 'query': 'data.ResourceSecurityClassification:"PUBLIC"',
# 'returnedFields': [
# 'id'
# ],
# 'queryAsOwner': 'false',
# 'spatialFilter': {
# 'field': 'data.dlLatLongWGS84',
# 'byBoundingBox': {
# 'topLeft': {
# 'latitude': 34.742612,
# 'longitude': -101.074218
# },
# 'bottomRight': {
# 'latitude': 32.934928,
# 'longitude': -80.799072
# }
# }
# },
# 'offset': 0
# })
# response = client.query_records_from_dict({
# "kind": "opendes:osdu:well:*",
# "limit": 30,
# "query": "data.ResourceSecurityClassification:\"PUBLIC\""
# })
# response = client.query_records_from_dict({
# "kind": "opendes:*:*:*",
# "returnedFields": [
# "kind"
# ],
# "aggregations": "kind"
# })
query_request = QueryRequest(kind='opendes:osdu:well:*', limit=30,
query='data.ResourceSecurityClassification:"PUBLIC"')
response = client.query_records(query_request)
print(response)
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class AggregationResponse:
def __init__(self, key: str, count: int):
self.key = key
self.count = count
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from osdu_api.model.search.coordinate import Coordinate
class ByBoundingBox:
def __init__(self, top_left: Coordinate, bottom_right: Coordinate):
self.top_left = top_left
self.bottom_right = bottom_right
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from osdu_api.model.search.coordinate import Coordinate
class ByDistance:
def __init__(self, distance: float, coordinate: Coordinate):
self.distance = distance
self.coordinate = coordinate
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class ByGeoPolygon:
def __init__(self, coordinates: list):
self.coordinates = coordinates
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class Coordinate:
# python's built-in float has double precision
def __init__(self, latitude: float, longitude: float):
self.latitude = latitude
self.longitude = longitude
\ No newline at end of file
# Copyright © Amazon Web Services
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.