intersect-sdk 0.9.1__tar.gz → 0.9.3__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.
Files changed (36) hide show
  1. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/PKG-INFO +1 -1
  2. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/pyproject.toml +3 -2
  3. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/pydantic_schema_generator.py +53 -14
  4. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/README.md +0 -0
  5. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/__init__.py +0 -0
  6. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/__init__.py +0 -0
  7. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/constants.py +0 -0
  8. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/event_metadata.py +0 -0
  9. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/function_metadata.py +0 -0
  10. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/generic_serializer.py +0 -0
  11. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/interfaces.py +0 -0
  12. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/logger.py +0 -0
  13. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/schema.py +0 -0
  14. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/service_queue_name.py +0 -0
  15. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/status_metadata.py +0 -0
  16. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/stoppable_thread.py +0 -0
  17. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/_internal/utils.py +0 -0
  18. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/app_lifecycle.py +0 -0
  19. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/capability/__init__.py +0 -0
  20. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/capability/base.py +0 -0
  21. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/capability/universal_capability/__init__.py +0 -0
  22. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/capability/universal_capability/status.py +0 -0
  23. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/capability/universal_capability/universal_capability.py +0 -0
  24. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/client.py +0 -0
  25. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/client_callback_definitions.py +0 -0
  26. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/config/__init__.py +0 -0
  27. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/config/client.py +0 -0
  28. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/config/service.py +0 -0
  29. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/exceptions.py +0 -0
  30. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/py.typed +0 -0
  31. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/schema.py +0 -0
  32. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/service.py +0 -0
  33. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/service_callback_definitions.py +0 -0
  34. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/service_definitions.py +0 -0
  35. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/shared_callback_definitions.py +0 -0
  36. {intersect_sdk-0.9.1 → intersect_sdk-0.9.3}/src/intersect_sdk/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: intersect-sdk
3
- Version: 0.9.1
3
+ Version: 0.9.3
4
4
  Summary: Python SDK to interact with INTERSECT
5
5
  Keywords: intersect
6
6
  Author: Lance Drane, Marshall McDonnell, Seth Hitefield, Andrew Ayres, Gregory Cage, Jesse McGaha, Robert Smith, Gavin Wiggins, Michael Brim, Rick Archibald, Addi Malviya Thakur
@@ -14,7 +14,7 @@ authors = [
14
14
  { name = "Rick Archibald", email = "archibaldrk@ornl.gov" },
15
15
  { name = "Addi Malviya Thakur", email = "malviyaa@ornl.gov" },
16
16
  ]
17
- version = "0.9.1"
17
+ version = "0.9.3"
18
18
  readme = "README.md"
19
19
  license = { text = "BSD-3-Clause" }
20
20
  requires-python = ">=3.10,<4.0"
@@ -51,7 +51,8 @@ dev = [
51
51
  "codespell>=2.3.0",
52
52
  "pytest>=7.3.2",
53
53
  "pytest-cov>=4.1.0",
54
- "httpretty>=1.1.4",
54
+ "fastapi",
55
+ "uvicorn",
55
56
  ]
56
57
 
57
58
  [build-system]
@@ -3,6 +3,7 @@
3
3
  See: https://docs.pydantic.dev/latest/api/json_schema/#pydantic.json_schema.GenerateJsonSchema
4
4
  """
5
5
 
6
+ import collections
6
7
  from typing import (
7
8
  Any,
8
9
  )
@@ -10,14 +11,24 @@ from typing import (
10
11
  from jsonschema import Draft202012Validator as SchemaValidator
11
12
  from jsonschema import ValidationError as SchemaValidationError
12
13
  from jsonschema.validators import validator_for
13
- from pydantic import PydanticInvalidForJsonSchema, PydanticSchemaGenerationError, TypeAdapter
14
+ from pydantic import (
15
+ PydanticInvalidForJsonSchema,
16
+ PydanticSchemaGenerationError,
17
+ TypeAdapter,
18
+ )
14
19
  from pydantic.json_schema import (
15
20
  GenerateJsonSchema,
16
21
  JsonSchemaMode,
17
22
  JsonSchemaValue,
18
23
  )
19
24
  from pydantic.type_adapter import _type_has_config
20
- from pydantic_core import CoreSchema, PydanticSerializationError, core_schema, to_jsonable_python
25
+ from pydantic_core import (
26
+ CoreSchema,
27
+ PydanticSerializationError,
28
+ core_schema,
29
+ to_jsonable_python,
30
+ )
31
+ from referencing.exceptions import Unresolvable
21
32
 
22
33
 
23
34
  # build nested dictionary from list of keys. i.e. if keys = ['one', 'two', 'three']
@@ -73,7 +84,8 @@ def validate_schema(json_schema: Any) -> list[str]:
73
84
  # custom impl. of check_schema() , gather all errors instead of throwing on first error
74
85
  validator_cls = validator_for(SchemaValidator.META_SCHEMA, default=SchemaValidator)
75
86
  metavalidator: SchemaValidator = validator_cls(
76
- SchemaValidator.META_SCHEMA, format_checker=SchemaValidator.FORMAT_CHECKER
87
+ SchemaValidator.META_SCHEMA,
88
+ format_checker=SchemaValidator.FORMAT_CHECKER,
77
89
  )
78
90
  return [
79
91
  f'{error.json_path} : {error.message}' for error in metavalidator.iter_errors(json_schema)
@@ -120,7 +132,10 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
120
132
  ref_parts = self.ref_template.split('/')[1:-1]
121
133
  defs_schema = build_nested_dict(ref_parts, defs)
122
134
 
123
- for default, inner_schema in self.intersect_sdk_postgeneration_defaults:
135
+ for (
136
+ default,
137
+ inner_schema,
138
+ ) in self.intersect_sdk_postgeneration_defaults:
124
139
  final_schema = {**defs_schema, **inner_schema}
125
140
  try:
126
141
  validate_against_schema(final_schema, default)
@@ -146,7 +161,8 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
146
161
  The generated JSON schema.
147
162
  """
