Skip to content

fix: reset user agent for each requests in local pfs #10444

fix: reset user agent for each requests in local pfs

fix: reset user agent for each requests in local pfs #10444

GitHub Actions / promptflow SDK CLI Azure E2E Test Result [zhangxingzhi/reset-user-agent-for-each-pfs-request](https://github.com/microsoft/promptflow/actions/workflows/promptflow-sdk-cli-azure-e2e-test.yml?query=branch:zhangxingzhi/reset-user-agent-for-each-pfs-request++) failed Mar 12, 2024 in 0s

1 errors, 4 fail, 19 skipped, 144 pass in 3m 46s

  4 files  ±0    4 suites  ±0   3m 46s ⏱️ -5s
168 tests ±0  144 ✅  -  5  19 💤 ±0   4 ❌ + 4  1 🔥 +1 
672 runs  ±0  579 ✅  - 17  76 💤 ±0  13 ❌ +13  4 🔥 +4 

Results for commit 9d307e0. ± Comparison against earlier commit 668685d.

Annotations

Check warning on line 0 in tests.sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry

See this annotation in the file changed.

@github-actions github-actions / promptflow SDK CLI Azure E2E Test Result [zhangxingzhi/reset-user-agent-for-each-pfs-request](https://github.com/microsoft/promptflow/actions/workflows/promptflow-sdk-cli-azure-e2e-test.yml?query=branch:zhangxingzhi/reset-user-agent-for-each-pfs-request++)

All 4 runs failed: test_sdk_telemetry_ua (tests.sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry)

artifacts/Test Results (Python 3.10) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.11) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.8) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.9) (OS ubuntu-latest)/test-results.xml [took 0s]
Raw output
AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'
self = <sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry object at 0x7f7feba54b20>
pf = <promptflow.azure._pf_client.PFClient object at 0x7f7fffcb6640>

    def test_sdk_telemetry_ua(self, pf):
        from promptflow import PFClient
        from promptflow.azure import PFClient as PFAzureClient
    
        # log activity will pick correct ua
        def assert_ua(*args, **kwargs):
            ua = pydash.get(kwargs, "extra.custom_dimensions.user_agent", None)
            ua_dict = parse_ua_to_dict(ua)
            assert ua_dict.keys() == {"promptflow-sdk"}
    
        logger = MagicMock()
        logger.info = MagicMock()
        logger.info.side_effect = assert_ua
    
        # clear user agent before test
        context = OperationContext().get_instance()
        context.user_agent = ""
        # get telemetry logger from SDK should not have extension ua
        # start a clean local SDK client
        with environment_variable_overwrite(PF_USER_AGENT, ""):
>           PFClient()

tests/sdk_cli_azure_test/e2etests/test_telemetry.py:243: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <promptflow._sdk._pf_client.PFClient object at 0x7f7fffc99d90>
kwargs = {}

    def __init__(self, **kwargs):
        logger.debug("PFClient init with kwargs: %s", kwargs)
        # when this is set, telemetry from this client will use this user agent instead of the one from OperationContext
        if isinstance(kwargs.get(BONDED_USER_AGENT_KEY), str):
            self._bonded_user_agent = kwargs[BONDED_USER_AGENT_KEY]
        self._connection_provider = kwargs.pop("connection_provider", None)
        self._config = kwargs.get("config", None) or {}
        # The credential is used as an option to override
        # DefaultAzureCredential when using workspace connection provider
        self._credential = kwargs.get("credential", None)
    
        # bonded_user_agent will be applied to all TelemetryMixin operations
>       self._runs = RunOperations(self, bonded_user_agent=self._bonded_user_agent)
E       AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'

promptflow/_sdk/_pf_client.py:49: AttributeError

Check warning on line 0 in tests.sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry

See this annotation in the file changed.

