Skip to content

Commit ca70445

Browse files
committed
fix: Leave pagination params out of the at least one parameter guard
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1RzepycXEYA3LStfjt8cY
1 parent eca5e24 commit ca70445

47 files changed

Lines changed: 2013 additions & 3301 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎codegen/layouts/partials/method-docstring.hbs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
:param wait_for_action_attempt: Whether, and for how long, to wait for the action attempt to finish.{{/if}}{{#unless (eq returnType "None")}}
66

7-
:returns: {{{indent (pythonDoc responseDescription) 8}}}{{/unless}}{{#if hasRequiredParameters}}
7+
:returns: {{{indent (pythonDoc responseDescription) 8}}}{{/unless}}{{#if requiresAtLeastOneParameter}}
88

99
:raises ValueError: At least one parameter must be provided.{{/if}}{{#if isDeprecated}}
1010

‎codegen/layouts/partials/route-method.hbs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@route_metadata(path="{{path}}", has_required_parameters={{#if hasRequiredParameters}}True{{else}}False{{/if}}, has_pagination={{#if hasPagination}}True{{else}}False{{/if}})
1+
@route_metadata(path="{{path}}", at_least_one_parameter_names=({{#each atLeastOneParameterNames}}"{{this}}",{{#unless @last}} {{/unless}}{{/each}}), has_pagination={{#if hasPagination}}True{{else}}False{{/if}})
22
{{#if isAsync}}async {{/if}}def {{> method-signature}}:
33
"""{{> method-docstring}}"""
44
{{payloadVar}}: Dict[str, Any] = {}
@@ -7,9 +7,12 @@
77
if {{name}} is not None:
88
{{../payloadVar}}["{{name}}"] = {{name}}
99
{{/each}}
10-
{{#if hasRequiredParameters}}
10+
{{#if requiresAtLeastOneParameter}}
1111

12-
if not {{payloadVar}}:
12+
if all(
13+
param is None
14+
for param in ({{#each atLeastOneParameterNames}}{{this}},{{#unless @last}} {{/unless}}{{/each}})
15+
):
1316
raise ValueError("At least one parameter is required for {{path}}")
1417
{{/if}}
1518

‎codegen/lib/layouts/route.ts‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export interface MethodLayoutContext {
1414
httpVerb: string
1515
payloadVar: string
1616
payloadArg: string
17-
hasRequiredParameters: boolean
17+
requiresAtLeastOneParameter: boolean
18+
atLeastOneParameterNames: string[]
1819
hasPagination: boolean
1920
description: string
2021
responseDescription: string
@@ -66,6 +67,16 @@ export interface RouteLayoutContext {
6667
methods: MethodLayoutContext[]
6768
}
6869

70+
const paginationParameterNames = new Set(['limit', 'page_cursor'])
71+
72+
const getAtLeastOneParameterNames = (method: ClassMethod): string[] =>
73+
method.hasRequiredParameters &&
74+
method.parameters.every(({ required }) => !(required ?? false))
75+
? method.parameters
76+
.map(({ name }) => name)
77+
.filter((name) => !paginationParameterNames.has(name))
78+
: []
79+
6980
const getRequestLayoutContext = (
7081
preferredMethod: string,
7182
): Pick<MethodLayoutContext, 'httpVerb' | 'payloadVar' | 'payloadArg'> => {
@@ -84,7 +95,8 @@ export const getMethodLayoutContext = (
8495
name: method.methodName,
8596
path: method.path,
8697
...getRequestLayoutContext(method.preferredMethod),
87-
hasRequiredParameters: method.hasRequiredParameters,
98+
requiresAtLeastOneParameter: getAtLeastOneParameterNames(method).length > 0,
99+
atLeastOneParameterNames: getAtLeastOneParameterNames(method),
88100
hasPagination: method.hasPagination,
89101
description: method.description,
90102
responseDescription: method.responseDescription,

‎seam/route.py‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
from typing import Any, Callable, TypeVar, cast
1+
from typing import Any, Callable, Tuple, TypeVar, cast
22

33
F = TypeVar("F", bound=Callable)
44

55

6-
def route_metadata(*, path: str, has_required_parameters: bool, has_pagination: bool):
6+
def route_metadata(
7+
*,
8+
path: str,
9+
has_pagination: bool,
10+
at_least_one_parameter_names: Tuple[str, ...] = (),
11+
):
712
"""Attach generated route metadata to a request callable."""
813

914
def decorate(request: F) -> F:
1015
# Functions do not declare these attributes, so set them through Any.
1116
route = cast(Any, request)
1217
route.__seam_path__ = path
13-
route.__seam_has_required_parameters__ = has_required_parameters
1418
route.__seam_has_pagination__ = has_pagination
19+
route.__seam_at_least_one_parameter_names__ = at_least_one_parameter_names
1520
return request
1621

1722
return decorate

0 commit comments

Comments
 (0)