internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: PrefectHQ/prefect

Issue:
Fully functional “Cloud Flow” example
## Proposed behavior
*Please describe your proposed change to the current behavior*
* Welcome flow example
* More complex example with retries



## Example
*Please give an example of how the enhancement would be useful*
This would be useful for users new to Prefect Cloud. These would be some good flows to deploy to their Team for testing.



Discussion:
I think we could even take this to the level of a Tutorial which walks a user through deploying a small sqlite3 database in kubernetes, and then a corresponding "real" ETL workflow.
Tutorial meaning it's in Cloud UI? Or documentation with more detailed instructions?
https://docs.prefect.io/core/tutorials/ vs. https://docs.prefect.io/core/examples/

Examples are just code with minimal comments, tutorials are fleshed out content with explanation.

Resolving patch:
diff --git a/src/prefect/tasks/shell.py b/src/prefect/tasks/shell.py
--- a/src/prefect/tasks/shell.py
+++ b/src/prefect/tasks/shell.py
@@ -70,10 +70,9 @@ def run(self, command: str = None, env: dict = None) -> str:
                 the subprocess
 
         Returns:
-            - last line of stdout (string) if any and return_all is True, None
-                otherwise. All lines of stdout (array of strings) if return_all is
-                False: returns (last line of) stdout, which is useful for passing
-                result of shell command to other downstream tasks.
+            - stdout (string): if `return_all` is `False` (the default), only the last line of stdout
+                is returned, otherwise all lines are returned, which is useful for passing
+                result of shell command to other downstream tasks. If there is no output, `None` is returned.
 
         Raises:
             - prefect.engine.signals.FAIL: if command has an exit code other


Test patch:
diff --git a/tests/tasks/test_shell.py b/tests/tasks/test_shell.py
--- a/tests/tasks/test_shell.py
+++ b/tests/tasks/test_shell.py
@@ -38,6 +38,14 @@ def test_shell_initializes_and_multiline_output_returns_last_line():
     assert out.result[task].result == "42"
 
 
+def test_shell_returns_none_if_empty_output():
+    with Flow(name="test") as f:
+        task = ShellTask()(command="ls > /dev/null")
+    out = f.run()
+    assert out.is_successful()
+    assert out.result[task].result is None
+
+
 def test_shell_initializes_and_multiline_output_optionally_returns_all_lines():
     with Flow(name="test") as f:
         task = ShellTask(return_all=True)(command="echo -n 'hello world\n42'")
Repository: PrefectHQ/prefect

Issue:
Link to "coverage" directly from API sidebar
This vuepress enhancement will allow it, but depends on #770:

https://github.com/vuejs/vuepress/pull/1534


Discussion:

Resolving patch:
diff --git a/docs/generate_docs.py b/docs/generate_docs.py
--- a/docs/generate_docs.py
+++ b/docs/generate_docs.py
@@ -342,22 +342,6 @@ def create_tutorial_notebooks(tutorial):
         shutil.rmtree("api/unreleased", ignore_errors=True)
         os.makedirs("api/unreleased", exist_ok=True)
 
