elements-api 2025.11.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- elements_api-2025.11.4/LICENSE +7 -0
- elements_api-2025.11.4/PKG-INFO +11 -0
- elements_api-2025.11.4/README.md +7 -0
- elements_api-2025.11.4/pyproject.toml +3 -0
- elements_api-2025.11.4/setup.cfg +4 -0
- elements_api-2025.11.4/setup.py +29 -0
- elements_api-2025.11.4/src/py/elements_api/__init__.py +8 -0
- elements_api-2025.11.4/src/py/elements_api/async_client.py +43 -0
- elements_api-2025.11.4/src/py/elements_api/async_interceptors.py +105 -0
- elements_api-2025.11.4/src/py/elements_api/elements_base_api.py +454 -0
- elements_api-2025.11.4/src/py/elements_api/models/__init__.py +47 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_computation_execution_pb2.py +48 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_computation_execution_pb2.pyi +84 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_computation_pb2.py +61 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_computation_pb2.pyi +134 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_config_pb2.py +90 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_config_pb2.pyi +185 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_manifest_pb2.py +43 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_manifest_pb2.pyi +25 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_pb2.py +57 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_pb2.pyi +96 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_version_pb2.py +88 -0
- elements_api-2025.11.4/src/py/elements_api/models/algorithm_version_pb2.pyi +233 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_computation_pb2.py +69 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_computation_pb2.pyi +159 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_config_pb2.py +127 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_config_pb2.pyi +180 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_pb2.py +57 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_pb2.pyi +98 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_version_pb2.py +77 -0
- elements_api-2025.11.4/src/py/elements_api/models/analysis_version_pb2.pyi +141 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_catalog_pb2.py +71 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_catalog_pb2.pyi +162 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_collection_pb2.py +67 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_collection_pb2.pyi +146 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_export_pb2.py +48 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_export_pb2.pyi +62 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_pb2.py +66 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_pb2.pyi +191 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_transaction_pb2.py +52 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_transaction_pb2.pyi +56 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_version_pb2.py +63 -0
- elements_api-2025.11.4/src/py/elements_api/models/aoi_version_pb2.pyi +171 -0
- elements_api-2025.11.4/src/py/elements_api/models/common_models_pb2.py +36 -0
- elements_api-2025.11.4/src/py/elements_api/models/common_models_pb2.pyi +15 -0
- elements_api-2025.11.4/src/py/elements_api/models/credit_pb2.py +79 -0
- elements_api-2025.11.4/src/py/elements_api/models/credit_pb2.pyi +216 -0
- elements_api-2025.11.4/src/py/elements_api/models/data_source_pb2.py +53 -0
- elements_api-2025.11.4/src/py/elements_api/models/data_source_pb2.pyi +86 -0
- elements_api-2025.11.4/src/py/elements_api/models/data_tracking_pb2.py +60 -0
- elements_api-2025.11.4/src/py/elements_api/models/data_tracking_pb2.pyi +127 -0
- elements_api-2025.11.4/src/py/elements_api/models/data_type_pb2.py +51 -0
- elements_api-2025.11.4/src/py/elements_api/models/data_type_pb2.pyi +74 -0
- elements_api-2025.11.4/src/py/elements_api/models/filter_pb2.py +63 -0
- elements_api-2025.11.4/src/py/elements_api/models/filter_pb2.pyi +133 -0
- elements_api-2025.11.4/src/py/elements_api/models/forgot_password_pb2.py +42 -0
- elements_api-2025.11.4/src/py/elements_api/models/forgot_password_pb2.pyi +19 -0
- elements_api-2025.11.4/src/py/elements_api/models/notification_pb2.py +82 -0
- elements_api-2025.11.4/src/py/elements_api/models/notification_pb2.pyi +180 -0
- elements_api-2025.11.4/src/py/elements_api/models/order_pb2.py +68 -0
- elements_api-2025.11.4/src/py/elements_api/models/order_pb2.pyi +181 -0
- elements_api-2025.11.4/src/py/elements_api/models/order_recommendation_pb2.py +53 -0
- elements_api-2025.11.4/src/py/elements_api/models/order_recommendation_pb2.pyi +99 -0
- elements_api-2025.11.4/src/py/elements_api/models/permission_pb2.py +84 -0
- elements_api-2025.11.4/src/py/elements_api/models/permission_pb2.pyi +177 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_analysis_config_pb2.py +154 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_analysis_config_pb2.pyi +76 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_aoi_pb2.py +66 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_aoi_pb2.pyi +118 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_collaborator_pb2.py +54 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_collaborator_pb2.pyi +74 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_filter_pb2.py +55 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_filter_pb2.pyi +61 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_group_pb2.py +198 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_group_pb2.pyi +119 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_pb2.py +217 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_pb2.pyi +314 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_result_pb2.py +123 -0
- elements_api-2025.11.4/src/py/elements_api/models/project_result_pb2.pyi +221 -0
- elements_api-2025.11.4/src/py/elements_api/models/provider_quotas_pb2.py +42 -0
- elements_api-2025.11.4/src/py/elements_api/models/provider_quotas_pb2.pyi +33 -0
- elements_api-2025.11.4/src/py/elements_api/models/resource_pb2.py +64 -0
- elements_api-2025.11.4/src/py/elements_api/models/resource_pb2.pyi +133 -0
- elements_api-2025.11.4/src/py/elements_api/models/result_pb2.py +65 -0
- elements_api-2025.11.4/src/py/elements_api/models/result_pb2.pyi +158 -0
- elements_api-2025.11.4/src/py/elements_api/models/s3_pb2.py +52 -0
- elements_api-2025.11.4/src/py/elements_api/models/s3_pb2.pyi +49 -0
- elements_api-2025.11.4/src/py/elements_api/models/subject_pb2.py +36 -0
- elements_api-2025.11.4/src/py/elements_api/models/subject_pb2.pyi +11 -0
- elements_api-2025.11.4/src/py/elements_api/models/system_pb2.py +47 -0
- elements_api-2025.11.4/src/py/elements_api/models/system_pb2.pyi +28 -0
- elements_api-2025.11.4/src/py/elements_api/models/tasking_order_pb2.py +75 -0
- elements_api-2025.11.4/src/py/elements_api/models/tasking_order_pb2.pyi +156 -0
- elements_api-2025.11.4/src/py/elements_api/models/tile_pb2.py +52 -0
- elements_api-2025.11.4/src/py/elements_api/models/tile_pb2.pyi +77 -0
- elements_api-2025.11.4/src/py/elements_api/models/toi_pb2.py +67 -0
- elements_api-2025.11.4/src/py/elements_api/models/toi_pb2.pyi +138 -0
- elements_api-2025.11.4/src/py/elements_api/models/token_pb2.py +42 -0
- elements_api-2025.11.4/src/py/elements_api/models/token_pb2.pyi +23 -0
- elements_api-2025.11.4/src/py/elements_api/models/user_collection_pb2.py +78 -0
- elements_api-2025.11.4/src/py/elements_api/models/user_collection_pb2.pyi +172 -0
- elements_api-2025.11.4/src/py/elements_api/models/user_pb2.py +86 -0
- elements_api-2025.11.4/src/py/elements_api/models/user_pb2.pyi +183 -0
- elements_api-2025.11.4/src/py/elements_api/models/visualization_pb2.py +70 -0
- elements_api-2025.11.4/src/py/elements_api/models/visualization_pb2.pyi +187 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/__init__.py +47 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/algorithm_computation_execution_pb2_grpc.py +111 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/algorithm_computation_pb2_grpc.py +251 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/algorithm_config_pb2_grpc.py +377 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/algorithm_manifest_pb2_grpc.py +99 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/algorithm_pb2_grpc.py +239 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/algorithm_version_pb2_grpc.py +336 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/analysis_computation_pb2_grpc.py +239 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/analysis_config_pb2_grpc.py +283 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/analysis_pb2_grpc.py +192 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/analysis_version_pb2_grpc.py +198 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/aoi_catalog_pb2_grpc.py +273 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/aoi_collection_pb2_grpc.py +327 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/aoi_export_pb2_grpc.py +144 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/aoi_pb2_grpc.py +241 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/aoi_transaction_pb2_grpc.py +145 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/aoi_version_pb2_grpc.py +192 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/common_models_pb2_grpc.py +24 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/credit_pb2_grpc.py +418 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/data_source_pb2_grpc.py +144 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/data_tracking_pb2_grpc.py +140 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/data_type_pb2_grpc.py +189 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/filter_pb2_grpc.py +234 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/forgot_password_pb2_grpc.py +100 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/notification_pb2_grpc.py +414 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/order_pb2_grpc.py +279 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/order_recommendation_pb2_grpc.py +183 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/permission_pb2_grpc.py +282 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_analysis_config_pb2_grpc.py +99 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_aoi_pb2_grpc.py +279 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_collaborator_pb2_grpc.py +189 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_filter_pb2_grpc.py +144 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_group_pb2_grpc.py +234 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_pb2_grpc.py +504 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/project_result_pb2_grpc.py +234 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/provider_quotas_pb2_grpc.py +99 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/resource_pb2_grpc.py +228 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/result_pb2_grpc.py +99 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/s3_pb2_grpc.py +99 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/subject_pb2_grpc.py +24 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/system_pb2_grpc.py +142 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/tasking_order_pb2_grpc.py +279 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/tile_pb2_grpc.py +99 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/toi_pb2_grpc.py +281 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/token_pb2_grpc.py +100 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/user_collection_pb2_grpc.py +370 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/user_pb2_grpc.py +559 -0
- elements_api-2025.11.4/src/py/elements_api/stubs/visualization_pb2_grpc.py +234 -0
- elements_api-2025.11.4/src/py/elements_api/sync_client.py +34 -0
- elements_api-2025.11.4/src/py/elements_api.egg-info/PKG-INFO +11 -0
- elements_api-2025.11.4/src/py/elements_api.egg-info/SOURCES.txt +157 -0
- elements_api-2025.11.4/src/py/elements_api.egg-info/dependency_links.txt +1 -0
- elements_api-2025.11.4/src/py/elements_api.egg-info/requires.txt +3 -0
- elements_api-2025.11.4/src/py/elements_api.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2022 Orbital Insight, Inc.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: elements-api
|
|
3
|
+
Version: 2025.11.4
|
|
4
|
+
Summary: Elements API Client
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Dist: grpcio
|
|
7
|
+
Requires-Dist: grpcio-status
|
|
8
|
+
Requires-Dist: requests
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
Dynamic: requires-dist
|
|
11
|
+
Dynamic: summary
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Orbital Insight Platform API (OI Papi)
|
|
2
|
+
|
|
3
|
+
PAPI (Platform API) is the gateway to Orbital Insight's Terra platform. PAPI provides a single, unified API for developers to build geospatial analytics solutions tailed to their specific domains. PAPI provides both gRPC and HTTP Rest endpoints.
|
|
4
|
+
|
|
5
|
+
For more information about PAPI endpoints please refer to the [API documentation](https://sphinx.core3.orbitalinsight.io/oi_papi/latest/api-docs/).
|
|
6
|
+
|
|
7
|
+
If you are developer of PAPI itself, please refer to the [Local Setup and Testing](docs/local_setup_and_testing.md) document to get started.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A setuptools based setup module.
|
|
3
|
+
Based on:
|
|
4
|
+
https://packaging.python.org/en/latest/distributing.html
|
|
5
|
+
https://github.com/pypa/sampleproject
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
import setuptools # type: ignore
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_version(version_file_loc):
|
|
13
|
+
with open(version_file_loc, 'r') as stream:
|
|
14
|
+
data = yaml.load(stream, yaml.SafeLoader)
|
|
15
|
+
return (data.get('version'))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
setuptools.setup(
|
|
19
|
+
name='elements-api',
|
|
20
|
+
version=get_version('ops/conda-recipe/conda_build_config.yaml'),
|
|
21
|
+
description='Elements API Client',
|
|
22
|
+
package_dir={'': 'src/py'},
|
|
23
|
+
packages=setuptools.find_packages('src/py', exclude=[
|
|
24
|
+
'mocked_services',
|
|
25
|
+
'oi_papi',
|
|
26
|
+
'oi_papi.*'
|
|
27
|
+
]),
|
|
28
|
+
install_requires=['grpcio', 'grpcio-status', 'requests']
|
|
29
|
+
)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Copyright 2017-2021 Orbital Insight Inc., all rights reserved.
|
|
2
|
+
# Contains confidential and trade secret information.
|
|
3
|
+
# Government Users: Commercial Computer Software - Use governed by
|
|
4
|
+
# terms of Orbital Insight commercial license agreement.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from elements_api.sync_client import ElementsSyncClient # noqa
|
|
8
|
+
from elements_api.async_client import ElementsAsyncClient # noqa
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright 2017-2021 Orbital Insight Inc., all rights reserved.
|
|
2
|
+
# Contains confidential and trade secret information.
|
|
3
|
+
# Government Users: Commercial Computer Software - Use governed by
|
|
4
|
+
# terms of Orbital Insight commercial license agreement.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import grpc
|
|
8
|
+
from elements_api.elements_base_api import ElementsBaseApi
|
|
9
|
+
from elements_api import models
|
|
10
|
+
from elements_api.async_interceptors import (
|
|
11
|
+
ContextInjectorUnaryUnary, ContextInjectorStreamUnary, ContextInjectorUnaryStream, ContextInjectorStreamStream
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ElementsAsyncClient:
|
|
16
|
+
def __init__(self, oi_papi_url, port=443, secure=True, api_token=None, root_certificates_file=None):
|
|
17
|
+
self.api = ElementsAsyncApi(oi_papi_url, port, secure, api_token=api_token,
|
|
18
|
+
root_certificates_file=root_certificates_file)
|
|
19
|
+
self.models = models
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ElementsAsyncApi(ElementsBaseApi):
|
|
23
|
+
def __init__(self, oi_papi_url, port=443, secure=True, api_token=None, root_certificates_file=None):
|
|
24
|
+
self.context_injecting_interceptors = [
|
|
25
|
+
# materialize distributed context from request headers
|
|
26
|
+
ContextInjectorUnaryUnary(), ContextInjectorUnaryStream(),
|
|
27
|
+
ContextInjectorStreamUnary(), ContextInjectorStreamStream()
|
|
28
|
+
]
|
|
29
|
+
super(ElementsAsyncApi, self).__init__(oi_papi_url, port, secure, api_token,
|
|
30
|
+
root_certificates_file)
|
|
31
|
+
|
|
32
|
+
def _get_channel(self, channel_credentials: grpc.ChannelCredentials):
|
|
33
|
+
token_creds = grpc.access_token_call_credentials(self.access_token)
|
|
34
|
+
creds = grpc.composite_channel_credentials(channel_credentials, token_creds)
|
|
35
|
+
return grpc.aio.secure_channel(f"{self._oi_papi_url}:{self._port}",
|
|
36
|
+
creds,
|
|
37
|
+
options=self.options,
|
|
38
|
+
compression=None,
|
|
39
|
+
interceptors=self.context_injecting_interceptors)
|
|
40
|
+
|
|
41
|
+
# TODO: async destructor
|
|
42
|
+
def __adel__(self):
|
|
43
|
+
self._channel.close()
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from typing import Callable, Union
|
|
3
|
+
|
|
4
|
+
import grpc
|
|
5
|
+
from grpc.aio import \
|
|
6
|
+
UnaryUnaryClientInterceptor, \
|
|
7
|
+
UnaryStreamClientInterceptor, \
|
|
8
|
+
StreamUnaryClientInterceptor, \
|
|
9
|
+
StreamStreamClientInterceptor, \
|
|
10
|
+
ClientCallDetails
|
|
11
|
+
from grpc.aio._call import \
|
|
12
|
+
UnaryUnaryCall, \
|
|
13
|
+
UnaryStreamCall, \
|
|
14
|
+
StreamUnaryCall, \
|
|
15
|
+
StreamStreamCall
|
|
16
|
+
|
|
17
|
+
from grpc.aio._typing import RequestType, ResponseIterableType, ResponseType, \
|
|
18
|
+
RequestIterableType
|
|
19
|
+
|
|
20
|
+
if importlib.util.find_spec('oi_tracing'):
|
|
21
|
+
from oi_tracing import inject_current_span
|
|
22
|
+
else:
|
|
23
|
+
def inject_current_span(_headers):
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
if importlib.util.find_spec('mercury_client'):
|
|
27
|
+
from mercury_client.context import context_as_dict
|
|
28
|
+
else:
|
|
29
|
+
def context_as_dict():
|
|
30
|
+
return {}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def inject_current_context_into_header(client_call_details: ClientCallDetails)\
|
|
34
|
+
-> ClientCallDetails:
|
|
35
|
+
|
|
36
|
+
if client_call_details.metadata is None: # grpc.aio._metadata.Metadata
|
|
37
|
+
client_call_details.metadata = grpc.aio._metadata.Metadata()
|
|
38
|
+
|
|
39
|
+
new_headers = context_as_dict()
|
|
40
|
+
# Remove any Auth headers and let this be controlled by Papi's token setting
|
|
41
|
+
for key in ('Authorization', 'X-Orbitalinsight-Auth-Token'):
|
|
42
|
+
new_headers.pop(key, None)
|
|
43
|
+
|
|
44
|
+
inject_current_span(new_headers)
|
|
45
|
+
# inject_current_auth(new_headers)
|
|
46
|
+
|
|
47
|
+
for k, v in new_headers.items():
|
|
48
|
+
client_call_details.metadata.add(k, str(v))
|
|
49
|
+
# todo not clear if it is safe to modify or a new copy needs to be made
|
|
50
|
+
# at this point returning modified original object
|
|
51
|
+
return client_call_details
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ContextInjectorUnaryUnary(UnaryUnaryClientInterceptor):
|
|
55
|
+
|
|
56
|
+
async def intercept_unary_unary(
|
|
57
|
+
self, continuation: Callable[[ClientCallDetails, RequestType],
|
|
58
|
+
UnaryUnaryCall],
|
|
59
|
+
client_call_details: ClientCallDetails,
|
|
60
|
+
request: RequestType) \
|
|
61
|
+
-> Union[UnaryUnaryCall, ResponseType]:
|
|
62
|
+
new_details = inject_current_context_into_header(client_call_details)
|
|
63
|
+
response = continuation(new_details, request)
|
|
64
|
+
return await response
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class ContextInjectorUnaryStream(UnaryStreamClientInterceptor):
|
|
68
|
+
|
|
69
|
+
async def intercept_unary_stream(
|
|
70
|
+
self,
|
|
71
|
+
continuation: Callable[[ClientCallDetails, RequestType],
|
|
72
|
+
UnaryStreamCall],
|
|
73
|
+
client_call_details: ClientCallDetails,
|
|
74
|
+
request: RequestType) \
|
|
75
|
+
-> Union[ResponseIterableType, UnaryStreamCall]:
|
|
76
|
+
new_details = inject_current_context_into_header(client_call_details)
|
|
77
|
+
response = continuation(new_details, request)
|
|
78
|
+
return await response
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ContextInjectorStreamUnary(StreamUnaryClientInterceptor):
|
|
82
|
+
|
|
83
|
+
async def intercept_stream_unary(
|
|
84
|
+
self,
|
|
85
|
+
continuation: Callable[[ClientCallDetails, RequestType],
|
|
86
|
+
StreamUnaryCall],
|
|
87
|
+
client_call_details: ClientCallDetails,
|
|
88
|
+
request_iterator: RequestIterableType,
|
|
89
|
+
) -> StreamUnaryCall:
|
|
90
|
+
new_details = inject_current_context_into_header(client_call_details)
|
|
91
|
+
response = continuation(new_details, request_iterator)
|
|
92
|
+
return await response
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ContextInjectorStreamStream(StreamStreamClientInterceptor):
|
|
96
|
+
async def intercept_stream_stream(
|
|
97
|
+
self,
|
|
98
|
+
continuation: Callable[[ClientCallDetails, RequestType],
|
|
99
|
+
StreamStreamCall],
|
|
100
|
+
client_call_details: ClientCallDetails,
|
|
101
|
+
request_iterator: RequestIterableType,
|
|
102
|
+
) -> Union[ResponseIterableType, StreamStreamCall]:
|
|
103
|
+
new_details = inject_current_context_into_header(client_call_details)
|
|
104
|
+
response = continuation(new_details, request_iterator)
|
|
105
|
+
return await response
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# Copyright 2017-2021 Orbital Insight Inc., all rights reserved.
|
|
2
|
+
# Contains confidential and trade secret information.
|
|
3
|
+
# Government Users: Commercial Computer Software - Use governed by
|
|
4
|
+
# terms of Orbital Insight commercial license agreement.
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
import json
|
|
9
|
+
import time
|
|
10
|
+
import base64
|
|
11
|
+
from typing import Optional
|
|
12
|
+
from functools import lru_cache, wraps
|
|
13
|
+
import requests
|
|
14
|
+
|
|
15
|
+
import grpc
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
API_TOKEN = 'TERRASCOPE_API_TOKEN'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@lru_cache(maxsize=128)
|
|
22
|
+
def json_from_jwt(jwt_token: str) -> dict[str, object]:
|
|
23
|
+
# see also similar function in user svc client
|
|
24
|
+
# returns claims dict
|
|
25
|
+
try:
|
|
26
|
+
[_header, payload, _signature] = jwt_token.split('.')
|
|
27
|
+
payload_text = base64.b64decode(payload + "===", '-_')
|
|
28
|
+
payload_json = json.loads(payload_text)
|
|
29
|
+
return payload_json
|
|
30
|
+
except BaseException:
|
|
31
|
+
return {}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def is_token_expiring(jwt_token_str, within_secs=300) -> bool:
|
|
35
|
+
claims = json_from_jwt(jwt_token_str)
|
|
36
|
+
return claims.get('exp') < time.time() + within_secs
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def is_offline_token(jwt_token_str) -> bool:
|
|
40
|
+
claims = json_from_jwt(jwt_token_str)
|
|
41
|
+
return claims.get('typ') == 'Offline'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def check_access_token(func) -> bool:
|
|
45
|
+
# decorator
|
|
46
|
+
@wraps(func)
|
|
47
|
+
def wrapper(*args, **kwargs): # The instance is passed as the first argument
|
|
48
|
+
self = args[0]
|
|
49
|
+
# check if current access token is expired
|
|
50
|
+
self.refresh_access_token_and_recreate_stubs()
|
|
51
|
+
result = func(self)
|
|
52
|
+
return result
|
|
53
|
+
return wrapper
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ElementsBaseApi(ABC):
|
|
57
|
+
|
|
58
|
+
def __init__(self, oi_papi_url: str, port: int = 443, secure=True, api_token: str = None, root_certificates_file=None):
|
|
59
|
+
self._oi_papi_url = oi_papi_url
|
|
60
|
+
self._port = port
|
|
61
|
+
self._secure = secure
|
|
62
|
+
self._root_certificates_file = root_certificates_file
|
|
63
|
+
self._channel = None
|
|
64
|
+
self.api_token: Optional[str] = os.environ.get(API_TOKEN, "").strip() if api_token is None else api_token.strip()
|
|
65
|
+
|
|
66
|
+
# check if this is an offline token, which is a refresh token, and obtain access tokens from it periodically
|
|
67
|
+
self.is_offline_token: bool = is_offline_token(self.api_token)
|
|
68
|
+
self.access_token: Optional[str] = self.api_token if not is_offline_token else None
|
|
69
|
+
self.access_token_expiration_threshold = int(os.getenv('ACCESS_TOKEN_EXPIRATION_THRESHOLD', '300'))
|
|
70
|
+
# (token will be renewed when it has less than this threshhold before expiry)
|
|
71
|
+
self.options = [('grpc.max_send_message_length', -1),
|
|
72
|
+
('grpc.max_receive_message_length', -1),
|
|
73
|
+
('grpc.max_metadata_size', 16000)]
|
|
74
|
+
service_config_json: str = json.dumps({
|
|
75
|
+
"methodConfig": [{
|
|
76
|
+
"name": [{}], # Apply retry to all methods by using [{}]
|
|
77
|
+
"retryPolicy": {
|
|
78
|
+
"maxAttempts": 5,
|
|
79
|
+
"initialBackoff": "1.0s",
|
|
80
|
+
"maxBackoff": "60s",
|
|
81
|
+
"backoffMultiplier": 2,
|
|
82
|
+
"retryableStatusCodes": ["UNAVAILABLE"],
|
|
83
|
+
},
|
|
84
|
+
}]
|
|
85
|
+
})
|
|
86
|
+
self.options.append(("grpc.service_config", service_config_json))
|
|
87
|
+
|
|
88
|
+
self.refresh_access_token()
|
|
89
|
+
self.new_channel()
|
|
90
|
+
self.recreate_stubs()
|
|
91
|
+
|
|
92
|
+
def recreate_stubs(self):
|
|
93
|
+
from elements_api import stubs
|
|
94
|
+
# unauthenticated users can access forgot_password
|
|
95
|
+
self._forgot_password = stubs.forgot_password.ForgotPasswordApiStub(self._channel)
|
|
96
|
+
|
|
97
|
+
if self.api_token:
|
|
98
|
+
self._algorithm = stubs.algorithm.AlgorithmApiStub(self._channel)
|
|
99
|
+
self._algorithm_version = stubs.algorithm_version.AlgorithmVersionApiStub(self._channel)
|
|
100
|
+
self._algorithm_config = stubs.algorithm_config.AlgorithmConfigApiStub(self._channel)
|
|
101
|
+
self._aoi = stubs.aoi.AOIApiStub(self._channel)
|
|
102
|
+
self._aoi_collection = stubs.aoi_collection.AOICollectionApiStub(self._channel)
|
|
103
|
+
self._aoi_version = stubs.aoi_version.AOIVersionApiStub(self._channel)
|
|
104
|
+
self._aoi_catalog = stubs.aoi_catalog.AOICatalogApiStub(self._channel)
|
|
105
|
+
self._aoi_transaction = stubs.aoi_transaction.AOITransactionApiStub(self._channel)
|
|
106
|
+
self._aoi_export = stubs.aoi_export.AOIExportApiStub(self._channel)
|
|
107
|
+
self._algorithm_computation = stubs.algorithm_computation.AlgorithmComputationApiStub(self._channel)
|
|
108
|
+
self._algorithm_computation_execution = \
|
|
109
|
+
stubs.algorithm_computation_execution.AlgorithmComputationExecutionApiStub(self._channel)
|
|
110
|
+
self._analysis = stubs.analysis.AnalysisApiStub(self._channel)
|
|
111
|
+
self._analysis_version = stubs.analysis_version.AnalysisVersionApiStub(self._channel)
|
|
112
|
+
self._credit = stubs.credit.CreditApiStub(self._channel)
|
|
113
|
+
self._result = stubs.result.ResultApiStub(self._channel)
|
|
114
|
+
self._analysis_config = stubs.analysis_config.AnalysisConfigApiStub(self._channel)
|
|
115
|
+
self._analysis_computation = stubs.analysis_computation.AnalysisComputationApiStub(self._channel)
|
|
116
|
+
self._system = stubs.system.SystemApiStub(self._channel)
|
|
117
|
+
self._toi = stubs.toi.TOIApiStub(self._channel)
|
|
118
|
+
self._permission = stubs.permission.PermissionApiStub(self._channel)
|
|
119
|
+
self._user = stubs.user.UserApiStub(self._channel)
|
|
120
|
+
self._user_collection = stubs.user_collection.UserCollectionApiStub(self._channel)
|
|
121
|
+
self._token = stubs.token.TokenApiStub(self._channel)
|
|
122
|
+
self._visualization = stubs.visualization.VisualizationApiStub(self._channel)
|
|
123
|
+
self._tile = stubs.tile.TileApiStub(self._channel)
|
|
124
|
+
self._notification = stubs.notification.NotificationApiStub(self._channel)
|
|
125
|
+
self._data_source = stubs.data_source.DataSourceAPIStub(self._channel)
|
|
126
|
+
self._data_type = stubs.data_type.DataTypeAPIStub(self._channel)
|
|
127
|
+
self._data_tracking = stubs.data_tracking.DataTrackingApiStub(self._channel)
|
|
128
|
+
self._project = stubs.project.ProjectApiStub(self._channel)
|
|
129
|
+
self._project_analysis_config = stubs.project_analysis_config.ProjectAnalysisConfigApiStub(self._channel)
|
|
130
|
+
self._project_collaborator = stubs.project_collaborator.ProjectCollaboratorApiStub(self._channel)
|
|
131
|
+
self._project_group = stubs.project_group.ProjectGroupApiStub(self._channel)
|
|
132
|
+
self._project_result = stubs.project_result.ProjectResultApiStub(self._channel)
|
|
133
|
+
self._project_filter = stubs.project_filter.ProjectFilterApiStub(self._channel)
|
|
134
|
+
self._filter = stubs.filter.FilterApiStub(self._channel)
|
|
135
|
+
self._project_aoi = stubs.project_aoi.ProjectAOIApiStub(self._channel)
|
|
136
|
+
self._order = stubs.order.OrderApiStub(self._channel)
|
|
137
|
+
self._order_recommendation = stubs.order_recommendation.OrderRecommendationApiStub(self._channel)
|
|
138
|
+
self._tasking_order = stubs.tasking_order.TaskingOrderApiStub(self._channel)
|
|
139
|
+
self._provider_quotas = stubs.provider_quotas.ProviderQuotasApiStub(self._channel)
|
|
140
|
+
self._resource = stubs.resource.ResourceApiStub(self._channel)
|
|
141
|
+
self._s3 = stubs.s3.S3ApiStub(self._channel)
|
|
142
|
+
|
|
143
|
+
def new_channel(self):
|
|
144
|
+
# if self._channel is not None:
|
|
145
|
+
# self._channel.close() # todo this is async, and channel.__del__ takes care of it
|
|
146
|
+
self._channel = self._get_channel(
|
|
147
|
+
self._get_ssl_channel_credentials(
|
|
148
|
+
self._secure,
|
|
149
|
+
root_certificates_file=self._root_certificates_file))
|
|
150
|
+
return self._channel
|
|
151
|
+
|
|
152
|
+
def refresh_access_token(self) -> bool:
|
|
153
|
+
"""
|
|
154
|
+
Refreshes the access token if it is expired.
|
|
155
|
+
returns True if the access token was refreshed, False otherwise.
|
|
156
|
+
"""
|
|
157
|
+
# check if current access token is expired
|
|
158
|
+
if self.api_token and not is_offline_token(self.api_token):
|
|
159
|
+
return False # in which case it is an access token, and it was not refreshed
|
|
160
|
+
# check expiration on the access_token
|
|
161
|
+
|
|
162
|
+
if self.access_token and not is_token_expiring(
|
|
163
|
+
self.access_token,
|
|
164
|
+
within_secs=self.access_token_expiration_threshold
|
|
165
|
+
):
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
oidc_base_url = os.getenv(
|
|
169
|
+
'OIDC_BASE_URL',
|
|
170
|
+
'https://keycloak.orbitalinsight.com')
|
|
171
|
+
oidc_realm = os.getenv('OIDC_REALM', 'elements')
|
|
172
|
+
oidc_token_endpoint = os.getenv(
|
|
173
|
+
'OIDC_TOKEN_ENDPOINT',
|
|
174
|
+
f'{oidc_base_url}/realms/{oidc_realm}/protocol/openid-connect/token')
|
|
175
|
+
|
|
176
|
+
# note: api token is an offline token, which is a special refresh token.
|
|
177
|
+
oidc_client_id = os.getenv('OIDC_CLIENT_ID', 'login-ui')
|
|
178
|
+
oidc_client_secret = os.getenv('OIDC_CLIENT_SECRET')
|
|
179
|
+
|
|
180
|
+
request_json = {
|
|
181
|
+
'refresh_token': self.api_token,
|
|
182
|
+
'client_id': oidc_client_id,
|
|
183
|
+
'grant_type': 'refresh_token',
|
|
184
|
+
'scope': 'openid offline_access'
|
|
185
|
+
}
|
|
186
|
+
if oidc_client_secret:
|
|
187
|
+
request_json['client_secret'] = oidc_client_secret
|
|
188
|
+
|
|
189
|
+
response = requests.post(
|
|
190
|
+
oidc_token_endpoint,
|
|
191
|
+
data=request_json,
|
|
192
|
+
headers={'Content-Type': 'application/x-www-form-urlencoded'})
|
|
193
|
+
if not response.ok:
|
|
194
|
+
raise Exception(f"Failed to refresh token: {response.text}")
|
|
195
|
+
|
|
196
|
+
self.access_token = response.json().get('access_token')
|
|
197
|
+
return True
|
|
198
|
+
|
|
199
|
+
def refresh_access_token_and_recreate_stubs(self) -> bool:
|
|
200
|
+
# check if current access token is expired
|
|
201
|
+
if not self.refresh_access_token():
|
|
202
|
+
return False
|
|
203
|
+
self.new_channel()
|
|
204
|
+
self.recreate_stubs()
|
|
205
|
+
return True
|
|
206
|
+
# individual api accessors are properties, since underlying channel may need to change
|
|
207
|
+
# at any time due to its token change. Do not store property result in a variable,
|
|
208
|
+
# as it will not be refreshed automatically when the token changes
|
|
209
|
+
# token freshness is checked in every call, then if it expired and changed,
|
|
210
|
+
# (all) stubs are regenerated. A new channel is created with that token in each stub
|
|
211
|
+
|
|
212
|
+
@property
|
|
213
|
+
@check_access_token
|
|
214
|
+
def forgot_password(self):
|
|
215
|
+
return self._forgot_password
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
@check_access_token
|
|
219
|
+
def algorithm(self):
|
|
220
|
+
return self._algorithm
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
@check_access_token
|
|
224
|
+
def algorithm_version(self):
|
|
225
|
+
return self._algorithm_version
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
@check_access_token
|
|
229
|
+
def algorithm_config(self):
|
|
230
|
+
return self._algorithm_config
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
@check_access_token
|
|
234
|
+
def aoi(self):
|
|
235
|
+
return self._aoi
|
|
236
|
+
|
|
237
|
+
@property
|
|
238
|
+
@check_access_token
|
|
239
|
+
def aoi_collection(self):
|
|
240
|
+
return self._aoi_collection
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
@check_access_token
|
|
244
|
+
def aoi_version(self):
|
|
245
|
+
return self._aoi_version
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
@check_access_token
|
|
249
|
+
def aoi_catalog(self):
|
|
250
|
+
return self._aoi_catalog
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
@check_access_token
|
|
254
|
+
def aoi_transaction(self):
|
|
255
|
+
return self._aoi_transaction
|
|
256
|
+
|
|
257
|
+
@property
|
|
258
|
+
@check_access_token
|
|
259
|
+
def aoi_export(self):
|
|
260
|
+
return self._aoi_export
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
@check_access_token
|
|
264
|
+
def algorithm_computation(self):
|
|
265
|
+
return self._algorithm_computation
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
@check_access_token
|
|
269
|
+
def algorithm_computation_execution(self):
|
|
270
|
+
return self._algorithm_computation_execution
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
@check_access_token
|
|
274
|
+
def analysis(self):
|
|
275
|
+
return self._analysis
|
|
276
|
+
|
|
277
|
+
@property
|
|
278
|
+
@check_access_token
|
|
279
|
+
def analysis_version(self):
|
|
280
|
+
return self._analysis_version
|
|
281
|
+
|
|
282
|
+
@property
|
|
283
|
+
@check_access_token
|
|
284
|
+
def credit(self):
|
|
285
|
+
return self._credit
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
@check_access_token
|
|
289
|
+
def result(self):
|
|
290
|
+
return self._result
|
|
291
|
+
|
|
292
|
+
@property
|
|
293
|
+
@check_access_token
|
|
294
|
+
def analysis_config(self):
|
|
295
|
+
return self._analysis_config
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
@check_access_token
|
|
299
|
+
def analysis_computation(self):
|
|
300
|
+
return self._analysis_computation
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
@check_access_token
|
|
304
|
+
def system(self):
|
|
305
|
+
return self._system
|
|
306
|
+
|
|
307
|
+
@property
|
|
308
|
+
@check_access_token
|
|
309
|
+
def toi(self):
|
|
310
|
+
return self._toi
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
@check_access_token
|
|
314
|
+
def permission(self):
|
|
315
|
+
return self._permission
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
@check_access_token
|
|
319
|
+
def user(self):
|
|
320
|
+
return self._user
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
@check_access_token
|
|
324
|
+
def user_collection(self):
|
|
325
|
+
return self._user_collection
|
|
326
|
+
|
|
327
|
+
@property
|
|
328
|
+
@check_access_token
|
|
329
|
+
def token(self):
|
|
330
|
+
return self._token
|
|
331
|
+
|
|
332
|
+
@property
|
|
333
|
+
@check_access_token
|
|
334
|
+
def visualization(self):
|
|
335
|
+
return self._visualization
|
|
336
|
+
|
|
337
|
+
@property
|
|
338
|
+
@check_access_token
|
|
339
|
+
def tile(self):
|
|
340
|
+
return self._tile
|
|
341
|
+
|
|
342
|
+
@property
|
|
343
|
+
@check_access_token
|
|
344
|
+
def notification(self):
|
|
345
|
+
return self._notification
|
|
346
|
+
|
|
347
|
+
@property
|
|
348
|
+
@check_access_token
|
|
349
|
+
def data_source(self):
|
|
350
|
+
return self._data_source
|
|
351
|
+
|
|
352
|
+
@property
|
|
353
|
+
@check_access_token
|
|
354
|
+
def data_type(self):
|
|
355
|
+
return self._data_type
|
|
356
|
+
|
|
357
|
+
@property
|
|
358
|
+
@check_access_token
|
|
359
|
+
def data_tracking(self):
|
|
360
|
+
return self._data_tracking
|
|
361
|
+
|
|
362
|
+
@property
|
|
363
|
+
@check_access_token
|
|
364
|
+
def project(self):
|
|
365
|
+
return self._project
|
|
366
|
+
|
|
367
|
+
@property
|
|
368
|
+
@check_access_token
|
|
369
|
+
def project_analysis_config(self):
|
|
370
|
+
return self._project_analysis_config
|
|
371
|
+
|
|
372
|
+
@property
|
|
373
|
+
@check_access_token
|
|
374
|
+
def project_collaborator(self):
|
|
375
|
+
return self._project_collaborator
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
@check_access_token
|
|
379
|
+
def project_group(self):
|
|
380
|
+
return self._project_group
|
|
381
|
+
|
|
382
|
+
@property
|
|
383
|
+
@check_access_token
|
|
384
|
+
def project_result(self):
|
|
385
|
+
return self._project_result
|
|
386
|
+
|
|
387
|
+
@property
|
|
388
|
+
@check_access_token
|
|
389
|
+
def project_filter(self):
|
|
390
|
+
return self._project_filter
|
|
391
|
+
|
|
392
|
+
@property
|
|
393
|
+
@check_access_token
|
|
394
|
+
def filter(self):
|
|
395
|
+
return self._filter
|
|
396
|
+
|
|
397
|
+
@property
|
|
398
|
+
@check_access_token
|
|
399
|
+
def project_aoi(self):
|
|
400
|
+
return self._project_aoi
|
|
401
|
+
|
|
402
|
+
@property
|
|
403
|
+
@check_access_token
|
|
404
|
+
def order(self):
|
|
405
|
+
return self._order
|
|
406
|
+
|
|
407
|
+
@property
|
|
408
|
+
@check_access_token
|
|
409
|
+
def order_recommendation(self):
|
|
410
|
+
return self._order_recommendation
|
|
411
|
+
|
|
412
|
+
@property
|
|
413
|
+
@check_access_token
|
|
414
|
+
def tasking_order(self):
|
|
415
|
+
return self._tasking_order
|
|
416
|
+
|
|
417
|
+
@property
|
|
418
|
+
@check_access_token
|
|
419
|
+
def provider_quotas(self):
|
|
420
|
+
return self._provider_quotas
|
|
421
|
+
|
|
422
|
+
@property
|
|
423
|
+
@check_access_token
|
|
424
|
+
def provider(self):
|
|
425
|
+
return self._provider
|
|
426
|
+
|
|
427
|
+
@property
|
|
428
|
+
@check_access_token
|
|
429
|
+
def resource(self):
|
|
430
|
+
return self._resource
|
|
431
|
+
|
|
432
|
+
@property
|
|
433
|
+
@check_access_token
|
|
434
|
+
def s3(self):
|
|
435
|
+
return self._s3
|
|
436
|
+
|
|
437
|
+
def _get_ssl_channel_credentials(self, secure, root_certificates_file=None):
|
|
438
|
+
# note: with all defaults, gRPC will search for cert as described here:
|
|
439
|
+
# https://github.com/grpc/grpc/blob/7a63bd5407d5e14b30f19a5aaf4b6cd1b80f00e1/include/grpc/grpc_security.h#L287
|
|
440
|
+
# for local env, use local_channel_credentials:
|
|
441
|
+
# https://grpc.github.io/grpc/python/grpc.html#grpc.local_channel_credentials
|
|
442
|
+
if secure:
|
|
443
|
+
root_certificates = None
|
|
444
|
+
if root_certificates_file:
|
|
445
|
+
with open(root_certificates_file, 'rb') as file:
|
|
446
|
+
root_certificates = file.read()
|
|
447
|
+
|
|
448
|
+
return grpc.ssl_channel_credentials(root_certificates=root_certificates,
|
|
449
|
+
private_key=None, certificate_chain=None)
|
|
450
|
+
return grpc.local_channel_credentials()
|
|
451
|
+
|
|
452
|
+
@abstractmethod
|
|
453
|
+
def _get_channel(self, channel_credentials: grpc.ChannelCredentials):
|
|
454
|
+
...
|