Skip to content

Commit

Permalink
Merge pull request #7 from Arlula/automatedTests
Browse files Browse the repository at this point in the history
Version 2.0.3 - Minor Fixes and Unit Testing
  • Loading branch information
martejj authored Dec 17, 2021
2 parents 5b92adb + 5286c1f commit 7140972
Show file tree
Hide file tree
Showing 14 changed files with 374 additions and 33 deletions.
14 changes: 12 additions & 2 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@ on:
types: [published]

jobs:
deploy:
test:
uses: Arlula/nodejs-core-sdk/.github/workflows/test-pr.yml@main
secrets:
TEST_API_HOST: ${{ secrets.TEST_API_HOST }}
TEST_API_KEY: ${{ secrets.TEST_API_KEY }}
TEST_API_SECRET: ${{ secrets.TEST_API_SECRET }}
TEST_API_ORDER_KEY: ${{ secrets.TEST_API_ORDER_KEY }}
TEST_API_ORDER_EULA: ${{ secrets.TEST_API_ORDER_EULA }}
TEST_API_ORDER_ID: ${{ secrets.TEST_API_ORDER_ID }}
TEST_API_RESOURCE_ID: ${{ secrets.TEST_API_RESOURCE_ID }}

deploy:
needs: test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Test Python Package

