PrefectHQ/prefect

Can't use ephemeral server after running "prefect server start"

Closed this issue · 4 comments

Bug summary

In a from scratch helloworld type example, once I ran prefect server start once, I can no longer get the flow to run with the ephemeral server. The only fix is to delete ~/.prefect/prfiles.toml.

Version info

Version:             3.1.4
API version:         0.8.4
Python version:      3.12.4
Git commit:          78ee41cb
Built:               Wed, Nov 20, 2024 7:37 PM
OS/Arch:             darwin/arm64
Profile:             ephemeral
Server type:         unconfigured
Pydantic version:    2.10.1
Integrations:
  prefect-dask:      0.3.2

Additional context

Steps to reproduce:

  1. Delete ~/.prefect
  2. Run prefect config view to verify that PREFECT_API_URL is not set.
  3. From a new venv, run a flow with the ephemeral server and verify that it succeeded.
  4. Run touch ~/.prefect/profiles.toml
  5. Run the flow again, now it will fail with ValueError: No Prefect API URL provided. Please set PREFECT_API_URL to the address of a running Prefect server.

A simple reproduct way, following this tutorial: https://docs.prefect.io/v3/get-started/quickstart

  1. rm -rf ~/.prefect
  2. prefect server start
  3. python my_workflow.py

It will shows ValueError: No Prefect API URL provided. Please set PREFECT_API_URL to the address of a running Prefect server.

Run prefect config view will get PREFECT_API_URL ='http://127.0.0.1:4200/api' (from profile)

SettingContext.settings did not include profile settings, I've created a pr to fix it: #16112, by attaching profile settings into root context

class SettingsContext(ContextModel):
"""
The context for a Prefect settings.
This allows for safe concurrent access and modification of settings.
Attributes:
profile: The profile that is in use.
settings: The complete settings model.
"""
profile: Profile
settings: Settings
__var__: ContextVar = ContextVar("settings")
def __hash__(self) -> int:
return hash(self.settings)
@classmethod
def get(cls) -> "SettingsContext":
# Return the global context instead of `None` if no context exists
return super().get() or GLOBAL_SETTINGS_CONTEXT

Thanks for the issue @joe-dannce and thanks for looking into it @Wh1isper! I tracked down the root cause to be that we aren't handling empty profile files correctly. We should be falling back to the default ephemeral profile, but we aren't. I think this should be fixed in #16119 if either of you want to take a look!

The patch looks great!