scale-nucleus 0.1.24__py3-none-any.whl → 0.6.4__py3-none-any.whl

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.
Files changed (73) hide show
  1. cli/client.py +14 -0
  2. cli/datasets.py +77 -0
  3. cli/helpers/__init__.py +0 -0
  4. cli/helpers/nucleus_url.py +10 -0
  5. cli/helpers/web_helper.py +40 -0
  6. cli/install_completion.py +33 -0
  7. cli/jobs.py +42 -0
  8. cli/models.py +35 -0
  9. cli/nu.py +42 -0
  10. cli/reference.py +8 -0
  11. cli/slices.py +62 -0
  12. cli/tests.py +121 -0
  13. nucleus/__init__.py +446 -710
  14. nucleus/annotation.py +405 -85
  15. nucleus/autocurate.py +9 -0
  16. nucleus/connection.py +87 -0
  17. nucleus/constants.py +5 -1
  18. nucleus/data_transfer_object/__init__.py +0 -0
  19. nucleus/data_transfer_object/dataset_details.py +9 -0
  20. nucleus/data_transfer_object/dataset_info.py +26 -0
  21. nucleus/data_transfer_object/dataset_size.py +5 -0
  22. nucleus/data_transfer_object/scenes_list.py +18 -0
  23. nucleus/dataset.py +1137 -212
  24. nucleus/dataset_item.py +130 -26
  25. nucleus/dataset_item_uploader.py +297 -0
  26. nucleus/deprecation_warning.py +32 -0
  27. nucleus/errors.py +9 -0
  28. nucleus/job.py +71 -3
  29. nucleus/logger.py +9 -0
  30. nucleus/metadata_manager.py +45 -0
  31. nucleus/metrics/__init__.py +10 -0
  32. nucleus/metrics/base.py +117 -0
  33. nucleus/metrics/categorization_metrics.py +197 -0
  34. nucleus/metrics/errors.py +7 -0
  35. nucleus/metrics/filters.py +40 -0
  36. nucleus/metrics/geometry.py +198 -0
  37. nucleus/metrics/metric_utils.py +28 -0
  38. nucleus/metrics/polygon_metrics.py +480 -0
  39. nucleus/metrics/polygon_utils.py +299 -0
  40. nucleus/model.py +121 -15
  41. nucleus/model_run.py +34 -57
  42. nucleus/payload_constructor.py +29 -19
  43. nucleus/prediction.py +259 -17
  44. nucleus/pydantic_base.py +26 -0
  45. nucleus/retry_strategy.py +4 -0
  46. nucleus/scene.py +204 -19
  47. nucleus/slice.py +230 -67
  48. nucleus/upload_response.py +20 -9
  49. nucleus/url_utils.py +4 -0
  50. nucleus/utils.py +134 -37
  51. nucleus/validate/__init__.py +24 -0
  52. nucleus/validate/client.py +168 -0
  53. nucleus/validate/constants.py +20 -0
  54. nucleus/validate/data_transfer_objects/__init__.py +0 -0
  55. nucleus/validate/data_transfer_objects/eval_function.py +81 -0
  56. nucleus/validate/data_transfer_objects/scenario_test.py +19 -0
  57. nucleus/validate/data_transfer_objects/scenario_test_evaluations.py +11 -0
  58. nucleus/validate/data_transfer_objects/scenario_test_metric.py +12 -0
  59. nucleus/validate/errors.py +6 -0
  60. nucleus/validate/eval_functions/__init__.py +0 -0
  61. nucleus/validate/eval_functions/available_eval_functions.py +212 -0
  62. nucleus/validate/eval_functions/base_eval_function.py +60 -0
  63. nucleus/validate/scenario_test.py +143 -0
  64. nucleus/validate/scenario_test_evaluation.py +114 -0
  65. nucleus/validate/scenario_test_metric.py +14 -0
  66. nucleus/validate/utils.py +8 -0
  67. {scale_nucleus-0.1.24.dist-info → scale_nucleus-0.6.4.dist-info}/LICENSE +0 -0
  68. scale_nucleus-0.6.4.dist-info/METADATA +213 -0
  69. scale_nucleus-0.6.4.dist-info/RECORD +71 -0
  70. {scale_nucleus-0.1.24.dist-info → scale_nucleus-0.6.4.dist-info}/WHEEL +1 -1
  71. scale_nucleus-0.6.4.dist-info/entry_points.txt +3 -0
  72. scale_nucleus-0.1.24.dist-info/METADATA +0 -85
  73. scale_nucleus-0.1.24.dist-info/RECORD +0 -21