-        ## write link to hosted coverage reports
-        with open("api/unreleased/coverage.md", "w+") as f:
-            f.write(
-                textwrap.dedent(
-                    """
-                ---
-                title: Test Coverage
-                ---
-
-                # Unit test coverage report
-
-                To view test coverage reports, <a href="https://codecov.io/gh/PrefectHQ/prefect">click here</a>.
-                """
-                ).lstrip()
-            )
-
         ## UPDATE README
         with open("api/unreleased/README.md", "w+") as f:
             f.write(


Test patch:
Repository: PrefectHQ/prefect

Issue:
K8s Agent references old prefect docker image name
## Description
Whenever the kubernetes agent creates a job, it references our old docker image naming conventions in at least on place [here](https://github.com/PrefectHQ/prefect/blob/d204261c6f9856dbfd7442a194de91c4be768e7f/src/prefect/agent/kubernetes/agent.py#L198).  We should audit all such references and update them for our new naming scheme, which can be inferred from our `circleci/config.yml` file [here](https://github.com/PrefectHQ/prefect/blob/master/.circleci/config.yml#L296-L324)

**cc:** @joshmeek 


Discussion:
Due to the tagging changes we have a couple options around `"prefecthq/prefect:{}".format(image_version)`
1. Add a check here to use the new tagging conventions for >= 0.7.0 and old simple version convention for < 0.7.0
2. Add a new tag to the old images to follow the new convention in order to avoid a check
option 2.) seems like the easiest to me - no maintenance burden, just a one time tag / push of a lot of images
@cicdw Okay great, I'll make the PR and before it's merged we can tag those old images
Images for 0.6.7 and 0.6.6 have been built and pushed with the new naming schema.

Resolving patch:
diff --git a/src/prefect/agent/kubernetes/agent.py b/src/prefect/agent/kubernetes/agent.py
--- a/src/prefect/agent/kubernetes/agent.py
+++ b/src/prefect/agent/kubernetes/agent.py
@@ -179,7 +179,7 @@ def generate_deployment_yaml(
         labels = labels or []
 
         version = prefect.__version__.split("+")
-        image_version = "latest" if len(version) > 1 else version[0]
+        image_version = "latest" if len(version) > 1 else (version[0] + "-python3.6")
 
         with open(
             path.join(path.dirname(__file__), "deployment.yaml"), "r"


Test patch:
diff --git a/tests/agent/test_k8s_agent.py b/tests/agent/test_k8s_agent.py
--- a/tests/agent/test_k8s_agent.py
+++ b/tests/agent/test_k8s_agent.py
@@ -229,7 +229,7 @@ def test_k8s_agent_generate_deployment_yaml(monkeypatch, runner_token):
 @pytest.mark.parametrize(
     "version",
     [
-        ("0.6.3", "0.6.3"),
+        ("0.6.3", "0.6.3-python3.6"),
         ("0.5.3+114.g35bc7ba4", "latest"),
         ("0.5.2+999.gr34343.dirty", "latest"),
     ],
Repository: PrefectHQ/prefect

Issue:
What is the purpose of the empty "prefect.flows" module?
What is the purpose of the empty "prefect.flows" module?
It is also imported here https://github.com/PrefectHQ/prefect/blob/6f1015957019a86bb86a0504555c354cd8f4af6e/src/prefect/__init__.py#L14



Discussion:
AFAIK this does not serve any purpose and can be deleted. It was added by @jlowin so maybe he knows if it is needed
Ah, definitely not needed now. Originally this was to contain some composable “mini flows” before we adopted the pattern of using a function to generate tasks (like with ifelse). One day it might hold examples or something but it’s just a vestige now. 

Resolving patch:
diff --git a/src/prefect/__init__.py b/src/prefect/__init__.py
--- a/src/prefect/__init__.py
+++ b/src/prefect/__init__.py
@@ -11,7 +11,6 @@
 from prefect.core import Task, Flow, Parameter
 import prefect.engine
 import prefect.tasks
-import prefect.flows
 from prefect.utilities.tasks import task, tags, unmapped
 
 import prefect.serialization
diff --git a/src/prefect/flows/__init__.py b/src/prefect/flows/__init__.py
deleted file mode 100644
--- a/src/prefect/flows/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-


Test patch:
Repository: PrefectHQ/prefect

Issue:
Explore Upgrading Python K8s library
We're currently bound by 10.0 

https://github.com/kubernetes-client/python/releases/tag/v11.0.0a1\

**cc:** @joshmeek 


Discussion:
Only reason this is ticket worthy is that we've had issues in the past with python-kubernetes versions

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -23,7 +23,7 @@
         "google-cloud-bigquery >= 1.6.0, < 2.0",
         "google-cloud-storage >= 1.13, < 2.0",
     ],
-    "kubernetes": ["kubernetes >= 9.0.0a1, < 10.0", "dask-kubernetes >= 0.8.0"],
+    "kubernetes": ["kubernetes >= 9.0.0a1, <= 11.0.0b2", "dask-kubernetes >= 0.8.0"],
     "postgres": ["psycopg2-binary >= 2.8.2"],
     "redis": ["redis >= 3.2.1"],
     "rss": ["feedparser >= 5.0.1, < 6.0"],


Test patch:
Repository: PrefectHQ/prefect

Issue:
Agent shutdown can take up to 10 seconds
## Current behavior
Today, when an agent is signaled to exit it can take up to 10 seconds to respond and shutdown. This is due to a canned sleep in a polling loop.


## Proposed behavior
The agent should respond immediately to exit requests, especially when sleeping.



Discussion:

Resolving patch:
diff --git a/src/prefect/agent/agent.py b/src/prefect/agent/agent.py
--- a/src/prefect/agent/agent.py
+++ b/src/prefect/agent/agent.py
@@ -3,6 +3,7 @@
 import signal
 import sys
 import time
+import threading
 from contextlib import contextmanager
 from typing import Any, Callable, Generator, Iterable, Union
 
@@ -26,20 +27,18 @@
 """
 
 
-def _exit(agent: "Agent") -> Callable:
+@contextmanager
+def exit_handler(agent: "Agent") -> Generator:
+    exit_event = threading.Event()
+
     def _exit_handler(*args: Any, **kwargs: Any) -> None:
-        agent.is_running = False
         agent.logger.info("Keyboard Interrupt received: Agent is shutting down.")
+        exit_event.set()
 
-    return _exit_handler
-
-
-@contextmanager
-def keyboard_handler(agent: "Agent") -> Generator:
     original = signal.getsignal(signal.SIGINT)
     try:
-        signal.signal(signal.SIGINT, _exit(agent))
-        yield
+        signal.signal(signal.SIGINT, _exit_handler)
+        yield exit_event
     finally:
         signal.signal(signal.SIGINT, original)
 
@@ -117,15 +116,14 @@ def start(self) -> None:
         The main entrypoint to the agent. This function loops and constantly polls for
         new flow runs to deploy
         """
-        with keyboard_handler(self):
-            self.is_running = True
+        with exit_handler(self) as exit_event:
             tenant_id = self.agent_connect()
 
             # Loop intervals for query sleep backoff
             loop_intervals = {0: 0.25, 1: 0.5, 2: 1.0, 3: 2.0, 4: 4.0, 5: 8.0, 6: 10.0}
 
             index = 0
-            while self.is_running:
+            while not exit_event.wait(timeout=loop_intervals[index]):
                 self.heartbeat()
 
                 runs = self.agent_process(tenant_id)
@@ -139,7 +137,6 @@ def start(self) -> None:
                         loop_intervals[index]
                     )
                 )
-                time.sleep(loop_intervals[index])
 
     def agent_connect(self) -> str:
         """


Test patch:
Repository: PrefectHQ/prefect

Issue:
Aggregate Minor Version API Docs
Instead of `0.9.0` and `0.9.1` the latest documentation will point to `0.9.x`. This is due to the low changes in API documentation between patch releases. Will remove the extra step of regenerating all API docs every couple weeks.


Discussion:
We should also rename "unreleased" to "latest"

Resolving patch:
diff --git a/docs/generate_docs.py b/docs/generate_docs.py
--- a/docs/generate_docs.py
+++ b/docs/generate_docs.py
@@ -339,11 +339,11 @@ def create_tutorial_notebooks(tutorial):
             """
         ).lstrip()
 
