You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix: build BatchRequestItem urls relative to the API version - #1118
Fixes#1116. A BatchRequestItem built from a RequestInformation kept the full https://graph.microsoft.com/v1.0/... URL, so the $batch body carried absolute URLs. set_url() should strip the version, but API_VERSION_REGEX = re.compile(r'/\/(v1.0|beta)/') is a JavaScript regex literal ported as-is: in Python both / and \/ are literal slashes, so it only matched //v1.0/.
The regex is now r'^/(v1\.0|beta)(?=/|$)', the version as the first path segment only, so /sites/beta-site and /sites/beta/lists stay. ME_TOKEN_REGEX gets the same fix and set_url() uses it. The constructor goes through set_url(), which already handles the me-token, query and fragment. This matches the JavaScript SDK, whose tests expect /me/drive/root/children.
Notes
Tests that pinned the old behaviour (url == base_url, "/v1.0/me") now expect the relative form. Code that stripped the version from item.url itself now gets a relative URL; the batch body it sends doesn't change. Open PRs #711 and #996 touch serialize(), not these lines.
Testing Instructions
pytest tests/requests/test_batch_request_item.py after pip install -r requirements-dev.txt: 4 new cases (beta URL with query and fragment, relative path, version-like segment, beta after the first segment), 7 updated.
BatchRequestItem kept the absolute request URL, and set_url() could not strip the version because its regex only matched //v1.0/ (a JavaScript regex literal ported as-is). The constructor now goes through set_url(), and the regex matches /v1.0 or /beta as a path segment. Fixesmicrosoftgraph#1116.
Max Azatian (Max Azatian (@HardMax71)) please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
(default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
(when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
Any chance this gets a review? The workflows on this PR are still waiting for approval, so Build and test has not run here; locally the full suite passes on the PR head. The branch is two workflow-only commits behind main and merges cleanly, and I can rebase if you prefer.
Still reproduces on 1.5.1 with msgraph-sdk 1.63.0. It is easy to miss: a fresh request builder gives a relative URL, and the absolute one only appears after a request has been sent through the same builder chain, because the adapter writes baseurl into the shared path parameters.
repro
# pip install msgraph-sdk==1.63.0 Deprecated (Deprecated is the missing dependency from #1030)importasynciofromimportlib.metadataimportversionimporthttpxfromkiota_abstractions.authenticationimportAnonymousAuthenticationProviderfrommsgraphimportGraphRequestAdapter, GraphServiceClientfrommsgraph.generated.users.item.messages.item.move.move_post_request_bodyimportMovePostRequestBodyfrommsgraph_coreimportGraphClientFactoryfrommsgraph_core.requests.batch_request_itemimportBatchRequestItemasyncdefmain():
print("msgraph-core", version("msgraph-core"), "msgraph-sdk", version("msgraph-sdk"))
transport=httpx.MockTransport(lambdarequest: httpx.Response(200, json={"value": []}))
http=GraphClientFactory.create_with_default_middleware(client=httpx.AsyncClient(transport=transport))
client=GraphServiceClient(request_adapter=GraphRequestAdapter(AnonymousAuthenticationProvider(), client=http))
user=client.users.by_user_id("u1")
defitem_url():
info=user.messages.by_message_id("m1").move.to_post_request_information(MovePostRequestBody(destination_id="f1"))
returnBatchRequestItem(request_information=info, id="m1").urlprint("before any request:", item_url())
awaituser.messages.get()
print("after user.messages.get():", item_url())
asyncio.run(main())
1.5.1:
before any request: /users/u1/messages/m1/move
after user.messages.get(): https://graph.microsoft.com/v1.0/users/u1/messages/m1/move
this PR:
before any request: /users/u1/messages/m1/move
after user.messages.get(): /users/u1/messages/m1/move
set_url() also runs on relative URLs, and the unanchored pattern turned /sites/beta/lists into /sites/lists. ME_TOKEN_REGEX is now the pattern set_url() applies, instead of a second copy of the literal.
ME_TOKEN_REGEX matches the placeholder as a prefix rather than as a complete path segment. A legitimate URL such as /users/me-token-to-replace-extra is therefore rewritten to /me-extra, and the same can happen when that string is part of a longer user-id segment. Add a path-segment boundary, as was done for the API-version regex, so only the exact placeholder segment is replaced.
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
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.
Overview
Fixes #1116. A
BatchRequestItembuilt from aRequestInformationkept the fullhttps://graph.microsoft.com/v1.0/...URL, so the$batchbody carried absolute URLs.set_url()should strip the version, butAPI_VERSION_REGEX = re.compile(r'/\/(v1.0|beta)/')is a JavaScript regex literal ported as-is: in Python both/and\/are literal slashes, so it only matched//v1.0/.The regex is now
r'^/(v1\.0|beta)(?=/|$)', the version as the first path segment only, so/sites/beta-siteand/sites/beta/listsstay.ME_TOKEN_REGEXgets the same fix andset_url()uses it. The constructor goes throughset_url(), which already handles the me-token, query and fragment. This matches the JavaScript SDK, whose tests expect/me/drive/root/children.Notes
Tests that pinned the old behaviour (
url == base_url,"/v1.0/me") now expect the relative form. Code that stripped the version fromitem.urlitself now gets a relative URL; the batch body it sends doesn't change. Open PRs #711 and #996 touchserialize(), not these lines.Testing Instructions
pytest tests/requests/test_batch_request_item.pyafterpip install -r requirements-dev.txt: 4 new cases (beta URL with query and fragment, relative path, version-like segment,betaafter the first segment), 7 updated.yapf -dr src,mypy src,pylint src --disable=W --rcfile=.pylintrcclean.POST .../v1.0/users/u1/messages/m1/moveitem now serializesurlas/users/u1/messages/m1/move.