Skip to content

Commit

Permalink
fix issues
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric05 committed Dec 28, 2024
1 parent db78a24 commit 7d23965
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 84 deletions.
4 changes: 2 additions & 2 deletions dotextensions/server/handlers/http2postman.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,14 @@ def get_http_to_postman_request(http: HttpDef, description="") -> RequestClass:
# json to key value pairs
json_to_urlencoded_array(
# textx object to json
json_or_array_to_json(payload.data, lambda k: k)
json_or_array_to_json(payload.data)
)
]
request.body = body
elif json_payload := payload.json:
body.mode = Mode.RAW
body.options = {"language": "json"}
body.raw = json.dumps(json_or_array_to_json(json_payload, lambda x: x))
body.raw = json.dumps(json_or_array_to_json(json_payload))
if not request.header:
request.header = []
request.header.append(
Expand Down
2 changes: 1 addition & 1 deletion dothttp/models/parse_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ class ImportStmt:
@dataclass
class MultidefHttp:
import_list: Optional[ImportStmt]
variables : List[Variable]
allhttps: List[Http]
variables : List[Variable] = field(default_factory=lambda: [])


# one can get list of services and regions from
Expand Down
6 changes: 3 additions & 3 deletions dothttp/parse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def _load_props_from_content(self, content, property_util: PropertyProvider):
def load_properties_from_var(model, property_util):
for variable in model.variables:
if variable.value:
var_value = jsonmodel_to_json(variable.value, lambda k:k)
var_value = jsonmodel_to_json(variable.value)
property_util.infile_properties[variable.name] = Property([''], variable.name, var_value)


Expand Down Expand Up @@ -561,7 +561,7 @@ def _load_payload(self):
request_logger.debug(f"payload for request is `{content}`")
return Payload(content, header=mimetype)
elif data_json := self.http.payload.datajson:
d = json_or_array_to_json(data_json, self.get_updated_content)
d = json_or_array_to_json(data_json, self.property_util)
if isinstance(d, list):
raise PayloadDataNotValidException(
payload=f"data should be json/str, current: {d}"
Expand All @@ -572,7 +572,7 @@ def _load_payload(self):
elif upload_filename := self.http.payload.file:
return self.load_payload_fileinput(upload_filename)
elif json_data := self.http.payload.json:
d = json_or_array_to_json(json_data, self.get_updated_content)
d = json_or_array_to_json(json_data, self.property_util)
return Payload(json=d, header=MIME_TYPE_JSON)
elif files_wrap := self.http.payload.fileswrap:
files = []
Expand Down
110 changes: 54 additions & 56 deletions dothttp/parse/dsl_jsonparser.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,65 @@
import json
from typing import Dict, List, Union
from typing import Dict, List, Optional, Union

from ..utils.property_util import PropertyProvider
from ..utils.common import triple_or_double_tostring


def json_or_array_to_json(model, update_content_func) -> Union[Dict, List]:
if isinstance(model, Dict) or isinstance(model, List):
# TODO
# this is bad
# hooking here could lead to other issues
return model
if array := model.array:
return [jsonmodel_to_json(value, update_content_func) for value in array.values]
elif json_object := model.object:
return {
# TODO i'm confused about key weather it should be string or int or float (value has float, number,
# boolean, null) but key is unsupported by requests
get_key(member, update_content_func): jsonmodel_to_json(
member.value, update_content_func
)
for member in json_object.members
}
class JsonParser:
def __init__(self, property_util: PropertyProvider):
self.property_util = property_util

def json_or_array_to_json(self, model) -> Union[Dict, List]:
if isinstance(model, Dict) or isinstance(model, List):
return model
if array := model.array:
return [self.jsonmodel_to_json(value) for value in array.values]
elif json_object := model.object:
return {
self.get_key(member): self.jsonmodel_to_json(member.value)
for member in json_object.members
}

def get_key(member, update_content_func):
if member.key:
return triple_or_double_tostring(member.key, update_content_func)
elif member.var:
return update_content_func(member.var)
def get_key(self, member):
if member.key:
return triple_or_double_tostring(member.key, self.property_util.get_updated_content)
elif member.var:
return self.property_util.get_updated_obj_content(member.var)

def jsonmodel_to_json(self, model):
if str_value := model.strs:
return triple_or_double_tostring(str_value, self.property_util.get_updated_content)
elif var_value := model.var:
return self.property_util.get_updated_obj_content(var_value)
elif int_val := model.int:
return int_val.value
elif flt := model.flt:
return flt.value
elif bl := model.bl:
return bl.value
elif json_object := model.object:
return {
self.get_key(member): self.jsonmodel_to_json(member.value)
for member in json_object.members
}
elif array := model.array:
return [self.jsonmodel_to_json(value) for value in array.values]
elif model == "null":
return None
elif expr := model.expr:
return eval(expr)

def jsonmodel_to_json(model, update_content_func):
# if length if array is 0, which means, its not string
if str_value := model.strs:
return triple_or_double_tostring(str_value, update_content_func)
elif var_value := model.var:
return get_json_data(var_value, update_content_func)
elif int_val := model.int:
return int_val.value
elif flt := model.flt:
return flt.value
elif bl := model.bl:
return bl.value
elif json_object := model.object:
return {
get_key(member, update_content_func): jsonmodel_to_json(
member.value, update_content_func
)
for member in json_object.members
}
elif array := model.array:
return [jsonmodel_to_json(value, update_content_func) for value in array.values]
elif model == "null":
return None
elif expr := model.expr:
return eval(expr)

# Supporting function
def json_or_array_to_json(model, property_util: Optional[PropertyProvider]=None) -> Union[Dict, List]:
if property_util is None:
property_util = PropertyProvider()
parser = JsonParser(property_util)
return parser.json_or_array_to_json(model)

def get_json_data(var_value, update_content_func):
content: str = update_content_func(var_value)
if content == var_value:
return var_value
try:
return json.loads(content)
except ValueError:
return content

def jsonmodel_to_json(model, property_util: Optional[PropertyProvider]=None) -> Union[Dict, List]:
if property_util is None:
property_util = PropertyProvider()
parser = JsonParser(property_util)
return parser.jsonmodel_to_json(model)
4 changes: 2 additions & 2 deletions dothttp/parse/request_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,12 @@ def check_for_quotes(line):
data = "'" + data.replace("'", "\\'") + "'"
p = f'text({data}{(" ," + mime_type) if mime_type else ""})'
if datajson := payload.datajson:
parsed_data = json_or_array_to_json(datajson, lambda a: a)
parsed_data = json_or_array_to_json(datajson)
p = f"urlencoded({json.dumps(parsed_data, indent=4)})"
elif filetype := payload.file:
p = f'< "{filetype}" {(" ;" + mime_type) if mime_type else ""}'
elif json_data := payload.json:
parsed_data = json_or_array_to_json(json_data, lambda a: a)
parsed_data = json_or_array_to_json(json_data)
p = f"json({JSON_ENCODER.encode(parsed_data)})"
elif files_wrap := payload.fileswrap:

Expand Down
38 changes: 22 additions & 16 deletions dothttp/utils/property_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,19 @@ def get_updated_content(self, content, type="str"):
content_prop_needed, props_needed = self.check_properties_for_content(
content)
for var in props_needed:
# command line props take preference
func = (
self.resolve_property_string
if type == "str"
else self.resolve_property_object
)
value = func(var)
base_logger.debug(f"using `{value}` for property {var}")
for text_to_replace in content_prop_needed[var].text:
content = content.replace("{{" + text_to_replace + "}}", str(value))
if type == "str":
value = self.resolve_property_string(var)
for text_to_replace in content_prop_needed[var].text:
content = content.replace(
"{{" + text_to_replace + "}}", str(value)
)
else:
content = self.resolve_property_object(var)
base_logger.debug(f"using `{content}` for property {var}")
return content

def get_updated_obj_content(self, content):
return self.get_updated_content(content, "obj")

def validate_n_gen(self, prop, cache: Dict[str, Property]):
p: Union[Property, None] = None
Expand Down Expand Up @@ -380,10 +382,14 @@ def find_according_to_category(key):
)
return prop_value

def resolve_property_object(self, key: str) -> object:
val = self.resolve_property_string(key)
try:
return json.loads(val)
except JSONDecodeError:
base_logger.debug(f"property `{key}` value non json decodable")
def resolve_property_object(self, content: str) -> object:
val = self.resolve_property_string(content)
# if val is string then try to convert to json
if isinstance(val, str):
try:
return json.loads(val)
except JSONDecodeError:
base_logger.debug(f"property `{content}` value non json decodable")
return val
else:
return val
10 changes: 6 additions & 4 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
@pytest.fixture(scope='session', autouse=True)
def start_httpbin_container():
# Setup: Start the Docker container
container_id = subprocess.check_output(
["docker", "run", "-d", "-p", "8000:80", "kennethreitz/httpbin"]
).decode().strip()

try:
container_id = subprocess.check_output(
["docker", "run", "-d", "-p", "8000:80", "kennethreitz/httpbin"]
).decode().strip()
except:
pass
# Wait for the container to be ready
time.sleep(5) # Adjust the sleep time as needed

Expand Down

0 comments on commit 7d23965

Please sign in to comment.