-        shutil.rmtree("api/unreleased", ignore_errors=True)
-        os.makedirs("api/unreleased", exist_ok=True)
+        shutil.rmtree("api/latest", ignore_errors=True)
+        os.makedirs("api/latest", exist_ok=True)
 
         ## UPDATE README
-        with open("api/unreleased/README.md", "w+") as f:
+        with open("api/latest/README.md", "w+") as f:
             f.write(
                 textwrap.dedent(
                     """
@@ -377,7 +377,7 @@ def create_tutorial_notebooks(tutorial):
                 f.write(auto_generated_footer)
 
         ## UPDATE CHANGELOG
-        with open("api/unreleased/changelog.md", "w+") as f:
+        with open("api/latest/changelog.md", "w+") as f:
             f.write(
                 textwrap.dedent(
                     """
@@ -400,7 +400,7 @@ def create_tutorial_notebooks(tutorial):
                 page.get("classes", []),
                 page.get("functions", []),
             )
-            fname = f"api/unreleased/{fname}"
+            fname = f"api/latest/{fname}"
             directory = os.path.dirname(fname)
             if directory:
                 os.makedirs(directory, exist_ok=True)


Test patch:
Repository: PrefectHQ/prefect

Issue:
Investigate clock test failure
https://circleci.com/gh/PrefectHQ/prefect/52671

```
================================== FAILURES ===================================
_____________ TestCronClock.test_cron_clock_respects_microseconds _____________
self = <tests.schedules.test_clocks.TestCronClock object at 0x0000008C18CFE9C8>
    def test_cron_clock_respects_microseconds(self):
        every_day = "0 0 * * *"
        start_date = pendulum.datetime(2050, 1, 1, 0, 0, 0, 1)
        c = clocks.CronClock(every_day, start_date=start_date)
>       assert islice(c.events(), 1) == [pendulum.datetime(2050, 1, 2)]
E       AssertionError: assert [DateTime(205...ezone('UTC'))] == [DateTime(205...ezone('UTC'))]
E         At index 0 diff: DateTime(2050, 1, 1, 0, 0, 0, tzinfo=Timezone('UTC')) != DateTime(2050, 1, 2, 0, 0, 0, tzinfo=Timezone('UTC'))
E         Use -v to get the full diff
tests\schedules\test_clocks.py:298: AssertionError
```


Discussion:
Croniter was updated https://github.com/kiorky/croniter/commit/ab4a0a0188bca54109469aefed3b38160a4a1576 to remove

```python
# milliseconds/microseconds rounds	
if start_time.microsecond:	
    start_time = start_time + relativedelta(seconds=1)
```

Either we can update the single failing test or add this rounding back into the Clock's `events`. Open to suggestions

The previous expected behavior was that get_next on `(2050, 1, 1, 0, 0, 0, 1)` would return `(2050, 1, 2, 0, 0, 0, 0)` but instead it now returns `(2050, 1, 1, 0, 0, 0, 0)`
Hm, first off that is incredibly frustrating.  It seems that we've been running into a few microsecond-based issues recently, so I wonder if we should simply start ignoring microseconds (e.g., setting microsecond = 0 for all scheduling datetimes in Prefect using `replace`).  I suspect this doesn't actually impact anything given the coarse level we tend to schedule at, but it'd be good to sort out.
I bounded `croniter` above in #1894 to get tests passing but we should fix this more robustly and remove that bound when we do.

Resolving patch:
diff --git a/src/prefect/schedules/clocks.py b/src/prefect/schedules/clocks.py
--- a/src/prefect/schedules/clocks.py
+++ b/src/prefect/schedules/clocks.py
@@ -198,6 +198,10 @@ class CronClock(Clock):
 
     Note that this behavior is different from the `IntervalClock`.
 
+    NOTE: `CronClock` respects microseconds meaning for a clock that runs once a day, if
+    the start time is `(2020, 1, 1, 0, 0, 0, 1)` then the first scheduled run will be
+    `(2020, 1, 2, 0, 0, 0, 0)`.
+
     Args:
         - cron (str): a valid cron string
         - start_date (datetime, optional): an optional start date for the clock
@@ -264,6 +268,11 @@ def events(self, after: datetime = None) -> Iterable[ClockEvent]:
                 microsecond=after.microsecond,
             )
         )
