moonstream/clients/python/moonstream/client.py

252 wiersze
6.9 KiB
Python
Czysty Zwykły widok Historia

2022-10-26 11:29:25 +00:00
import uuid
from typing import Any, Dict, Union
import requests
2022-10-27 12:18:34 +00:00
try:
from .aws.bucket import upload_to_aws_s3_bucket
except Exception as e:
pass
2022-10-26 11:29:25 +00:00
from .data import (
APISpec,
AuthType,
Method,
MoonstreamQueries,
MoonstreamQuery,
MoonstreamQueryResultUrl,
2022-10-27 11:35:35 +00:00
OutputType,
2022-10-26 11:29:25 +00:00
)
from .exceptions import MoonstreamResponseException, MoonstreamUnexpectedResponse
2022-10-27 09:38:35 +00:00
from .settings import MOONSTREAM_API_URL, MOONSTREAM_REQUEST_TIMEOUT
ENDPOINT_PING = "/ping"
ENDPOINT_VERSION = "/version"
ENDPOINT_NOW = "/now"
2022-10-26 11:29:25 +00:00
ENDPOINT_QUERIES = "/queries"
2021-09-20 23:49:29 +00:00
2021-09-20 21:40:33 +00:00
ENDPOINTS = [
ENDPOINT_PING,
ENDPOINT_VERSION,
ENDPOINT_NOW,
2022-10-26 11:29:25 +00:00
ENDPOINT_QUERIES,
2021-09-20 21:40:33 +00:00
]
2021-09-20 20:38:18 +00:00
def moonstream_endpoints(url: str) -> Dict[str, str]:
"""
Creates a dictionary of Moonstream API endpoints at the given Moonstream API URL.
"""
2022-10-26 11:29:25 +00:00
if not (url.startswith("http://") or url.startswith("https://")):
url = f"http://{url}"
2022-10-26 11:29:25 +00:00
normalized_url = url.rstrip("/")
return {endpoint: f"{normalized_url}{endpoint}" for endpoint in ENDPOINTS}
class Moonstream:
"""
A Moonstream client configured to communicate with a given Moonstream API server.
"""
2022-10-27 09:38:35 +00:00
def __init__(self, moonstream_api_url: str = MOONSTREAM_API_URL):
"""
Initializes a Moonstream API client.
2022-10-26 11:29:25 +00:00
Arguments:
url - Moonstream API URL. By default this points to the production Moonstream API at https://api.moonstream.to,
but you can replace it with the URL of any other Moonstream API instance.
"""
2022-10-26 11:29:25 +00:00
endpoints = moonstream_endpoints(moonstream_api_url)
self.api = APISpec(url=moonstream_api_url, endpoints=endpoints)
2022-10-27 09:38:35 +00:00
def _call(
self,
method: Method,
url: str,
timeout: float = MOONSTREAM_REQUEST_TIMEOUT,
**kwargs,
):
2022-10-26 11:29:25 +00:00
try:
2022-10-27 09:38:35 +00:00
response = requests.request(
method.value, url=url, timeout=timeout, **kwargs
)
2022-10-26 11:29:25 +00:00
response.raise_for_status()
except Exception as e:
raise MoonstreamUnexpectedResponse(str(e))
return response.json()
def ping(self) -> Dict[str, Any]:
2021-09-20 20:38:18 +00:00
"""
Checks that you have a connection to the Moonstream API.
"""
2022-10-26 11:29:25 +00:00
result = self._call(method=Method.GET, url=self.api.endpoints[ENDPOINT_PING])
return result
def version(self) -> Dict[str, Any]:
2021-09-20 20:38:18 +00:00
"""
Gets the Moonstream API version information from the server.
"""
2022-10-26 11:29:25 +00:00
result = self._call(method=Method.GET, url=self.api.endpoints[ENDPOINT_VERSION])
return result
2021-09-20 21:40:33 +00:00
2022-10-26 11:29:25 +00:00
def create_query(
self,
token: Union[str, uuid.UUID],
query: str,
name: str,
public: bool = False,
auth_type: AuthType = AuthType.bearer,
2022-10-27 09:38:35 +00:00
timeout: float = MOONSTREAM_REQUEST_TIMEOUT,
2022-10-26 11:29:25 +00:00
) -> MoonstreamQuery:
"""
Creates new query.
"""
json = {
"query": query,
"name": name,
"public": public,
}
headers = {
"Authorization": f"{auth_type.value} {token}",
}
response = self._call(
method=Method.POST,
2022-10-27 15:38:58 +00:00
url=f"{self.api.endpoints[ENDPOINT_QUERIES]}/",
2022-10-26 11:29:25 +00:00
headers=headers,
json=json,
2022-10-27 09:38:35 +00:00
timeout=timeout,
2021-09-20 21:40:33 +00:00
)
2021-09-20 23:49:29 +00:00
2022-10-26 11:29:25 +00:00
return MoonstreamQuery(
id=response["id"],
journal_url=response["journal_url"],
name=response["title"],
query=response["content"],
tags=response["tags"],
created_at=response["created_at"],
updated_at=response["updated_at"],
2021-09-20 23:49:29 +00:00
)
2022-10-26 11:29:25 +00:00
def list_queries(
self,
token: Union[str, uuid.UUID],
auth_type: AuthType = AuthType.bearer,
2022-10-27 09:38:35 +00:00
timeout: float = MOONSTREAM_REQUEST_TIMEOUT,
2022-10-26 11:29:25 +00:00
) -> MoonstreamQueries:
2021-09-20 23:49:29 +00:00
"""
2022-10-26 11:29:25 +00:00
Returns list of all queries available to user.
2021-09-20 23:49:29 +00:00
"""
2022-10-26 11:29:25 +00:00
headers = {
"Authorization": f"{auth_type.value} {token}",
2021-09-20 23:49:29 +00:00
}
2022-10-26 11:29:25 +00:00
response = self._call(
method=Method.GET,
url=f"{self.api.endpoints[ENDPOINT_QUERIES]}/list",
headers=headers,
2022-10-27 09:38:35 +00:00
timeout=timeout,
2021-09-20 23:49:29 +00:00
)
2022-10-26 11:29:25 +00:00
return MoonstreamQueries(
queries=[
MoonstreamQuery(
id=query["entry_id"],
name=query["name"],
query_type=query["type"],
user=query["user"],
user_id=query["user_id"],
)
for query in response
]
2021-09-20 23:49:29 +00:00
)
2022-10-26 11:29:25 +00:00
def exec_query(
2021-09-20 23:49:29 +00:00
self,
2022-10-26 11:29:25 +00:00
token: Union[str, uuid.UUID],
name: str,
params: Dict[str, Any] = {},
auth_type: AuthType = AuthType.bearer,
2022-10-27 09:38:35 +00:00
timeout: float = MOONSTREAM_REQUEST_TIMEOUT,
2022-10-26 11:29:25 +00:00
) -> MoonstreamQueryResultUrl:
2021-09-20 23:49:29 +00:00
"""
2022-10-26 11:29:25 +00:00
Executes queries and upload data to external storage.
2021-09-20 23:49:29 +00:00
"""
2022-10-26 11:29:25 +00:00
headers = {
"Authorization": f"{auth_type.value} {token}",
}
json = {
"params": params,
2021-09-20 23:49:29 +00:00
}
2022-10-26 11:29:25 +00:00
response = self._call(
method=Method.POST,
url=f"{self.api.endpoints[ENDPOINT_QUERIES]}/{name}/update_data",
headers=headers,
json=json,
2022-10-27 09:38:35 +00:00
timeout=timeout,
2022-10-26 11:29:25 +00:00
)
2021-09-20 23:49:29 +00:00
2022-10-26 11:29:25 +00:00
return MoonstreamQueryResultUrl(url=response["url"])
2021-09-20 23:49:29 +00:00
2022-10-27 11:35:35 +00:00
def download_query_results(
self,
url: str,
output_type: OutputType = OutputType.JSON,
timeout: float = MOONSTREAM_REQUEST_TIMEOUT,
**kwargs,
) -> Any:
"""
Fetch results of query from url.
"""
try:
response = requests.request(
Method.GET.value, url=url, timeout=timeout, **kwargs
)
response.raise_for_status()
except Exception as e:
raise Exception(str(e))
output = response
if output_type == OutputType.JSON:
output = response.json()
return output
2022-10-27 12:18:34 +00:00
def upload_query_results(
self, data: str, bucket: str, key: str, metadata: Dict[str, Any] = {}
) -> str:
"""
Uploads data to AWS S3 bucket.
Requirements: "pip install -e .[aws]" with "boto3" module.
"""
try:
url = upload_to_aws_s3_bucket(
data=data, bucket=bucket, key=key, metadata=metadata
)
except Exception as e:
raise Exception(str(e))
return url
2022-10-26 11:29:25 +00:00
def delete_query(
self,
2022-10-26 11:29:25 +00:00
token: Union[str, uuid.UUID],
name: str,
auth_type: AuthType = AuthType.bearer,
2022-10-27 09:38:35 +00:00
timeout: float = MOONSTREAM_REQUEST_TIMEOUT,
2022-10-26 11:29:25 +00:00
) -> uuid.UUID:
"""
2022-10-26 11:29:25 +00:00
Deletes query specified by name.
"""
2022-10-26 11:29:25 +00:00
headers = {
"Authorization": f"{auth_type.value} {token}",
}
response = self._call(
method=Method.DELETE,
url=f"{self.api.endpoints[ENDPOINT_QUERIES]}/{name}",
headers=headers,
2022-10-27 09:38:35 +00:00
timeout=timeout,
2022-10-26 11:29:25 +00:00
)
2022-10-26 11:29:25 +00:00
return response["id"]