Skip to content

Commit

Permalink
fix(metagen): client file upload fixup (#936)
Browse files Browse the repository at this point in the history
<!--
Pull requests are squashed and merged using:
- their title as the commit message
- their description as the commit body

Having a good title and description is important for the users to get
readable changelog.
-->

<!-- 1. Explain WHAT the change is about -->

- Make reusable file on multiple path for python and added tests for TS
and Python.

<!-- 3. Explain HOW users should update their code -->

#### Migration notes

---

- [ ] The change comes with new or modified tests
- [ ] Hard-to-understand functions have explanatory comments
- [ ] End-user documentation is updated to reflect the change
  • Loading branch information
luckasRanarison authored Dec 10, 2024
1 parent 3643286 commit 64ed210
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 36 deletions.
26 changes: 19 additions & 7 deletions src/metagen/src/client_py/static/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,13 @@ def selection_to_nodes(
SelectionT = typing.TypeVar("SelectionT")


@dc.dataclass
class File:
content: bytes
name: str
mimetype: typing.Optional[str] = None
def __init__(
self, content: bytes, name: str, mimetype: typing.Optional[str] = None
):
self.content = content
self.name = name
self.mimetype = mimetype


#
Expand Down Expand Up @@ -613,11 +615,21 @@ def build_req(
if len(files) > 0:
form_data = MultiPartForm()
form_data.add_field("operations", body)
file_map = {}
map = {}

for idx, (path, file) in enumerate(files.items()):
map[idx] = ["variables" + path]
form_data.add_file(f"{idx}", file)
for path, file in files.items():
array = file_map.get(file)
variable = "variables" + path
if array is not None:
array.append(variable)
else:
file_map[file] = [variable]

for idx, (file, variables) in enumerate(file_map.items()):
key = str(idx)
map[key] = variables
form_data.add_file(key, file)

form_data.add_field("map", json.dumps(map))
headers.update({"Content-type": form_data.get_content_type()})
Expand Down
36 changes: 23 additions & 13 deletions tests/metagen/metagen_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,42 +656,52 @@ Meta.test(
assertEquals(res.code, 0);

const expectedSchemaU1 = zod.object({
upload: zod.boolean(),
upload: zod.literal(true),
});
const expectedSchemaU2 = zod.object({
uploadFirst: zod.literal(true),
uploadSecond: zod.literal(true),
});
const expectedSchemaUn = zod.object({
uploadMany: zod.boolean(),
uploadMany: zod.literal(true),
});

const expectedSchema = zod.tuple([
expectedSchemaU1,
// expectedSchemaU1,
expectedSchemaUn,
expectedSchemaU1,
expectedSchemaUn,
]);

const cases = [
{
name: "client_rs_upload",
skip: false,
command: $`cargo run`.cwd(join(scriptsPath, "rs_upload")),
expected: expectedSchema,
expected: zod.tuple([
expectedSchemaU1,
// expectedSchemaU1,
expectedSchemaUn,
expectedSchemaU1,
expectedSchemaUn,
]),
},
{
name: "client_py_upload",
skip: false,
command: $`bash -c "python main.py"`.cwd(
join(scriptsPath, "py_upload"),
),
expected: zod.tuple([expectedSchemaU1, expectedSchemaUn]),
expected: zod.tuple([
expectedSchemaU1,
expectedSchemaUn,
expectedSchemaU2,
]),
},
{
name: "client_ts_upload",
skip: false,
command: $`bash -c "deno run -A main.ts"`.cwd(
join(scriptsPath, "ts_upload"),
),
expected: zod.tuple([expectedSchemaU1, expectedSchemaUn]),
expected: zod.tuple([
expectedSchemaU1,
expectedSchemaUn,
expectedSchemaU2,
]),
},
];

Expand Down
26 changes: 19 additions & 7 deletions tests/metagen/typegraphs/sample/py/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,13 @@ def selection_to_nodes(
SelectionT = typing.TypeVar("SelectionT")


@dc.dataclass
class File:
content: bytes
name: str
mimetype: typing.Optional[str] = None
def __init__(
self, content: bytes, name: str, mimetype: typing.Optional[str] = None
):
self.content = content
self.name = name
self.mimetype = mimetype


#
Expand Down Expand Up @@ -616,11 +618,21 @@ def build_req(
if len(files) > 0:
form_data = MultiPartForm()
form_data.add_field("operations", body)
file_map = {}
map = {}

for idx, (path, file) in enumerate(files.items()):
map[idx] = ["variables" + path]
form_data.add_file(f"{idx}", file)
for path, file in files.items():
array = file_map.get(file)
variable = "variables" + path
if array is not None:
array.append(variable)
else:
file_map[file] = [variable]

for idx, (file, variables) in enumerate(file_map.items()):
key = str(idx)
map[key] = variables
form_data.add_file(key, file)

form_data.add_field("map", json.dumps(map))
headers.update({"Content-type": form_data.get_content_type()})
Expand Down
26 changes: 19 additions & 7 deletions tests/metagen/typegraphs/sample/py_upload/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,13 @@ def selection_to_nodes(
SelectionT = typing.TypeVar("SelectionT")


@dc.dataclass
class File:
content: bytes
name: str
mimetype: typing.Optional[str] = None
def __init__(
self, content: bytes, name: str, mimetype: typing.Optional[str] = None
):
self.content = content
self.name = name
self.mimetype = mimetype


#
Expand Down Expand Up @@ -616,11 +618,21 @@ def build_req(
if len(files) > 0:
form_data = MultiPartForm()
form_data.add_field("operations", body)
file_map = {}
map = {}

for idx, (path, file) in enumerate(files.items()):
map[idx] = ["variables" + path]
form_data.add_file(f"{idx}", file)
for path, file in files.items():
array = file_map.get(file)
variable = "variables" + path
if array is not None:
array.append(variable)
else:
file_map[file] = [variable]

for idx, (file, variables) in enumerate(file_map.items()):
key = str(idx)
map[key] = variables
form_data.add_file(key, file)

form_data.add_field("map", json.dumps(map))
headers.update({"Content-type": form_data.get_content_type()})
Expand Down
11 changes: 10 additions & 1 deletion tests/metagen/typegraphs/sample/py_upload/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@
}
)

print(json.dumps([res1, res2]))
file = File(b"Hello", "reusable.txt")

res3 = gql.mutation(
{
"uploadFirst": api.upload({"file": file, "path": "python/first.txt"}),
"uploadSecond": api.upload({"file": file, "path": "python/second.txt"}),
}
)

print(json.dumps([res1, res2, res3]))
9 changes: 8 additions & 1 deletion tests/metagen/typegraphs/sample/ts_upload/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ const res2 = await gql.mutation({
}),
});

console.log(JSON.stringify([res1, res2]));
const file = new File(["Hello"], "reusable.txt", { type: "text/plain" });

const res3 = await gql.mutation({
uploadFirst: qg.upload({ file, path: "deno/first.txt" }),
uploadSecond: qg.upload({ file, path: "deno/second.txt" }),
});

console.log(JSON.stringify([res1, res2, res3]));

0 comments on commit 64ed210

Please sign in to comment.