Skip to content

Commit 207f581

Browse files
Properly handle optional<binary> endpoint return type and binary-related aliases (#1052)
1 parent 237dd5d commit 207f581

File tree

8 files changed

+360
-25
lines changed

8 files changed

+360
-25
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type: fix
2+
fix:
3+
description: Properly handle optional<binary> endpoint return type and binary-related
4+
aliases
5+
links:
6+
- https://github.com/palantir/conjure-python/pull/1052

conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import com.palantir.conjure.python.types.MyPyTypeNameVisitor;
3232
import com.palantir.conjure.python.types.PythonTypeNameVisitor;
3333
import com.palantir.conjure.spec.EndpointDefinition;
34-
import com.palantir.conjure.spec.PrimitiveType;
3534
import com.palantir.conjure.spec.ServiceDefinition;
3635
import com.palantir.conjure.spec.Type;
3736
import com.palantir.conjure.visitor.DealiasingTypeVisitor;
@@ -125,14 +124,29 @@ private PythonEndpointDefinition generateEndpoint(
125124
.params(params)
126125
.pythonReturnType(endpointDef.getReturns().map(type -> type.accept(pythonTypeNameVisitor)))
127126
.myPyReturnType(endpointDef.getReturns().map(type -> type.accept(myPyTypeNameVisitor)))
127+
// Set to true iff the de-aliased type is binary.
128128
.isRequestBinary(endpointDef.getArgs().stream()
129129
.anyMatch(argumentDef -> argumentDef.getParamType().accept(ParameterTypeVisitor.IS_BODY)
130-
&& argumentDef.getType().accept(TypeVisitor.IS_BINARY)))
130+
&& dealiasingTypeVisitor
131+
.dealias(argumentDef.getType())
132+
.fold(_typeDefinition -> false, type -> type.accept(TypeVisitor.IS_BINARY))))
133+
// Set to true iff 1) the de-aliased type is binary or 2) the de-aliased type is optional<binary> (both
134+
// outer and inner type de-aliased).
131135
.isResponseBinary(endpointDef
132136
.getReturns()
133-
// We do not need to handle alias of binary since they are treated differently over the wire
134-
.map(rt -> rt.accept(TypeVisitor.IS_PRIMITIVE)
135-
&& rt.accept(TypeVisitor.PRIMITIVE).get() == PrimitiveType.Value.BINARY)
137+
.map(rt -> dealiasingTypeVisitor
138+
.dealias(rt)
139+
.fold(
140+
_typeDefinition -> false,
141+
type -> type.accept(TypeVisitor.IS_BINARY)
142+
|| (type.accept(TypeVisitor.IS_OPTIONAL)
143+
&& dealiasingTypeVisitor
144+
.dealias(type.accept(TypeVisitor.OPTIONAL)
145+
.getItemType())
146+
.fold(
147+
_typeDefinition -> false,
148+
itemType -> itemType.accept(
149+
TypeVisitor.IS_BINARY)))))
136150
.orElse(false))
137151
.isOptionalReturnType(endpointDef
138152
.getReturns()

conjure-python-core/src/main/java/com/palantir/conjure/python/poet/PythonEndpointDefinition.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,21 @@ default void emit(PythonPoetWriter poetWriter) {
225225
poetWriter.decreaseIndent();
226226

227227
poetWriter.writeLine();
228+
if (isOptionalReturnType()) {
229+
poetWriter.writeIndentedLine("if _response.status_code == 204:");
230+
poetWriter.increaseIndent();
231+
poetWriter.writeIndentedLine("return None");
232+
poetWriter.decreaseIndent();
233+
}
228234
if (isResponseBinary()) {
229235
poetWriter.writeIndentedLine("_raw = _response.raw");
230236
poetWriter.writeIndentedLine("_raw.decode_content = True");
231237
poetWriter.writeIndentedLine("return _raw");
232238
} else if (pythonReturnType().isPresent()) {
233239
poetWriter.writeIndentedLine("_decoder = ConjureDecoder()");
234-
if (isOptionalReturnType()) {
235-
poetWriter.writeIndentedLine(
236-
"return None if _response.status_code == 204 else _decoder.decode(_response.json()"
237-
+ ", %s, self._return_none_for_unknown_union_types)",
238-
pythonReturnType().get());
239-
} else {
240-
poetWriter.writeIndentedLine(
241-
"return _decoder.decode(_response.json(), %s, self._return_none_for_unknown_union_types)",
242-
pythonReturnType().get());
243-
}
240+
poetWriter.writeIndentedLine(
241+
"return _decoder.decode(_response.json(), %s, self._return_none_for_unknown_union_types)",
242+
pythonReturnType().get());
244243
} else {
245244
poetWriter.writeIndentedLine("return");
246245
}

conjure-python-core/src/test/resources/services/expected/package_name/_impl.py

Lines changed: 144 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-python-core/src/test/resources/services/expected/package_name/product/__init__.py

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conjure-python-core/src/test/resources/types/example-service.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ types:
5252
- value: PYPI
5353
- value: CONDA
5454

55+
BinaryAlias:
56+
alias: binary
57+
58+
OptionalStringAlias:
59+
alias: optional<string>
60+
5561
services:
5662
TestService:
5763
name: Test Service
@@ -98,6 +104,10 @@ services:
98104
- Safe
99105
returns: binary
100106

107+
getAliasedRawData:
108+
http: GET /get-aliased-raw
109+
returns: BinaryAlias
110+
101111
maybeGetRawData:
102112
http: GET /datasets/{datasetRid}/raw-maybe
103113
args:
@@ -107,13 +117,33 @@ services:
107117
- Safe
108118
returns: optional<binary>
109119

120+
maybeGetAliasedRawData:
121+
http: GET /datasets/{datasetRid}/raw-maybe-alias
122+
args:
123+
datasetRid:
124+
type: rid
125+
markers:
126+
- Safe
127+
returns: optional<BinaryAlias>
128+
129+
getAliasedReturn:
130+
http: GET /aliased-return
131+
returns: OptionalStringAlias
132+
110133
uploadRawData:
111134
http: POST /datasets/upload-raw
112135
args:
113136
input:
114137
type: binary
115138
param-type: body
116139

140+
uploadAliasedRawData:
141+
http: POST /datasets/upload-raw-alias
142+
args:
143+
input:
144+
type: BinaryAlias
145+
param-type: body
146+
117147
uploadPythonPackage:
118148
http: POST /data/python/{uploadType}
119149
args:

0 commit comments

Comments
 (0)