+
+        # Respect microseconds by rounding up
+        if after_localized.microsecond:
+            after_localized = after_localized + timedelta(seconds=1)
+
         cron = croniter(self.cron, after_localized)
         dates = set()  # type: Set[datetime]
 


Test patch:
Repository: PrefectHQ/prefect

Issue:
AuthorizationError when watching logs from CLI
When running with `prefect run cloud --logs`, after a few minutes I see the following error:
```
prefect.utilities.exceptions.AuthorizationError: [{'message': 'AuthenticationError', 'locations': [], 'path': ['flow_run'], 'extensions': {'code': 'UNAUTHENTICATED'}}]
```
The run itself succeeds but the logs stop at that point, so I guess the token is initially valid but just expires...?

cc @joshmeek @cicdw 


Discussion:
Thanks for opening! Will look into the refresh of tokens that are generated via the Personal Access Token 👍 

Resolving patch:
diff --git a/src/prefect/cli/run.py b/src/prefect/cli/run.py
--- a/src/prefect/cli/run.py
+++ b/src/prefect/cli/run.py
@@ -202,7 +202,7 @@ def cloud(
         }
 
         while True:
-            result = Client().graphql(query)
+            result = client.graphql(query)
 
             flow_run = result.data.flow_run
             if not flow_run:


Test patch:
Repository: PrefectHQ/prefect

Issue:
Add code examples to Result Handler concept docs
The docs for results and result handlers could use some code examples either in the concept doc itself or linking to other tutorials/examples around using results https://docs.prefect.io/core/concepts/results.html


Discussion:

Resolving patch:
diff --git a/src/prefect/engine/cloud/task_runner.py b/src/prefect/engine/cloud/task_runner.py
--- a/src/prefect/engine/cloud/task_runner.py
+++ b/src/prefect/engine/cloud/task_runner.py
@@ -43,8 +43,7 @@ class CloudTaskRunner(TaskRunner):
             If multiple functions are passed, then the `new_state` argument will be the
             result of the previous handler.
         - result_handler (ResultHandler, optional): the handler to use for