@github-actions github-actions / promptflow SDK CLI Azure E2E Test Result [zhangxingzhi/reset-user-agent-for-each-pfs-request](https://github.com/microsoft/promptflow/actions/workflows/promptflow-sdk-cli-azure-e2e-test.yml?query=branch:zhangxingzhi/reset-user-agent-for-each-pfs-request++)

All 4 runs failed: test_different_request_id (tests.sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry)

artifacts/Test Results (Python 3.10) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.11) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.8) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.9) (OS ubuntu-latest)/test-results.xml [took 0s]
Raw output
AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'
self = <sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry object at 0x7f7feb98d550>

    def test_different_request_id(self):
        from promptflow import PFClient
    
>       pf = PFClient()

tests/sdk_cli_azure_test/e2etests/test_telemetry.py:314: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <promptflow._sdk._pf_client.PFClient object at 0x7f7fffdf7af0>
kwargs = {}

    def __init__(self, **kwargs):
        logger.debug("PFClient init with kwargs: %s", kwargs)
        # when this is set, telemetry from this client will use this user agent instead of the one from OperationContext
        if isinstance(kwargs.get(BONDED_USER_AGENT_KEY), str):
            self._bonded_user_agent = kwargs[BONDED_USER_AGENT_KEY]
        self._connection_provider = kwargs.pop("connection_provider", None)
        self._config = kwargs.get("config", None) or {}
        # The credential is used as an option to override
        # DefaultAzureCredential when using workspace connection provider
        self._credential = kwargs.get("credential", None)
    
        # bonded_user_agent will be applied to all TelemetryMixin operations
>       self._runs = RunOperations(self, bonded_user_agent=self._bonded_user_agent)
E       AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'

promptflow/_sdk/_pf_client.py:49: AttributeError

Check warning on line 0 in tests.sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry

See this annotation in the file changed.

@github-actions github-actions / promptflow SDK CLI Azure E2E Test Result [zhangxingzhi/reset-user-agent-for-each-pfs-request](https://github.com/microsoft/promptflow/actions/workflows/promptflow-sdk-cli-azure-e2e-test.yml?query=branch:zhangxingzhi/reset-user-agent-for-each-pfs-request++)

All 4 runs failed: test_different_event_for_node_run (tests.sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry)

artifacts/Test Results (Python 3.10) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.11) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.8) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.9) (OS ubuntu-latest)/test-results.xml [took 0s]
Raw output
AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'
self = <sdk_cli_azure_test.e2etests.test_telemetry.TestTelemetry object at 0x7f7feb98dd90>

    def test_different_event_for_node_run(self):
        from promptflow import PFClient
    
>       pf = PFClient()

tests/sdk_cli_azure_test/e2etests/test_telemetry.py:379: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <promptflow._sdk._pf_client.PFClient object at 0x7f7fffb552e0>
kwargs = {}

    def __init__(self, **kwargs):
        logger.debug("PFClient init with kwargs: %s", kwargs)
        # when this is set, telemetry from this client will use this user agent instead of the one from OperationContext
        if isinstance(kwargs.get(BONDED_USER_AGENT_KEY), str):
            self._bonded_user_agent = kwargs[BONDED_USER_AGENT_KEY]
        self._connection_provider = kwargs.pop("connection_provider", None)
        self._config = kwargs.get("config", None) or {}
        # The credential is used as an option to override
        # DefaultAzureCredential when using workspace connection provider
        self._credential = kwargs.get("credential", None)
    
        # bonded_user_agent will be applied to all TelemetryMixin operations
>       self._runs = RunOperations(self, bonded_user_agent=self._bonded_user_agent)
E       AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'

promptflow/_sdk/_pf_client.py:49: AttributeError

Check failure on line 0 in tests.sdk_cli_azure_test.e2etests.test_flow_serve

See this annotation in the file changed.

