meshagent-api 0.52.4__tar.gz → 0.53.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meshagent_api-0.52.4/meshagent_api.egg-info → meshagent_api-0.53.0}/PKG-INFO +1 -1
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/client.py +34 -3
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/client_test.py +54 -0
- meshagent_api-0.53.0/meshagent/api/version.py +1 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0/meshagent_api.egg-info}/PKG-INFO +1 -1
- meshagent_api-0.52.4/meshagent/api/version.py +0 -1
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/LICENSE +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/MANIFEST.in +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/README.md +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/__init__.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/agent_content.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/aiohttp_redaction.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/chan.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/crdt.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/dataset_schema.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/entrypoint.js +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/error_codes.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/helpers.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/http.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/image_runtime.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/keys.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/llm_router_config.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/managed_agents.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/managed_agents_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/messaging.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/messaging_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/mime_types.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/mime_types_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth_branding.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth_scopes.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/oauth_scopes_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/participant.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/participant_token.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/participant_token_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/port_forward.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/port_forward_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/protocol.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/protocol_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/py.typed +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/reasoning_schema.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/registry_auth.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/room_ports.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/room_server_client.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/room_server_client_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/runtime.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/runtime_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_document.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_document_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_registry.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/schema_util.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/service_spec_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/service_template_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/services.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/services_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/specs/service.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sql.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sql_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sqlite_transfer.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/sqlite_transfer_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/token_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/urls.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/webhooks.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/webhooks_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/websocket_protocol.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent/api/websocket_protocol_test.py +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/SOURCES.txt +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/dependency_links.txt +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/requires.txt +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/meshagent_api.egg-info/top_level.txt +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/pyproject.toml +0 -0
- {meshagent_api-0.52.4 → meshagent_api-0.53.0}/setup.cfg +0 -0
|
@@ -265,6 +265,7 @@ ProjectRole = Literal[
|
|
|
265
265
|
"usage_reporter",
|
|
266
266
|
"billing_manager",
|
|
267
267
|
"group_manager",
|
|
268
|
+
"user_profile_editor",
|
|
268
269
|
]
|
|
269
270
|
ResourceRole = Literal["viewer", "operator", "developer", "admin"]
|
|
270
271
|
CustomDomainRole = Literal["viewer", "user", "admin"]
|
|
@@ -708,6 +709,17 @@ class User(BaseModel):
|
|
|
708
709
|
first_name: Optional[str] = None
|
|
709
710
|
last_name: Optional[str] = None
|
|
710
711
|
email: str
|
|
712
|
+
metadata: dict[str, JsonValue] = Field(default_factory=dict)
|
|
713
|
+
annotations: dict[str, str] = Field(default_factory=dict)
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
class UpdateUserProfileRequest(BaseModel):
|
|
717
|
+
model_config = ConfigDict(extra="forbid", strict=True)
|
|
718
|
+
|
|
719
|
+
first_name: str | None = None
|
|
720
|
+
last_name: str | None = None
|
|
721
|
+
metadata: dict[str, JsonValue] = Field(default_factory=dict)
|
|
722
|
+
annotations: dict[str, str] = Field(default_factory=dict)
|
|
711
723
|
|
|
712
724
|
|
|
713
725
|
class UserRoomGrant(BaseModel):
|
|
@@ -1584,15 +1596,34 @@ class Meshagent:
|
|
|
1584
1596
|
return await resp.json()
|
|
1585
1597
|
|
|
1586
1598
|
async def update_user_profile(
|
|
1587
|
-
self,
|
|
1599
|
+
self,
|
|
1600
|
+
user_id: str,
|
|
1601
|
+
first_name: str | None = None,
|
|
1602
|
+
last_name: str | None = None,
|
|
1603
|
+
*,
|
|
1604
|
+
metadata: dict[str, JsonValue] | None = None,
|
|
1605
|
+
annotations: dict[str, str] | None = None,
|
|
1606
|
+
project_id: str | None = None,
|
|
1588
1607
|
) -> Dict[str, Any]:
|
|
1589
1608
|
"""
|
|
1590
1609
|
Corresponds to: PUT /accounts/profiles/:id
|
|
1591
|
-
|
|
1610
|
+
Omitted fields are preserved; metadata and annotations replace their maps.
|
|
1611
|
+
Editing another user or annotations requires the user_profile_editor role
|
|
1612
|
+
in project_id, and the target must belong to that project.
|
|
1592
1613
|
Returns a JSON dict with { "ok": True } on success.
|
|
1593
1614
|
"""
|
|
1594
1615
|
url = f"{self.base_url}/accounts/profiles/{user_id}"
|
|
1595
|
-
body
|
|
1616
|
+
body: dict[str, Any] = {}
|
|
1617
|
+
if first_name is not None:
|
|
1618
|
+
body["first_name"] = first_name
|
|
1619
|
+
if last_name is not None:
|
|
1620
|
+
body["last_name"] = last_name
|
|
1621
|
+
if metadata is not None:
|
|
1622
|
+
body["metadata"] = metadata
|
|
1623
|
+
if annotations is not None:
|
|
1624
|
+
body["annotations"] = annotations
|
|
1625
|
+
if project_id is not None:
|
|
1626
|
+
url += f"?project_id={quote(project_id, safe='')}"
|
|
1596
1627
|
|
|
1597
1628
|
async with self._session.put(
|
|
1598
1629
|
url, headers=self._get_headers(), json=body
|
|
@@ -20,6 +20,8 @@ from meshagent.api.client import (
|
|
|
20
20
|
Meshagent,
|
|
21
21
|
Room,
|
|
22
22
|
RoomDisabledError,
|
|
23
|
+
UpdateUserProfileRequest,
|
|
24
|
+
User,
|
|
23
25
|
room_scope_for_role_compat,
|
|
24
26
|
)
|
|
25
27
|
from meshagent.api.specs.service import (
|
|
@@ -2738,3 +2740,55 @@ async def test_access_evaluator_methods_use_access_routes():
|
|
|
2738
2740
|
{"subject": {"type": "user", "id": "user-1"}},
|
|
2739
2741
|
),
|
|
2740
2742
|
]
|
|
2743
|
+
|
|
2744
|
+
|
|
2745
|
+
@pytest.mark.asyncio
|
|
2746
|
+
async def test_update_user_profile_supports_partial_metadata_and_editor_context():
|
|
2747
|
+
session = _FakeSession(
|
|
2748
|
+
[
|
|
2749
|
+
_FakeResponse(status=200, payload={"ok": True}),
|
|
2750
|
+
_FakeResponse(status=200, payload={"ok": True}),
|
|
2751
|
+
]
|
|
2752
|
+
)
|
|
2753
|
+
client = Meshagent(base_url="http://example.test", token="token", session=session)
|
|
2754
|
+
await client.update_user_profile("me", metadata={})
|
|
2755
|
+
await client.update_user_profile(
|
|
2756
|
+
"user-2",
|
|
2757
|
+
"Grace",
|
|
2758
|
+
"Hopper",
|
|
2759
|
+
metadata={"theme": "dark"},
|
|
2760
|
+
annotations={"department": "research"},
|
|
2761
|
+
project_id="project-1",
|
|
2762
|
+
)
|
|
2763
|
+
assert session.calls == [
|
|
2764
|
+
("put", "http://example.test/accounts/profiles/me", {"metadata": {}}),
|
|
2765
|
+
(
|
|
2766
|
+
"put",
|
|
2767
|
+
"http://example.test/accounts/profiles/user-2?project_id=project-1",
|
|
2768
|
+
{
|
|
2769
|
+
"first_name": "Grace",
|
|
2770
|
+
"last_name": "Hopper",
|
|
2771
|
+
"metadata": {"theme": "dark"},
|
|
2772
|
+
"annotations": {"department": "research"},
|
|
2773
|
+
},
|
|
2774
|
+
),
|
|
2775
|
+
]
|
|
2776
|
+
|
|
2777
|
+
|
|
2778
|
+
def test_user_profile_models_preserve_json_metadata_and_string_annotations():
|
|
2779
|
+
user = User.model_validate(
|
|
2780
|
+
{
|
|
2781
|
+
"id": "user-1",
|
|
2782
|
+
"email": "ada@example.test",
|
|
2783
|
+
"metadata": {"nested": {"numbers": [1, 2]}, "active": True},
|
|
2784
|
+
"annotations": {"department": "engineering"},
|
|
2785
|
+
}
|
|
2786
|
+
)
|
|
2787
|
+
assert user.model_dump()["metadata"] == {
|
|
2788
|
+
"nested": {"numbers": [1, 2]},
|
|
2789
|
+
"active": True,
|
|
2790
|
+
}
|
|
2791
|
+
assert user.annotations == {"department": "engineering"}
|
|
2792
|
+
assert User(id="old-user", email="old@example.test").metadata == {}
|
|
2793
|
+
update = UpdateUserProfileRequest.model_validate({"metadata": {}})
|
|
2794
|
+
assert update.model_dump(exclude_unset=True) == {"metadata": {}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.53.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.52.4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|