-            retrieving and storing state results during execution (if the Task doesn't already have one);
-            if not provided here or by the Task, will default to the one specified in your config
+            retrieving and storing state results during execution (if the Task doesn't already have one)
     """
 
     def __init__(
diff --git a/src/prefect/engine/result.py b/src/prefect/engine/result.py
--- a/src/prefect/engine/result.py
+++ b/src/prefect/engine/result.py
@@ -101,7 +101,7 @@ class SafeResult(ResultInterface):
     the serialized value of a task's result, and a result handler specifying how to deserialize this value
 
     Args:
-        - value (Any): the safe represenation of a value
+        - value (Any): the safe representation of a value
         - result_handler (ResultHandler): the result handler to use when reading this result's value
     """
 
diff --git a/src/prefect/engine/task_runner.py b/src/prefect/engine/task_runner.py
--- a/src/prefect/engine/task_runner.py
+++ b/src/prefect/engine/task_runner.py
@@ -77,8 +77,7 @@ class TaskRunner(Runner):
             If multiple functions are passed, then the `new_state` argument will be the
             result of the previous handler.
         - result_handler (ResultHandler, optional): the handler to use for
-            retrieving and storing state results during execution (if the Task doesn't already have one);
-            if not provided here or by the Task, will default to the one specified in your config
+            retrieving and storing state results during execution (if the Task doesn't already have one)
     """
 
     def __init__(


Test patch:
Repository: PrefectHQ/prefect

Issue:
Deserializing data mutates the input payload in place
## Description
*A clear description of the bug*
Loading data mutates the input payload by stripping its version tag. This means that in an (unusual) situation where a serialized payload is deserialized twice in sequence, the first time has an opportunity to look at its version information but the second time does not because the key is deleted.



## Expected Behavior
*What did you expect to happen instead?*
The input payload should not be mutated.




## Reproduction
*A minimal example that exhibits the behavior.*

```python
from prefect import Task
from prefect.serialization.task import TaskSchema

serialized = TaskSchema().dump(Task())
assert '__version__' in serialized 

deserialized = TaskSchema().load(serialized)
assert '__version__' not in serialized # oh no!
```

## Environment
*Any additional information about your environment*



Discussion:

Resolving patch:
diff --git a/src/prefect/utilities/serialization.py b/src/prefect/utilities/serialization.py
--- a/src/prefect/utilities/serialization.py
+++ b/src/prefect/utilities/serialization.py
@@ -102,6 +102,8 @@ def _remove_version(self, data: dict, **kwargs: Any) -> dict:
         Returns:
             - dict: the data dict, without its __version__ field
         """
+        # don't mutate data
+        data = data.copy()
         data.pop("__version__", None)
         return data
 
@@ -116,6 +118,8 @@ def _add_version(self, data: dict, **kwargs: Any) -> dict:
         Returns:
             - dict: the data dict, with an additional __version__ field
         """
+        # don't mutate data
+        data = data.copy()
         data.setdefault("__version__", prefect.__version__)
         return data
 


Test patch:
diff --git a/tests/utilities/test_serialization.py b/tests/utilities/test_serialization.py
--- a/tests/utilities/test_serialization.py
+++ b/tests/utilities/test_serialization.py
@@ -299,6 +299,22 @@ class Meta:
         serialized = Schema().dump(TestObject(x=5))
         assert serialized == {"__version__": prefect.__version__, "x": 5}
 
+    def test_schema_doesnt_mutate_object_on_load(self):
+        class TestObject:
+            def __init__(self, x):
+                self.x = x
+
+        class Schema(ObjectSchema):
+            class Meta:
+                object_class = TestObject
+
+            x = marshmallow.fields.Int()
+
+        serialized = Schema().dump(TestObject(x=5))
+
+        Schema().load(serialized)
+        assert serialized == {"__version__": prefect.__version__, "x": 5}
+
     def test_schema_creates_object(self):
         class TestObject:
             def __init__(self, x):
Repository: PrefectHQ/prefect

Issue:
Update Context documentation
We need to update:
- https://docs.prefect.io/api/latest/utilities/context.html 
- https://docs.prefect.io/core/concepts/execution.html#context 

with more information as to what context can be used for, how you can override values and why you might want to use custom values.


Discussion:

Resolving patch:
diff --git a/src/prefect/utilities/context.py b/src/prefect/utilities/context.py
--- a/src/prefect/utilities/context.py
+++ b/src/prefect/utilities/context.py
@@ -52,7 +52,7 @@
 | `task_run_id` | the id of the current task run |
 | `task_run_version` | the state version of the current task run |
 
-Users can also provide values to context at runtime.
+Users can also provide values to context at runtime. For more information, see the [Context concept doc](https://docs.prefect.io/core/concepts/execution.html#context).
 """
 
 import contextlib


Test patch: