Skip to content

Commit aea99d3

Browse files
committed
manually create get_invalid_validation; remove changes to async_to_sync; add a way to skip async_to_sync for generator
1 parent c509b36 commit aea99d3

File tree

3 files changed

+88
-15
lines changed

3 files changed

+88
-15
lines changed

synapseclient/api/json_schema_services.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ async def get_invalid_json_schema_validation(
147147
yield item
148148

149149

150+
def get_invalid_json_schema_validation_sync(
151+
synapse_id: str, *, synapse_client: Optional["Synapse"] = None
152+
):
153+
request_body = {"containerId": synapse_id}
154+
response = synapse_client._POST_paginated(
155+
f"/entity/{synapse_id}/schema/validation/invalid", request_body
156+
)
157+
for item in response:
158+
yield item
159+
160+
150161
async def get_json_schema_derived_keys(
151162
synapse_id: str, *, synapse_client: Optional["Synapse"] = None
152163
) -> "JSONSchemaDerivedKeys":

synapseclient/core/async_utils.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import asyncio
44
import functools
5-
import inspect
65
from typing import TYPE_CHECKING, Any, Callable, Coroutine, Union
76

87
import nest_asyncio
@@ -114,16 +113,7 @@ def newmethod(self, *args, **kwargs):
114113

115114
async def wrapper(*args, **kwargs):
116115
"""Wrapper for the function to be called in an async context."""
117-
result = getattr(self, async_method_name)(*args, **kwargs)
118-
if inspect.isasyncgen(result):
119-
# collect all values into a list
120-
return [item async for item in result]
121-
elif inspect.iscoroutine(result):
122-
return await result
123-
else:
124-
raise TypeError(
125-
f"Expected an async generator or coroutine, got {type(result)}"
126-
)
116+
return await getattr(self, async_method_name)(*args, **kwargs)
127117

128118
loop = None
129119

@@ -144,9 +134,11 @@ async def wrapper(*args, **kwargs):
144134

145135
methods_to_update = []
146136
for k in methods:
137+
if getattr(cls.__dict__[k], "_skip_conversion", False):
138+
continue
139+
147140
if "async" in k and (new_method_name := k.replace("_async", "")):
148141
new_method = create_method(k)
149-
150142
new_method.fn.__name__ = new_method_name
151143
new_method.__name__ = new_method_name
152144

@@ -163,3 +155,8 @@ async def wrapper(*args, **kwargs):
163155
)
164156

165157
return cls
158+
159+
160+
def skip_async_to_sync(func):
161+
func._skip_conversion = True
162+
return func

synapseclient/models/mixins/json_schema.py

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
from dataclasses import dataclass, field
2-
from typing import TYPE_CHECKING, AsyncGenerator, List, Optional, Union
2+
from typing import TYPE_CHECKING, AsyncGenerator, Generator, List, Optional, Union
33

44
from synapseclient.api.json_schema_services import (
55
bind_json_schema_to_entity,
66
delete_json_schema_from_entity,
77
get_invalid_json_schema_validation,
8+
get_invalid_json_schema_validation_sync,
89
get_json_schema_derived_keys,
910
get_json_schema_from_entity,
1011
get_json_schema_validation_statistics,
1112
validate_entity_with_json_schema,
1213
)
13-
from synapseclient.core.async_utils import async_to_sync
14+
from synapseclient.core.async_utils import async_to_sync, skip_async_to_sync
1415
from synapseclient.models.protocols.json_schema_protocol import (
1516
BaseJSONSchemaProtocol,
1617
ContainerEntityJSONSchemaProtocol,
@@ -412,9 +413,10 @@ async def get_schema_validation_statistics_async(
412413
number_of_unknown_children=response.get("numberOfUnknownChildren", None),
413414
)
414415

416+
@skip_async_to_sync
415417
async def get_invalid_validation_async(
416418
self, *, synapse_client: Optional["Synapse"] = None
417-
) -> AsyncGenerator[InvalidJSONSchemaValidation, None]:
419+
) -> AsyncGenerator[InvalidJSONSchemaValidation, None, None]:
418420
"""
419421
Get invalid JSON schema validation results for a container entity.
420422
@@ -473,3 +475,66 @@ async def get_invalid_validation_async(
473475
],
474476
),
475477
)
478+
479+
def get_invalid_validation(
480+
self, *, synapse_client: Optional["Synapse"] = None
481+
) -> Generator[InvalidJSONSchemaValidation, None, None]:
482+
"""
483+
Get invalid JSON schema validation results for a container entity.
484+
485+
Arguments:
486+
synapse_client (Optional[Synapse], optional): The Synapse client instance. If not provided,
487+
the last created instance from the Synapse class constructor will be used.
488+
489+
Yields:
490+
InvalidJSONSchemaValidation: An object containing the validation response, all validation messages,
491+
and the validation exception details.
492+
"""
493+
gen = get_invalid_json_schema_validation_sync(
494+
synapse_client=synapse_client, synapse_id=self.id
495+
)
496+
497+
for item in gen:
498+
yield InvalidJSONSchemaValidation(
499+
validation_response=JSONSchemaValidation(
500+
object_id=item.get("objectId", None),
501+
object_type=item.get("objectType", None),
502+
object_etag=item.get("objectEtag", None),
503+
id=item.get("schema$id", None),
504+
is_valid=item.get("isValid", None),
505+
validated_on=item.get("validatedOn", None),
506+
),
507+
validation_error_message=item.get("validationErrorMessage", None),
508+
all_validation_messages=item.get("allValidationMessages", []),
509+
validation_exception=ValidationException(
510+
pointer_to_violation=item.get("validationException", {}).get(
511+
"pointerToViolation", None
512+
),
513+
message=item.get("validationException", {}).get("message", None),
514+
schema_location=item.get("validationException", {}).get(
515+
"schemaLocation", None
516+
),
517+
causing_exceptions=[
518+
CausingException(
519+
keyword=ce.get("keyword", None),
520+
pointer_to_violation=ce.get("pointerToViolation", None),
521+
message=ce.get("message", None),
522+
schema_location=ce.get("schemaLocation", None),
523+
causing_exceptions=[
524+
CausingException(
525+
keyword=nce.get("keyword", None),
526+
pointer_to_violation=nce.get(
527+
"pointerToViolation", None
528+
),
529+
message=nce.get("message", None),
530+
schema_location=nce.get("schemaLocation", None),
531+
)
532+
for nce in ce.get("causingExceptions", [])
533+
],
534+
)
535+
for ce in item.get("validationException", {}).get(
536+
"causingExceptions", []
537+
)
538+
],
539+
),
540+
)

0 commit comments

Comments
 (0)