Skip to content

Commit

Permalink
fix(interactive): Fix multiple match problem when deserializing json …
Browse files Browse the repository at this point in the history
…string to GSDataType (#4091)

The Python code generated by OpenAPI Generators fails to differentiate
between LongText and VarChar, treating both types the same for the JSON
string

```
{"string": {"var_char": {"max_length": 64}}}
```

To address this issue, we added the generated `long_text.py` to our git
repository and manually fixed the problem.
  • Loading branch information
zhanglei1949 authored Jul 31, 2024
1 parent a909854 commit 98eb62b
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ flex/interactive/sdk/python/gs_interactive/configuration.py
flex/interactive/sdk/python/gs_interactive/exceptions.py
flex/interactive/sdk/python/gs_interactive/rest.py
!flex/interactive/sdk/python/gs_interactive/client/generated/__init__.py
!flex/interactive/sdk/python/gs_interactive/models/long_text.py


**/.cache/
1 change: 1 addition & 0 deletions flex/interactive/sdk/python/.openapi-generator-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
README.md
setup.py
gs_interactive/client
gs_interactive/models/long_text.py
requirements.txt
test-requirements.txt
test/
98 changes: 98 additions & 0 deletions flex/interactive/sdk/python/gs_interactive/models/long_text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# coding: utf-8

"""
GraphScope Interactive API v0.3
This is the definition of GraphScope Interactive API, including - AdminService API - Vertex/Edge API - QueryService AdminService API (with tag AdminService) defines the API for GraphManagement, ProcedureManagement and Service Management. Vertex/Edge API (with tag GraphService) defines the API for Vertex/Edge management, including creation/updating/delete/retrive. QueryService API (with tag QueryService) defines the API for procedure_call, Ahodc query.
The version of the OpenAPI document: 1.0.0
Contact: [email protected]
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501


from __future__ import annotations
import pprint
import re # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
from typing_extensions import Self

class LongText(BaseModel):
"""
LongText
""" # noqa: E501
long_text: Optional[StrictStr]
__properties: ClassVar[List[str]] = ["long_text"]

model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
extra= "forbid",
)


def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))

def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
return self.model_dump_json(by_alias=True, exclude_unset=True)

@classmethod
def from_json(cls, json_str: str) -> Optional[Self]:
"""Create an instance of LongText from a JSON string"""
return cls.from_dict(json.loads(json_str))

def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
excluded_fields: Set[str] = set([
])

_dict = self.model_dump(
by_alias=True,
exclude=excluded_fields,
exclude_none=True,
)
# set to None if long_text (nullable) is None
# and model_fields_set contains the field
if self.long_text is None and "long_text" in self.model_fields_set:
_dict['long_text'] = None

return _dict

@classmethod
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"""Create an instance of LongText from a dict"""
if obj is None:
return None

if not isinstance(obj, dict):
return cls.model_validate(obj)

# Forbid extra fields, in order to avoid matching var_char
for key in obj:
if key not in cls.__properties:
raise ValueError(f"Unexpected field {key} for LongText")

_obj = cls.model_validate({
"long_text": obj.get("long_text")
})
return _obj


55 changes: 55 additions & 0 deletions flex/interactive/sdk/python/test/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,52 @@
from gs_interactive.client.status import StatusCode


test_graph_def = {
"name": "modern_graph",
"description": "This is a test graph",
"schema": {
"vertex_types": [
{
"type_name": "person",
"properties": [
{
"property_name": "id",
"property_type": {"primitive_type": "DT_SIGNED_INT64"},
},
{
"property_name": "name",
"property_type": {"string": {"var_char": {"max_length" : 16}}},
},
{
"property_name": "age",
"property_type": {"primitive_type": "DT_SIGNED_INT32"},
},
],
"primary_keys": ["id"],
}
],
"edge_types": [
{
"type_name": "knows",
"vertex_type_pair_relations": [
{
"source_vertex": "person",
"destination_vertex": "person",
"relation": "MANY_TO_MANY",
}
],
"properties": [
{
"property_name": "weight",
"property_type": {"primitive_type": "DT_DOUBLE"},
}
],
"primary_keys": [],
}
],
},
}

class TestDriver(unittest.TestCase):
"""Test usage of driver"""

Expand Down Expand Up @@ -62,6 +108,7 @@ def tearDown(self):
print("delete graph: ", rep2)

def test_example(self):
self.createGraphFromDict()
self._graph_id = self.createGraph()
self.bulkLoading()
self.bulkLoadingUploading()
Expand All @@ -81,6 +128,14 @@ def test_example(self):
# test stop the service, and submit queries
self.queryWithServiceStop()
self.createDriver()

def createGraphFromDict(self):
create_graph_request = CreateGraphRequest.from_dict(test_graph_def)
resp = self._sess.create_graph(create_graph_request)
assert resp.is_ok()
graph_id = resp.get_value().graph_id
print("Graph id: ", graph_id)
return graph_id

def createGraph(self):
create_graph = CreateGraphRequest(name="test_graph", description="test graph")
Expand Down
7 changes: 5 additions & 2 deletions flex/openapi/openapi_interactive.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ components:
LongText:
x-body-name: long_text
type: object
additionalProperties: false
required:
- long_text
properties:
Expand All @@ -1109,19 +1110,21 @@ components:
FixedChar:
x-body-name: fixed_char
type: object
additionalProperties: false
required:
- char
properties:
char:
type: object
required:
- fixed_char
- fixed_length
properties:
fixed_char:
fixed_length:
type: integer
VarChar:
x-body-name: var_char
type: object
additionalProperties: false
required:
- var_char
properties:
Expand Down

0 comments on commit 98eb62b

Please sign in to comment.