148
163
  return self.handle_invalid_for_json_schema(
149
- schema, 'Any or object : dynamic typing is not allowed for INTERSECT schemas'
164
+ schema,
165
+ 'Any or object : dynamic typing is not allowed for INTERSECT schemas',
150
166
  )
151
167
 
152
168
  def is_subclass_schema(self, schema: core_schema.IsSubclassSchema) -> JsonSchemaValue:
@@ -249,12 +265,14 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
249
265
  """
250
266
  if not schema.get('items_schema'):
251
267
  return self.handle_invalid_for_json_schema(
252
- schema, 'generator yield subtyping (first argument) may not be dynamic in INTERSECT'
268
+ schema,
269
+ 'generator yield subtyping (first argument) may not be dynamic in INTERSECT',
253
270
  )
254
271
  json_schema = super().generator_schema(schema)
255
272
  if not json_schema.get('items'):
256
273
  return self.handle_invalid_for_json_schema(
257
- schema, 'generator yield subtyping (first argument) may not be dynamic in INTERSECT'
274
+ schema,
275
+ 'generator yield subtyping (first argument) may not be dynamic in INTERSECT',
258
276
  )
259
277
  return json_schema
260
278
 
@@ -281,7 +299,8 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
281
299
  )
282
300
  if 'values_schema' not in schema:
283
301
  return self.handle_invalid_for_json_schema(
284
- schema, 'dict or mapping: value type cannot be Any/object for INTERSECT'
302
+ schema,
303
+ 'dict or mapping: value type cannot be Any/object for INTERSECT',
285
304
  )
286
305
  keys_schema = self.generate_inner(schema['keys_schema']).copy()
287
306
  values_schema = self.generate_inner(schema['values_schema']).copy()
@@ -343,6 +362,19 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
343
362
  return json_schema
344
363
  default = schema['default']
345
364
 
365
+ # Sort set/frozenset defaults to ensure deterministic JSON schema generation
366
+ # We only sort if len > 1 because sets of size 0 or 1 are already deterministic
367
+ if isinstance(default, collections.abc.Set) and len(default) > 1:
368
+ try:
369
+ default = sorted(default)
370
+ except TypeError:
371
+ # If items aren't comparable (e.g. mixed types), we can't sort them.
372
+ # Unlike Pydantic, we will actually raise an error here, as we want to force deterministic schema generation
373
+ err_msg = (
374
+ f'Do not use "{default}" as a default value: sets must contain the same types'
375
+ )
376
+ raise PydanticInvalidForJsonSchema(err_msg) # noqa: B904 (TypeError provides indirection)
377
+
346
378
  try:
347
379
  encoded_default = self.encode_default(default)
348
380
  except PydanticSerializationError:
@@ -352,17 +384,22 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
352
384
  f"Default value '{default}' is not JSON serializable; use pydantic.Field's 'default_factory' argument for this.",
353
385
  )
354
386
 
355
- if '$ref' in json_schema:
356
- # TODO - not best way to handle this
357
- # validate this default later, when all $refs have been resolved
358
- # IMPORTANT!!! You must send the "json_schema" object itself, it will be modified later internally by Pydantic
387
+ def postpone_default_validation(json_schema: Any, encoded_default: Any) -> dict[str, Any]:
359
388
  self.intersect_sdk_postgeneration_defaults.append((encoded_default, json_schema))
360
389
  # Since reference schemas do not support child keys, we wrap the reference schema in a single-case allOf:
361
390
  return {'allOf': [json_schema], 'default': encoded_default}
362
391
 
363
- # if this schema does not have a $ref, we should instead validate immediately
392
+ # check if the schema has $ref in it directly
393
+ # if it does, we must validate this during $ref construction
394
+ if '$ref' in json_schema:
395
+ return postpone_default_validation(json_schema, encoded_default)
396
+
364
397
  try:
365
398
  validate_against_schema(json_schema, encoded_default)
399
+ except Unresolvable:
400
+ # this will sometimes happen with boolean schema composition keywords, i.e. oneOf or anyOf, IF these contain $ref keywords themselves
401
+ # we can recover from this by postponing validation
402
+ return postpone_default_validation(json_schema, encoded_default)
366
403
  except SchemaValidationError as e:
367
404
  err_msg = f"Default value '{default}' does not validate against schema\n{e}"
368
405
  raise PydanticInvalidForJsonSchema(err_msg) from e
@@ -479,7 +516,9 @@ class GenerateTypedJsonSchema(GenerateJsonSchema):
479
516
  return super().kw_arguments_schema(arguments, var_kwargs_schema)
480
517
 
481
518
  def p_arguments_schema(
482
- self, arguments: list[core_schema.ArgumentsParameter], var_args_schema: CoreSchema | None
519
+ self,
520
+ arguments: list[core_schema.ArgumentsParameter],
521
+ var_args_schema: CoreSchema | None,
483
522
  ) -> JsonSchemaValue:
484
523
  """Generates a JSON schema that matches a schema that defines a function's positional arguments.
485
524
 
File without changes