nucleus/connection.py ADDED
@@ -0,0 +1,87 @@
1
+ import time
2
+
3
+ import requests
4
+
5
+ from .constants import DEFAULT_NETWORK_TIMEOUT_SEC
6
+ from .errors import NucleusAPIError
7
+ from .logger import logger
8
+ from .retry_strategy import RetryStrategy
9
+
10
+
11
+ class Connection:
12
+ """Wrapper of HTTP requests to the Nucleus endpoint."""
13
+
14
+ def __init__(self, api_key: str, endpoint: str = None):
15
+ self.api_key = api_key
16
+ self.endpoint = endpoint
17
+
18
+ def __repr__(self):
19
+ return (
20
+ f"Connection(api_key='{self.api_key}', endpoint='{self.endpoint}')"
21
+ )
22
+
23
+ def __eq__(self, other):
24
+ return (
25
+ self.api_key == other.api_key and self.endpoint == other.endpoint
26
+ )
27
+
28
+ def delete(self, route: str):
29
+ return self.make_request({}, route, requests_command=requests.delete)
30
+
31
+ def get(self, route: str):
32
+ return self.make_request({}, route, requests_command=requests.get)
33
+
34
+ def post(self, payload: dict, route: str):
35
+ return self.make_request(
36
+ payload, route, requests_command=requests.post
37
+ )
38
+
39
+ def put(self, payload: dict, route: str):
40
+ return self.make_request(payload, route, requests_command=requests.put)
41
+
42
+ def make_request(
43
+ self, payload: dict, route: str, requests_command=requests.post
44
+ ) -> dict:
45
+ """
46
+ Makes a request to Nucleus endpoint and logs a warning if not
47
+ successful.
48
+
49
+ :param payload: given payload
50
+ :param route: route for the request
51
+ :param requests_command: requests.post, requests.get, requests.delete
52
+ :return: response JSON
53
+ """
54
+ endpoint = f"{self.endpoint}/{route}"
55
+
56
+ logger.info("Make request to %s", endpoint)
57
+
58
+ for retry_wait_time in RetryStrategy.sleep_times:
59
+ response = requests_command(
60
+ endpoint,
61
+ json=payload,
62
+ headers={"Content-Type": "application/json"},
63
+ auth=(self.api_key, ""),
64
+ timeout=DEFAULT_NETWORK_TIMEOUT_SEC,
65
+ )
66
+ logger.info(
67
+ "API request has response code %s", response.status_code
68
+ )
69
+ if response.status_code not in RetryStrategy.statuses:
70
+ break
71
+ time.sleep(retry_wait_time)
72
+
73
+ if not response.ok:
74
+ self.handle_bad_response(endpoint, requests_command, response)
75
+
76
+ return response.json()
77
+
78
+ def handle_bad_response(
79
+ self,
80
+ endpoint,
81
+ requests_command,
82
+ requests_response=None,
83
+ aiohttp_response=None,
84
+ ):
85
+ raise NucleusAPIError(
86
+ endpoint, requests_command, requests_response, aiohttp_response
87
+ )
nucleus/constants.py CHANGED
@@ -3,6 +3,7 @@ ANNOTATIONS_KEY = "annotations"
3
3
  ANNOTATIONS_PROCESSED_KEY = "annotations_processed"
4
4
  ANNOTATION_ID_KEY = "annotation_id"
5
5
  ANNOTATION_METADATA_SCHEMA_KEY = "annotation_metadata_schema"
6
+ BACKFILL_JOB_KEY = "backfill_job"
6
7
  BOX_TYPE = "box"
7
8
  POLYGON_TYPE = "polygon"
8
9
  MASK_TYPE = "mask"
