fix(ai): stop percent-encoding slashes in ai.run() model_name#2738
Open
nileshpatil6 wants to merge 1 commit into
Open
fix(ai): stop percent-encoding slashes in ai.run() model_name#2738nileshpatil6 wants to merge 1 commit into
nileshpatil6 wants to merge 1 commit into
Conversation
client.ai.run() builds its request path with path_template(), which percent-encodes every character in a path placeholder, including slashes. Model names like @cf/meta/llama-3.1-8b-instruct end up as @cf%2Fmeta%2Fllama-3.1-8b-instruct, and the API returns a 400 No route for that URI error. Added support for RFC 6570 reserved expansion syntax in path_template (a placeholder written as {+name} keeps slashes in the interpolated value unescaped, other characters are still percent-encoded, and dot-segment rejection still applies). Updated the ai.run() path template to use {+model_name} instead of {model_name}. Added test cases for the new {+name} syntax in test_path.py, covering normal usage, other special characters still being escaped, that the same variable used elsewhere in the template without + is unaffected, and that dot-segment protection still triggers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2718
client.ai.run() builds its request path with path_template(), which percent-encodes every character in a path placeholder, including forward slashes. Model names like
@cf/meta/llama-3.1-8b-instructend up in the URL as@cf%2Fmeta%2Fllama-3.1-8b-instruct, and the API responds with a 400 "No route for that URI". This broke every ai.run() call after the v5 rewrite, since v4.3.1 did not encode slashes this way.Root cause is in
src/cloudflare/_utils/_path.py.path_template()treats/as unsafe in the path portion (correct for a normal single path segment, since it protects against path traversal and segment confusion), butmodel_nameis not a single path segment, it is a slash separated identifier that the Cloudflare API expects literally in the URL.Fix: added support for RFC 6570 reserved expansion syntax in
path_template. A placeholder written as{+name}keeps/unescaped in the interpolated value while still percent-encoding every other unsafe character, and the existing dot-segment rejection (./..) still runs on the fully assembled path, so this does not weaken the path traversal protection that was added for the normal{name}syntax. Updated theai.run()path template (both sync and async) to use{+model_name}instead of{model_name}.I picked the reserved-expansion approach instead of a one-off hack in ai.py because this is a general problem: any path parameter that is itself a multi-segment identifier (this one, and potentially others in the future) needs the same treatment, and RFC 6570 already has a standard operator for exactly this.
Testing:
tests/test_utils/test_path.pycovering: the reported model_name case, that other special characters (space,?) are still escaped under{+name}, that the same variable used elsewhere in the same template without+is unaffected, and that dot-segment rejection still fires for{+name}.test_path.pysuite locally, 56 passed.ruff checkandruff format --diffon the changed files, both clean.@cf%2Fblack-forest-labs%2Fflux-1-schnell) and confirmed the fix produces@cf/black-forest-labs/flux-1-schnell.