@github-actions github-actions / promptflow SDK CLI Azure E2E Test Result [zhangxingzhi/reset-user-agent-for-each-pfs-request](https://github.com/microsoft/promptflow/actions/workflows/promptflow-sdk-cli-azure-e2e-test.yml?query=branch:zhangxingzhi/reset-user-agent-for-each-pfs-request++)

All 4 runs with error: test_azureml_serving_api_with_connection_data_override (tests.sdk_cli_azure_test.e2etests.test_flow_serve)

artifacts/Test Results (Python 3.10) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.11) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.8) (OS ubuntu-latest)/test-results.xml [took 0s]
artifacts/Test Results (Python 3.9) (OS ubuntu-latest)/test-results.xml [took 0s]
Raw output
failed on setup with "AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'"
mocker = <pytest_mock.plugin.MockerFixture object at 0x7f7fff8cbaf0>
remote_workspace_resource_id = 'azureml:/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000'

    @pytest.fixture
    def serving_client_with_connection_data_override(mocker: MockerFixture, remote_workspace_resource_id):
        model_name = "llm_connection_override"
        model_path = (Path(MODEL_ROOT) / model_name).resolve().absolute()
        # load arm connection template
        connection_arm_template = model_path.joinpath("connection_arm_template.json").read_text()
        connections = {
            "aoai_connection": connection_arm_template,
            "PROMPTFLOW_CONNECTION_PROVIDER": remote_workspace_resource_id,
        }
>       return create_serving_client_with_connections(model_name, mocker, connections)