@@ -16,6 +17,7 @@ ANNOTATION_TYPES = (
16
17
  SEGMENTATION_TYPE,
17
18
  CUBOID_TYPE,
18
19
  CATEGORY_TYPE,
20
+ MULTICATEGORY_TYPE,
19
21
  )
20
22
  ANNOTATION_UPDATE_KEY = "update"
21
23
  AUTOTAGS_KEY = "autotags"
@@ -27,6 +29,8 @@ CONFIDENCE_KEY = "confidence"
27
29
  CX_KEY = "cx"
28
30
  CY_KEY = "cy"
29
31
  DATASET_ID_KEY = "dataset_id"
32
+ DATASET_IS_SCENE_KEY = "is_scene"
33
+ DATASET_ITEM_ID_KEY = "dataset_item_id"
30
34
  DATASET_LENGTH_KEY = "length"
31
35
  DATASET_MODEL_RUNS_KEY = "model_run_ids"
32
36
  DATASET_NAME_KEY = "name"
@@ -46,6 +50,7 @@ FY_KEY = "fy"
46
50
  GEOMETRY_KEY = "geometry"
47
51
  HEADING_KEY = "heading"
48
52
  HEIGHT_KEY = "height"
53
+ ID_KEY = "id"
49
54
  IGNORED_ITEMS = "ignored_items"
50
55
  IMAGE_KEY = "image"
51
56
  IMAGE_LOCATION_KEY = "image_location"
@@ -54,7 +59,6 @@ INDEX_KEY = "index"
54
59
  INDEX_CONTINUOUS_ENABLE_KEY = "enable"
55
60
  ITEMS_KEY = "items"
56
61
  ITEM_KEY = "item"
57
- ITEMS_KEY = "items"
58
62
  ITEM_METADATA_SCHEMA_KEY = "item_metadata_schema"
59
63
  JOB_ID_KEY = "job_id"
60
64
  KEEP_HISTORY_KEY = "keep_history"
File without changes
@@ -0,0 +1,9 @@
1
+ from nucleus.pydantic_base import DictCompatibleModel
2
+
3
+
4
+ class DatasetDetails(DictCompatibleModel):
5
+ """Pydantic model to parse DatasetDetails response from JSON"""
6
+
7
+ id: str
8
+ name: str
9
+ is_public: bool
@@ -0,0 +1,26 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from nucleus.pydantic_base import DictCompatibleModel
4
+
5
+
6
+ class DatasetInfo(DictCompatibleModel):
7
+ """High-level :class:`Dataset` information
8
+
9
+ Attributes:
10
+ dataset_id: Nucleus-generated dataset ID
11
+ name: User-defined name of dataset
12
+ length: Number of :class:`DatasetItem` in :class:`Dataset`
13
+ model_run_ids: (deprecated)
14
+ slice_ids: List :class:`Slice` IDs associated with the :class:`Dataset`
15
+ annotation_metadata_schema: Dict defining annotation-level metadata schema.
16
+ item_metadata_schema: Dict defining item metadata schema.
17
+ """
18
+
19
+ dataset_id: str
20
+ name: str
21
+ length: int
22
+ model_run_ids: List[str]
23
+ slice_ids: List[str]
24
+ # TODO: Expand the following into pydantic models to formalize schema
25
+ annotation_metadata_schema: Optional[Dict[str, Any]] = None
26
+ item_metadata_schema: Optional[Dict[str, Any]] = None
@@ -0,0 +1,5 @@
1
+ from nucleus.pydantic_base import DictCompatibleModel
2
+
3
+
4
+ class DatasetSize(DictCompatibleModel):
5
+ count: int
@@ -0,0 +1,18 @@
1
+ from typing import List, Optional
2
+
3
+ from nucleus.pydantic_base import DictCompatibleImmutableModel
4
+
5
+
6
+ class ScenesListEntry(DictCompatibleImmutableModel):
7
+ """/dataset/{dataset_id}/scenes_list nested payload"""
8
+
9
+ id: str
10
+ reference_id: str
11
+ type: str
12
+ metadata: Optional[dict] = {}
13
+
14
+
15
+ class ScenesList(DictCompatibleImmutableModel):
16
+ """/dataset/{dataset_id}/scenes_list payload"""
17
+
18
+ scenes: List[ScenesListEntry]