Skip to content

Commit

Permalink
Split the clients into separate modules to eliminate the boto3 depend…
Browse files Browse the repository at this point in the history
…ency for those who don't need the AwsOsduClient (#21)

Split the clients into separate modules to eliminate the boto3 dependency for those who don't need the AwsOsduClient.
  • Loading branch information
puremcc authored Oct 13, 2020
1 parent 7e2368b commit 4435a5e
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 120 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ A simple python client for the [OSDU](https://community.opengroup.org/osdu) data
+ [Search with paging](#search-with-paging)
+ [Get a record](#get-a-record)
+ [Upsert records](#upsert-records)
- [Release Notes](release-notes.md)

## Clients

Expand All @@ -27,13 +28,15 @@ Choose the client that best meets your needs. The same methods are all supported
BYOT: Bring your own token. Great for backend service or business logic that supplements a
front-end application.

*This client assumes you are obtaining a token yourself (e.g. via your application's
This client assumes you are obtaining a token yourself (e.g. via your application's
login form or otheer mechanism. With this SimpleOsduClient, you simply provide that token.
With this simplicity, you are also then respnsible for reefreeshing the token as needed and
re-instantiating the client with the new token.*
re-instantiating the client with the new token.

### AwsOsduClient

**Requires**: `boto3==1.15.*`

Good for batch tasks that don't have an interactive front-end. Token management is handled
with the boto3 library directly through the Cognito service. You have to supply additional arguments for this.

Expand Down Expand Up @@ -65,7 +68,7 @@ pip install osdupy
If environment variable `OSDU_API_URL` is set, then it does not need to be passed as an argument. Otherwise it must be passed as keyword argument.

```python
from osdu.client import SimpleOsduClient
from osdu.client.simple import SimpleOsduClient

data_partition = 'opendes'
token = 'token-received-from-front-end-app'
Expand All @@ -90,7 +93,7 @@ Environment variables:
1. `OSDU_PASSWORD`

```python
from osdu.client import AwsOsduClient
from osdu.client.aws import AwsOsduClient

data_partition = 'opendes'

Expand All @@ -101,7 +104,7 @@ If you have not set the above environment variales—or you have only set some

```python
from getpass import getpass
from osdu.client import AwsOsduClient
from osdu.client.aws import AwsOsduClient

api_url = 'https://your.api.url.com' # Must be base URL only
client_id = 'YOURCLIENTID'
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.10
0.1.0
110 changes: 0 additions & 110 deletions osdu/client.py

This file was deleted.

1 change: 1 addition & 0 deletions osdu/client/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__ = ['aws', 'simple']
35 changes: 35 additions & 0 deletions osdu/client/aws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import os
import boto3

from .base import BaseOsduClient


class AwsOsduClient(BaseOsduClient):
"""Good for batch tasks that don't have an interactive front-end. Token management is handled
with the boto3 library directly through the Cognito service. You have to supply additional arguments for this.
Requires: `boto3`
"""

def __init__(self, data_partition_id, api_url:str=None, client_id:str=None, user:str=None, password:str=None) -> None:
super().__init__(data_partition_id, api_url)

self._client_id = client_id or os.environ.get('OSDU_CLIENT_ID')
self._user = user or os.environ.get('OSDU_USER')
if password:
self.get_tokens(password)
password = None # Don't leave password lying around.
else:
self.get_tokens(os.environ.get('OSDU_PASSWORD'))


def get_tokens(self, password) -> None:
client = boto3.client('cognito-idp')
response = client.initiate_auth(
AuthFlow='USER_PASSWORD_AUTH',
ClientId=self._client_id,
AuthParameters={ 'USERNAME': self._user, 'PASSWORD': password }
)

self._access_token = response['AuthenticationResult']['AccessToken']
self._refresh_token = response['AuthenticationResult']['RefreshToken']
61 changes: 61 additions & 0 deletions osdu/client/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
""" Handles the authentication and token management for interacting with the OSDU platform.
"""

import os

from osdu.delivery import DeliveryService
from osdu.search import SearchService
from osdu.storage import StorageService


class BaseOsduClient:

@property
def access_token(self):
return self._access_token

@property
def api_url(self):
return self._api_url

@property
def search(self):
return self._search

@property
def storage(self):
return self._storage

@property
def delivery(self):
return self._delivery

@property
def data_partition_id(self):
return self._data_partition_id

@data_partition_id.setter
def data_partition_id(self, val):
self._data_partition_id = val


def __init__(self, data_partition_id, api_url:str=None):
"""Authenticate and instantiate a new OSDU client.
'api_url' must be only the base URL, e.g. https://myapi.myregion.mydomain.com
"""
self._data_partition_id = data_partition_id
# TODO: Validate api_url against URL regex pattern.
self._api_url = (api_url or os.environ.get('OSDU_API_URL')).rstrip('/')

# Instantiate services.
self._search = SearchService(self)
self._storage = StorageService(self)
self._delivery = DeliveryService(self)
# TODO: Implement these services.
# self.__legal = LegaService(self)
# self.__entitlements = EntitlementsService(self)

# Abstract Method
def get_tokens(self, password):
raise NotImplementedError('This method must be implemented by a subclass')
20 changes: 20 additions & 0 deletions osdu/client/simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from .base import BaseOsduClient


class SimpleOsduClient(BaseOsduClient):
"""BYOT: Bring your own token.
This client assumes you are obtaining a token yourself (e.g. via your application's
login form or otheer mechanism. With this SimpleOsduClient, you simply provide that token.
With this simplicity, you are also then respnsible for reefreeshing the token as needed and
re-instantiating the client with the new token.
"""

def __init__(self, data_partition_id: str, access_token: str, api_url: str=None) -> None:
"""
:param: access_token: The access token only (not including the 'Bearer ' prefix).
:param: api_url: must be only the base URL, e.g. https://myapi.myregion.mydomain.com
"""
super().__init__(data_partition_id, api_url)

self._access_token = access_token
26 changes: 26 additions & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Release Notes

## `0.1.0`

**Release Date**: 2020.10.13

Split the clients into separate modules to eliminate the boto3 dependency for those who don't need the `AwsOsduClient`

The change is very minor, and the only impacts will be:

1. `osdupy` will no longer explicitly depend on `boto3` . You will instead need to separately install `boto3` if you intend to use the `AwsOsduClient` class.
2. Client imports will have require additional namespace on import statements:

`v0.0.10`

```python
from osdu.client import AwsOsduClient
from osdu.client import SimpleOsduClient
```

`v0.1.0`

```python
from osdu.client.aws import AwsOsduClient
from osdu.client.simple import SimpleOsduClient
```
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
boto3>=1.14
requests>=2.0
requests==2.20.*
3 changes: 2 additions & 1 deletion tests/tests_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from unittest import TestCase

import requests
from osdu.client import AwsOsduClient, SimpleOsduClient
from osdu.client.aws import AwsOsduClient
from osdu.client.simple import SimpleOsduClient


class TestSimpleOsduClient(TestCase):
Expand Down
3 changes: 2 additions & 1 deletion tests/tests_unit.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Pattern
from unittest import TestCase, mock

from osdu.client import AwsOsduClient, SimpleOsduClient
from osdu.client.aws import AwsOsduClient
from osdu.client.simple import SimpleOsduClient


class TestAwsOsduClient(TestCase):
Expand Down

0 comments on commit 4435a5e

Please sign in to comment.