Skip to content

Commit

Permalink
feat: record spike progress before revert
Browse files Browse the repository at this point in the history
  • Loading branch information
dwinston committed Aug 14, 2022
1 parent ef3dcce commit 449953c
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 6 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
init:
pip install --upgrade pip-tools pip setuptools
pip install --editable .
pip install --editable nmdc_runtime_client/
pip install --upgrade -r requirements/main.txt -r requirements/dev.txt

update-deps:
Expand Down Expand Up @@ -74,9 +75,12 @@ dagster-deploy-spin:
rancher kubectl rollout restart deployment/dagit-readonly --namespace=nmdc-runtime-dev
rancher kubectl rollout restart deployment/dagster-daemon --namespace=nmdc-runtime-dev

publish:
publish-all:
invoke publish

publish-client:
cd nmdc_runtime_client && invoke publish

docs-dev:
mkdocs serve -a localhost:8080

Expand Down
Empty file removed nmdc_runtime/client/__init__.py
Empty file.
14 changes: 14 additions & 0 deletions nmdc_runtime_client/nmdc_runtime/client/lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from datetime import timedelta, datetime, timezone


def now(as_str=False):
dt = datetime.now(timezone.utc)
return dt.isoformat() if as_str else dt


def expiry_dt_from_now(days=0, hours=0, minutes=0, seconds=0):
return now() + timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)


def has_passed(dt):
return now() > dt
130 changes: 130 additions & 0 deletions nmdc_runtime_client/nmdc_runtime/client/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,134 @@
from datetime import timedelta

import click
import requests
from nmdc_runtime.
from nmdc_runtime.client.lib import expiry_dt_from_now, has_passed
from pydash import merge


class RuntimeApiSiteClient:
def __init__(self, base_url: str, site_id: str, client_id: str, client_secret: str):
self.base_url = base_url
self.site_id = site_id
self.client_id = client_id
self.client_secret = client_secret
self.headers = {}
self.token_response = None
self.refresh_token_after = None
self.get_token()

def request(self, method, url_path, params_or_json_data=None):
self.ensure_token()
kwargs = {"url": self.base_url + url_path, "headers": self.headers}
if method.upper() == "GET":
kwargs["params"] = params_or_json_data
else:
kwargs["json"] = params_or_json_data
return requests.request(method, **kwargs)

def get_token(self):
rv = requests.post(
self.base_url + "/token",
data={
"grant_type": "client_credentials",
"client_id": self.client_id,
"client_secret": self.client_secret,
},
)
self.token_response = rv.json()
if "access_token" not in self.token_response:
raise Exception(f"Getting token failed: {self.token_response}")

self.headers["Authorization"] = f'Bearer {self.token_response["access_token"]}'
self.refresh_token_after = expiry_dt_from_now(
**self.token_response["expires"]
) - timedelta(seconds=5)

def ensure_token(self):
if has_passed(self.refresh_token_after):
self.get_token()

def put_object_in_site(self, object_in):
return self.request("POST", f"/sites/{self.site_id}:putObject", object_in)

def get_site_object_link(self, access_method):
return self.request(
"POST", f"/sites/{self.site_id}:getObjectLink", access_method
)

def get_operation(self, op_id):
return self.request("GET", f"/operations/{op_id}")

def operation_is_done(self, op_id):
op = self.get_operation(op_id).json()
return op.get("done") is True

def update_operation(self, op_id, op_patch):
return self.request("PATCH", f"/operations/{op_id}", op_patch)

def list_operations(self, req):
rv = self.request("GET", "/operations", req)
lor = ListOperationsResponse(**rv.json())
resources_so_far = lor.resources
if not lor.next_page_token:
return resources_so_far
else:
resources_rest = self.list_operations(
merge(req, {"page_token": lor.next_page_token})
)
return resources_so_far + resources_rest

def create_object(self, drs_object_in: DrsObjectIn):
DrsObjectIn(**drs_object_in) # validate before network request
return self.request("POST", "/objects", drs_object_in)

def create_object_from_op(self, op_doc):
return self.request("POST", "/objects", op_doc["result"])

def ensure_object_tag(self, object_id, tag_id):
object_type_ids = [
t["id"] for t in self.request("GET", f"/objects/{object_id}/types").json()
]
if tag_id not in object_type_ids:
return self.request(
"PUT", f"/objects/{object_id}/types", object_type_ids + [tag_id]
)

def get_object_info(self, object_id):
return self.request("GET", f"/objects/{object_id}")

def get_object_access(self, object_id, access_id):
return self.request("GET", f"/objects/{object_id}/access/{access_id}")

def get_object_bytes(self, object_id) -> requests.Response:
obj = DrsObject(**self.get_object_info(object_id).json())
method = obj.access_methods[0]
if method.access_url is None:
access = AccessURL(
**self.get_object_access(object_id, method.access_id).json()
)
if access.url.startswith(
os.getenv("API_HOST_EXTERNAL")
) and self.base_url == os.getenv("API_HOST"):
access.url = access.url.replace(
os.getenv("API_HOST_EXTERNAL"), os.getenv("API_HOST")
)
else:
access = AccessURL(url=method.access_url.url)
return requests.get(access.url)

def list_jobs(self, list_request=None):
if list_request is None:
params = {}
else:
if "filter" in list_request and isinstance(list_request["filter"], dict):
list_request["filter"] = json.dumps(list_request["filter"])
params = ListRequest(**list_request)
return self.request("GET", "/jobs", params)

def claim_job(self, job_id):
return self.request("POST", f"/jobs/{job_id}:claim")


@click.command()
Expand Down
3 changes: 1 addition & 2 deletions nmdc_runtime_client/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
name="nmdc_runtime_client",
url="https://github.com/microbiomedata/nmdc-runtime",
packages=["nmdc_runtime.client"],
use_scm_version=True,
setup_requires=["setuptools_scm"],
version="0.1.0",
author="Donny Winston",
author_email="[email protected]",
description="Client for the NMDC Runtime",
Expand Down
8 changes: 8 additions & 0 deletions nmdc_runtime_client/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from invoke import task


@task
def publish(c):
c.run("rm dist/*.*", warn=True)
c.run("python setup.py sdist bdist_wheel")
c.run("twine upload dist/*")
4 changes: 1 addition & 3 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,5 @@ def publish(c):
run(["git", "push"])
run(["git", "push", "--tags"])
c.run("rm dist/*.*", warn=True)
# c.run("python setup.py sdist bdist_wheel")
# c.run("twine upload dist/*")
c.run("cd nmdc_runtime_client && python setup.py sdist bdist_wheel")
c.run("python setup.py sdist bdist_wheel")
c.run("twine upload dist/*")

0 comments on commit 449953c

Please sign in to comment.