Repository: posit-dev/posit-sdk-py

Issue:
SDK client should fetch the current user info at initialization
It would be nice if the SDK populated the client config with some basic info about the current user when it is initialized.

Specifically, for the `OAuthIntegrations` endpoint, I would like the current user's guid to be available with something like `self.config.current_user.guid`, assuming my endpoint looks something like this:

```python
class OAuthIntegration:
    def __init__(
        self, config: Config, session: Session, *args
    ) -> None:
        super().__init__()
        self.config = config
        self.session = session

    def get_credentials(self, content_identity: Optional[str]) -> Response:
        endpoint = os.path.join(self.config.endpoint, "v1/oauth/integrations/credentials")

        # craft a basic credential exchange request where the self.config.api_key owner
        # is requesting their own credentials
        data = dict()
        data["grant_type"] = "urn:ietf:params:oauth:grant-type:token-exchange"
        data["subject_token_type"] = "urn:posit:connect:user-guid"
        data["subject_token"] = self.config.current_user.guid

        # if this content is running on Connect, then it is allowed to request
        # the content viewer's credentials
        if content_identity:
            data["subject_token"] = parse_viewer_guid(content_identity)
            data["actor_token_type"] = "urn:posit:connect:content-identity-token"
            data["actor_token"] = content_identity

        return self.session.post(endpoint, data=data)
```

Discussion:
github-actions[bot]: # ☂️ Python Coverage
> current status: ✅
## Overall Coverage
| Lines | Covered | Coverage | Threshold | Status |
| :---: | :-----: | :------: | :-------: | :----: |
|  438  |   438   |   100%   |    80%    |   🟢   |
## New Files
No new covered files...
## Modified Files
| File                             | Coverage | Status |
| :------------------------------- | :------: | :----: |
| src/posit/connect/client.py      |   100%   |   🟢   |
| src/posit/connect/client_test.py |   100%   |   🟢   |
| **TOTAL**                        | **100%** |   🟢   |


> **updated for commit: `cb8e52e` by [action](https://github.com/marketplace/actions/python-coverage)🐍**

Patch:
diff --git a/src/posit/connect/client.py b/src/posit/connect/client.py
index 0614257..87160f2 100644
--- a/src/posit/connect/client.py
+++ b/src/posit/connect/client.py
@@ -7,7 +7,7 @@ from . import hooks, urls
 
 from .auth import Auth
 from .config import Config
-from .users import Users
+from .users import User, Users
 
 
 class Client:
@@ -35,14 +35,20 @@ class Client:
         # Store the Session object.
         self.session = session
 
-        # Place to cache the server settings
-        self.server_settings = None
+        # Internal attributes to hold settings we fetch lazily
+        self._server_settings = None
 
     @property
     def connect_version(self):
-        if self.server_settings is None:
-            self.server_settings = self.get("server_settings").json()
-        return self.server_settings["version"]
+        if self._server_settings is None:
+            self._server_settings = self.get("server_settings").json()
+        return self._server_settings["version"]
+
+    @property
+    def me(self) -> User:
+        url = urls.append_path(self.config.url, "v1/user")
+        response = self.session.get(url)
+        return User(**response.json())
 
     @property
     def users(self) -> Users:


Test patch:
diff --git a/src/posit/connect/client_test.py b/src/posit/connect/client_test.py
index 349fb3a..435f895 100644
--- a/src/posit/connect/client_test.py
+++ b/src/posit/connect/client_test.py
@@ -75,6 +75,28 @@ class TestClient:
         )
         assert client.connect_version == "2024.01.0"
 
+    @responses.activate
+    def test_me_request(self):
+        responses.get(
+            "https://connect.example/__api__/v1/user",
+            json={
+                "email": "carlos@connect.example",
+                "username": "carlos12",
+                "first_name": "Carlos",
+                "last_name": "User",
+                "user_role": "publisher",
+                "created_time": "2019-09-09T15:24:32Z",
+                "updated_time": "2022-03-02T20:25:06Z",
+                "active_time": "2020-05-11T16:58:45Z",
+                "confirmed": True,
+                "locked": False,
+                "guid": "20a79ce3-6e87-4522-9faf-be24228800a4",
+            },
+        )
+
+        con = Client(api_key="12345", url="https://connect.example/")
+        assert con.me["username"] == "carlos12"
+
     def test_request(self, MockSession):
         api_key = "foobar"
         url = "http://foo.bar/__api__"