on:
workflow_dispatch:
workflow_call:
secrets:
TEST_API_KEY:
required: true
TEST_API_SECRET:
required: true
TEST_API_ORDER_KEY:
required: true
TEST_API_ORDER_EULA:
required: true
TEST_API_HOST:
required: true
TEST_API_ORDER_ID:
required: true
TEST_API_RESOURCE_ID:
required: true
pull_request:
types: [opened,edited,synchronize,reopened,ready_for_review,review_requested,]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- run: pip3 install -r requirements.txt
- run: python3 -m unittest tests/test_archive.py tests/test_orders.py tests/test_rfc3339.py
env:
API_KEY: ${{ secrets.TEST_API_KEY }}
API_SECRET: ${{ secrets.TEST_API_SECRET }}
API_ORDER_KEY: ${{ secrets.TEST_API_ORDER_KEY}}
API_ORDER_EULA: ${{ secrets.TEST_API_ORDER_EULA }}
API_HOST: ${{ secrets.TEST_API_HOST }}
API_ORDER_ID: ${{ secrets.TEST_API_ORDER_ID }}
API_RESOURCE_ID: ${{ secrets.TEST_API_RESOURCE_ID }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ __pycache__
*.cpython
arlulaapi.egg-info
test.py
credentials.json
credentials.json
.env
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,8 @@ order = orders.get(

# Get a specific resource, for example thumbnails, tiffs, json metadata.
# Streams to a file and returns the file handle.
f = orders.get_resource_as_file(
id="b7adb198-3e6e-4217-9e67-fb26eb355cc4",
filepath="downloads/thumbnail.jpg",
)
with orders.get_resource_as_file(id="b7adb198-3e6e-4217-9e67-fb26eb355cc4",filepath="downloads/thumbnail.jpg") as f:
f.read(...)

# Get a specific resource, for example thumbnails, tiffs, json metadata.
# Returns the memory buffer of the requested resource.
Expand Down
4 changes: 4 additions & 0 deletions arlulacore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@
from .exception import (
ArlulaSessionError
)

from .util import (
parse_rfc3339
)
18 changes: 10 additions & 8 deletions arlulacore/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .auth import Session
from .exception import ArlulaSessionError
from .orders import DetailedOrderResult
from .util import parse_rfc3339


@dataclass
Expand Down Expand Up @@ -62,8 +63,7 @@ def __init__(self, data):
self.id = data["id"]
self.scene_id = data["sceneID"]
self.platform = data["platform"]
if str(data["date"]).endswith("Z"):
self.date = datetime.fromisoformat(data["date"][:-1])
self.date = parse_rfc3339(data["date"])
self.center = CenterPoint(**data["center"])
self.bounding = data["bounding"]
self.area = data["area"]
Expand Down Expand Up @@ -157,14 +157,16 @@ def set_maximum_cloud_cover(self, cloud: float) -> "SearchRequest":
return self

def dict(self):
param_dict = {"start": str(self.start), "end": str(self.end),
param_dict = {
"start": str(self.start) if self.start != None else None,
"end": str(self.end) if self.end != None else None,
"res": self.res, "cloud": self.cloud,
"lat": self.lat, "long": self.long,
"north": self.north, "south": self.south, "east": self.east,
"west": self.west, "supplier": self.supplier, "off-nadir": self.off_nadir}

query_params = {k: v for k, v in param_dict.items()
if v is not None or v == 0}
if v is not None}

return query_params

Expand All @@ -188,20 +190,20 @@ def __init__(self,
self.webhooks = webhooks
self.emails = emails

def set_webhook(self, webhook: str) -> "OrderRequest":
def add_webhook(self, webhook: str) -> "OrderRequest":
self.webhooks.append(webhook)
return self

def set_webhooks(self, webhooks: typing.List[str]) -> "OrderRequest":
self.webhooks = webhooks
return self

def set_email(self, email: str) -> "OrderRequest":
self.webhooks.append(email)
def add_email(self, email: str) -> "OrderRequest":
self.emails.append(email)
return self

def set_emails(self, emails: typing.List[str]) -> "OrderRequest":
self.webhooks = emails
self.emails = emails
return self

def dumps(self):
Expand Down
9 changes: 6 additions & 3 deletions arlulacore/auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
import platform
import base64
import typing
import requests

from .exception import ArlulaSessionError
Expand All @@ -9,7 +10,7 @@
name = "arlulacore"

# User agent setting
sdk_version = "2.0.2"
sdk_version = "2.0.3"
py_version = sys.version.split(' ')[0]
os_version = platform.platform()
def_ua = "core-sdk " + \
Expand All @@ -26,7 +27,9 @@ class Session:
def __init__(self,
key: str,
secret: str,
user_agent: str = def_ua):
user_agent: typing.Optional[str] = def_ua,
url: typing.Optional[str] = "https://api.arlula.com"
):
# Encode the key and secret
def atob(x): return x.encode('utf-8')
self.token = base64.b64encode(atob(
Expand All @@ -36,7 +39,7 @@ def atob(x): return x.encode('utf-8')
'User-Agent': user_agent,
'X-API-Version': x_api_version
}
self.baseURL = "https://api.arlula.com"
self.baseURL = url
self.validate_creds()

# Check the credentials are valid
Expand Down
33 changes: 19 additions & 14 deletions arlulacore/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Objects specific to the orders api
'''

from datetime import datetime
import typing
import json
import requests
Expand All @@ -10,11 +11,12 @@
from .auth import Session
from .exception import ArlulaSessionError
from .common import ArlulaObject
from .util import parse_rfc3339

class Resource(ArlulaObject):
id: str
created_at: str
updated_at: str
created_at: datetime
updated_at: datetime
order: str
name: str
type: str
Expand All @@ -25,8 +27,8 @@ class Resource(ArlulaObject):

def __init__(self, data):
self.id = data["id"]
self.created_at = data["createdAt"]
self.updated_at = data["updatedAt"]
self.created_at = parse_rfc3339(data["createdAt"])
self.updated_at = parse_rfc3339(data["updatedAt"])
self.order = data["order"]
self.name = data["name"]
self.type = data["type"]
Expand All @@ -37,8 +39,8 @@ def __init__(self, data):

class OrderResult(ArlulaObject):
id: str
created_at: str
updated_at: str
created_at: datetime
updated_at: datetime
supplier: str
imagery_id: str
scene_id: str
Expand All @@ -49,8 +51,8 @@ class OrderResult(ArlulaObject):

def __init__(self, data):
self.id = data["id"]
self.created_at = data["createdAt"]
self.updated_at = data["updatedAt"]
self.created_at = parse_rfc3339(data["createdAt"])
self.updated_at = parse_rfc3339(data["updatedAt"])
self.supplier = data["supplier"]
self.imagery_id = data["imageryID"]
self.scene_id = data["sceneID"]
Expand All @@ -61,8 +63,8 @@ def __init__(self, data):

class DetailedOrderResult(ArlulaObject):
id: str
created_at: str
updated_at: str
created_at: datetime
updated_at: datetime
supplier: str
imagery_id: str
scene_id: str
Expand All @@ -74,8 +76,8 @@ class DetailedOrderResult(ArlulaObject):

def __init__(self, data):
self.id = data["id"]
self.created_at = data["createdAt"]
self.updated_at = data["updatedAt"]
self.created_at = parse_rfc3339(data["createdAt"])
self.updated_at = parse_rfc3339(data["updatedAt"])
self.supplier = data["supplier"]
self.imagery_id = data["imageryID"]
self.scene_id = data["sceneID"]
Expand Down Expand Up @@ -140,7 +142,7 @@ def get_resource_as_file(self,
progress_generator: typing.Optional[typing.Generator[typing.Optional[float], None, None]] = None) -> typing.BinaryIO:
'''
Get a resource and stream it to the specified file. If supress is true, it will output extra information to standard output.
This is recommended for large files. Returns the file, which must be closed.
This is recommended for large files. Returns the file, which must be closed. The returned file is seeked back to it's beginning.
'''

url = self.url + "/resource/get"
Expand All @@ -153,7 +155,7 @@ def get_resource_as_file(self,
if progress_generator is not None:
next(progress_generator)

f = open(filepath, 'wb')
f = open(filepath, "w+b")

# Stream response
response = requests.request(
Expand Down Expand Up @@ -192,6 +194,9 @@ def get_resource_as_file(self,
if not suppress:
sys.stdout.write('\n')
sys.stdout.write('download complete\n')

# So the file is able to be read from the beginning.
f.seek(0)

return f

Expand Down
44 changes: 44 additions & 0 deletions arlulacore/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import re
from datetime import datetime, timezone, timedelta

__date_rx__ = re.compile(r"^(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[Tt](?P<hour>\d\d):(?P<minute>\d\d):(?P<second>\d\d)(?:\.(?P<sec_frac>\d+))?(?P<offset>(?:[zZ]|(?P<offset_sign>[+-])(?P<offset_hour>\d{2}):(?P<offset_minute>\d{2})))$")

def parse_rfc3339(dt_str: str) -> datetime:
try:
result = re.search(__date_rx__, dt_str)

if result.lastindex < 7 or result.lastindex > 11:
return None

sec_frac_int = 0

sec_frac = result["sec_frac"]
if sec_frac is not None:
sec_frac_str = sec_frac[:6] if len(sec_frac) > 6 else sec_frac
sec_frac_int = int(sec_frac_str)*(10**(6 - len(sec_frac_str)))

tz = timezone(timedelta())

if not (result["offset"] == "z" or result["offset"] == "Z"):

offset_hour = int(result["offset_hour"])
offset_minute = int(result["offset_minute"])

if result["offset_sign"] == "-":
offset_minute *= -1
offset_hour *= -1

tz = timezone(timedelta(hours=offset_hour, minutes=offset_minute))

return datetime(
int(result["year"]),
int(result["month"]),
int(result["day"]),
int(result["hour"]),
int(result["minute"]),
int(result["second"]),
sec_frac_int,
tz
)
except:
return None
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name='arlulacore',
version='2.0.2',
version='2.0.3',
author="Arlula",
author_email="[email protected]",
description="A package to facilitate access to the Arlula Imagery Marketplace API",
Expand Down
Loading

0 comments on commit 7140972

Please sign in to comment.