We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add `prefect cloud logout` command
### First check

- [X] I added a descriptive title to this issue.
- [X] I used the GitHub search to find a similar request and didn't find it.
- [X] I searched the Prefect documentation for this feature.

### Prefect Version

2.x

### Describe the current behavior

Add `prefect cloud logout` to log out of a workspace 

### Describe the proposed behavior

Likely by unsetting the `PREFECT_API_KEY` and `PREFECT_API_URL` back to default

### Example Use

_No response_

### Additional context

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/prefect/cli/cloud.py`
Content:
```
1 """
2 Command line interface for interacting with Prefect Cloud
3 """
4 import re
5 from typing import Dict, Iterable
6 
7 import httpx
8 import readchar
9 import typer
10 from rich.live import Live
11 from rich.table import Table
12 
13 import prefect.context
14 import prefect.settings
15 from prefect.cli._types import PrefectTyper
16 from prefect.cli._utilities import exit_with_error, exit_with_success
17 from prefect.cli.root import app
18 from prefect.client.cloud import CloudUnauthorizedError, get_cloud_client
19 from prefect.settings import (
20     PREFECT_API_KEY,
21     PREFECT_API_URL,
22     PREFECT_CLOUD_URL,
23     load_profiles,
24     save_profiles,
25     update_current_profile,
26 )
27 
28 cloud_app = PrefectTyper(
29     name="cloud", help="Commands for interacting with Prefect Cloud"
30 )
31 workspace_app = PrefectTyper(
32     name="workspace", help="Commands for interacting with Prefect Cloud Workspaces"
33 )
34 cloud_app.add_typer(workspace_app, aliases=["workspaces"])
35 app.add_typer(cloud_app)
36 
37 
38 def build_url_from_workspace(workspace: Dict) -> str:
39     return (
40         f"{PREFECT_CLOUD_URL.value()}"
41         f"/accounts/{workspace['account_id']}"
42         f"/workspaces/{workspace['workspace_id']}"
43     )
44 
45 
46 def confirm_logged_in():
47     if not PREFECT_API_KEY:
48         profile = prefect.context.get_settings_context().profile
49         exit_with_error(
50             f"Currently not authenticated in profile {profile.name!r}. "
51             "Please login with `prefect cloud login --key <API_KEY>`."
52         )
53 
54 
55 def get_current_workspace(workspaces):
56     workspace_handles_by_id = {
57         workspace[
58             "workspace_id"
59         ]: f"{workspace['account_handle']}/{workspace['workspace_handle']}"
60         for workspace in workspaces
61     }
62     current_workspace_id = re.match(
63         r".*accounts/.{36}/workspaces/(.{36})\Z", PREFECT_API_URL.value()
64     ).groups()[0]
65     return workspace_handles_by_id[current_workspace_id]
66 
67 
68 def build_table(selected_idx: int, workspaces: Iterable[str]) -> Table:
69     """
70     Generate a table of workspaces. The `select_idx` of workspaces will be highlighted.
71 
72     Args:
73         selected_idx: currently selected index
74         workspaces: Iterable of strings
75 
76     Returns:
77         rich.table.Table
78     """
79 
80     table = Table()
81     table.add_column(
82         "[#024dfd]Select a Workspace:", justify="right", style="#8ea0ae", no_wrap=True
83     )
84 
85     for i, workspace in enumerate(sorted(workspaces)):
86         if i == selected_idx:
87             table.add_row("[#024dfd on #FFFFFF]> " + workspace)
88         else:
89             table.add_row("  " + workspace)
90     return table
91 
92 
93 def select_workspace(workspaces: Iterable[str]) -> str:
94     """
95     Given a list of workspaces, display them to user in a Table
96     and allow them to select one.
97 
98     Args:
99         workspaces: List of workspaces to choose from
100 
101     Returns:
102         str: the selected workspace
103     """
104 
105     workspaces = sorted(workspaces)
106     current_idx = 0
107     selected_workspace = None
108 
109     with Live(
110         build_table(current_idx, workspaces), auto_refresh=False, console=app.console
111     ) as live:
112         while selected_workspace is None:
113             key = readchar.readkey()
114 
115             if key == readchar.key.UP:
116                 current_idx = current_idx - 1
117                 # wrap to bottom if at the top
118                 if current_idx < 0:
119                     current_idx = len(workspaces) - 1
120             elif key == readchar.key.DOWN:
121                 current_idx = current_idx + 1
122                 # wrap to top if at the bottom
123                 if current_idx >= len(workspaces):
124                     current_idx = 0
125             elif key == readchar.key.CTRL_C:
126                 # gracefully exit with no message
127                 exit_with_error("")
128             elif key == readchar.key.ENTER:
129                 selected_workspace = workspaces[current_idx]
130 
131             live.update(build_table(current_idx, workspaces), refresh=True)
132 
133         return selected_workspace
134 
135 
136 @cloud_app.command()
137 async def login(
138     key: str = typer.Option(
139         ..., "--key", "-k", help="API Key to authenticate with Prefect", prompt=True
140     ),
141     workspace_handle: str = typer.Option(
142         None,
143         "--workspace",
144         "-w",
145         help="Full handle of workspace, in format '<account_handle>/<workspace_handle>'",
146     ),
147 ):
148     """
149     Log in to Prefect Cloud.
150     Creates a new profile configured to use the specified PREFECT_API_KEY.
151     Uses a previously configured profile if it exists.
152     """
153     profiles = load_profiles()
154 
155     async with get_cloud_client(api_key=key) as client:
156         try:
157             workspaces = await client.read_workspaces()
158             workspace_handle_details = {
159                 f"{workspace['account_handle']}/{workspace['workspace_handle']}": workspace
160                 for workspace in workspaces
161             }
162         except CloudUnauthorizedError:
163             if key.startswith("pcu"):
164                 help_message = "It looks like you're using API key from Cloud 1 (https://cloud.prefect.io). Make sure that you generate API key using Cloud 2 (https://app.prefect.cloud)"
165             elif not key.startswith("pnu"):
166                 help_message = "Your key is not in our expected format."
167             else:
168                 help_message = "Please ensure your credentials are correct."
169             exit_with_error(
170                 f"Unable to authenticate with Prefect Cloud. {help_message}"
171             )
172         except httpx.HTTPStatusError as exc:
173             exit_with_error(f"Error connecting to Prefect Cloud: {exc!r}")
174 
175     for profile_name in profiles:
176         if key == profiles[profile_name].settings.get(PREFECT_API_KEY):
177             profiles.set_active(profile_name)
178             save_profiles(profiles)
179             with prefect.context.use_profile(profile_name):
180                 current_workspace = get_current_workspace(workspaces)
181 
182                 if workspace_handle is not None:
183                     if workspace_handle not in workspace_handle_details:
184                         exit_with_error(f"Workspace {workspace_handle!r} not found.")
185 
186                     update_current_profile(
187                         {
188                             PREFECT_API_URL: build_url_from_workspace(
189                                 workspace_handle_details[workspace_handle]
190                             )
191                         }
192                     )
193                     current_workspace = workspace_handle
194 
195                 exit_with_success(
196                     f"Logged in to Prefect Cloud using profile {profile_name!r}.\n"
197                     f"Workspace is currently set to {current_workspace!r}. "
198                     f"The workspace can be changed using `prefect cloud workspace set`."
199                 )
200 
201     workspace_handle_details = {
202         f"{workspace['account_handle']}/{workspace['workspace_handle']}": workspace
203         for workspace in workspaces
204     }
205 
206     if not workspace_handle:
207         workspace_handle = select_workspace(workspace_handle_details.keys())
208 
209     cloud_profile_name = app.console.input(
210         "Creating a profile for this Prefect Cloud login. Please specify a profile name: "
211     )
212 
213     cloud_profile_name = cloud_profile_name.strip()
214     if cloud_profile_name == "":
215         exit_with_error("Please provide a non-empty profile name.")
216 
217     if cloud_profile_name in profiles:
218         exit_with_error(f"Profile {cloud_profile_name!r} already exists.")
219 
220     profiles.add_profile(
221         profiles[profiles.active_name].copy(
222             update={
223                 "name": cloud_profile_name,
224             }
225         )
226     )
227 
228     profiles.update_profile(
229         cloud_profile_name,
230         {
231             PREFECT_API_URL: build_url_from_workspace(
232                 workspace_handle_details[workspace_handle]
233             ),
234             PREFECT_API_KEY: key,
235         },
236     )
237 
238     profiles.set_active(cloud_profile_name)
239     save_profiles(profiles)
240 
241     exit_with_success(
242         f"Logged in to Prefect Cloud using profile {cloud_profile_name!r}.\n"
243         f"Workspace is currently set to {workspace_handle!r}. "
244         f"The workspace can be changed using `prefect cloud workspace set`."
245     )
246 
247 
248 @workspace_app.command()
249 async def ls():
250     """List available workspaces."""
251 
252     confirm_logged_in()
253 
254     async with get_cloud_client() as client:
255         try:
256             workspaces = await client.read_workspaces()
257         except CloudUnauthorizedError:
258             exit_with_error(
259                 "Unable to authenticate. Please ensure your credentials are correct."
260             )
261 
262     workspace_handle_details = {
263         f"{workspace['account_handle']}/{workspace['workspace_handle']}": workspace
264         for workspace in workspaces
265     }
266 
267     current_workspace = get_current_workspace(workspaces)
268 
269     table = Table(caption="* active workspace")
270     table.add_column(
271         "[#024dfd]Available Workspaces:", justify="right", style="#8ea0ae", no_wrap=True
272     )
273 
274     for i, workspace_handle in enumerate(sorted(workspace_handle_details)):
275         if workspace_handle == current_workspace:
276             table.add_row(f"[green]  * {workspace_handle}[/green]")
277         else:
278             table.add_row(f"  {workspace_handle}")
279     app.console.print(table)
280 
281 
282 @workspace_app.command()
283 async def set(
284     workspace_handle: str = typer.Option(
285         None,
286         "--workspace",
287         "-w",
288         help="Full handle of workspace, in format '<account_handle>/<workspace_handle>'",
289     ),
290 ):
291     """Set current workspace. Shows a workspace picker if no workspace is specified."""
292     confirm_logged_in()
293 
294     async with get_cloud_client() as client:
295         try:
296             workspaces = await client.read_workspaces()
297         except CloudUnauthorizedError:
298             exit_with_error(
299                 "Unable to authenticate. Please ensure your credentials are correct."
300             )
301     workspaces = {
302         f"{workspace['account_handle']}/{workspace['workspace_handle']}": workspace
303         for workspace in workspaces
304     }
305 
306     if not workspace_handle:
307         workspace_handle = select_workspace(workspaces)
308 
309     if workspace_handle not in workspaces:
310         exit_with_error(
311             f"Workspace {workspace_handle!r} not found. "
312             "Leave `--workspace` blank to select a workspace."
313         )
314 
315     profile = update_current_profile(
316         {PREFECT_API_URL: build_url_from_workspace(workspaces[workspace_handle])}
317     )
318 
319     exit_with_success(
320         f"Successfully set workspace to {workspace_handle!r} in profile {profile.name!r}."
321     )
322
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/prefect/cli/cloud.py b/src/prefect/cli/cloud.py
--- a/src/prefect/cli/cloud.py
+++ b/src/prefect/cli/cloud.py
@@ -150,8 +150,6 @@
     Creates a new profile configured to use the specified PREFECT_API_KEY.
     Uses a previously configured profile if it exists.
     """
-    profiles = load_profiles()
-
     async with get_cloud_client(api_key=key) as client:
         try:
             workspaces = await client.read_workspaces()
@@ -172,6 +170,8 @@
         except httpx.HTTPStatusError as exc:
             exit_with_error(f"Error connecting to Prefect Cloud: {exc!r}")
 
+    profiles = load_profiles()
+
     for profile_name in profiles:
         if key == profiles[profile_name].settings.get(PREFECT_API_KEY):
             profiles.set_active(profile_name)
@@ -192,41 +192,19 @@
                     )
                     current_workspace = workspace_handle
 
-                exit_with_success(
-                    f"Logged in to Prefect Cloud using profile {profile_name!r}.\n"
-                    f"Workspace is currently set to {current_workspace!r}. "
-                    f"The workspace can be changed using `prefect cloud workspace set`."
-                )
-
-    workspace_handle_details = {
-        f"{workspace['account_handle']}/{workspace['workspace_handle']}": workspace
-        for workspace in workspaces
-    }
+            exit_with_success(
+                f"Logged in to Prefect Cloud using profile {profile_name!r}.\n"
+                f"Workspace is currently set to {current_workspace!r}. "
+                f"The workspace can be changed using `prefect cloud workspace set`."
+            )
 
     if not workspace_handle:
         workspace_handle = select_workspace(workspace_handle_details.keys())
 
-    cloud_profile_name = app.console.input(
-        "Creating a profile for this Prefect Cloud login. Please specify a profile name: "
-    )
-
-    cloud_profile_name = cloud_profile_name.strip()
-    if cloud_profile_name == "":
-        exit_with_error("Please provide a non-empty profile name.")
+    if workspace_handle not in workspace_handle_details:
+        exit_with_error(f"Workspace {workspace_handle!r} not found.")
 
-    if cloud_profile_name in profiles:
-        exit_with_error(f"Profile {cloud_profile_name!r} already exists.")
-
-    profiles.add_profile(
-        profiles[profiles.active_name].copy(
-            update={
-                "name": cloud_profile_name,
-            }
-        )
-    )
-
-    profiles.update_profile(
-        cloud_profile_name,
+    current_profile = update_current_profile(
         {
             PREFECT_API_URL: build_url_from_workspace(
                 workspace_handle_details[workspace_handle]
@@ -235,16 +213,36 @@
         },
     )
 
-    profiles.set_active(cloud_profile_name)
-    save_profiles(profiles)
-
     exit_with_success(
-        f"Logged in to Prefect Cloud using profile {cloud_profile_name!r}.\n"
+        f"Logged in to Prefect Cloud using profile {current_profile.name!r}.\n"
         f"Workspace is currently set to {workspace_handle!r}. "
         f"The workspace can be changed using `prefect cloud workspace set`."
     )
 
 
+@cloud_app.command()
+async def logout():
+    """
+    Logout the current workspace.
+    Reset PREFECT_API_KEY and PREFECT_API_URL to default.
+    """
+    current_profile = prefect.context.get_settings_context().profile
+    if current_profile is None:
+        exit_with_error("There is no current profile set.")
+
+    if current_profile.settings.get(PREFECT_API_KEY) is None:
+        exit_with_error("Current profile is not logged into Prefect Cloud.")
+
+    update_current_profile(
+        {
+            PREFECT_API_URL: None,
+            PREFECT_API_KEY: None,
+        },
+    )
+
+    exit_with_success("Logged out from Prefect Cloud.")
+
+
 @workspace_app.command()
 async def ls():
     """List available workspaces."""

{"golden_diff": "diff --git a/src/prefect/cli/cloud.py b/src/prefect/cli/cloud.py\n--- a/src/prefect/cli/cloud.py\n+++ b/src/prefect/cli/cloud.py\n@@ -150,8 +150,6 @@\n     Creates a new profile configured to use the specified PREFECT_API_KEY.\n     Uses a previously configured profile if it exists.\n     \"\"\"\n-    profiles = load_profiles()\n-\n     async with get_cloud_client(api_key=key) as client:\n         try:\n             workspaces = await client.read_workspaces()\n@@ -172,6 +170,8 @@\n         except httpx.HTTPStatusError as exc:\n             exit_with_error(f\"Error connecting to Prefect Cloud: {exc!r}\")\n \n+    profiles = load_profiles()\n+\n     for profile_name in profiles:\n         if key == profiles[profile_name].settings.get(PREFECT_API_KEY):\n             profiles.set_active(profile_name)\n@@ -192,41 +192,19 @@\n                     )\n                     current_workspace = workspace_handle\n \n-                exit_with_success(\n-                    f\"Logged in to Prefect Cloud using profile {profile_name!r}.\\n\"\n-                    f\"Workspace is currently set to {current_workspace!r}. \"\n-                    f\"The workspace can be changed using `prefect cloud workspace set`.\"\n-                )\n-\n-    workspace_handle_details = {\n-        f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n-        for workspace in workspaces\n-    }\n+            exit_with_success(\n+                f\"Logged in to Prefect Cloud using profile {profile_name!r}.\\n\"\n+                f\"Workspace is currently set to {current_workspace!r}. \"\n+                f\"The workspace can be changed using `prefect cloud workspace set`.\"\n+            )\n \n     if not workspace_handle:\n         workspace_handle = select_workspace(workspace_handle_details.keys())\n \n-    cloud_profile_name = app.console.input(\n-        \"Creating a profile for this Prefect Cloud login. Please specify a profile name: \"\n-    )\n-\n-    cloud_profile_name = cloud_profile_name.strip()\n-    if cloud_profile_name == \"\":\n-        exit_with_error(\"Please provide a non-empty profile name.\")\n+    if workspace_handle not in workspace_handle_details:\n+        exit_with_error(f\"Workspace {workspace_handle!r} not found.\")\n \n-    if cloud_profile_name in profiles:\n-        exit_with_error(f\"Profile {cloud_profile_name!r} already exists.\")\n-\n-    profiles.add_profile(\n-        profiles[profiles.active_name].copy(\n-            update={\n-                \"name\": cloud_profile_name,\n-            }\n-        )\n-    )\n-\n-    profiles.update_profile(\n-        cloud_profile_name,\n+    current_profile = update_current_profile(\n         {\n             PREFECT_API_URL: build_url_from_workspace(\n                 workspace_handle_details[workspace_handle]\n@@ -235,16 +213,36 @@\n         },\n     )\n \n-    profiles.set_active(cloud_profile_name)\n-    save_profiles(profiles)\n-\n     exit_with_success(\n-        f\"Logged in to Prefect Cloud using profile {cloud_profile_name!r}.\\n\"\n+        f\"Logged in to Prefect Cloud using profile {current_profile.name!r}.\\n\"\n         f\"Workspace is currently set to {workspace_handle!r}. \"\n         f\"The workspace can be changed using `prefect cloud workspace set`.\"\n     )\n \n \n+@cloud_app.command()\n+async def logout():\n+    \"\"\"\n+    Logout the current workspace.\n+    Reset PREFECT_API_KEY and PREFECT_API_URL to default.\n+    \"\"\"\n+    current_profile = prefect.context.get_settings_context().profile\n+    if current_profile is None:\n+        exit_with_error(\"There is no current profile set.\")\n+\n+    if current_profile.settings.get(PREFECT_API_KEY) is None:\n+        exit_with_error(\"Current profile is not logged into Prefect Cloud.\")\n+\n+    update_current_profile(\n+        {\n+            PREFECT_API_URL: None,\n+            PREFECT_API_KEY: None,\n+        },\n+    )\n+\n+    exit_with_success(\"Logged out from Prefect Cloud.\")\n+\n+\n @workspace_app.command()\n async def ls():\n     \"\"\"List available workspaces.\"\"\"\n", "issue": "Add `prefect cloud logout` command\n### First check\n\n- [X] I added a descriptive title to this issue.\n- [X] I used the GitHub search to find a similar request and didn't find it.\n- [X] I searched the Prefect documentation for this feature.\n\n### Prefect Version\n\n2.x\n\n### Describe the current behavior\n\nAdd `prefect cloud logout` to log out of a workspace \n\n### Describe the proposed behavior\n\nLikely by unsetting the `PREFECT_API_KEY` and `PREFECT_API_URL` back to default\n\n### Example Use\n\n_No response_\n\n### Additional context\n\n_No response_\n", "before_files": [{"content": "\"\"\"\nCommand line interface for interacting with Prefect Cloud\n\"\"\"\nimport re\nfrom typing import Dict, Iterable\n\nimport httpx\nimport readchar\nimport typer\nfrom rich.live import Live\nfrom rich.table import Table\n\nimport prefect.context\nimport prefect.settings\nfrom prefect.cli._types import PrefectTyper\nfrom prefect.cli._utilities import exit_with_error, exit_with_success\nfrom prefect.cli.root import app\nfrom prefect.client.cloud import CloudUnauthorizedError, get_cloud_client\nfrom prefect.settings import (\n    PREFECT_API_KEY,\n    PREFECT_API_URL,\n    PREFECT_CLOUD_URL,\n    load_profiles,\n    save_profiles,\n    update_current_profile,\n)\n\ncloud_app = PrefectTyper(\n    name=\"cloud\", help=\"Commands for interacting with Prefect Cloud\"\n)\nworkspace_app = PrefectTyper(\n    name=\"workspace\", help=\"Commands for interacting with Prefect Cloud Workspaces\"\n)\ncloud_app.add_typer(workspace_app, aliases=[\"workspaces\"])\napp.add_typer(cloud_app)\n\n\ndef build_url_from_workspace(workspace: Dict) -> str:\n    return (\n        f\"{PREFECT_CLOUD_URL.value()}\"\n        f\"/accounts/{workspace['account_id']}\"\n        f\"/workspaces/{workspace['workspace_id']}\"\n    )\n\n\ndef confirm_logged_in():\n    if not PREFECT_API_KEY:\n        profile = prefect.context.get_settings_context().profile\n        exit_with_error(\n            f\"Currently not authenticated in profile {profile.name!r}. \"\n            \"Please login with `prefect cloud login --key <API_KEY>`.\"\n        )\n\n\ndef get_current_workspace(workspaces):\n    workspace_handles_by_id = {\n        workspace[\n            \"workspace_id\"\n        ]: f\"{workspace['account_handle']}/{workspace['workspace_handle']}\"\n        for workspace in workspaces\n    }\n    current_workspace_id = re.match(\n        r\".*accounts/.{36}/workspaces/(.{36})\\Z\", PREFECT_API_URL.value()\n    ).groups()[0]\n    return workspace_handles_by_id[current_workspace_id]\n\n\ndef build_table(selected_idx: int, workspaces: Iterable[str]) -> Table:\n    \"\"\"\n    Generate a table of workspaces. The `select_idx` of workspaces will be highlighted.\n\n    Args:\n        selected_idx: currently selected index\n        workspaces: Iterable of strings\n\n    Returns:\n        rich.table.Table\n    \"\"\"\n\n    table = Table()\n    table.add_column(\n        \"[#024dfd]Select a Workspace:\", justify=\"right\", style=\"#8ea0ae\", no_wrap=True\n    )\n\n    for i, workspace in enumerate(sorted(workspaces)):\n        if i == selected_idx:\n            table.add_row(\"[#024dfd on #FFFFFF]> \" + workspace)\n        else:\n            table.add_row(\"  \" + workspace)\n    return table\n\n\ndef select_workspace(workspaces: Iterable[str]) -> str:\n    \"\"\"\n    Given a list of workspaces, display them to user in a Table\n    and allow them to select one.\n\n    Args:\n        workspaces: List of workspaces to choose from\n\n    Returns:\n        str: the selected workspace\n    \"\"\"\n\n    workspaces = sorted(workspaces)\n    current_idx = 0\n    selected_workspace = None\n\n    with Live(\n        build_table(current_idx, workspaces), auto_refresh=False, console=app.console\n    ) as live:\n        while selected_workspace is None:\n            key = readchar.readkey()\n\n            if key == readchar.key.UP:\n                current_idx = current_idx - 1\n                # wrap to bottom if at the top\n                if current_idx < 0:\n                    current_idx = len(workspaces) - 1\n            elif key == readchar.key.DOWN:\n                current_idx = current_idx + 1\n                # wrap to top if at the bottom\n                if current_idx >= len(workspaces):\n                    current_idx = 0\n            elif key == readchar.key.CTRL_C:\n                # gracefully exit with no message\n                exit_with_error(\"\")\n            elif key == readchar.key.ENTER:\n                selected_workspace = workspaces[current_idx]\n\n            live.update(build_table(current_idx, workspaces), refresh=True)\n\n        return selected_workspace\n\n\n@cloud_app.command()\nasync def login(\n    key: str = typer.Option(\n        ..., \"--key\", \"-k\", help=\"API Key to authenticate with Prefect\", prompt=True\n    ),\n    workspace_handle: str = typer.Option(\n        None,\n        \"--workspace\",\n        \"-w\",\n        help=\"Full handle of workspace, in format '<account_handle>/<workspace_handle>'\",\n    ),\n):\n    \"\"\"\n    Log in to Prefect Cloud.\n    Creates a new profile configured to use the specified PREFECT_API_KEY.\n    Uses a previously configured profile if it exists.\n    \"\"\"\n    profiles = load_profiles()\n\n    async with get_cloud_client(api_key=key) as client:\n        try:\n            workspaces = await client.read_workspaces()\n            workspace_handle_details = {\n                f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n                for workspace in workspaces\n            }\n        except CloudUnauthorizedError:\n            if key.startswith(\"pcu\"):\n                help_message = \"It looks like you're using API key from Cloud 1 (https://cloud.prefect.io). Make sure that you generate API key using Cloud 2 (https://app.prefect.cloud)\"\n            elif not key.startswith(\"pnu\"):\n                help_message = \"Your key is not in our expected format.\"\n            else:\n                help_message = \"Please ensure your credentials are correct.\"\n            exit_with_error(\n                f\"Unable to authenticate with Prefect Cloud. {help_message}\"\n            )\n        except httpx.HTTPStatusError as exc:\n            exit_with_error(f\"Error connecting to Prefect Cloud: {exc!r}\")\n\n    for profile_name in profiles:\n        if key == profiles[profile_name].settings.get(PREFECT_API_KEY):\n            profiles.set_active(profile_name)\n            save_profiles(profiles)\n            with prefect.context.use_profile(profile_name):\n                current_workspace = get_current_workspace(workspaces)\n\n                if workspace_handle is not None:\n                    if workspace_handle not in workspace_handle_details:\n                        exit_with_error(f\"Workspace {workspace_handle!r} not found.\")\n\n                    update_current_profile(\n                        {\n                            PREFECT_API_URL: build_url_from_workspace(\n                                workspace_handle_details[workspace_handle]\n                            )\n                        }\n                    )\n                    current_workspace = workspace_handle\n\n                exit_with_success(\n                    f\"Logged in to Prefect Cloud using profile {profile_name!r}.\\n\"\n                    f\"Workspace is currently set to {current_workspace!r}. \"\n                    f\"The workspace can be changed using `prefect cloud workspace set`.\"\n                )\n\n    workspace_handle_details = {\n        f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n        for workspace in workspaces\n    }\n\n    if not workspace_handle:\n        workspace_handle = select_workspace(workspace_handle_details.keys())\n\n    cloud_profile_name = app.console.input(\n        \"Creating a profile for this Prefect Cloud login. Please specify a profile name: \"\n    )\n\n    cloud_profile_name = cloud_profile_name.strip()\n    if cloud_profile_name == \"\":\n        exit_with_error(\"Please provide a non-empty profile name.\")\n\n    if cloud_profile_name in profiles:\n        exit_with_error(f\"Profile {cloud_profile_name!r} already exists.\")\n\n    profiles.add_profile(\n        profiles[profiles.active_name].copy(\n            update={\n                \"name\": cloud_profile_name,\n            }\n        )\n    )\n\n    profiles.update_profile(\n        cloud_profile_name,\n        {\n            PREFECT_API_URL: build_url_from_workspace(\n                workspace_handle_details[workspace_handle]\n            ),\n            PREFECT_API_KEY: key,\n        },\n    )\n\n    profiles.set_active(cloud_profile_name)\n    save_profiles(profiles)\n\n    exit_with_success(\n        f\"Logged in to Prefect Cloud using profile {cloud_profile_name!r}.\\n\"\n        f\"Workspace is currently set to {workspace_handle!r}. \"\n        f\"The workspace can be changed using `prefect cloud workspace set`.\"\n    )\n\n\n@workspace_app.command()\nasync def ls():\n    \"\"\"List available workspaces.\"\"\"\n\n    confirm_logged_in()\n\n    async with get_cloud_client() as client:\n        try:\n            workspaces = await client.read_workspaces()\n        except CloudUnauthorizedError:\n            exit_with_error(\n                \"Unable to authenticate. Please ensure your credentials are correct.\"\n            )\n\n    workspace_handle_details = {\n        f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n        for workspace in workspaces\n    }\n\n    current_workspace = get_current_workspace(workspaces)\n\n    table = Table(caption=\"* active workspace\")\n    table.add_column(\n        \"[#024dfd]Available Workspaces:\", justify=\"right\", style=\"#8ea0ae\", no_wrap=True\n    )\n\n    for i, workspace_handle in enumerate(sorted(workspace_handle_details)):\n        if workspace_handle == current_workspace:\n            table.add_row(f\"[green]  * {workspace_handle}[/green]\")\n        else:\n            table.add_row(f\"  {workspace_handle}\")\n    app.console.print(table)\n\n\n@workspace_app.command()\nasync def set(\n    workspace_handle: str = typer.Option(\n        None,\n        \"--workspace\",\n        \"-w\",\n        help=\"Full handle of workspace, in format '<account_handle>/<workspace_handle>'\",\n    ),\n):\n    \"\"\"Set current workspace. Shows a workspace picker if no workspace is specified.\"\"\"\n    confirm_logged_in()\n\n    async with get_cloud_client() as client:\n        try:\n            workspaces = await client.read_workspaces()\n        except CloudUnauthorizedError:\n            exit_with_error(\n                \"Unable to authenticate. Please ensure your credentials are correct.\"\n            )\n    workspaces = {\n        f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n        for workspace in workspaces\n    }\n\n    if not workspace_handle:\n        workspace_handle = select_workspace(workspaces)\n\n    if workspace_handle not in workspaces:\n        exit_with_error(\n            f\"Workspace {workspace_handle!r} not found. \"\n            \"Leave `--workspace` blank to select a workspace.\"\n        )\n\n    profile = update_current_profile(\n        {PREFECT_API_URL: build_url_from_workspace(workspaces[workspace_handle])}\n    )\n\n    exit_with_success(\n        f\"Successfully set workspace to {workspace_handle!r} in profile {profile.name!r}.\"\n    )\n", "path": "src/prefect/cli/cloud.py"}], "after_files": [{"content": "\"\"\"\nCommand line interface for interacting with Prefect Cloud\n\"\"\"\nimport re\nfrom typing import Dict, Iterable\n\nimport httpx\nimport readchar\nimport typer\nfrom rich.live import Live\nfrom rich.table import Table\n\nimport prefect.context\nimport prefect.settings\nfrom prefect.cli._types import PrefectTyper\nfrom prefect.cli._utilities import exit_with_error, exit_with_success\nfrom prefect.cli.root import app\nfrom prefect.client.cloud import CloudUnauthorizedError, get_cloud_client\nfrom prefect.settings import (\n    PREFECT_API_KEY,\n    PREFECT_API_URL,\n    PREFECT_CLOUD_URL,\n    load_profiles,\n    save_profiles,\n    update_current_profile,\n)\n\ncloud_app = PrefectTyper(\n    name=\"cloud\", help=\"Commands for interacting with Prefect Cloud\"\n)\nworkspace_app = PrefectTyper(\n    name=\"workspace\", help=\"Commands for interacting with Prefect Cloud Workspaces\"\n)\ncloud_app.add_typer(workspace_app, aliases=[\"workspaces\"])\napp.add_typer(cloud_app)\n\n\ndef build_url_from_workspace(workspace: Dict) -> str:\n    return (\n        f\"{PREFECT_CLOUD_URL.value()}\"\n        f\"/accounts/{workspace['account_id']}\"\n        f\"/workspaces/{workspace['workspace_id']}\"\n    )\n\n\ndef confirm_logged_in():\n    if not PREFECT_API_KEY:\n        profile = prefect.context.get_settings_context().profile\n        exit_with_error(\n            f\"Currently not authenticated in profile {profile.name!r}. \"\n            \"Please login with `prefect cloud login --key <API_KEY>`.\"\n        )\n\n\ndef get_current_workspace(workspaces):\n    workspace_handles_by_id = {\n        workspace[\n            \"workspace_id\"\n        ]: f\"{workspace['account_handle']}/{workspace['workspace_handle']}\"\n        for workspace in workspaces\n    }\n    current_workspace_id = re.match(\n        r\".*accounts/.{36}/workspaces/(.{36})\\Z\", PREFECT_API_URL.value()\n    ).groups()[0]\n    return workspace_handles_by_id[current_workspace_id]\n\n\ndef build_table(selected_idx: int, workspaces: Iterable[str]) -> Table:\n    \"\"\"\n    Generate a table of workspaces. The `select_idx` of workspaces will be highlighted.\n\n    Args:\n        selected_idx: currently selected index\n        workspaces: Iterable of strings\n\n    Returns:\n        rich.table.Table\n    \"\"\"\n\n    table = Table()\n    table.add_column(\n        \"[#024dfd]Select a Workspace:\", justify=\"right\", style=\"#8ea0ae\", no_wrap=True\n    )\n\n    for i, workspace in enumerate(sorted(workspaces)):\n        if i == selected_idx:\n            table.add_row(\"[#024dfd on #FFFFFF]> \" + workspace)\n        else:\n            table.add_row(\"  \" + workspace)\n    return table\n\n\ndef select_workspace(workspaces: Iterable[str]) -> str:\n    \"\"\"\n    Given a list of workspaces, display them to user in a Table\n    and allow them to select one.\n\n    Args:\n        workspaces: List of workspaces to choose from\n\n    Returns:\n        str: the selected workspace\n    \"\"\"\n\n    workspaces = sorted(workspaces)\n    current_idx = 0\n    selected_workspace = None\n\n    with Live(\n        build_table(current_idx, workspaces), auto_refresh=False, console=app.console\n    ) as live:\n        while selected_workspace is None:\n            key = readchar.readkey()\n\n            if key == readchar.key.UP:\n                current_idx = current_idx - 1\n                # wrap to bottom if at the top\n                if current_idx < 0:\n                    current_idx = len(workspaces) - 1\n            elif key == readchar.key.DOWN:\n                current_idx = current_idx + 1\n                # wrap to top if at the bottom\n                if current_idx >= len(workspaces):\n                    current_idx = 0\n            elif key == readchar.key.CTRL_C:\n                # gracefully exit with no message\n                exit_with_error(\"\")\n            elif key == readchar.key.ENTER:\n                selected_workspace = workspaces[current_idx]\n\n            live.update(build_table(current_idx, workspaces), refresh=True)\n\n        return selected_workspace\n\n\n@cloud_app.command()\nasync def login(\n    key: str = typer.Option(\n        ..., \"--key\", \"-k\", help=\"API Key to authenticate with Prefect\", prompt=True\n    ),\n    workspace_handle: str = typer.Option(\n        None,\n        \"--workspace\",\n        \"-w\",\n        help=\"Full handle of workspace, in format '<account_handle>/<workspace_handle>'\",\n    ),\n):\n    \"\"\"\n    Log in to Prefect Cloud.\n    Creates a new profile configured to use the specified PREFECT_API_KEY.\n    Uses a previously configured profile if it exists.\n    \"\"\"\n    async with get_cloud_client(api_key=key) as client:\n        try:\n            workspaces = await client.read_workspaces()\n            workspace_handle_details = {\n                f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n                for workspace in workspaces\n            }\n        except CloudUnauthorizedError:\n            if key.startswith(\"pcu\"):\n                help_message = \"It looks like you're using API key from Cloud 1 (https://cloud.prefect.io). Make sure that you generate API key using Cloud 2 (https://app.prefect.cloud)\"\n            elif not key.startswith(\"pnu\"):\n                help_message = \"Your key is not in our expected format.\"\n            else:\n                help_message = \"Please ensure your credentials are correct.\"\n            exit_with_error(\n                f\"Unable to authenticate with Prefect Cloud. {help_message}\"\n            )\n        except httpx.HTTPStatusError as exc:\n            exit_with_error(f\"Error connecting to Prefect Cloud: {exc!r}\")\n\n    profiles = load_profiles()\n\n    for profile_name in profiles:\n        if key == profiles[profile_name].settings.get(PREFECT_API_KEY):\n            profiles.set_active(profile_name)\n            save_profiles(profiles)\n            with prefect.context.use_profile(profile_name):\n                current_workspace = get_current_workspace(workspaces)\n\n                if workspace_handle is not None:\n                    if workspace_handle not in workspace_handle_details:\n                        exit_with_error(f\"Workspace {workspace_handle!r} not found.\")\n\n                    update_current_profile(\n                        {\n                            PREFECT_API_URL: build_url_from_workspace(\n                                workspace_handle_details[workspace_handle]\n                            )\n                        }\n                    )\n                    current_workspace = workspace_handle\n\n            exit_with_success(\n                f\"Logged in to Prefect Cloud using profile {profile_name!r}.\\n\"\n                f\"Workspace is currently set to {current_workspace!r}. \"\n                f\"The workspace can be changed using `prefect cloud workspace set`.\"\n            )\n\n    if not workspace_handle:\n        workspace_handle = select_workspace(workspace_handle_details.keys())\n\n    if workspace_handle not in workspace_handle_details:\n        exit_with_error(f\"Workspace {workspace_handle!r} not found.\")\n\n    current_profile = update_current_profile(\n        {\n            PREFECT_API_URL: build_url_from_workspace(\n                workspace_handle_details[workspace_handle]\n            ),\n            PREFECT_API_KEY: key,\n        },\n    )\n\n    exit_with_success(\n        f\"Logged in to Prefect Cloud using profile {current_profile.name!r}.\\n\"\n        f\"Workspace is currently set to {workspace_handle!r}. \"\n        f\"The workspace can be changed using `prefect cloud workspace set`.\"\n    )\n\n\n@cloud_app.command()\nasync def logout():\n    \"\"\"\n    Logout the current workspace.\n    Reset PREFECT_API_KEY and PREFECT_API_URL to default.\n    \"\"\"\n    current_profile = prefect.context.get_settings_context().profile\n    if current_profile is None:\n        exit_with_error(\"There is no current profile set.\")\n\n    if current_profile.settings.get(PREFECT_API_KEY) is None:\n        exit_with_error(\"Current profile is not logged into Prefect Cloud.\")\n\n    update_current_profile(\n        {\n            PREFECT_API_URL: None,\n            PREFECT_API_KEY: None,\n        },\n    )\n\n    exit_with_success(\"Logged out from Prefect Cloud.\")\n\n\n@workspace_app.command()\nasync def ls():\n    \"\"\"List available workspaces.\"\"\"\n\n    confirm_logged_in()\n\n    async with get_cloud_client() as client:\n        try:\n            workspaces = await client.read_workspaces()\n        except CloudUnauthorizedError:\n            exit_with_error(\n                \"Unable to authenticate. Please ensure your credentials are correct.\"\n            )\n\n    workspace_handle_details = {\n        f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n        for workspace in workspaces\n    }\n\n    current_workspace = get_current_workspace(workspaces)\n\n    table = Table(caption=\"* active workspace\")\n    table.add_column(\n        \"[#024dfd]Available Workspaces:\", justify=\"right\", style=\"#8ea0ae\", no_wrap=True\n    )\n\n    for i, workspace_handle in enumerate(sorted(workspace_handle_details)):\n        if workspace_handle == current_workspace:\n            table.add_row(f\"[green]  * {workspace_handle}[/green]\")\n        else:\n            table.add_row(f\"  {workspace_handle}\")\n    app.console.print(table)\n\n\n@workspace_app.command()\nasync def set(\n    workspace_handle: str = typer.Option(\n        None,\n        \"--workspace\",\n        \"-w\",\n        help=\"Full handle of workspace, in format '<account_handle>/<workspace_handle>'\",\n    ),\n):\n    \"\"\"Set current workspace. Shows a workspace picker if no workspace is specified.\"\"\"\n    confirm_logged_in()\n\n    async with get_cloud_client() as client:\n        try:\n            workspaces = await client.read_workspaces()\n        except CloudUnauthorizedError:\n            exit_with_error(\n                \"Unable to authenticate. Please ensure your credentials are correct.\"\n            )\n    workspaces = {\n        f\"{workspace['account_handle']}/{workspace['workspace_handle']}\": workspace\n        for workspace in workspaces\n    }\n\n    if not workspace_handle:\n        workspace_handle = select_workspace(workspaces)\n\n    if workspace_handle not in workspaces:\n        exit_with_error(\n            f\"Workspace {workspace_handle!r} not found. \"\n            \"Leave `--workspace` blank to select a workspace.\"\n        )\n\n    profile = update_current_profile(\n        {PREFECT_API_URL: build_url_from_workspace(workspaces[workspace_handle])}\n    )\n\n    exit_with_success(\n        f\"Successfully set workspace to {workspace_handle!r} in profile {profile.name!r}.\"\n    )\n", "path": "src/prefect/cli/cloud.py"}]}