tests/sdk_cli_azure_test/conftest.py:215: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/sdk_cli_azure_test/conftest.py:234: in create_serving_client_with_connections
    app = create_serving_app(
promptflow/_sdk/_serving/app.py:220: in create_app
    app.init(**kwargs)
promptflow/_sdk/_serving/app.py:96: in init
    raise e
promptflow/_sdk/_serving/app.py:93: in init
    self.init_invoker_if_not_exist()
promptflow/_sdk/_serving/app.py:112: in init_invoker_if_not_exist
    self.flow_invoker = FlowInvoker(
promptflow/_sdk/_serving/flow_invoker.py:74: in __init__
    self._init_connections(connection_provider)
promptflow/_sdk/_serving/flow_invoker.py:88: in _init_connections
    client=PFClient(config={"connection.provider": connection_provider}, credential=self._credential),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <promptflow._sdk._pf_client.PFClient object at 0x7f7fff89d6a0>
kwargs = {'config': {'connection.provider': 'azureml:/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000'}, 'credential': None}

    def __init__(self, **kwargs):
        logger.debug("PFClient init with kwargs: %s", kwargs)
        # when this is set, telemetry from this client will use this user agent instead of the one from OperationContext
        if isinstance(kwargs.get(BONDED_USER_AGENT_KEY), str):
            self._bonded_user_agent = kwargs[BONDED_USER_AGENT_KEY]
        self._connection_provider = kwargs.pop("connection_provider", None)
        self._config = kwargs.get("config", None) or {}
        # The credential is used as an option to override
        # DefaultAzureCredential when using workspace connection provider
        self._credential = kwargs.get("credential", None)
    
        # bonded_user_agent will be applied to all TelemetryMixin operations
>       self._runs = RunOperations(self, bonded_user_agent=self._bonded_user_agent)
E       AttributeError: 'PFClient' object has no attribute '_bonded_user_agent'

promptflow/_sdk/_pf_client.py:49: AttributeError

Check warning on line 0 in tests.sdk_cli_azure_test.e2etests.test_flow_operations.TestFlow

See this annotation in the file changed.

@github-actions github-actions / promptflow SDK CLI Azure E2E Test Result [zhangxingzhi/reset-user-agent-for-each-pfs-request](https://github.com/microsoft/promptflow/actions/workflows/promptflow-sdk-cli-azure-e2e-test.yml?query=branch:zhangxingzhi/reset-user-agent-for-each-pfs-request++)

1 out of 4 runs failed: test_update_flow (tests.sdk_cli_azure_test.e2etests.test_flow_operations.TestFlow)

artifacts/Test Results (Python 3.10) (OS ubuntu-latest)/test-results.xml [took 0s]
Raw output
AssertionError: Regex pattern did not match.
 Regex: 'Flow with id fake_flow_name not found'
 Input: "Failed to update azure flow 'fake_flow_name' due to: Calling update_flow failed with request id: 678911e5-075e-41fd-bb5e-581e6dd69218 \nStatus code: 401 \nReason: Invalid token \nError message: (UserError) Invalid token\nCode: UserError\nMessage: Invalid token \n. If the flow is not found in azure, please make sure the flow name is correct."
self = <promptflow.azure._restclient.flow_service_caller.FlowServiceCaller object at 0x7fc09b53c7f0>
args = ()
kwargs = {'body': {'description': 'SDK test flow description', 'flow_name': 'A new test flow', 'tags': {'key1': 'value1', 'owne..._id': 'fake_flow_name', 'resource_group_name': '00000', 'subscription_id': '00000000-0000-0000-0000-000000000000', ...}

    @wraps(func)
    def wrapper(self, *args, **kwargs):
        if not isinstance(self, RequestTelemetryMixin):
            raise PromptflowException(f"Wrapped function is not RequestTelemetryMixin, got {type(self)}")
        # refresh request before each request
        self._refresh_request_id_for_telemetry()
        try:
>           return func(self, *args, **kwargs)

promptflow/azure/_restclient/flow_service_caller.py:63: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
promptflow/azure/_restclient/flow_service_caller.py:185: in update_flow
    return self.caller.flows.update_flow(
/opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/azure/core/tracing/decorator.py:78: in wrapper_use_tracer
    return func(*args, **kwargs)
promptflow/azure/_restclient/flow/operations/_flows_operations.py:1354: in update_flow
    map_error(status_code=response.status_code, response=response, error_map=error_map)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

status_code = 401
response = <RequestsTransportResponse: 401 Invalid token, Content-Type: application/json>
error_map = {401: <class 'azure.core.exceptions.ClientAuthenticationError'>, 404: <class 'azure.core.exceptions.ResourceNotFoundError'>, 409: <class 'azure.core.exceptions.ResourceExistsError'>}

    def map_error(
        status_code: int, response: _HttpResponseCommonAPI, error_map: Mapping[int, Type[HttpResponseError]]
    ) -> None:
        if not error_map:
            return
        error_type = error_map.get(status_code)
        if not error_type:
            return
        error = error_type(response=response)
>       raise error
E       azure.core.exceptions.ClientAuthenticationError: (UserError) Invalid token
E       Code: UserError
E       Message: Invalid token

/opt/hostedtoolcache/Python/3.10.13/x64/lib/python3.10/site-packages/azure/core/exceptions.py:164: ClientAuthenticationError

During handling of the above exception, another exception occurred:

self = <promptflow.azure.operations._flow_operations.FlowOperations object at 0x7fc099447fa0>
flow = <promptflow.azure._entities._flow.Flow object at 0x7fc09b5da230>
display_name = 'A new test flow', kwargs = {}
description = 'SDK test flow description'
tags = {'key1': 'value1', 'owner': 'sdk-test'}
body = {'description': 'SDK test flow description', 'flow_name': 'A new test flow', 'tags': {'key1': 'value1', 'owner': 'sdk-test'}}

    def _update_azure_flow(self, flow: Flow, display_name, **kwargs):
        """Update an existing flow in azure."""
        logger.info("Validating flow update parameters.")
    
        display_name = display_name or flow.display_name
        if not isinstance(display_name, str) and display_name is not None:
            logger.warn(f"Display name must be a string, got {display_name!r}.")
            display_name = None
    
        description = kwargs.get("description", flow.description)
        if not isinstance(description, str) and description is not None:
            logger.warn(f"Description must be a string, got {description!r}.")
            description = None
    
        tags = kwargs.get("tags", flow.tags)
        if not isinstance(tags, dict) and tags is not None:
            logger.warn(f"Tags must be a dictionary, got {tags!r}.")
            tags = None
    
        body = {
            "flow_name": display_name,
            "description": description,
            "tags": tags,
        }
        body = {k: v for k, v in body.items() if v is not None}
        logger.debug(f"Updating flow {flow.name!r} with data {body}.")
    
        try:
>           self._service_caller.update_flow(
                subscription_id=self._operation_scope.subscription_id,
                resource_group_name=self._operation_scope.resource_group_name,
                workspace_name=self._operation_scope.workspace_name,
                flow_id=flow.name,
                body=body,
            )

promptflow/azure/operations/_flow_operations.py:187: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <promptflow.azure._restclient.flow_service_caller.FlowServiceCaller object at 0x7fc09b53c7f0>
args = ()
kwargs = {'body': {'description': 'SDK test flow description', 'flow_name': 'A new test flow', 'tags': {'key1': 'value1', 'owne..._id': 'fake_flow_name', 'resource_group_name': '00000', 'subscription_id': '00000000-0000-0000-0000-000000000000', ...}

    @wraps(func)
    def wrapper(self, *args, **kwargs):
        if not isinstance(self, RequestTelemetryMixin):
            raise PromptflowException(f"Wrapped function is not RequestTelemetryMixin, got {type(self)}")
        # refresh request before each request
        self._refresh_request_id_for_telemetry()
        try:
            return func(self, *args, **kwargs)
        except HttpResponseError as e:
>           raise FlowRequestException(
                f"Calling {func.__name__} failed with request id: {self._request_id} \n"
                f"Status code: {e.status_code} \n"
                f"Reason: {e.reason} \n"
                f"Error message: {e.message} \n"
            )
E           promptflow.azure._restclient.flow_service_caller.FlowRequestException: Calling update_flow failed with request id: 678911e5-075e-41fd-bb5e-581e6dd69218 
E           Status code: 401 
E           Reason: Invalid token 
E           Error message: (UserError) Invalid token
E           Code: UserError
E           Message: Invalid token

promptflow/azure/_restclient/flow_service_caller.py:65: FlowRequestException

The above exception was the direct cause of the following exception:

self = <sdk_cli_azure_test.e2etests.test_flow_operations.TestFlow object at 0x7fc0b4501090>
pf = <promptflow.azure._pf_client.PFClient object at 0x7fc0994ebac0>
created_flow = <promptflow.azure._entities._flow.Flow object at 0x7fc09b5db6d0>

    def test_update_flow(self, pf, created_flow: Flow):
    
        test_meta = {
            "display_name": "SDK test flow",
            "description": "SDK test flow description",
            "tags": {"owner": "sdk-test", "key1": "value1"},
        }
        # update flow
        updated_flow = pf.flows.create_or_update(flow=created_flow, **test_meta)
    
        assert updated_flow.display_name == test_meta["display_name"]
        assert updated_flow.description == test_meta["description"]
        assert updated_flow.tags == test_meta["tags"]
    
        # test update with wrong flow id
        with pytest.raises(UserErrorException, match=r"Flow with id fake_flow_name not found"):
            updated_flow.name = "fake_flow_name"
>           pf.flows.create_or_update(updated_flow, display_name="A new test flow")

tests/sdk_cli_azure_test/e2etests/test_flow_operations.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
promptflow/_sdk/_telemetry/activity.py:259: in wrapper
    return f(self, *args, **kwargs)
promptflow/azure/operations/_flow_operations.py:127: in create_or_update
    return self._update_azure_flow(flow=flow, display_name=display_name, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <promptflow.azure.operations._flow_operations.FlowOperations object at 0x7fc099447fa0>
flow = <promptflow.azure._entities._flow.Flow object at 0x7fc09b5da230>
display_name = 'A new test flow', kwargs = {}
description = 'SDK test flow description'
tags = {'key1': 'value1', 'owner': 'sdk-test'}
body = {'description': 'SDK test flow description', 'flow_name': 'A new test flow', 'tags': {'key1': 'value1', 'owner': 'sdk-test'}}

    def _update_azure_flow(self, flow: Flow, display_name, **kwargs):
        """Update an existing flow in azure."""
        logger.info("Validating flow update parameters.")
    
        display_name = display_name or flow.display_name
        if not isinstance(display_name, str) and display_name is not None:
            logger.warn(f"Display name must be a string, got {display_name!r}.")
            display_name = None
    
        description = kwargs.get("description", flow.description)
        if not isinstance(description, str) and description is not None:
            logger.warn(f"Description must be a string, got {description!r}.")
            description = None
    
        tags = kwargs.get("tags", flow.tags)
        if not isinstance(tags, dict) and tags is not None:
            logger.warn(f"Tags must be a dictionary, got {tags!r}.")
            tags = None
    
        body = {
            "flow_name": display_name,
            "description": description,
            "tags": tags,
        }
        body = {k: v for k, v in body.items() if v is not None}
        logger.debug(f"Updating flow {flow.name!r} with data {body}.")
    
        try:
            self._service_caller.update_flow(
                subscription_id=self._operation_scope.subscription_id,
                resource_group_name=self._operation_scope.resource_group_name,
                workspace_name=self._operation_scope.workspace_name,
                flow_id=flow.name,
                body=body,
            )
        except Exception as e:
>           raise FlowOperationError(
                f"Failed to update azure flow {flow.name!r} due to: {str(e)}. If the flow is not found in azure, "
                f"please make sure the flow name is correct."
            ) from e
E           promptflow._sdk._errors.FlowOperationError: Failed to update azure flow 'fake_flow_name' due to: Calling update_flow failed with request id: 678911e5-075e-41fd-bb5e-581e6dd69218 
E           Status code: 401 
E           Reason: Invalid token 
E           Error message: (UserError) Invalid token
E           Code: UserError
E           Message: Invalid token 
E           . If the flow is not found in azure, please make sure the flow name is correct.

promptflow/azure/operations/_flow_operations.py:195: FlowOperationError

During handling of the above exception, another exception occurred:

self = <sdk_cli_azure_test.e2etests.test_flow_operations.TestFlow object at 0x7fc0b4501090>
pf = <promptflow.azure._pf_client.PFClient object at 0x7fc0994ebac0>
created_flow = <promptflow.azure._entities._flow.Flow object at 0x7fc09b5db6d0>

    def test_update_flow(self, pf, created_flow: Flow):
    
        test_meta = {
            "display_name": "SDK test flow",
            "description": "SDK test flow description",
            "tags": {"owner": "sdk-test", "key1": "value1"},
        }
        # update flow
        updated_flow = pf.flows.create_or_update(flow=created_flow, **test_meta)
    
        assert updated_flow.display_name == test_meta["display_name"]
        assert updated_flow.description == test_meta["description"]
        assert updated_flow.tags == test_meta["tags"]
    
        # test update with wrong flow id
>       with pytest.raises(UserErrorException, match=r"Flow with id fake_flow_name not found"):
E       AssertionError: Regex pattern did not match.
E        Regex: 'Flow with id fake_flow_name not found'
E        Input: "Failed to update azure flow 'fake_flow_name' due to: Calling update_flow failed with request id: 678911e5-075e-41fd-bb5e-581e6dd69218 \nStatus code: 401 \nReason: Invalid token \nError message: (UserError) Invalid token\nCode: UserError\nMessage: Invalid token \n. If the flow is not found in azure, please make sure the flow name is correct."

tests/sdk_cli_azure_test/e2etests/test_flow_operations.py:56: AssertionError