From 9cb7869b318eddb6d97b7c430da7011ba2cfc4a2 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 25 Apr 2024 14:24:19 +0800 Subject: [PATCH 01/12] [Doc] Add flex flow doc (#2981) # Description Please add an informative description that covers that changes made by the pull request and link all relevant issues. # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --------- Co-authored-by: Zhengfei Wang <38847871+zhengfeiwang@users.noreply.github.com> Co-authored-by: Clement Wang Co-authored-by: Clement Wang --- docs/README.md | 2 +- .../azureai/run-promptflow-in-azure-ai.md | 2 +- .../azureai/use-flow-in-azure-ml-pipeline.md | 4 +- docs/concepts/concept-flows.md | 15 +- .../add-conditional-control-to-a-flow.md | 0 .../develop-chat-flow.md | 0 .../develop-evaluation-flow.md | 0 .../develop-standard-flow.md | 0 .../how-to-guides/develop-a-dag-flow/index.md | 26 ++ .../init-and-test-a-flow.md | 0 .../process-image-in-flow.md | 0 ...ing-external-files-or-folders-in-a-flow.md | 0 .../develop-a-flex-flow/class-based-flow.md | 296 ++++++++++++++++++ .../function-based-flow.md | 144 +++++++++ .../develop-a-flex-flow/index.md | 26 ++ .../input-output-format.md | 43 +++ docs/how-to-guides/develop-a-flow/index.md | 14 - docs/how-to-guides/develop-a-prompty/index.md | 2 +- .../prompty-output-format.md | 2 +- ...in-flex-flow.md => use-prompty-in-flow.md} | 8 +- docs/how-to-guides/index.md | 3 +- docs/how-to-guides/quick-start.md | 10 +- .../run-and-evaluate-a-flow/index.md | 4 +- docs/index.md | 2 +- scripts/docs/conf.py | 5 +- 25 files changed, 572 insertions(+), 36 deletions(-) rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/add-conditional-control-to-a-flow.md (100%) rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/develop-chat-flow.md (100%) rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/develop-evaluation-flow.md (100%) rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/develop-standard-flow.md (100%) create mode 100644 docs/how-to-guides/develop-a-dag-flow/index.md rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/init-and-test-a-flow.md (100%) rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/process-image-in-flow.md (100%) rename docs/how-to-guides/{develop-a-flow => develop-a-dag-flow}/referencing-external-files-or-folders-in-a-flow.md (100%) create mode 100644 docs/how-to-guides/develop-a-flex-flow/class-based-flow.md create mode 100644 docs/how-to-guides/develop-a-flex-flow/function-based-flow.md create mode 100644 docs/how-to-guides/develop-a-flex-flow/index.md create mode 100644 docs/how-to-guides/develop-a-flex-flow/input-output-format.md delete mode 100644 docs/how-to-guides/develop-a-flow/index.md rename docs/how-to-guides/develop-a-prompty/{use-prompty-in-flex-flow.md => use-prompty-in-flow.md} (93%) diff --git a/docs/README.md b/docs/README.md index e7f4a169822..b900ae65d62 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,7 @@ Below is a table of important doc pages. |----------------|----------------| |Quick start|[Getting started with prompt flow](./how-to-guides/quick-start.md)| |Concepts|[Flows](./concepts/concept-flows.md)
[Tools](./concepts/concept-tools.md)
[Connections](./concepts/concept-connections.md)
[Variants](./concepts/concept-variants.md)
| -|How-to guides|[How to initialize and test a flow](./how-to-guides/develop-a-flow/init-and-test-a-flow.md)
[How to run and evaluate a flow](./how-to-guides/run-and-evaluate-a-flow/index.md)
[How to tune prompts using variants](./how-to-guides/tune-prompts-with-variants.md)
[How to deploy a flow](./how-to-guides/deploy-a-flow/index.md)
[How to create and use your own tool package](./how-to-guides/develop-a-tool/create-and-use-tool-package.md)| +|How-to guides|[How to initialize and test a flow](./how-to-guides/develop-a-dag-flow/init-and-test-a-flow.md)
[How to run and evaluate a flow](./how-to-guides/run-and-evaluate-a-flow/index.md)
[How to tune prompts using variants](./how-to-guides/tune-prompts-with-variants.md)
[How to deploy a flow](./how-to-guides/deploy-a-flow/index.md)
[How to create and use your own tool package](./how-to-guides/develop-a-tool/create-and-use-tool-package.md)| |Tools reference|[LLM tool](./reference/tools-reference/llm-tool.md)
[Prompt tool](./reference/tools-reference/prompt-tool.md)
[Python tool](./reference/tools-reference/python-tool.md)
[Embedding tool](./reference/tools-reference/embedding_tool.md)
[SERP API tool](./reference/tools-reference/serp-api-tool.md) || diff --git a/docs/cloud/azureai/run-promptflow-in-azure-ai.md b/docs/cloud/azureai/run-promptflow-in-azure-ai.md index fe4c7f75b1f..e0bb471bcce 100644 --- a/docs/cloud/azureai/run-promptflow-in-azure-ai.md +++ b/docs/cloud/azureai/run-promptflow-in-azure-ai.md @@ -155,7 +155,7 @@ At the end of stream logs, you can find the `portal_url` of the submitted run, c ### Run snapshot of the flow with additional includes -Flows that enabled [additional include](../../how-to-guides/develop-a-flow/referencing-external-files-or-folders-in-a-flow.md) files can also be submitted for execution in the workspace. Please note that the specific additional include files or folders will be uploaded and organized within the **Files** folder of the run snapshot in the cloud. +Flows that enabled [additional include](../../how-to-guides/develop-a-dag-flow/referencing-external-files-or-folders-in-a-flow.md) files can also be submitted for execution in the workspace. Please note that the specific additional include files or folders will be uploaded and organized within the **Files** folder of the run snapshot in the cloud. ![img](../../media/cloud/azureml/run-with-additional-includes.png) diff --git a/docs/cloud/azureai/use-flow-in-azure-ml-pipeline.md b/docs/cloud/azureai/use-flow-in-azure-ml-pipeline.md index f1c8b9d44bb..bb87a56babf 100644 --- a/docs/cloud/azureai/use-flow-in-azure-ml-pipeline.md +++ b/docs/cloud/azureai/use-flow-in-azure-ml-pipeline.md @@ -1,7 +1,7 @@ # Use flow in Azure ML pipeline job In practical scenarios, flows fulfill various functions. For example, consider an offline flow specifically designed to assess the relevance score for communication sessions between humans and agents. This flow is triggered nightly and processes a substantial amount of session data. In such a context, Parallel component and AzureML pipeline emerge as the optimal choices for handling large-scale, highly resilient, and efficient offline batch requirements. -Once you’ve developed and thoroughly tested your flow using the guidelines in the [init and test a flow](../../how-to-guides/develop-a-flow/init-and-test-a-flow.md) section, this guide will walk you through utilizing your flow as a parallel component within an AzureML pipeline job. +Once you’ve developed and thoroughly tested your flow, this guide will walk you through utilizing your flow as a parallel component within an AzureML pipeline job. :::{admonition} Pre-requirements To enable this feature, customer need to: @@ -329,7 +329,7 @@ Given above, if your flow has logic relying on identity or environment variable, | key | source | type | description | | ----------- | ------ | ---------------------- | ------------------------------------------------------------ | | data | fixed | uri_folder or uri_file | required; to pass in input data. Supported format includes [`mltable`](https://learn.microsoft.com/en-us/azure/machine-learning/how-to-mltable?view=azureml-api-2&tabs=cli#authoring-mltable-files) and list of jsonl files. | -| run_outputs | fixed | uri_folder | optional; to pass in output of a standard flow for [an evaluation flow](../../how-to-guides/develop-a-flow/develop-evaluation-flow.md). Should be linked to a `flow_outputs` of a previous flow node in the pipeline. | +| run_outputs | fixed | uri_folder | optional; to pass in output of a standard flow for [an evaluation flow](../../how-to-guides/develop-a-dag-flow/develop-evaluation-flow.md). Should be linked to a `flow_outputs` of a previous flow node in the pipeline. | ### Output ports diff --git a/docs/concepts/concept-flows.md b/docs/concepts/concept-flows.md index ff58925b1a1..b3d7012f1ab 100644 --- a/docs/concepts/concept-flows.md +++ b/docs/concepts/concept-flows.md @@ -12,7 +12,7 @@ Our [examples](https://github.com/microsoft/promptflow/tree/main/examples/flex-f Thus LLM apps can be defined as Directed Acyclic Graphs (DAGs) of function calls. These DAGs are flows in prompt flow. -A flow in prompt flow is a DAG of functions (we call them [tools](./concept-tools.md)). These functions/tools connected via input/output dependencies and executed based on the topology by prompt flow executor. +A `DAG flow` in prompt flow is a DAG of functions (we call them [tools](./concept-tools.md)). These functions/tools connected via input/output dependencies and executed based on the topology by prompt flow executor. A flow is represented as a YAML file and can be visualized with our [Prompt flow for VS Code extension](https://marketplace.visualstudio.com/items?itemName=prompt-flow.prompt-flow). Here is an example `flow.dag.yaml`: @@ -20,6 +20,17 @@ A flow is represented as a YAML file and can be visualized with our [Prompt flow Please refer to our [examples](https://github.com/microsoft/promptflow/tree/main/examples/flows) to learn how to write a `DAG flow`. +## When to use Flex or DAG flow + +`Dag flow` provides a UI-friendly way to develop your LLM app, which has the following benifits: +- **Low code**: user can drag-and-drop in UI to create a LLM app. +- **DAG Visualization**: user can easily understand the logic structure of the app with DAG view. + +`Flex flow` provides a code-friendly way to develop your LLM app, which has the following benifits: +- **Quick start**: Users can quickly test with a simple prompt, then customize with python code with Tracing visualization UI. +- **More advanced orchestration**: Users can write complex flow with Python built-in control operators (if-else, foreach) or other 3rd party / open-source library. +- **Easy onboard from other platforms**: user might already onboard platforms like `langchain` and `sematic kernel` with existing code. User can easily onboard promptflow with a few code changes. + ## Flow types Prompt flow examples organize flows by three categories: @@ -42,6 +53,6 @@ DAG flow [examples](https://github.com/microsoft/promptflow/tree/main/examples/f ## Next steps - [Quick start](../how-to-guides/quick-start.md) -- [Initialize and test a flow](../how-to-guides/develop-a-flow/init-and-test-a-flow.md) +- [Initialize and test a flow](../how-to-guides/develop-a-dag-flow/init-and-test-a-flow.md) - [Run and evaluate a flow](../how-to-guides/run-and-evaluate-a-flow/index.md) - [Tune prompts using variants](../how-to-guides/tune-prompts-with-variants.md) \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-flow/add-conditional-control-to-a-flow.md b/docs/how-to-guides/develop-a-dag-flow/add-conditional-control-to-a-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/add-conditional-control-to-a-flow.md rename to docs/how-to-guides/develop-a-dag-flow/add-conditional-control-to-a-flow.md diff --git a/docs/how-to-guides/develop-a-flow/develop-chat-flow.md b/docs/how-to-guides/develop-a-dag-flow/develop-chat-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/develop-chat-flow.md rename to docs/how-to-guides/develop-a-dag-flow/develop-chat-flow.md diff --git a/docs/how-to-guides/develop-a-flow/develop-evaluation-flow.md b/docs/how-to-guides/develop-a-dag-flow/develop-evaluation-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/develop-evaluation-flow.md rename to docs/how-to-guides/develop-a-dag-flow/develop-evaluation-flow.md diff --git a/docs/how-to-guides/develop-a-flow/develop-standard-flow.md b/docs/how-to-guides/develop-a-dag-flow/develop-standard-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/develop-standard-flow.md rename to docs/how-to-guides/develop-a-dag-flow/develop-standard-flow.md diff --git a/docs/how-to-guides/develop-a-dag-flow/index.md b/docs/how-to-guides/develop-a-dag-flow/index.md new file mode 100644 index 00000000000..162d99dd855 --- /dev/null +++ b/docs/how-to-guides/develop-a-dag-flow/index.md @@ -0,0 +1,26 @@ +# Develop a dag flow + +LLM apps can be defined as Directed Acyclic Graphs (DAGs) of function calls. These DAGs are flows in prompt flow. + +A `DAG flow` in prompt flow is a DAG of functions (we call them [tools](../../concepts//concept-tools.md)). These functions/tools connected via input/output dependencies and executed based on the topology by prompt flow executor. + +A flow is represented as a YAML file and can be visualized with our [Prompt flow for VS Code extension](https://marketplace.visualstudio.com/items?itemName=prompt-flow.prompt-flow). Here is an example `flow.dag.yaml`: + +![flow_dag](../../media/how-to-guides/quick-start/flow_dag.png) + +Please refer to our [examples](https://github.com/microsoft/promptflow/tree/main/examples/flows) and guides in this section to learn how to write a `DAG flow`. + +Note: +- promptflow also support user develop a a flow using code. learn more on comparasion of these two [flow concepts](../../concepts/concept-flows.md). + +```{toctree} +:maxdepth: 1 + +init-and-test-a-flow +develop-standard-flow +develop-chat-flow +develop-evaluation-flow +add-conditional-control-to-a-flow +process-image-in-flow +referencing-external-files-or-folders-in-a-flow +``` \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-flow/init-and-test-a-flow.md b/docs/how-to-guides/develop-a-dag-flow/init-and-test-a-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/init-and-test-a-flow.md rename to docs/how-to-guides/develop-a-dag-flow/init-and-test-a-flow.md diff --git a/docs/how-to-guides/develop-a-flow/process-image-in-flow.md b/docs/how-to-guides/develop-a-dag-flow/process-image-in-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/process-image-in-flow.md rename to docs/how-to-guides/develop-a-dag-flow/process-image-in-flow.md diff --git a/docs/how-to-guides/develop-a-flow/referencing-external-files-or-folders-in-a-flow.md b/docs/how-to-guides/develop-a-dag-flow/referencing-external-files-or-folders-in-a-flow.md similarity index 100% rename from docs/how-to-guides/develop-a-flow/referencing-external-files-or-folders-in-a-flow.md rename to docs/how-to-guides/develop-a-dag-flow/referencing-external-files-or-folders-in-a-flow.md diff --git a/docs/how-to-guides/develop-a-flex-flow/class-based-flow.md b/docs/how-to-guides/develop-a-flex-flow/class-based-flow.md new file mode 100644 index 00000000000..5f73e0a9248 --- /dev/null +++ b/docs/how-to-guides/develop-a-flex-flow/class-based-flow.md @@ -0,0 +1,296 @@ +# Class based flow + +:::{admonition} Experimental feature +This is an experimental feature, and may change at any time. Learn [more](../faq.md#stable-vs-experimental). +::: + +When user need to persist objects (like connection) in memory during multiple rounds of flow runs, they can write a callable class as flow entry and put persist params in `__init__` method. + +If user need to log metrics on batch run outputs, they can add an `__aggregate__` method and it will be scheduled after batch run finishes. +The `__aggregate__` method should only contain 1 params which is list of batch run results. + +See [connection support](#connection-support) & [aggregation support](#aggregation-support) for more details. + +## Class as a flow + +Assume we have a file `flow_entry.py`: + +```python +class Reply(TypedDict): + output: str + +class MyFlow: + def __init__(self, model_config: AzureOpenAIModelConfiguration, flow_config: dict): + """Flow initialization logic goes here.""" + self.model_config = model_config + self.flow_config = flow_config + + def __call__(question: str) -> Reply: + """Flow execution logic goes here.""" + return Reply(output=output) + + def __aggregate__(self, line_results: List[str]) -> dict: + """Aggregation logic goes here. Return key-value pair as metrics.""" + return {"key": val} +``` + + +## Flow test + +Since flow's definition is function/callable class. We recommend user directly run it like running other scripts: + +```python +class MyFlow: + pass +if __name__ == "__main__": + flow = MyFlow(model_config, flow_config) + output = flow(question) + metrics = flow.__aggregate__([output]) + # check metrics here +``` + +You can also test the flow using CLI: +```bash +# flow entry syntax: path.to.module:ClassName +pf flow test --flow flow_entry:MyFlow --inputs question="What's the capital of France?" --init init.json +``` + +Check out a full example here: [basic-chat](https://github.com/microsoft/promptflow/tree/main/examples/flex-flows/basic-chat) + +### Chat with a flow + +Chat with flow in CLI is supported: + +```bash +pf flow test --flow flow_entry:MyFlow --inputs inputs.json --init init.json --ui +``` + +Check [here](../chat-with-a-flow/index.md) for more information. + +## Batch run + +User can also batch run a flow. + +::::{tab-set} +:::{tab-item} CLI +:sync: CLI + +```bash +pf run create --flow "path.to.module:ClassName" --data "./data.jsonl" +``` + +::: + +:::{tab-item} SDK +:sync: SDK +```python +# user can also directly use entry in `flow` param for batch run +pf.run(flow="path.to.module:ClassName", init="./init.jsonl", data="./data.jsonl") +``` + +::: +:::: + +Or directly run the imported flow class or flow instance. + +```python +class MyFlow: + pass +pf.run(flow=MyFlow, init={"model_config": config, "flow_config": {}}, data="./data.jsonl") +# or +flow_obj = MyFlow(model_config=config, flow_config={}) +pf.run(flow=flow_obj, data="./data.jsonl") +``` + +Learn more on this topic on [Run and evaluate a flow](../run-and-evaluate-a-flow/index.md) + +## Define a flow yaml + +User can write a YAML file with name `flow.flex.yaml` manually or save a function/callable entry to YAML file. +This is required for advanced scenario like deployment or run in cloud. +A flow YAML may look like this: + +```yaml +$schema: https://azuremlschemas.azureedge.net/promptflow/latest/Flow.schema.json +entry: path.to.module:ClassName +``` + +## Batch run with YAML + +User can batch run a flow. Flow init function's param is supported by `init` parameter. + +::::{tab-set} +:::{tab-item} CLI +:sync: CLI + +User need to write an JSON file as init's value since it's hard to write model config in command line. + +```json +{ + "model_config": { + "azure_endpoint": "my_endpoint", + "azure_deployment": "my_deployment", + "api_key": "actual_api_key" + }, + "flow_config": {} +} +``` + +```bash +pf run create --flow "./flow.flex.yaml" --data "./data.jsonl" --init init.json +``` + +::: + +:::{tab-item} SDK +:sync: SDK + +```python +pf = PFClient() + +config = AzureOpenAIModelConfiguration( + azure_deployment="my_deployment", + api_key="actual_key" +) +# if init's value is not json serializable, raise user error +pf.run(flow="./flow.flex.yaml", init={"model_config": config, "flow_config": {}}, data="./data.jsonl") + +# when submit to cloud, user can only use connection +# in runtime executor will resolve connection in AzureOpenAIModelConfiguration and set connection's fields to ModelConfig: equal to original ModelConfiguration.from_connection() +config = AzureOpenAIModelConfiguration( + azure_deployment="my_embedding_deployment", + connection="my-aoai-connection", +) +pfazure.run(flow="./flow.flex.yaml", init={"model_config": config, "flow_config": {}}, data="./data.jsonl") +``` + +::: +:::: + +## Deploy a flow + +User can serve a flow. Flow init function's param is supported by `init` parameter. +The flow should have complete init/inputs/outputs specification in YAML to make sure serving swagger can be generated. + +User need to write an JSON file as init's value since it's hard to write model config in command line. + +```json +{ + "model_config": { + "azure_endpoint": "my_endpoint", + "azure_deployment": "my_deployment", + "api_key": "actual_api_key" + }, + "flow_config": {} +} +``` + +```bash +# user can only pass model config by file +pf flow serve --source "./" --port 8088 --host localhost --init path/to/init.json +``` + +Learn more: [Deploy a flow](../deploy-a-flow/index.md). + +## Connection support + +### Model config in `__init__` + +Just like example in [batch run](#batch-run-with-yaml), it's supported to reference connection in ModelConfig. +And connection will be resolved and flatten connection's fields to ModelConfig. + +### Connection in `__init__` + +It's also supported to directly pass connection by **name** in `__init__`. + +```python +class MyFlow: + def __init__(self, my_connection: AzureOpenAIConnection): + pass +``` + +Note: + +- Union of connection types(`Union[OpenAIConnection, AzureOpenAIConnection]`) is not supported. + +#### Batch run with connection + +User can pass connection name to connection field in `init`. + +In local, the connection name will be replaced with local connection object in execution time. +In cloud, the connection name will be replaced with workspace's connection object in execution time. + +```python +# local connection "my_connection"'s instance will be passed to `__init__` +pf.run(flow="./flow.flex.yaml", init={"connection": "my_connection"}, data="./data.jsonl") +# cloud connection "my_cloud_connection"'s instance will be passed to `__init__` +pfazure.run(flow="./flow.flex.yaml", init={"connection": "my_cloud_connection"}, data="./data.jsonl") +``` + +### Environment variable connections(EVC) + +If flow YAML has `environment_variables` and it's value is a connection reference like this: + +```yaml +environment_variables: + AZURE_OPENAI_API_KEY: ${open_ai_connection.api_key} + AZURE_OPENAI_ENDPOINT: ${open_ai_connection.api_base} +``` + +The environment variable's value will be resolved to actual value in runtime. +If the connection not exist (in local or cloud), connection not found error will be raised. + +**Note**: User can override the `environment_variables` with existing environment variable keys in `flow.flex.yaml`: + +```bash +pf run create --flow . --data ./data.jsonl --environment-variables AZURE_OPENAI_API_KEY='${new_connection.api_key}' AZURE_OPENAI_ENDPOINT='my_endpoint' +``` + +Overriding with environment variable names which not exist in `flow.flex.yaml` is not supported. +Which means if user added environment variables which does not exist in `flow.flex.yaml` in runtime, it's value won't be resolved. + +For example, + +```bash +pf run create --flow . --data ./data.jsonl --environment-variables NEW_API_KEY='${my_new_connection.api_key}' +``` + +The `NEW_API_KEY`'s value won't be resolved to connection's API key. + +## Aggregation support + +Aggregation support is introduce to help user calculate metrics. + +```python +class MyFlow: + def __call__(text: str) -> str: + """Flow execution logic goes here.""" + pass + + # will only execute once after batch run finished. + # the processed_results will be list of __call__'s output and we will log the return value as metrics automatically. + def __aggregate__(self, processed_results: List[str]) -> dict: + for element in processed_results: + # If __call__'s output is primitive type, element will be primitive type. + # If __call__'s output is dataclass, element will be a dictionary, but can access it's attribute with `element.attribute_name` + # For other cases, it's recommended to access by key `element["attribute_name"]` + +``` + +**Note**: + +There's several limitations on aggregation support: + +- The aggregation function will only execute in batch run. +- Only 1 hard coded `__aggregate__` function is supported. +- The `__aggregate__` will only be passed **1** positional arguments when executing. +- The aggregation function’s input will be flow run’s outputs list. + - Each element inside `processed_results` passed passed inside `__aggregate__` function is not same object with each line's `__call__` returns. + - The reconstructed element is a dictionary which supports 1 layer attribute access. But it's recommended to access them by key. See the above example for usage. +- If aggregation function accept more than 1 arguments, raise error in submission phase. + +## Next steps + +- [Input output format](./input-output-format.md) +- [Class based flow sample](https://github.com/microsoft/promptflow/blob/main/examples/flex-flows/chat-basic/README.md) +- [Class based flow evaluation sample](https://github.com/microsoft/promptflow/blob/main/examples/flex-flows/eval-code-quality/README.md) diff --git a/docs/how-to-guides/develop-a-flex-flow/function-based-flow.md b/docs/how-to-guides/develop-a-flex-flow/function-based-flow.md new file mode 100644 index 00000000000..2283b5d6b87 --- /dev/null +++ b/docs/how-to-guides/develop-a-flex-flow/function-based-flow.md @@ -0,0 +1,144 @@ +# Function based flow + +:::{admonition} Experimental feature +This is an experimental feature, and may change at any time. Learn [more](../faq.md#stable-vs-experimental). +::: + +User can directly use a function as flow entry. + +## Function as a flow + +Assume we have a file `flow_entry.py`: + +```python +from promptflow.tracing import trace + +class Reply(TypedDict): + output: str + +@trace +def my_flow(question: str) -> Reply: + # flow logic goes here + pass +``` + +**Note** function decorated with `@trace` will emit trace can be viewed in UI provided by PromptFlow. Check [here](../tracing/index.md) for more information. + +## Flow test + +Since flow's definition is normal python function/callable class. We recommend user directly run it like running other scripts: + +```python +from flow_entry import my_flow + +if __name__ == "__main__": + output = my_flow(question="What's the capital of France?") + print(output) +``` + +You can also test the flow using CLI: +```bash +# flow entry syntax: path.to.module:function_name +pf flow test --flow flow_entry:my_flow --inputs question="What's the capital of France?" +``` + +Check out a full example here: [basic](https://github.com/microsoft/promptflow/tree/main/examples/flex-flows/basic) + +### Chat with a flow + +Start a UI to chat with a flow: + +```bash +pf flow test --flow flow_entry:my_flow --inputs question="What's the capital of France?" --ui +``` + +Check [here](../chat-with-a-flow/index.md) for more information. + +## Batch run + +User can also batch run a flow. + +::::{tab-set} +:::{tab-item} CLI +:sync: CLI + +```bash +pf run create --flow "path.to.module:function_name" --data "./data.jsonl" +``` + +::: + +:::{tab-item} SDK +:sync: SDK +```python + +from path.to.module import my_flow +pf.run(flow=my_flow, data="./data.json;") + +# user can also directly use entry in `flow` param for batch run +pf.run(flow="path.to.module:function_name", data="./data.jsonl") +``` +::: +:::: + +Learn more on this topic on [Run and evaluate a flow](../run-and-evaluate-a-flow/index.md) + +## Define a flow yaml + +User can write a YAML file with name `flow.flex.yaml` manually or save a function/callable entry to YAML file. +This is required for advanced scenario like deployment or run in cloud. +A flow YAML may look like this: + +```yaml +$schema: https://azuremlschemas.azureedge.net/promptflow/latest/Flow.schema.json +entry: path.to.module:function_name +sample: + question: "what's the capital of France?" +``` + +## Batch run with YAML + +User can batch run a flow with YAML. + +::::{tab-set} +:::{tab-item} CLI +:sync: CLI + +```bash +# against flow file +pf run create --flow "path/to/flow/flow.flex.yaml" --data "./data.jsonl" +# against a folder if it has a flow.flex.yaml file +pf run create --flow "path/to/flow" --data "./data.jsonl" +``` + +::: + +:::{tab-item} SDK +:sync: SDK + +```python +pf = PFClient() +pf.run(flow="./flow.flex.yaml", data="./data.jsonl") +``` + +::: +:::: + +## Deploy a flow + +User can serve a flow as a http endpoint locally or deploy it to multiple platforms. + +```bash +# serve locally from a folder if it has a flow.flex.yaml file +pf flow serve --source "path/to/flow/dir" --port 8088 --host localhost + +# serve locally from certain file +pf flow serve --source "./flow.flex.yaml" --port 8088 --host localhost +``` +Learn more: [Deploy a flow](../deploy-a-flow/index.md). + +## Next steps + +- [Class based flow](./class-based-flow.md) +- [Input output format](./input-output-format.md) +- [Function based flow sample](https://github.com/microsoft/promptflow/blob/main/examples/flex-flows/basic/README.md) diff --git a/docs/how-to-guides/develop-a-flex-flow/index.md b/docs/how-to-guides/develop-a-flex-flow/index.md new file mode 100644 index 00000000000..b5db3e920ac --- /dev/null +++ b/docs/how-to-guides/develop-a-flex-flow/index.md @@ -0,0 +1,26 @@ +# Develop a flow + +:::{admonition} Experimental feature +This is an experimental feature, and may change at any time. Learn [more](../faq.md#stable-vs-experimental). +::: + +You can create LLM apps using a Python function or class as the entry point, which encapsulating your app logic. You can directly test or run these entries with pure code experience. + +In PromptFlow, these functions or classes are referred to as `flow` or `flex flow`. + +Alternatively, you can define a `flow.flex.yaml` that points to these entries (`entry:function_name` or `entry:ClassName`). This enables testing, running, or viewing traces via the [Promptflow VS Code Extension](https://marketplace.visualstudio.com/items?itemName=prompt-flow.prompt-flow). + +Our [examples](https://github.com/microsoft/promptflow/tree/main/examples/flex-flows) should give you a good idea on how to write flows. + +Note: +- The term *Flex* is a shorthand for *flexible*, indicating its adaptability to most scenarios with minimal adjustments. +- PromptFlow also supports the development of a `dag flow`. learn more on comparasion of these two [flow concepts](../../concepts/concept-flows.md). + + +```{toctree} +:maxdepth: 1 + +function-based-flow +class-based-flow +input-output-format +``` diff --git a/docs/how-to-guides/develop-a-flex-flow/input-output-format.md b/docs/how-to-guides/develop-a-flex-flow/input-output-format.md new file mode 100644 index 00000000000..bb7356494c1 --- /dev/null +++ b/docs/how-to-guides/develop-a-flex-flow/input-output-format.md @@ -0,0 +1,43 @@ +# Input output format + +:::{admonition} Experimental feature +This is an experimental feature, and may change at any time. Learn [more](../faq.md#stable-vs-experimental). +::: + +## Supported types + +Promptflow officially support below types in flow. + +- Inputs: primitive types(`int`, `float`, `bool`, `str`), `dict`, `TypedDict`, `list` + +- Outputs: primitive types(`int`, `float`, `bool`, `str`), `dict`, `TypedDict`, `dataclass`, `list` + +- Init: primitive types(`int`, `float`, `bool`, `str`), `Connection`, `ModelConfiguration`, `TypedDict`, `list` + +If user has non-supported types in code/YAML, validation error will be raised. + +```python +# using unsupported types in flow will fail with validation error +class MyOwnClass: + pass + +class MyFlow: + # not supported + def __init__(self, my_own_obj: MyOwnClass): + pass + +# not supported +def my_flow(my_own_obj: MyOwnClass): + pass +``` + +Sample validation error: "The input 'my_own_obj' is of a complex python type. Please use a dict instead." + + + +## Stream + +Stream is supported in flow, you just need to return a generator type in your function. +Reference openai doc on how to do it using plain python code: [how_to_stream_completions](https://cookbook.openai.com/examples/how_to_stream_completions). + +Reference this flow [sample](https://microsoft.github.io/promptflow/tutorials/stream-flex-flow.html) for details. \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-flow/index.md b/docs/how-to-guides/develop-a-flow/index.md deleted file mode 100644 index eb23ee252b8..00000000000 --- a/docs/how-to-guides/develop-a-flow/index.md +++ /dev/null @@ -1,14 +0,0 @@ -# Develop a flow -We provide guides on how to develop a flow by writing a flow yaml from scratch in this section. - -```{toctree} -:maxdepth: 1 - -init-and-test-a-flow -develop-standard-flow -develop-chat-flow -develop-evaluation-flow -add-conditional-control-to-a-flow -process-image-in-flow -referencing-external-files-or-folders-in-a-flow -``` \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-prompty/index.md b/docs/how-to-guides/develop-a-prompty/index.md index 99973117cc9..c9bc1790998 100644 --- a/docs/how-to-guides/develop-a-prompty/index.md +++ b/docs/how-to-guides/develop-a-prompty/index.md @@ -416,5 +416,5 @@ The trace UI will record the execution details of each line in the data file, pr :hidden: prompty-output-format -use-prompty-in-flex-flow +use-prompty-in-flow ``` \ No newline at end of file diff --git a/docs/how-to-guides/develop-a-prompty/prompty-output-format.md b/docs/how-to-guides/develop-a-prompty/prompty-output-format.md index bd0fedc1746..e27925d6f6c 100644 --- a/docs/how-to-guides/develop-a-prompty/prompty-output-format.md +++ b/docs/how-to-guides/develop-a-prompty/prompty-output-format.md @@ -66,7 +66,7 @@ Prompty can return the content of the first choice as a dictionary object when t - The `response_format` is defined as `type: json_object` in the parameters - The template specifies the JSON format for the return value. -**Note**: `response_format` is compatible with `GPT-4 Turbo` and all GPT-3.5 Turbo models newer than `gpt-3.5-turbo-1106`. For more details, refer to this [document](https://platform.openai.com/docs/api-reference/chat/create#chat-create-response_format). +**Note**: `json_object` response_format is compatible with `GPT-4 Turbo` and all GPT-3.5 Turbo models newer than `gpt-3.5-turbo-1106`. For more details, refer to this [document](https://platform.openai.com/docs/api-reference/chat/create#chat-create-response_format). Here’s how to configure a prompty for JSON object output: ```yaml diff --git a/docs/how-to-guides/develop-a-prompty/use-prompty-in-flex-flow.md b/docs/how-to-guides/develop-a-prompty/use-prompty-in-flow.md similarity index 93% rename from docs/how-to-guides/develop-a-prompty/use-prompty-in-flex-flow.md rename to docs/how-to-guides/develop-a-prompty/use-prompty-in-flow.md index efe93ba81a9..9c649e38c9c 100644 --- a/docs/how-to-guides/develop-a-prompty/use-prompty-in-flex-flow.md +++ b/docs/how-to-guides/develop-a-prompty/use-prompty-in-flow.md @@ -1,10 +1,10 @@ -# Using prompty in flex flow +# Using prompty in flow :::{admonition} Experimental feature This is an experimental feature, and may change at any time. Learn [more](../faq.md#stable-vs-experimental). ::: -Because Prompty can be called as a function, user can use prompty in a `flex flow` which is can be a python function or class. +Because Prompty can be called as a function, user can use prompty in a `flow` which is can be a python function or class. This allows user to do more customization logic with prompty. @@ -104,9 +104,9 @@ User can run above code as normal python file. python path/to/entry.py ``` -## Test the class as a flex flow +## Test the class as a flow -User can also leverage promptflow to test the class as a `flex flow`. +User can also leverage promptflow to test the class as a `flow`. ```bash pf flow test --flow file:ChatFlow --init init.json --inputs "question=What is ChatGPT?" diff --git a/docs/how-to-guides/index.md b/docs/how-to-guides/index.md index 7bd1036a7e4..3eebb29671f 100644 --- a/docs/how-to-guides/index.md +++ b/docs/how-to-guides/index.md @@ -17,7 +17,8 @@ develop-a-prompty/index ```{toctree} :caption: Flow :maxdepth: 1 -develop-a-flow/index +develop-a-flex-flow/index +develop-a-dag-flow/index execute-flow-as-a-function chat-with-a-flow/index run-and-evaluate-a-flow/index diff --git a/docs/how-to-guides/quick-start.md b/docs/how-to-guides/quick-start.md index ce51e3e4731..ae3a331b3ba 100644 --- a/docs/how-to-guides/quick-start.md +++ b/docs/how-to-guides/quick-start.md @@ -108,7 +108,7 @@ inputs: default: https://play.google.com/store/apps/details?id=com.twitter.android ... ``` -See more details of this topic in [Develop a flow](./develop-a-flow/index.md). +See more details of this topic in [Develop a flow](./develop-a-dag-flow/index.md). ### Create necessary connections @@ -288,14 +288,14 @@ Click the run flow button on the top of the visual editor to trigger flow test. :::: -See more details of this topic in [Initialize and test a flow](./develop-a-flow/init-and-test-a-flow.md). +See more details of this topic in [Initialize and test a flow](./develop-a-dag-flow/init-and-test-a-flow.md). ## Next steps Learn more on how to: -- [Develop a flow](./develop-a-flow/index.md): details on how to develop a flow by writing a flow yaml from scratch. -- [Initialize and test a flow](./develop-a-flow/init-and-test-a-flow.md): details on how develop a flow from scratch or existing code. -- [Add conditional control to a flow](./develop-a-flow/add-conditional-control-to-a-flow.md): how to use activate config to add conditional control to a flow. +- [Develop a flow](./develop-a-dag-flow/index.md): details on how to develop a flow by writing a flow yaml from scratch. +- [Initialize and test a flow](./develop-a-dag-flow/init-and-test-a-flow.md): details on how develop a flow from scratch or existing code. +- [Add conditional control to a flow](./develop-a-dag-flow/add-conditional-control-to-a-flow.md): how to use activate config to add conditional control to a flow. - [Run and evaluate a flow](./run-and-evaluate-a-flow/index.md): run and evaluate the flow using multi line data file. - [Deploy a flow](./deploy-a-flow/index.md): how to deploy the flow as a web app. - [Manage connections](./manage-connections.md): how to manage the endpoints/secrets information to access external services including LLMs. diff --git a/docs/how-to-guides/run-and-evaluate-a-flow/index.md b/docs/how-to-guides/run-and-evaluate-a-flow/index.md index 441fd124b30..b22b8defac6 100644 --- a/docs/how-to-guides/run-and-evaluate-a-flow/index.md +++ b/docs/how-to-guides/run-and-evaluate-a-flow/index.md @@ -1,6 +1,6 @@ # Run and evaluate a flow -After you have developed and tested the flow in [init and test a flow](../develop-a-flow/init-and-test-a-flow.md), this guide will help you learn how to run a flow with a larger dataset and then evaluate the flow you have created. +After you have developed and tested the flow in [init and test a flow](../develop-a-dag-flow/init-and-test-a-flow.md), this guide will help you learn how to run a flow with a larger dataset and then evaluate the flow you have created. ## Create a batch run @@ -113,7 +113,7 @@ We also have a more detailed documentation [Manage runs](./manage-runs.md) demo ## Evaluate your flow -You can use an evaluation method to evaluate your flow. The evaluation methods are also flows which use Python or LLM etc., to calculate metrics like accuracy, relevance score. Please refer to [Develop evaluation flow](../develop-a-flow/develop-evaluation-flow.md) to learn how to develop an evaluation flow. +You can use an evaluation method to evaluate your flow. The evaluation methods are also flows which use Python or LLM etc., to calculate metrics like accuracy, relevance score. Please refer to [Develop evaluation flow](../develop-a-dag-flow/develop-evaluation-flow.md) to learn how to develop an evaluation flow. In this guide, we use [eval-classification-accuracy](https://github.com/microsoft/promptflow/tree/main/examples/flows/evaluation/eval-classification-accuracy) flow to evaluate. This is a flow illustrating how to evaluate the performance of a classification system. It involves comparing each prediction to the groundtruth and assigns a `Correct` or `Incorrect` grade, and aggregating the results to produce metrics such as `accuracy`, which reflects how good the system is at classifying the data. diff --git a/docs/index.md b/docs/index.md index 05ea406c572..0c202fb9594 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ This documentation site contains guides for prompt flow [sdk, cli](https://pypi. - header: "📒 How-to Guides" content: " Articles guide user to complete a specific task in prompt flow.

- - [Develop a flow](how-to-guides/develop-a-flow/index.md)
+ - [Develop a flow](how-to-guides/develop-a-flex-flow/index.md)
- [Run and evaluate a flow](how-to-guides/run-and-evaluate-a-flow/index.md)
- [Develop custom tool](how-to-guides/develop-a-tool/create-and-use-tool-package.md)
- [Deploy a flow](how-to-guides/deploy-a-flow/index.md)
diff --git a/scripts/docs/conf.py b/scripts/docs/conf.py index 5b47fb08b02..4900c87f159 100644 --- a/scripts/docs/conf.py +++ b/scripts/docs/conf.py @@ -66,7 +66,10 @@ "deploy-using-docker.html", "deploy-using-kubernetes.html", "https://portal.azure.com/#create/Microsoft.CognitiveServicesTextAnalytics", # sphinx recognizes #create as an anchor while it's not. # noqa: E501 - "https://ms.portal.azure.com/#view/Microsoft_Azure_Marketplace/MarketplaceOffersBlade/searchQuery/machine%20learning", # noqa: E501 + "https://ms.portal.azure.com/#view/Microsoft_Azure_Marketplace/MarketplaceOffersBlade/searchQuery/machine%20learning", # noqa: E501, + # TODO(wanhan): update this link to sample + "https://microsoft.github.io/promptflow/tutorials/stream-flex-flow.html", + "https://github.com/microsoft/promptflow/tree/main/examples/flex-flows/basic-chat", ] linkcheck_exclude_documents = [ From 97f059ef43f4c319699320763378f54469fd6830 Mon Sep 17 00:00:00 2001 From: Lina Tang Date: Thu, 25 Apr 2024 14:59:49 +0800 Subject: [PATCH 02/12] [Executor] Provide exec_aggregation_async for script executor (#2945) # Description Provide exec_aggregation_async for script executor. # All Promptflow Contribution checklist: - [x] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [x] Title of the pull request is clear and informative. - [x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --------- Co-authored-by: Lina Tang --- .../promptflow/executor/_script_executor.py | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/promptflow-core/promptflow/executor/_script_executor.py b/src/promptflow-core/promptflow/executor/_script_executor.py index fbf1aecce86..744fa5f6834 100644 --- a/src/promptflow-core/promptflow/executor/_script_executor.py +++ b/src/promptflow-core/promptflow/executor/_script_executor.py @@ -35,6 +35,7 @@ from promptflow.executor._result import AggregationResult, LineResult from promptflow.storage import AbstractRunStorage from promptflow.storage._run_storage import DefaultRunStorage +from promptflow.tracing import ThreadPoolExecutorWithContext from promptflow.tracing._trace import _traced from promptflow.tracing._tracer import Tracer from promptflow.tracing.contracts.trace import TraceType @@ -193,10 +194,31 @@ def _exec_aggregation( ) -> AggregationResult: output, metrics = None, {} try: - if inspect.iscoroutinefunction(self._aggr_func): - output = async_run_allowing_running_loop(self._aggr_func, **{self._aggr_input_name: inputs}) - else: - output = self._aggr_func(**{self._aggr_input_name: inputs}) + output = self._aggr_func(**{self._aggr_input_name: inputs}) + metrics = output if isinstance(output, dict) else {"metrics": output} + for k, v in metrics.items(): + log_metric(k, v) + except Exception: + pass + return AggregationResult(output, metrics, {}) + + async def exec_aggregation_async( + self, + inputs: Mapping[str, Any], + aggregation_inputs: List[Any], + run_id: Optional[str] = None, + ): + if not self._aggr_func: + return AggregationResult({}, {}, {}) + # Similar to dag flow, add a prefix "reduce" for run id of aggregation function. + run_id = f"{run_id}_reduce" if run_id is not None else f"{str(uuid.uuid4())}_reduce" + with self._update_operation_context_for_aggregation(run_id): + return await self._exec_aggregation_async(aggregation_inputs) + + async def _exec_aggregation_async(self, inputs): + output = None + try: + output = await self._aggr_func_async(**{self._aggr_input_name: inputs}) metrics = output if isinstance(output, dict) else {"metrics": output} for k, v in metrics.items(): log_metric(k, v) @@ -430,7 +452,22 @@ def _initialize_aggr_function(self, flow_obj: object): ) if not hasattr(aggr_func, "__original_function"): aggr_func = _traced(aggr_func) - self._aggr_func = aggr_func + if inspect.iscoroutinefunction(aggr_func): + + def run_async_function_sync(*args, **kwargs): + return async_run_allowing_running_loop(aggr_func, *args, **kwargs) + + self._aggr_func = run_async_function_sync + self._aggr_func_async = aggr_func + else: + + async def run_sync_function_async(*args, **kwargs): + with ThreadPoolExecutorWithContext() as executor: + partial_func = partial(aggr_func, *args, **kwargs) + return await asyncio.get_event_loop().run_in_executor(executor, partial_func) + + self._aggr_func = aggr_func + self._aggr_func_async = run_sync_function_async self._aggr_input_name = list(sign.parameters.keys())[0] def _parse_flow_file(self): From 108e0674f4768b0426521ebd6842f6cf65582011 Mon Sep 17 00:00:00 2001 From: Philip Gao Date: Thu, 25 Apr 2024 15:42:59 +0800 Subject: [PATCH 03/12] Fix matrix, using recording even if it doesn't use it. (#2999) # Description Fix matrix # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --- .../workflows/promptflow-evals-e2e-test.yml | 2 +- .../workflows/promptflow-evals-unit-test.yml | 2 +- .../promptflow-release-testing-matrix.yml | 41 +++++++++++-------- .../workflows/promptflow-tracing-e2e-test.yml | 2 +- .../promptflow-tracing-unit-test.yml | 2 +- .../workflows/sdk-cli-perf-monitor-test.yml | 2 +- .../sdk_cli_test/e2etests/test_prompty.py | 9 ++-- src/promptflow-recording/pyproject.toml | 1 + 8 files changed, 32 insertions(+), 29 deletions(-) diff --git a/.github/workflows/promptflow-evals-e2e-test.yml b/.github/workflows/promptflow-evals-e2e-test.yml index b1e2ea80a1b..29967d30810 100644 --- a/.github/workflows/promptflow-evals-e2e-test.yml +++ b/.github/workflows/promptflow-evals-e2e-test.yml @@ -31,7 +31,7 @@ jobs: needs: build strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] python-version: ['3.8', '3.9', '3.10', '3.11'] fail-fast: false # snok/install-poetry need this to support Windows diff --git a/.github/workflows/promptflow-evals-unit-test.yml b/.github/workflows/promptflow-evals-unit-test.yml index 89c1be9a0d2..68c31094300 100644 --- a/.github/workflows/promptflow-evals-unit-test.yml +++ b/.github/workflows/promptflow-evals-unit-test.yml @@ -31,7 +31,7 @@ jobs: needs: build strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] python-version: ['3.8', '3.9', '3.10', '3.11'] fail-fast: false # snok/install-poetry need this to support Windows diff --git a/.github/workflows/promptflow-release-testing-matrix.yml b/.github/workflows/promptflow-release-testing-matrix.yml index fd384bc3b25..ba9a2991fc7 100644 --- a/.github/workflows/promptflow-release-testing-matrix.yml +++ b/.github/workflows/promptflow-release-testing-matrix.yml @@ -75,7 +75,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] pythonVersion: ['3.8', '3.9', '3.10', '3.11'] defaults: run: @@ -129,7 +129,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] pythonVersion: ['3.8', '3.9', '3.10', '3.11'] # snok/install-poetry need this to support Windows defaults: @@ -160,13 +160,11 @@ jobs: run: | poetry run pip install $(python -c "import glob; print(glob.glob('**/promptflow_tracing-*.whl', recursive=True)[0])") poetry run pip install $(python -c "import glob; print(glob.glob('**/promptflow_core-*.whl', recursive=True)[0])") + poetry run pip install -e ../promptflow-recording working-directory: ${{ env.WORKING_DIRECTORY }} - name: install test dependency group run: poetry install --only test working-directory: ${{ env.WORKING_DIRECTORY }} - - name: install recording - run: poetry install - working-directory: ${{ env.RECORD_DIRECTORY }} - name: run core tests run: poetry run pytest ./tests/core working-directory: ${{ env.WORKING_DIRECTORY }} @@ -186,7 +184,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] pythonVersion: ['3.8', '3.9', '3.10', '3.11'] # snok/install-poetry need this to support Windows defaults: @@ -209,13 +207,11 @@ jobs: run: | poetry run pip install $(python -c "import glob; print(glob.glob('**/promptflow_tracing-*.whl', recursive=True)[0])") poetry run pip install $(python -c "import glob; print(glob.glob('**/promptflow_core-*.whl', recursive=True)[0]+'[azureml-serving]')") + poetry run pip install -e ../promptflow-recording working-directory: ${{ env.WORKING_DIRECTORY }} - name: install test dependency group run: poetry install --only test working-directory: ${{ env.WORKING_DIRECTORY }} - - name: install recording - run: poetry install - working-directory: ${{ env.RECORD_DIRECTORY }} - name: run azureml-serving tests run: poetry run pytest ./tests/azureml-serving working-directory: ${{ env.WORKING_DIRECTORY }} @@ -236,7 +232,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] pythonVersion: ['3.8', '3.9', '3.10', '3.11'] # snok/install-poetry need this to support Windows defaults: @@ -274,9 +270,6 @@ jobs: - name: install test dependency group run: poetry install --only test working-directory: ${{ env.WORKING_DIRECTORY }} - - name: install recording - run: poetry install - working-directory: ${{ env.RECORD_DIRECTORY }} - name: run devkit tests run: poetry run pytest ./tests/sdk_cli_test ./tests/sdk_pfs_test -n auto -m "unittest or e2etest" working-directory: ${{ env.WORKING_DIRECTORY }} @@ -293,7 +286,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] pythonVersion: ['3.8', '3.9', '3.10', '3.11'] env: PROMPT_FLOW_TEST_MODE: "live" @@ -356,7 +349,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] pythonVersion: ['3.8', '3.9', '3.10', '3.11'] runs-on: ${{ matrix.os }} steps: @@ -401,7 +394,19 @@ jobs: gci ./promptflow -Recurse | % {if ($_.Name.Contains('.whl')) {python -m pip install "$($_.FullName)[azure,executor-service]"}} gci ./promptflow-tools -Recurse | % {if ($_.Name.Contains('.whl')) {python -m pip install "$($_.FullName)"}} pip freeze - - name: Run Executor Test + - name: Run Executor Unit Test + shell: pwsh + working-directory: ${{ github.workspace }} + run: | + pip install langchain + pip install numexpr + python scripts/building/run_coverage_tests.py ` + -p ${{ github.workspace }}/src/promptflow/promptflow ` + -t ${{ github.workspace }}/src/promptflow/tests/executor/unittests ` + -l eastus ` + -m "all" ` + -o "${{ github.workspace }}/test-results-executor-unit.xml" + - name: Run Executor E2E Test shell: pwsh working-directory: ${{ github.workspace }} run: | @@ -409,10 +414,10 @@ jobs: pip install numexpr python scripts/building/run_coverage_tests.py ` -p ${{ github.workspace }}/src/promptflow/promptflow ` - -t ${{ github.workspace }}/src/promptflow/tests/executor/e2etests ${{ github.workspace }}/src/promptflow/tests/executor/unittests ` + -t ${{ github.workspace }}/src/promptflow/tests/executor/e2etests ` -l eastus ` -m "all" ` - -o "${{ github.workspace }}/test-results-executor.xml" + -o "${{ github.workspace }}/test-results-executor-e2e.xml" - name: Upload pytest test results (Python ${{ matrix.pythonVersion }}) (OS ${{ matrix.os }}) if: ${{ always() }} uses: actions/upload-artifact@v3 diff --git a/.github/workflows/promptflow-tracing-e2e-test.yml b/.github/workflows/promptflow-tracing-e2e-test.yml index d0a342642fa..dcbb616fc4e 100644 --- a/.github/workflows/promptflow-tracing-e2e-test.yml +++ b/.github/workflows/promptflow-tracing-e2e-test.yml @@ -32,7 +32,7 @@ jobs: needs: build strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] python-version: ['3.8', '3.9', '3.10', '3.11'] fail-fast: false # snok/install-poetry need this to support Windows diff --git a/.github/workflows/promptflow-tracing-unit-test.yml b/.github/workflows/promptflow-tracing-unit-test.yml index 88ec810d74c..5b64e37a54b 100644 --- a/.github/workflows/promptflow-tracing-unit-test.yml +++ b/.github/workflows/promptflow-tracing-unit-test.yml @@ -32,7 +32,7 @@ jobs: needs: build strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] python-version: ['3.8', '3.9', '3.10', '3.11'] fail-fast: false # snok/install-poetry need this to support Windows diff --git a/.github/workflows/sdk-cli-perf-monitor-test.yml b/.github/workflows/sdk-cli-perf-monitor-test.yml index 011bc270171..6abeebb2f05 100644 --- a/.github/workflows/sdk-cli-perf-monitor-test.yml +++ b/.github/workflows/sdk-cli-perf-monitor-test.yml @@ -35,7 +35,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-13, windows-latest] defaults: run: shell: bash diff --git a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_prompty.py b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_prompty.py index 5507e7941a7..72664337a5a 100644 --- a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_prompty.py +++ b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_prompty.py @@ -19,7 +19,6 @@ ) from promptflow.core._model_configuration import AzureOpenAIModelConfiguration from promptflow.core._prompty_utils import convert_model_configuration_to_connection -from promptflow.recording.record_mode import is_live, is_record, is_replay TEST_ROOT = PROMPTFLOW_ROOT / "tests" DATA_DIR = TEST_ROOT / "test_configs/datas" @@ -242,12 +241,10 @@ def test_prompty_format_output(self, pf: PFClient): assert isinstance(result, ChatCompletion) def test_prompty_with_stream(self, pf: PFClient): - if is_live(): - # When running multiple test cases, the type is generator type. - # When running alone this case, the type is Stream. - stream_type = (types.GeneratorType, Stream) - elif is_record() or is_replay(): + if pytest.is_record or pytest.is_replay: stream_type = types.GeneratorType + else: + stream_type = (types.GeneratorType, Stream) # Test text format with stream=true prompty = Prompty.load(source=f"{PROMPTY_DIR}/prompty_example.prompty", model={"parameters": {"stream": True}}) result = prompty(question="what is the result of 1+1?") diff --git a/src/promptflow-recording/pyproject.toml b/src/promptflow-recording/pyproject.toml index 69836ddbf40..470f95aa54e 100644 --- a/src/promptflow-recording/pyproject.toml +++ b/src/promptflow-recording/pyproject.toml @@ -37,6 +37,7 @@ packages = [ [tool.poetry.dependencies] python = "<4.0,>=3.8" vcrpy = ">=5.1" +filelock = "*" promptflow-tracing = ">=0.1.0b1, <2.0.0" [tool.poetry.group.dev.dependencies] From 1c462b11dac99e1d43c51421f44dec2a79e895e1 Mon Sep 17 00:00:00 2001 From: Xingzhi Zhang <37076709+elliotzh@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:57:00 +0800 Subject: [PATCH 04/12] fix: avoid generating flow.tools.json for python dag flow on pfazure run create (#2997) # Description customer should be able to submit a pfazure dag flow even if they don't have a local runtime with all requirements installed. # All Promptflow Contribution checklist: - [x] **The pull request does not introduce [breaking changes].** - [x] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [x] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [x] Title of the pull request is clear and informative. - [x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --- .../tests/sdk_cli_azure_test/conftest.py | 5 +- .../e2etests/test_flow_operations.py | 3 + .../e2etests/test_run_operations.py | 19 +- .../_proxy/_base_inspector_proxy.py | 4 +- .../_proxy/_csharp_inspector_proxy.py | 29 +- .../_proxy/_python_inspector_proxy.py | 13 +- ..._operations_TestFlow_test_create_flow.yaml | 375 +++++--- ...low_operations_TestFlow_test_get_flow.yaml | 395 ++++++--- ..._operations_TestFlow_test_update_flow.yaml | 423 ++++++---- ...lowRun_test_run_bulk_with_remote_flow.yaml | 798 +++++++++++++----- ..._test_run_without_generate_tools_json.yaml | 659 +++++++++++++++ 11 files changed, 2104 insertions(+), 619 deletions(-) create mode 100644 src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_without_generate_tools_json.yaml diff --git a/src/promptflow-azure/tests/sdk_cli_azure_test/conftest.py b/src/promptflow-azure/tests/sdk_cli_azure_test/conftest.py index 7265e28dd16..a1a72f353d7 100644 --- a/src/promptflow-azure/tests/sdk_cli_azure_test/conftest.py +++ b/src/promptflow-azure/tests/sdk_cli_azure_test/conftest.py @@ -25,7 +25,7 @@ from mock import MagicMock, mock from pytest_mock import MockerFixture -from promptflow._sdk._constants import FlowType, RunStatus +from promptflow._sdk._constants import FLOW_TOOLS_JSON, PROMPT_FLOW_DIR_NAME, FlowType, RunStatus from promptflow._sdk.entities import Run from promptflow._utils.user_agent_utils import ClientUserAgentUtil from promptflow.azure import PFClient @@ -450,6 +450,9 @@ def created_flow(pf: PFClient, randstr: Callable[[str], str], variable_recorder) """Create a flow for test.""" flow_display_name = randstr("flow_display_name") flow_source = FLOWS_DIR / "simple_hello_world" + tool_json_path = f"{flow_source}/{PROMPT_FLOW_DIR_NAME}/{FLOW_TOOLS_JSON}" + if os.path.isfile(tool_json_path): + os.remove(tool_json_path) description = "test flow description" tags = {"owner": "sdk-test"} result = pf.flows.create_or_update( diff --git a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_flow_operations.py b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_flow_operations.py index c2d33b1481a..cc66879a9bc 100644 --- a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_flow_operations.py +++ b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_flow_operations.py @@ -6,6 +6,7 @@ import pytest from sdk_cli_azure_test.conftest import FLOWS_DIR +from promptflow._sdk._constants import FLOW_TOOLS_JSON, PROMPT_FLOW_DIR_NAME from promptflow.azure._entities._flow import Flow from promptflow.exceptions import UserErrorException @@ -24,6 +25,8 @@ class TestFlow: def test_create_flow(self, created_flow: Flow): # most of the assertions are in the fixture itself assert isinstance(created_flow, Flow) + flow_tools_json_path = FLOWS_DIR / "simple_hello_world" / PROMPT_FLOW_DIR_NAME / FLOW_TOOLS_JSON + assert not flow_tools_json_path.exists() def test_get_flow(self, pf, created_flow: Flow): result = pf.flows.get(name=created_flow.name) diff --git a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_operations.py b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_operations.py index 5dc2c37d80f..47c4f377346 100644 --- a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_operations.py +++ b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_operations.py @@ -22,7 +22,7 @@ from sdk_cli_azure_test.conftest import DATAS_DIR, FLOWS_DIR from promptflow._constants import FLOW_FLEX_YAML -from promptflow._sdk._constants import DownloadedRun, RunStatus +from promptflow._sdk._constants import FLOW_TOOLS_JSON, PROMPT_FLOW_DIR_NAME, DownloadedRun, RunStatus from promptflow._sdk._errors import InvalidRunError, InvalidRunStatusError, RunNotFoundError from promptflow._sdk._load_functions import load_run from promptflow._sdk.entities import Run @@ -79,6 +79,23 @@ def test_run_bulk(self, pf, runtime: str, randstr: Callable[[str], str]): assert isinstance(run, Run) assert run.name == name + @pytest.mark.skipif(not is_live(), reason="Recording issue.") + def test_run_without_generate_tools_json(self, pf, runtime: str, randstr: Callable[[str], str]): + name = randstr("name") + flow_dir = f"{FLOWS_DIR}/simple_hello_world" + tools_json_path = Path(flow_dir) / PROMPT_FLOW_DIR_NAME / FLOW_TOOLS_JSON + if tools_json_path.exists(): + tools_json_path.unlink() + run = pf.run( + flow=flow_dir, + data=f"{DATAS_DIR}/simple_hello_world.jsonl", + column_mapping={"name": "${data.name}"}, + name=name, + ) + assert isinstance(run, Run) + assert run.name == name + assert not tools_json_path.exists() + def test_run_resume(self, pf: PFClient, randstr: Callable[[str], str]): # Note: Use fixed run name here to ensure resume call has same body then can be recorded. name = "resume_from_run_using_automatic_runtime" diff --git a/src/promptflow-devkit/promptflow/_proxy/_base_inspector_proxy.py b/src/promptflow-devkit/promptflow/_proxy/_base_inspector_proxy.py index 7d1fd63426d..f2df915560f 100644 --- a/src/promptflow-devkit/promptflow/_proxy/_base_inspector_proxy.py +++ b/src/promptflow-devkit/promptflow/_proxy/_base_inspector_proxy.py @@ -55,7 +55,7 @@ def prepare_metadata( 3) before flow upload. For dag flow, it will generate flow.tools.json; - For python flex flow, it will do nothing; - For csharp flex flow, it will generate metadata based on a dotnet command. + For flex flow, it will generate metadata based on a dotnet command. + For python flow, we have a runtime to gather metadata in both local and cloud, so we don't prepare anything """ return diff --git a/src/promptflow-devkit/promptflow/_proxy/_csharp_inspector_proxy.py b/src/promptflow-devkit/promptflow/_proxy/_csharp_inspector_proxy.py index 5dd5c2d04cb..802787a4f0d 100644 --- a/src/promptflow-devkit/promptflow/_proxy/_csharp_inspector_proxy.py +++ b/src/promptflow-devkit/promptflow/_proxy/_csharp_inspector_proxy.py @@ -14,6 +14,7 @@ from promptflow._constants import FlowEntryRegex from promptflow._sdk._constants import ALL_CONNECTION_TYPES, FLOW_META_JSON, FLOW_TOOLS_JSON, PROMPT_FLOW_DIR_NAME from promptflow._utils.flow_utils import is_flex_flow, read_json_content +from promptflow._utils.logger_utils import get_cli_sdk_logger from promptflow._utils.yaml_utils import load_yaml from promptflow.exceptions import UserErrorException @@ -21,6 +22,9 @@ EXECUTOR_SERVICE_DLL = "Promptflow.dll" +# inspector proxy is mainly used in preparation stage instead of execution stage, so we use cli sdk logger here +logger = get_cli_sdk_logger() + class CSharpInspectorProxy(AbstractInspectorProxy): def __init__(self): @@ -113,16 +117,23 @@ def prepare_metadata( cwd=working_dir, ) except subprocess.CalledProcessError as e: + if is_flex_flow(flow_path=flow_file): + meta_path = working_dir / PROMPT_FLOW_DIR_NAME / FLOW_META_JSON + else: + meta_path = working_dir / PROMPT_FLOW_DIR_NAME / FLOW_TOOLS_JSON + + logger.warning( + f"Failed to generate flow meta for csharp flow. " + f"Command: {' '.join(command)} " + f"Working directory: {working_dir.as_posix()} " + f"Return code: {e.returncode} " + f"Output: {e.output}" + ) + if meta_path.is_file(): + logger.warning(f"Will try to use generated flow meta at {meta_path.as_posix()}.") raise UserErrorException( - message_format="Failed to generate flow meta for csharp flow.\n" - "Command: {command}\n" - "Working directory: {working_directory}\n" - "Return code: {return_code}\n" - "Output: {output}", - command=" ".join(command), - working_directory=working_dir.as_posix(), - return_code=e.returncode, - output=e.output, + "Failed to generate flow meta for csharp flow and not generated flow meta " + f"found at {meta_path.as_posix()}. Please check log for more details." ) finally: if temp_init_kwargs_file: diff --git a/src/promptflow-devkit/promptflow/_proxy/_python_inspector_proxy.py b/src/promptflow-devkit/promptflow/_proxy/_python_inspector_proxy.py index ccb5b051e5b..1bf798659df 100644 --- a/src/promptflow-devkit/promptflow/_proxy/_python_inspector_proxy.py +++ b/src/promptflow-devkit/promptflow/_proxy/_python_inspector_proxy.py @@ -5,7 +5,7 @@ from promptflow._constants import FlowEntryRegex from promptflow._core.entry_meta_generator import _generate_flow_meta from promptflow._sdk._constants import FLOW_META_JSON_GEN_TIMEOUT -from promptflow._utils.flow_utils import is_flex_flow, resolve_python_entry_file +from promptflow._utils.flow_utils import resolve_python_entry_file from ._base_inspector_proxy import AbstractInspectorProxy @@ -53,11 +53,6 @@ def prepare_metadata( working_dir: Path, **kwargs, ) -> None: - if not is_flex_flow(flow_path=flow_file, working_dir=working_dir): - from promptflow._sdk._utils import generate_flow_tools_json - - generate_flow_tools_json( - flow_directory=working_dir, - dump=True, - used_packages_only=True, - ) + # for python, we have a runtime to gather metadata in both local and cloud, so we don't prepare anything + # here so that people may submit the flow to cloud without local runtime + pass diff --git a/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_create_flow.yaml b/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_create_flow.yaml index 570ae259e1e..0a92464a84e 100644 --- a/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_create_flow.yaml +++ b/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_create_flow.yaml @@ -10,7 +10,7 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000 response: @@ -39,7 +39,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.031' + - '0.027' status: code: 200 message: OK @@ -54,7 +54,7 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory response: @@ -91,7 +91,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.103' + - '0.175' status: code: 200 message: OK @@ -108,7 +108,7 @@ interactions: - '0' User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory/listSecrets response: @@ -132,7 +132,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.087' + - '0.279' status: code: 200 message: OK @@ -148,9 +148,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:43 GMT + - Sun, 07 Apr 2024 06:34:25 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -166,7 +166,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:e3f0ab0c-701a-005f-37a8-90b9b0000000\nTime:2024-04-17T09:17:44.7892168Z" + specified resource already exists.\nRequestId:0c8640dc-601a-0088-35b5-88e885000000\nTime:2024-04-07T06:34:26.5829006Z" headers: content-length: - '228' @@ -193,9 +193,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:46 GMT + - Sun, 07 Apr 2024 06:34:27 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -211,7 +211,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:53fa3079-201a-0100-37a8-90f381000000\nTime:2024-04-17T09:17:47.7527765Z" + specified resource already exists.\nRequestId:2e0a24a6-701a-010d-58b5-883b55000000\nTime:2024-04-07T06:34:28.5285957Z" headers: content-length: - '228' @@ -238,9 +238,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:47 GMT + - Sun, 07 Apr 2024 06:34:28 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -256,7 +256,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:a622391e-601a-0111-1aa8-906935000000\nTime:2024-04-17T09:17:49.1386469Z" + specified resource already exists.\nRequestId:d60dae6f-e01a-00f4-45b5-88c67a000000\nTime:2024-04-07T06:34:29.2676781Z" headers: content-length: - '228' @@ -283,9 +283,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:49 GMT + - Sun, 07 Apr 2024 06:34:29 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -301,7 +301,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:ab9ba495-001a-00a1-52a8-90d6f1000000\nTime:2024-04-17T09:17:50.4404899Z" + specified resource already exists.\nRequestId:88493116-001a-00d3-3eb5-88d1be000000\nTime:2024-04-07T06:34:30.0186433Z" headers: content-length: - '228' @@ -326,9 +326,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:50 GMT + - Sun, 07 Apr 2024 06:34:29 GMT x-ms-version: - '2023-11-03' method: GET @@ -336,7 +336,7 @@ interactions: response: body: string: "\uFEFFResourceNotFoundThe - specified resource does not exist.\nRequestId:a6952a6c-101a-00e0-55a8-908e15000000\nTime:2024-04-17T09:17:51.7222172Z" + specified resource does not exist.\nRequestId:00b5a7f8-b01a-00e9-5fb5-88cbc6000000\nTime:2024-04-07T06:34:30.7371784Z" headers: content-length: - '223' @@ -365,9 +365,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:51 GMT + - Sun, 07 Apr 2024 06:34:30 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -387,21 +387,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:17:53 GMT + - Sun, 07 Apr 2024 06:34:31 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:17:53.0268687Z' + - '2024-04-07T06:34:31.4893341Z' x-ms-file-creation-time: - - '2024-04-17T09:17:53.0268687Z' + - '2024-04-07T06:34:31.4893341Z' x-ms-file-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-file-last-write-time: - - '2024-04-17T09:17:53.0268687Z' + - '2024-04-07T06:34:31.4893341Z' x-ms-file-parent-id: - - '16141035093245296640' + - '13835071545774440448' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -421,9 +421,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:53 GMT + - Sun, 07 Apr 2024 06:34:31 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -435,7 +435,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory response: body: string: '' @@ -443,21 +443,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:17:54 GMT + - Sun, 07 Apr 2024 06:34:32 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:17:54.3858935Z' + - '2024-04-07T06:34:32.2280808Z' x-ms-file-creation-time: - - '2024-04-17T09:17:54.3858935Z' + - '2024-04-07T06:34:32.2280808Z' x-ms-file-id: - - '13835170089504079872' + - '13835139715495362560' x-ms-file-last-write-time: - - '2024-04-17T09:17:54.3858935Z' + - '2024-04-07T06:34:32.2280808Z' x-ms-file-parent-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -477,9 +477,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:54 GMT + - Sun, 07 Apr 2024 06:34:32 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -491,7 +491,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory response: body: string: '' @@ -499,21 +499,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:17:55 GMT + - Sun, 07 Apr 2024 06:34:32 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:17:55.6802039Z' + - '2024-04-07T06:34:32.9897293Z' x-ms-file-creation-time: - - '2024-04-17T09:17:55.6802039Z' + - '2024-04-07T06:34:32.9897293Z' x-ms-file-id: - - '13835082128573857792' + - '13835104531123273728' x-ms-file-last-write-time: - - '2024-04-17T09:17:55.6802039Z' + - '2024-04-07T06:34:32.9897293Z' x-ms-file-parent-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -533,11 +533,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '14' x-ms-date: - - Wed, 17 Apr 2024 09:17:55 GMT + - Sun, 07 Apr 2024 06:34:32 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -559,21 +559,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:17:56 GMT + - Sun, 07 Apr 2024 06:34:33 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:17:56.9705319Z' + - '2024-04-07T06:34:33.7374366Z' x-ms-file-creation-time: - - '2024-04-17T09:17:56.9705319Z' + - '2024-04-07T06:34:33.7374366Z' x-ms-file-id: - - '13835152497318035456' + - '13835174899867451392' x-ms-file-last-write-time: - - '2024-04-17T09:17:56.9705319Z' + - '2024-04-07T06:34:33.7374366Z' x-ms-file-parent-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -599,9 +599,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:57 GMT + - Sun, 07 Apr 2024 06:34:33 GMT x-ms-range: - bytes=0-13 x-ms-version: @@ -619,11 +619,11 @@ interactions: content-md5: - nYmkCopuDuFj82431amzZw== last-modified: - - Wed, 17 Apr 2024 09:17:58 GMT + - Sun, 07 Apr 2024 06:34:34 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:17:58.3405083Z' + - '2024-04-07T06:34:34.4841507Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -643,11 +643,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - - '372' + - '631' x-ms-date: - - Wed, 17 Apr 2024 09:17:58 GMT + - Sun, 07 Apr 2024 06:34:34 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -661,7 +661,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log response: body: string: '' @@ -669,21 +669,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:17:59 GMT + - Sun, 07 Apr 2024 06:34:35 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:17:59.7224339Z' + - '2024-04-07T06:34:35.1990043Z' x-ms-file-creation-time: - - '2024-04-17T09:17:59.7224339Z' + - '2024-04-07T06:34:35.1990043Z' x-ms-file-id: - - '11529291895918297088' + - '13835086938937229312' x-ms-file-last-write-time: - - '2024-04-17T09:17:59.7224339Z' + - '2024-04-07T06:34:35.1990043Z' x-ms-file-parent-id: - - '13835170089504079872' + - '13835104531123273728' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -692,12 +692,137 @@ interactions: code: 201 message: Created - request: - body: "{\n \"code\": {\n \"hello_world.py\": {\n \"type\": - \"python\",\n \"inputs\": {\n \"name\": {\n - \ \"type\": [\n \"string\"\n ]\n - \ }\n },\n \"source\": \"hello_world.py\",\n - \ \"function\": \"hello_world\"\n }\n },\n \"package\": - {}\n}" + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start executing + nodes in thread pool mode. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start to run 1 + nodes with concurrency level 16. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing node + hello_world. node run id: d32eef14-ba6e-44d7-9410-d9c8491fd4fb_hello_world_0 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + 2024-04-07 03:33:32 +0000 718308 execution.flow WARNING Error occurred + while force flush tracer provider: ''ProxyTracerProvider'' object has no attribute + ''force_flush'' + + ' + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '631' + Content-MD5: + - 4xvZisyz3aqT9bHeHwyeyA== + Content-Type: + - application/octet-stream + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-date: + - Sun, 07 Apr 2024 06:34:35 GMT + x-ms-range: + - bytes=0-630 + x-ms-version: + - '2023-11-03' + x-ms-write: + - update + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log?comp=range + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - 4xvZisyz3aqT9bHeHwyeyA== + last-modified: + - Sun, 07 Apr 2024 06:34:35 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-last-write-time: + - '2024-04-07T06:34:35.9745899Z' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-content-length: + - '279' + x-ms-date: + - Sun, 07 Apr 2024 06:34:35 GMT + x-ms-file-attributes: + - none + x-ms-file-creation-time: + - now + x-ms-file-last-write-time: + - now + x-ms-file-permission: + - Inherit + x-ms-type: + - file + x-ms-version: + - '2023-11-03' + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log + response: + body: + string: '' + headers: + content-length: + - '0' + last-modified: + - Sun, 07 Apr 2024 06:34:36 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-attributes: + - Archive + x-ms-file-change-time: + - '2024-04-07T06:34:36.7043778Z' + x-ms-file-creation-time: + - '2024-04-07T06:34:36.7043778Z' + x-ms-file-id: + - '13835157307681406976' + x-ms-file-last-write-time: + - '2024-04-07T06:34:36.7043778Z' + x-ms-file-parent-id: + - '13835104531123273728' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing + node hello_world. node run id: f075dfe5-21f5-4d1b-84d1-46ac116bd4ab_hello_world_788fcf13-4cb3-4479-b4de-97a3b2ccd690 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + ' headers: Accept: - application/xml @@ -706,23 +831,23 @@ interactions: Connection: - keep-alive Content-Length: - - '372' + - '279' Content-MD5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:17:59 GMT + - Sun, 07 Apr 2024 06:34:36 GMT x-ms-range: - - bytes=0-371 + - bytes=0-278 x-ms-version: - '2023-11-03' x-ms-write: - update method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json?comp=range + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log?comp=range response: body: string: '' @@ -730,13 +855,13 @@ interactions: content-length: - '0' content-md5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== last-modified: - - Wed, 17 Apr 2024 09:18:01 GMT + - Sun, 07 Apr 2024 06:34:37 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:18:01.1043578Z' + - '2024-04-07T06:34:37.4311787Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -756,11 +881,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '250' x-ms-date: - - Wed, 17 Apr 2024 09:18:01 GMT + - Sun, 07 Apr 2024 06:34:37 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -782,21 +907,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:18:02 GMT + - Sun, 07 Apr 2024 06:34:38 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:18:02.4096190Z' + - '2024-04-07T06:34:38.1241284Z' x-ms-file-creation-time: - - '2024-04-17T09:18:02.4096190Z' + - '2024-04-07T06:34:38.1241284Z' x-ms-file-id: - - '13835187681690124288' + - '11529351681863057408' x-ms-file-last-write-time: - - '2024-04-17T09:18:02.4096190Z' + - '2024-04-07T06:34:38.1241284Z' x-ms-file-parent-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -823,9 +948,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:18:02 GMT + - Sun, 07 Apr 2024 06:34:38 GMT x-ms-range: - bytes=0-249 x-ms-version: @@ -843,11 +968,11 @@ interactions: content-md5: - CT1FTZp5JScB8fq+HjnINw== last-modified: - - Wed, 17 Apr 2024 09:18:03 GMT + - Sun, 07 Apr 2024 06:34:38 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:18:03.8721896Z' + - '2024-04-07T06:34:38.8748240Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -867,11 +992,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '110' x-ms-date: - - Wed, 17 Apr 2024 09:18:04 GMT + - Sun, 07 Apr 2024 06:34:38 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -893,21 +1018,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:18:05 GMT + - Sun, 07 Apr 2024 06:34:39 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:18:05.3377463Z' + - '2024-04-07T06:34:39.5926643Z' x-ms-file-creation-time: - - '2024-04-17T09:18:05.3377463Z' + - '2024-04-07T06:34:39.5926643Z' x-ms-file-id: - - '11529349070522941440' + - '13835122123309318144' x-ms-file-last-write-time: - - '2024-04-17T09:18:05.3377463Z' + - '2024-04-07T06:34:39.5926643Z' x-ms-file-parent-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -932,9 +1057,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:18:05 GMT + - Sun, 07 Apr 2024 06:34:39 GMT x-ms-range: - bytes=0-109 x-ms-version: @@ -952,11 +1077,11 @@ interactions: content-md5: - 3CPKwiOwfwiEOJC0UpjR0Q== last-modified: - - Wed, 17 Apr 2024 09:18:06 GMT + - Sun, 07 Apr 2024 06:34:40 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:18:06.8062899Z' + - '2024-04-07T06:34:40.3184710Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -976,31 +1101,31 @@ interactions: Connection: - keep-alive Content-Length: - - '258' + - '251' Content-Type: - application/json User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows response: body: - string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/c3d2c490-69a7-47db-9301-474ba455b4ff/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", - "flowId": "c3d2c490-69a7-47db-9301-474ba455b4ff", "flowName": "flow_display_name", + string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/3a620baa-25ea-444d-904a-8c4b87efe0e4/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "flowId": "3a620baa-25ea-444d-904a-8c4b87efe0e4", "flowName": "flow_display_name", "description": "test flow description", "tags": {"owner": "sdk-test"}, "flowType": "Default", "experimentId": "00000000-0000-0000-0000-000000000000", "createdDate": - "2024-04-17T09:18:09.9529539Z", "lastModifiedDate": "2024-04-17T09:18:09.9529539Z", + "2024-04-07T06:34:42.3877314Z", "lastModifiedDate": "2024-04-07T06:34:42.3877314Z", "owner": {"userObjectId": "00000000-0000-0000-0000-000000000000", "userTenantId": - "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang"}, "flowResourceId": - "azureml://locations/eastus/workspaces/00000/flows/c3d2c490-69a7-47db-9301-474ba455b4ff", + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao"}, "flowResourceId": + "azureml://locations/eastus/workspaces/00000/flows/3a620baa-25ea-444d-904a-8c4b87efe0e4", "isArchived": false, "flowDefinitionFilePath": "Users/unknown_user/promptflow/flow_name/flow.dag.yaml", "enableMultiContainer": false}' headers: connection: - keep-alive content-length: - - '1082' + - '1072' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1012,7 +1137,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.300' + - '0.473' status: code: 200 message: OK @@ -1026,9 +1151,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:18:10 GMT + - Sun, 07 Apr 2024 06:34:42 GMT x-ms-version: - '2023-11-03' method: HEAD @@ -1042,7 +1167,7 @@ interactions: content-type: - application/octet-stream last-modified: - - Wed, 17 Apr 2024 09:18:03 GMT + - Sun, 07 Apr 2024 06:34:38 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 vary: @@ -1050,15 +1175,15 @@ interactions: x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:18:03.8721896Z' + - '2024-04-07T06:34:38.8748240Z' x-ms-file-creation-time: - - '2024-04-17T09:18:02.4096190Z' + - '2024-04-07T06:34:38.1241284Z' x-ms-file-id: - - '13835187681690124288' + - '11529351681863057408' x-ms-file-last-write-time: - - '2024-04-17T09:18:03.8721896Z' + - '2024-04-07T06:34:38.8748240Z' x-ms-file-parent-id: - - '13835099720759902208' + - '13835069346751184896' x-ms-type: - File x-ms-version: diff --git a/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_get_flow.yaml b/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_get_flow.yaml index 8330b2cd168..e853e7b50ff 100644 --- a/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_get_flow.yaml +++ b/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_get_flow.yaml @@ -10,7 +10,7 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000 response: @@ -39,7 +39,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.030' + - '0.034' status: code: 200 message: OK @@ -54,7 +54,7 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory response: @@ -91,7 +91,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.104' + - '0.765' status: code: 200 message: OK @@ -108,7 +108,7 @@ interactions: - '0' User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory/listSecrets response: @@ -132,7 +132,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.082' + - '0.164' status: code: 200 message: OK @@ -148,9 +148,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:25 GMT + - Sun, 07 Apr 2024 06:43:59 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -166,7 +166,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:c66ced0a-701a-010d-3ba7-903b55000000\nTime:2024-04-17T09:16:26.6230580Z" + specified resource already exists.\nRequestId:88493934-001a-00d3-32b6-88d1be000000\nTime:2024-04-07T06:44:00.4619546Z" headers: content-length: - '228' @@ -193,9 +193,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:28 GMT + - Sun, 07 Apr 2024 06:44:01 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -211,7 +211,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:2a7c4bde-c01a-0028-7fa7-906c24000000\nTime:2024-04-17T09:16:29.6005553Z" + specified resource already exists.\nRequestId:7fdf331e-a01a-0097-27b6-885b81000000\nTime:2024-04-07T06:44:02.4623188Z" headers: content-length: - '228' @@ -238,9 +238,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:29 GMT + - Sun, 07 Apr 2024 06:44:02 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -256,7 +256,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:399b256e-101a-00cf-75a7-9083de000000\nTime:2024-04-17T09:16:31.0091452Z" + specified resource already exists.\nRequestId:7381b618-101a-010b-5db6-8808ea000000\nTime:2024-04-07T06:44:03.1735290Z" headers: content-length: - '228' @@ -283,9 +283,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:31 GMT + - Sun, 07 Apr 2024 06:44:03 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -301,7 +301,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:6134b832-801a-0016-5ca7-90fb5b000000\nTime:2024-04-17T09:16:32.3941771Z" + specified resource already exists.\nRequestId:42dff510-e01a-00db-4ab6-88cbb1000000\nTime:2024-04-07T06:44:03.9076891Z" headers: content-length: - '228' @@ -326,9 +326,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:32 GMT + - Sun, 07 Apr 2024 06:44:03 GMT x-ms-version: - '2023-11-03' method: GET @@ -336,7 +336,7 @@ interactions: response: body: string: "\uFEFFResourceNotFoundThe - specified resource does not exist.\nRequestId:bca319c5-201a-00d4-57a7-90bddd000000\nTime:2024-04-17T09:16:33.8183650Z" + specified resource does not exist.\nRequestId:0f615f6b-e01a-0086-4fb6-88c135000000\nTime:2024-04-07T06:44:04.6125141Z" headers: content-length: - '223' @@ -365,9 +365,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:33 GMT + - Sun, 07 Apr 2024 06:44:04 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -387,21 +387,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:35 GMT + - Sun, 07 Apr 2024 06:44:05 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:16:35.2219247Z' + - '2024-04-07T06:44:05.3130956Z' x-ms-file-creation-time: - - '2024-04-17T09:16:35.2219247Z' + - '2024-04-07T06:44:05.3130956Z' x-ms-file-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-file-last-write-time: - - '2024-04-17T09:16:35.2219247Z' + - '2024-04-07T06:44:05.3130956Z' x-ms-file-parent-id: - - '16141035093245296640' + - '13835071545774440448' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -421,9 +421,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:35 GMT + - Sun, 07 Apr 2024 06:44:05 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -435,7 +435,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory response: body: string: '' @@ -443,21 +443,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:36 GMT + - Sun, 07 Apr 2024 06:44:06 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:16:36.6327204Z' + - '2024-04-07T06:44:06.0279564Z' x-ms-file-creation-time: - - '2024-04-17T09:16:36.6327204Z' + - '2024-04-07T06:44:06.0279564Z' x-ms-file-id: - - '13835148099271524352' + - '11529314298467713024' x-ms-file-last-write-time: - - '2024-04-17T09:16:36.6327204Z' + - '2024-04-07T06:44:06.0279564Z' x-ms-file-parent-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -477,9 +477,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:36 GMT + - Sun, 07 Apr 2024 06:44:05 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -491,7 +491,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory response: body: string: '' @@ -499,21 +499,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:38 GMT + - Sun, 07 Apr 2024 06:44:06 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:16:38.0952908Z' + - '2024-04-07T06:44:06.7896105Z' x-ms-file-creation-time: - - '2024-04-17T09:16:38.0952908Z' + - '2024-04-07T06:44:06.7896105Z' x-ms-file-id: - - '13835183283643613184' + - '13835170501820940288' x-ms-file-last-write-time: - - '2024-04-17T09:16:38.0952908Z' + - '2024-04-07T06:44:06.7896105Z' x-ms-file-parent-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -533,11 +533,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '14' x-ms-date: - - Wed, 17 Apr 2024 09:16:38 GMT + - Sun, 07 Apr 2024 06:44:06 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -559,21 +559,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:39 GMT + - Sun, 07 Apr 2024 06:44:07 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:16:39.5080796Z' + - '2024-04-07T06:44:07.4984958Z' x-ms-file-creation-time: - - '2024-04-17T09:16:39.5080796Z' + - '2024-04-07T06:44:07.4984958Z' x-ms-file-id: - - '13835068934434324480' + - '13835082540890718208' x-ms-file-last-write-time: - - '2024-04-17T09:16:39.5080796Z' + - '2024-04-07T06:44:07.4984958Z' x-ms-file-parent-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -599,9 +599,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:39 GMT + - Sun, 07 Apr 2024 06:44:07 GMT x-ms-range: - bytes=0-13 x-ms-version: @@ -619,11 +619,11 @@ interactions: content-md5: - nYmkCopuDuFj82431amzZw== last-modified: - - Wed, 17 Apr 2024 09:16:40 GMT + - Sun, 07 Apr 2024 06:44:08 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:16:40.9208691Z' + - '2024-04-07T06:44:08.2332671Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -643,11 +643,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - - '372' + - '631' x-ms-date: - - Wed, 17 Apr 2024 09:16:41 GMT + - Sun, 07 Apr 2024 06:44:08 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -661,7 +661,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log response: body: string: '' @@ -669,21 +669,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:42 GMT + - Sun, 07 Apr 2024 06:44:08 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:16:42.3406264Z' + - '2024-04-07T06:44:08.9292109Z' x-ms-file-creation-time: - - '2024-04-17T09:16:42.3406264Z' + - '2024-04-07T06:44:08.9292109Z' x-ms-file-id: - - '13835139303178502144' + - '16141009112988123136' x-ms-file-last-write-time: - - '2024-04-17T09:16:42.3406264Z' + - '2024-04-07T06:44:08.9292109Z' x-ms-file-parent-id: - - '13835148099271524352' + - '13835170501820940288' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -692,12 +692,137 @@ interactions: code: 201 message: Created - request: - body: "{\n \"code\": {\n \"hello_world.py\": {\n \"type\": - \"python\",\n \"inputs\": {\n \"name\": {\n - \ \"type\": [\n \"string\"\n ]\n - \ }\n },\n \"source\": \"hello_world.py\",\n - \ \"function\": \"hello_world\"\n }\n },\n \"package\": - {}\n}" + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start executing + nodes in thread pool mode. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start to run 1 + nodes with concurrency level 16. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing node + hello_world. node run id: d32eef14-ba6e-44d7-9410-d9c8491fd4fb_hello_world_0 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + 2024-04-07 03:33:32 +0000 718308 execution.flow WARNING Error occurred + while force flush tracer provider: ''ProxyTracerProvider'' object has no attribute + ''force_flush'' + + ' + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '631' + Content-MD5: + - 4xvZisyz3aqT9bHeHwyeyA== + Content-Type: + - application/octet-stream + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-date: + - Sun, 07 Apr 2024 06:44:08 GMT + x-ms-range: + - bytes=0-630 + x-ms-version: + - '2023-11-03' + x-ms-write: + - update + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log?comp=range + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - 4xvZisyz3aqT9bHeHwyeyA== + last-modified: + - Sun, 07 Apr 2024 06:44:09 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-last-write-time: + - '2024-04-07T06:44:09.6370996Z' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-content-length: + - '279' + x-ms-date: + - Sun, 07 Apr 2024 06:44:09 GMT + x-ms-file-attributes: + - none + x-ms-file-creation-time: + - now + x-ms-file-last-write-time: + - now + x-ms-file-permission: + - Inherit + x-ms-type: + - file + x-ms-version: + - '2023-11-03' + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log + response: + body: + string: '' + headers: + content-length: + - '0' + last-modified: + - Sun, 07 Apr 2024 06:44:10 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-attributes: + - Archive + x-ms-file-change-time: + - '2024-04-07T06:44:10.3469815Z' + x-ms-file-creation-time: + - '2024-04-07T06:44:10.3469815Z' + x-ms-file-id: + - '11529243929723535360' + x-ms-file-last-write-time: + - '2024-04-07T06:44:10.3469815Z' + x-ms-file-parent-id: + - '13835170501820940288' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing + node hello_world. node run id: f075dfe5-21f5-4d1b-84d1-46ac116bd4ab_hello_world_788fcf13-4cb3-4479-b4de-97a3b2ccd690 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + ' headers: Accept: - application/xml @@ -706,23 +831,23 @@ interactions: Connection: - keep-alive Content-Length: - - '372' + - '279' Content-MD5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:42 GMT + - Sun, 07 Apr 2024 06:44:10 GMT x-ms-range: - - bytes=0-371 + - bytes=0-278 x-ms-version: - '2023-11-03' x-ms-write: - update method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json?comp=range + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log?comp=range response: body: string: '' @@ -730,13 +855,13 @@ interactions: content-length: - '0' content-md5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== last-modified: - - Wed, 17 Apr 2024 09:16:43 GMT + - Sun, 07 Apr 2024 06:44:11 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:16:43.7534160Z' + - '2024-04-07T06:44:11.0737879Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -756,11 +881,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '250' x-ms-date: - - Wed, 17 Apr 2024 09:16:43 GMT + - Sun, 07 Apr 2024 06:44:11 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -782,21 +907,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:45 GMT + - Sun, 07 Apr 2024 06:44:11 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:16:45.1642190Z' + - '2024-04-07T06:44:11.8135386Z' x-ms-file-creation-time: - - '2024-04-17T09:16:45.1642190Z' + - '2024-04-07T06:44:11.8135386Z' x-ms-file-id: - - '13835104118806413312' + - '13835152909634895872' x-ms-file-last-write-time: - - '2024-04-17T09:16:45.1642190Z' + - '2024-04-07T06:44:11.8135386Z' x-ms-file-parent-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -823,9 +948,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:45 GMT + - Sun, 07 Apr 2024 06:44:11 GMT x-ms-range: - bytes=0-249 x-ms-version: @@ -843,11 +968,11 @@ interactions: content-md5: - CT1FTZp5JScB8fq+HjnINw== last-modified: - - Wed, 17 Apr 2024 09:16:46 GMT + - Sun, 07 Apr 2024 06:44:12 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:16:46.5112920Z' + - '2024-04-07T06:44:12.5214287Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -867,11 +992,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '110' x-ms-date: - - Wed, 17 Apr 2024 09:16:46 GMT + - Sun, 07 Apr 2024 06:44:12 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -893,21 +1018,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:16:47 GMT + - Sun, 07 Apr 2024 06:44:13 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:16:47.9011810Z' + - '2024-04-07T06:44:13.2094055Z' x-ms-file-creation-time: - - '2024-04-17T09:16:47.9011810Z' + - '2024-04-07T06:44:13.2094055Z' x-ms-file-id: - - '13835174487550590976' + - '13835117725262807040' x-ms-file-last-write-time: - - '2024-04-17T09:16:47.9011810Z' + - '2024-04-07T06:44:13.2094055Z' x-ms-file-parent-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -932,9 +1057,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:48 GMT + - Sun, 07 Apr 2024 06:44:13 GMT x-ms-range: - bytes=0-109 x-ms-version: @@ -952,11 +1077,11 @@ interactions: content-md5: - 3CPKwiOwfwiEOJC0UpjR0Q== last-modified: - - Wed, 17 Apr 2024 09:16:49 GMT + - Sun, 07 Apr 2024 06:44:13 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:16:49.2860926Z' + - '2024-04-07T06:44:13.9531380Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -976,31 +1101,31 @@ interactions: Connection: - keep-alive Content-Length: - - '258' + - '251' Content-Type: - application/json User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows response: body: - string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/a3501b97-cde4-447c-a36d-8e09a641d0a9/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", - "flowId": "a3501b97-cde4-447c-a36d-8e09a641d0a9", "flowName": "flow_display_name", + string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "flowId": "9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3", "flowName": "flow_display_name", "description": "test flow description", "tags": {"owner": "sdk-test"}, "flowType": "Default", "experimentId": "00000000-0000-0000-0000-000000000000", "createdDate": - "2024-04-17T09:16:52.218392Z", "lastModifiedDate": "2024-04-17T09:16:52.218392Z", + "2024-04-07T06:44:15.9833326Z", "lastModifiedDate": "2024-04-07T06:44:15.9833326Z", "owner": {"userObjectId": "00000000-0000-0000-0000-000000000000", "userTenantId": - "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang"}, "flowResourceId": - "azureml://locations/eastus/workspaces/00000/flows/a3501b97-cde4-447c-a36d-8e09a641d0a9", + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao"}, "flowResourceId": + "azureml://locations/eastus/workspaces/00000/flows/9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3", "isArchived": false, "flowDefinitionFilePath": "Users/unknown_user/promptflow/flow_name/flow.dag.yaml", "enableMultiContainer": false}' headers: connection: - keep-alive content-length: - - '1080' + - '1072' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1012,7 +1137,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.244' + - '0.292' status: code: 200 message: OK @@ -1026,9 +1151,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:16:52 GMT + - Sun, 07 Apr 2024 06:44:16 GMT x-ms-version: - '2023-11-03' method: HEAD @@ -1042,7 +1167,7 @@ interactions: content-type: - application/octet-stream last-modified: - - Wed, 17 Apr 2024 09:16:46 GMT + - Sun, 07 Apr 2024 06:44:12 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 vary: @@ -1050,15 +1175,15 @@ interactions: x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:16:46.5112920Z' + - '2024-04-07T06:44:12.5214287Z' x-ms-file-creation-time: - - '2024-04-17T09:16:45.1642190Z' + - '2024-04-07T06:44:11.8135386Z' x-ms-file-id: - - '13835104118806413312' + - '13835152909634895872' x-ms-file-last-write-time: - - '2024-04-17T09:16:46.5112920Z' + - '2024-04-07T06:44:12.5214287Z' x-ms-file-parent-id: - - '13835077730527346688' + - '13835100133076762624' x-ms-type: - File x-ms-version: @@ -1077,27 +1202,27 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET - uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/a3501b97-cde4-447c-a36d-8e09a641d0a9?experimentId=00000000-0000-0000-0000-000000000000 + uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3?experimentId=00000000-0000-0000-0000-000000000000 response: body: - string: '{"timestamp": "2024-04-17T09:16:52.3401351+00:00", "eTag": {}, "studioPortalEndpoint": - "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/a3501b97-cde4-447c-a36d-8e09a641d0a9/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", - "flowId": "a3501b97-cde4-447c-a36d-8e09a641d0a9", "flowName": "flow_display_name", + string: '{"timestamp": "2024-04-07T06:44:16.1241604+00:00", "eTag": {}, "studioPortalEndpoint": + "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "flowId": "9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3", "flowName": "flow_display_name", "description": "test flow description", "tags": {"owner": "sdk-test"}, "flowType": "Default", "experimentId": "00000000-0000-0000-0000-000000000000", "createdDate": - "2024-04-17T09:16:52.218392Z", "lastModifiedDate": "2024-04-17T09:16:52.218392Z", + "2024-04-07T06:44:15.9833326Z", "lastModifiedDate": "2024-04-07T06:44:15.9833326Z", "owner": {"userObjectId": "00000000-0000-0000-0000-000000000000", "userTenantId": - "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang"}, "flowResourceId": - "azureml://locations/eastus/workspaces/00000/flows/a3501b97-cde4-447c-a36d-8e09a641d0a9", + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao"}, "flowResourceId": + "azureml://locations/eastus/workspaces/00000/flows/9d8104b3-f9fa-4fef-a5c1-66bbde09e4c3", "isArchived": false, "flowDefinitionFilePath": "Users/unknown_user/promptflow/flow_name/flow.dag.yaml", "enableMultiContainer": false}' headers: connection: - keep-alive content-length: - - '1128' + - '1120' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1109,7 +1234,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.169' + - '0.178' status: code: 200 message: OK diff --git a/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_update_flow.yaml b/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_update_flow.yaml index fa16c5f8eab..870155871f1 100644 --- a/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_update_flow.yaml +++ b/src/promptflow-recording/recordings/azure/test_flow_operations_TestFlow_test_update_flow.yaml @@ -10,7 +10,7 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000 response: @@ -39,7 +39,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.027' + - '0.045' status: code: 200 message: OK @@ -54,7 +54,7 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory response: @@ -91,7 +91,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.732' + - '0.079' status: code: 200 message: OK @@ -108,7 +108,7 @@ interactions: - '0' User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory/listSecrets response: @@ -132,7 +132,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.098' + - '0.103' status: code: 200 message: OK @@ -148,9 +148,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:41 GMT + - Sun, 07 Apr 2024 06:44:39 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -166,7 +166,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:c0d8bad7-801a-0109-45a7-90b652000000\nTime:2024-04-17T09:14:43.0070391Z" + specified resource already exists.\nRequestId:b3141a8d-501a-010a-68b7-885736000000\nTime:2024-04-07T06:44:40.4681707Z" headers: content-length: - '228' @@ -193,9 +193,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:44 GMT + - Sun, 07 Apr 2024 06:44:41 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -211,7 +211,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:8c0d1b8a-b01a-0112-3ea7-908851000000\nTime:2024-04-17T09:14:45.8424923Z" + specified resource already exists.\nRequestId:5db3e649-901a-0047-56b7-8866d7000000\nTime:2024-04-07T06:44:42.3806642Z" headers: content-length: - '228' @@ -238,9 +238,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:45 GMT + - Sun, 07 Apr 2024 06:44:42 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -256,7 +256,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:48ab2bdf-801a-00f2-19a7-90f5c5000000\nTime:2024-04-17T09:14:47.2317578Z" + specified resource already exists.\nRequestId:6fc18777-201a-00a6-09b7-88ba92000000\nTime:2024-04-07T06:44:43.3981770Z" headers: content-length: - '228' @@ -283,9 +283,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:47 GMT + - Sun, 07 Apr 2024 06:44:43 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -301,7 +301,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:98b7d0a7-e01a-0000-4aa7-900d8c000000\nTime:2024-04-17T09:14:48.8238999Z" + specified resource already exists.\nRequestId:6e9bf579-601a-00c5-55b7-882769000000\nTime:2024-04-07T06:44:44.1098095Z" headers: content-length: - '228' @@ -326,9 +326,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:48 GMT + - Sun, 07 Apr 2024 06:44:44 GMT x-ms-version: - '2023-11-03' method: GET @@ -336,7 +336,7 @@ interactions: response: body: string: "\uFEFFResourceNotFoundThe - specified resource does not exist.\nRequestId:7828e3d0-b01a-00a4-7fa7-90042a000000\nTime:2024-04-17T09:14:50.1624794Z" + specified resource does not exist.\nRequestId:43e6d5bf-001a-00fc-67b7-88dc75000000\nTime:2024-04-07T06:44:44.8321573Z" headers: content-length: - '223' @@ -365,9 +365,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:50 GMT + - Sun, 07 Apr 2024 06:44:44 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -387,21 +387,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:14:51 GMT + - Sun, 07 Apr 2024 06:44:45 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:14:51.5815464Z' + - '2024-04-07T06:44:45.5373581Z' x-ms-file-creation-time: - - '2024-04-17T09:14:51.5815464Z' + - '2024-04-07T06:44:45.5373581Z' x-ms-file-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-file-last-write-time: - - '2024-04-17T09:14:51.5815464Z' + - '2024-04-07T06:44:45.5373581Z' x-ms-file-parent-id: - - '16141035093245296640' + - '13835071545774440448' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -421,9 +421,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:51 GMT + - Sun, 07 Apr 2024 06:44:45 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -435,7 +435,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory response: body: string: '' @@ -443,21 +443,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:14:52 GMT + - Sun, 07 Apr 2024 06:44:46 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:14:52.9485368Z' + - '2024-04-07T06:44:46.2920417Z' x-ms-file-creation-time: - - '2024-04-17T09:14:52.9485368Z' + - '2024-04-07T06:44:46.2920417Z' x-ms-file-id: - - '13835109616364552192' + - '13835091336983740416' x-ms-file-last-write-time: - - '2024-04-17T09:14:52.9485368Z' + - '2024-04-07T06:44:46.2920417Z' x-ms-file-parent-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -477,9 +477,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:53 GMT + - Sun, 07 Apr 2024 06:44:46 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -491,7 +491,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory response: body: string: '' @@ -499,21 +499,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:14:54 GMT + - Sun, 07 Apr 2024 06:44:47 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T09:14:54.3294656Z' + - '2024-04-07T06:44:47.0128746Z' x-ms-file-creation-time: - - '2024-04-17T09:14:54.3294656Z' + - '2024-04-07T06:44:47.0128746Z' x-ms-file-id: - - '13835179985108729856' + - '13835161705727918080' x-ms-file-last-write-time: - - '2024-04-17T09:14:54.3294656Z' + - '2024-04-07T06:44:47.0128746Z' x-ms-file-parent-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -533,11 +533,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '14' x-ms-date: - - Wed, 17 Apr 2024 09:14:54 GMT + - Sun, 07 Apr 2024 06:44:46 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -559,21 +559,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:14:55 GMT + - Sun, 07 Apr 2024 06:44:47 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:14:55.6785346Z' + - '2024-04-07T06:44:47.7615848Z' x-ms-file-creation-time: - - '2024-04-17T09:14:55.6785346Z' + - '2024-04-07T06:44:47.7615848Z' x-ms-file-id: - - '13835092024178507776' + - '13835126521355829248' x-ms-file-last-write-time: - - '2024-04-17T09:14:55.6785346Z' + - '2024-04-07T06:44:47.7615848Z' x-ms-file-parent-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -599,9 +599,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:55 GMT + - Sun, 07 Apr 2024 06:44:47 GMT x-ms-range: - bytes=0-13 x-ms-version: @@ -619,11 +619,11 @@ interactions: content-md5: - nYmkCopuDuFj82431amzZw== last-modified: - - Wed, 17 Apr 2024 09:14:57 GMT + - Sun, 07 Apr 2024 06:44:48 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:14:57.0783808Z' + - '2024-04-07T06:44:48.5043216Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -643,11 +643,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - - '372' + - '631' x-ms-date: - - Wed, 17 Apr 2024 09:14:57 GMT + - Sun, 07 Apr 2024 06:44:48 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -661,7 +661,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log response: body: string: '' @@ -669,21 +669,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:14:58 GMT + - Sun, 07 Apr 2024 06:44:49 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:14:58.4563223Z' + - '2024-04-07T06:44:49.2112135Z' x-ms-file-creation-time: - - '2024-04-17T09:14:58.4563223Z' + - '2024-04-07T06:44:49.2112135Z' x-ms-file-id: - - '13835162392922685440' + - '13835196890100006912' x-ms-file-last-write-time: - - '2024-04-17T09:14:58.4563223Z' + - '2024-04-07T06:44:49.2112135Z' x-ms-file-parent-id: - - '13835109616364552192' + - '13835161705727918080' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -692,12 +692,137 @@ interactions: code: 201 message: Created - request: - body: "{\n \"code\": {\n \"hello_world.py\": {\n \"type\": - \"python\",\n \"inputs\": {\n \"name\": {\n - \ \"type\": [\n \"string\"\n ]\n - \ }\n },\n \"source\": \"hello_world.py\",\n - \ \"function\": \"hello_world\"\n }\n },\n \"package\": - {}\n}" + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start executing + nodes in thread pool mode. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start to run 1 + nodes with concurrency level 16. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing node + hello_world. node run id: d32eef14-ba6e-44d7-9410-d9c8491fd4fb_hello_world_0 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + 2024-04-07 03:33:32 +0000 718308 execution.flow WARNING Error occurred + while force flush tracer provider: ''ProxyTracerProvider'' object has no attribute + ''force_flush'' + + ' + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '631' + Content-MD5: + - 4xvZisyz3aqT9bHeHwyeyA== + Content-Type: + - application/octet-stream + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-date: + - Sun, 07 Apr 2024 06:44:49 GMT + x-ms-range: + - bytes=0-630 + x-ms-version: + - '2023-11-03' + x-ms-write: + - update + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log?comp=range + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - 4xvZisyz3aqT9bHeHwyeyA== + last-modified: + - Sun, 07 Apr 2024 06:44:49 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-last-write-time: + - '2024-04-07T06:44:49.9420014Z' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-content-length: + - '279' + x-ms-date: + - Sun, 07 Apr 2024 06:44:49 GMT + x-ms-file-attributes: + - none + x-ms-file-creation-time: + - now + x-ms-file-last-write-time: + - now + x-ms-file-permission: + - Inherit + x-ms-type: + - file + x-ms-version: + - '2023-11-03' + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log + response: + body: + string: '' + headers: + content-length: + - '0' + last-modified: + - Sun, 07 Apr 2024 06:44:50 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-attributes: + - Archive + x-ms-file-change-time: + - '2024-04-07T06:44:50.6827469Z' + x-ms-file-creation-time: + - '2024-04-07T06:44:50.6827469Z' + x-ms-file-id: + - '13835059451146534912' + x-ms-file-last-write-time: + - '2024-04-07T06:44:50.6827469Z' + x-ms-file-parent-id: + - '13835161705727918080' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing + node hello_world. node run id: f075dfe5-21f5-4d1b-84d1-46ac116bd4ab_hello_world_788fcf13-4cb3-4479-b4de-97a3b2ccd690 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + ' headers: Accept: - application/xml @@ -706,23 +831,23 @@ interactions: Connection: - keep-alive Content-Length: - - '372' + - '279' Content-MD5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:14:58 GMT + - Sun, 07 Apr 2024 06:44:50 GMT x-ms-range: - - bytes=0-371 + - bytes=0-278 x-ms-version: - '2023-11-03' x-ms-write: - update method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json?comp=range + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log?comp=range response: body: string: '' @@ -730,13 +855,13 @@ interactions: content-length: - '0' content-md5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== last-modified: - - Wed, 17 Apr 2024 09:14:59 GMT + - Sun, 07 Apr 2024 06:44:51 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:14:59.8571639Z' + - '2024-04-07T06:44:51.3856576Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -756,11 +881,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '250' x-ms-date: - - Wed, 17 Apr 2024 09:14:59 GMT + - Sun, 07 Apr 2024 06:44:51 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -782,21 +907,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:15:01 GMT + - Sun, 07 Apr 2024 06:44:52 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:15:01.2410806Z' + - '2024-04-07T06:44:52.0766213Z' x-ms-file-creation-time: - - '2024-04-17T09:15:01.2410806Z' + - '2024-04-07T06:44:52.0766213Z' x-ms-file-id: - - '13835127208550596608' + - '13835129819890712576' x-ms-file-last-write-time: - - '2024-04-17T09:15:01.2410806Z' + - '2024-04-07T06:44:52.0766213Z' x-ms-file-parent-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -823,9 +948,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:15:01 GMT + - Sun, 07 Apr 2024 06:44:52 GMT x-ms-range: - bytes=0-249 x-ms-version: @@ -843,11 +968,11 @@ interactions: content-md5: - CT1FTZp5JScB8fq+HjnINw== last-modified: - - Wed, 17 Apr 2024 09:15:02 GMT + - Sun, 07 Apr 2024 06:44:52 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:15:02.6488910Z' + - '2024-04-07T06:44:52.8243348Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -867,11 +992,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '110' x-ms-date: - - Wed, 17 Apr 2024 09:15:02 GMT + - Sun, 07 Apr 2024 06:44:52 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -893,21 +1018,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 09:15:04 GMT + - Sun, 07 Apr 2024 06:44:53 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:15:04.0507286Z' + - '2024-04-07T06:44:53.5859883Z' x-ms-file-creation-time: - - '2024-04-17T09:15:04.0507286Z' + - '2024-04-07T06:44:53.5859883Z' x-ms-file-id: - - '13835197577294774272' + - '13835094635518623744' x-ms-file-last-write-time: - - '2024-04-17T09:15:04.0507286Z' + - '2024-04-07T06:44:53.5859883Z' x-ms-file-parent-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -932,9 +1057,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:15:04 GMT + - Sun, 07 Apr 2024 06:44:53 GMT x-ms-range: - bytes=0-109 x-ms-version: @@ -952,11 +1077,11 @@ interactions: content-md5: - 3CPKwiOwfwiEOJC0UpjR0Q== last-modified: - - Wed, 17 Apr 2024 09:15:05 GMT + - Sun, 07 Apr 2024 06:44:54 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T09:15:05.4655090Z' + - '2024-04-07T06:44:54.3137885Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -976,31 +1101,31 @@ interactions: Connection: - keep-alive Content-Length: - - '258' + - '251' Content-Type: - application/json User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows response: body: - string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/e7dfa049-c635-4120-8a40-a9bcd3f58ca2/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", - "flowId": "e7dfa049-c635-4120-8a40-a9bcd3f58ca2", "flowName": "flow_display_name", + string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/f459d73c-74e8-4be7-9bab-47994a7ba9a8/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "flowId": "f459d73c-74e8-4be7-9bab-47994a7ba9a8", "flowName": "flow_display_name", "description": "test flow description", "tags": {"owner": "sdk-test"}, "flowType": "Default", "experimentId": "00000000-0000-0000-0000-000000000000", "createdDate": - "2024-04-17T09:15:08.3278317Z", "lastModifiedDate": "2024-04-17T09:15:08.327832Z", + "2024-04-07T06:44:56.7664158Z", "lastModifiedDate": "2024-04-07T06:44:56.7664333Z", "owner": {"userObjectId": "00000000-0000-0000-0000-000000000000", "userTenantId": - "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang"}, "flowResourceId": - "azureml://locations/eastus/workspaces/00000/flows/e7dfa049-c635-4120-8a40-a9bcd3f58ca2", + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao"}, "flowResourceId": + "azureml://locations/eastus/workspaces/00000/flows/f459d73c-74e8-4be7-9bab-47994a7ba9a8", "isArchived": false, "flowDefinitionFilePath": "Users/unknown_user/promptflow/flow_name/flow.dag.yaml", "enableMultiContainer": false}' headers: connection: - keep-alive content-length: - - '1081' + - '1072' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1012,7 +1137,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.322' + - '0.791' status: code: 200 message: OK @@ -1026,9 +1151,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 09:15:08 GMT + - Sun, 07 Apr 2024 06:44:57 GMT x-ms-version: - '2023-11-03' method: HEAD @@ -1042,7 +1167,7 @@ interactions: content-type: - application/octet-stream last-modified: - - Wed, 17 Apr 2024 09:15:02 GMT + - Sun, 07 Apr 2024 06:44:52 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 vary: @@ -1050,15 +1175,15 @@ interactions: x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T09:15:02.6488910Z' + - '2024-04-07T06:44:52.8243348Z' x-ms-file-creation-time: - - '2024-04-17T09:15:01.2410806Z' + - '2024-04-07T06:44:52.0766213Z' x-ms-file-id: - - '13835127208550596608' + - '13835129819890712576' x-ms-file-last-write-time: - - '2024-04-17T09:15:02.6488910Z' + - '2024-04-07T06:44:52.8243348Z' x-ms-file-parent-id: - - '13835144800736641024' + - '13835179297913962496' x-ms-type: - File x-ms-version: @@ -1082,9 +1207,9 @@ interactions: - application/json User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: PUT - uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/e7dfa049-c635-4120-8a40-a9bcd3f58ca2?experimentId=00000000-0000-0000-0000-000000000000 + uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/f459d73c-74e8-4be7-9bab-47994a7ba9a8?experimentId=00000000-0000-0000-0000-000000000000 response: body: string: '' @@ -1098,7 +1223,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.274' + - '0.314' status: code: 200 message: OK @@ -1113,27 +1238,27 @@ interactions: - keep-alive User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET - uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/e7dfa049-c635-4120-8a40-a9bcd3f58ca2?experimentId=00000000-0000-0000-0000-000000000000 + uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/f459d73c-74e8-4be7-9bab-47994a7ba9a8?experimentId=00000000-0000-0000-0000-000000000000 response: body: - string: '{"timestamp": "2024-04-17T09:15:12.996435+00:00", "eTag": {}, "studioPortalEndpoint": - "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/e7dfa049-c635-4120-8a40-a9bcd3f58ca2/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", - "flowId": "e7dfa049-c635-4120-8a40-a9bcd3f58ca2", "flowName": "SDK test flow", + string: '{"timestamp": "2024-04-07T06:45:00.2916894+00:00", "eTag": {}, "studioPortalEndpoint": + "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/f459d73c-74e8-4be7-9bab-47994a7ba9a8/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "flowId": "f459d73c-74e8-4be7-9bab-47994a7ba9a8", "flowName": "SDK test flow", "description": "SDK test flow description", "tags": {"owner": "sdk-test", "key1": "value1"}, "flowType": "Default", "experimentId": "00000000-0000-0000-0000-000000000000", - "createdDate": "2024-04-17T09:15:08.3278317Z", "lastModifiedDate": "2024-04-17T09:15:12.991197Z", + "createdDate": "2024-04-07T06:44:56.7664158Z", "lastModifiedDate": "2024-04-07T06:45:00.2852733Z", "owner": {"userObjectId": "00000000-0000-0000-0000-000000000000", "userTenantId": - "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang"}, "flowResourceId": - "azureml://locations/eastus/workspaces/00000/flows/e7dfa049-c635-4120-8a40-a9bcd3f58ca2", + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao"}, "flowResourceId": + "azureml://locations/eastus/workspaces/00000/flows/f459d73c-74e8-4be7-9bab-47994a7ba9a8", "isArchived": false, "flowDefinitionFilePath": "Users/unknown_user/promptflow/flow_name/flow.dag.yaml", "enableMultiContainer": false}' headers: connection: - keep-alive content-length: - - '1125' + - '1117' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1145,7 +1270,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.156' + - '0.166' status: code: 200 message: OK @@ -1165,7 +1290,7 @@ interactions: - application/json User-Agent: - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: PUT uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows/fake_flow_name?experimentId=00000000-0000-0000-0000-000000000000 response: @@ -1178,14 +1303,14 @@ interactions: {"type": "Microsoft.MachineLearning.Common.Core.Exceptions.BaseException", "message": "Flow with id fake_flow_name not found", "stackTrace": " at Microsoft.MachineLearning.Studio.MiddleTier.Services.PromptFlow.FlowsManagement.GetFlowTableEntity(String experimentId, String flowId, Boolean checkDefinition) in /mnt/vss/_work/1/s/src/azureml-api/src/Designer/src/MiddleTier/MiddleTier/Services/PromptFlow/FlowsManagement.Flow.cs:line - 444\n at Microsoft.MachineLearning.Studio.MiddleTier.Services.PromptFlow.FlowsManagement.GetExistingFlowTableEntityAndVerifyOwnership(String + 443\n at Microsoft.MachineLearning.Studio.MiddleTier.Services.PromptFlow.FlowsManagement.GetExistingFlowTableEntityAndVerifyOwnership(String experimentId, String flowId, Boolean checkDefinition) in /mnt/vss/_work/1/s/src/azureml-api/src/Designer/src/MiddleTier/MiddleTier/Services/PromptFlow/FlowsManagement.Flow.cs:line - 422\n at Microsoft.MachineLearning.Studio.MiddleTier.Services.PromptFlow.FlowsManagement.UpdateFlow(String + 421\n at Microsoft.MachineLearning.Studio.MiddleTier.Services.PromptFlow.FlowsManagement.UpdateFlow(String experimentId, String flowId, UpdateFlowRequest updateFlowRequest) in /mnt/vss/_work/1/s/src/azureml-api/src/Designer/src/MiddleTier/MiddleTier/Services/PromptFlow/FlowsManagement.Flow.cs:line - 175\n at Microsoft.MachineLearning.Studio.MiddleTier.Controllers.PromptFlow.FlowsController.UpdateFlow(String + 174\n at Microsoft.MachineLearning.Studio.MiddleTier.Controllers.PromptFlow.FlowsController.UpdateFlow(String subscriptionId, String resourceGroupName, String workspaceName, String flowId, String experimentId, UpdateFlowRequest updateFlowRequest) in /mnt/vss/_work/1/s/src/azureml-api/src/Designer/src/MiddleTier/MiddleTier/Controllers/PromptFlow/FlowsController.cs:line - 104\n at lambda_method2125(Closure , Object )\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper + 104\n at lambda_method343011(Closure , Object )\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Logged|12_1(ControllerActionInvoker invoker)\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker @@ -1207,7 +1332,7 @@ interactions: context) in /mnt/vss/_work/1/s/src/azureml-api/src/Common/WebApi/ActivityExtensions/JwtUserInformationExtraction.cs:line 102\n at Microsoft.MachineLearning.Studio.MiddleTier.Middleware.WebApiClientHandler.Invoke(HttpContext context) in /mnt/vss/_work/1/s/src/azureml-api/src/Designer/src/MiddleTier/MiddleTier/Middleware/WebApiClientHandler.cs:line - 436\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext + 435\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\n at Microsoft.MachineLearning.Studio.MiddleTierCommon.Middlerware.ApiTelemetryHandler.Invoke(HttpContext context) in /mnt/vss/_work/1/s/src/azureml-api/src/Designer/src/MiddleTier/MiddleTierCommon/Middleware/ApiTelemetryHandler.cs:line 83\n at Microsoft.MachineLearning.Studio.MiddleTierCommon.Middlerware.ExternalApiTelemetryHandler.Invoke(HttpContext @@ -1232,15 +1357,15 @@ interactions: "CodesHierarchy": ["UserError", "NotFound", "FlowNotFound"], "Code": "FlowNotFound"}, "Message": "Flow with id fake_flow_name not found", "MessageParameters": {"flowId": "fake_flow_name"}, "Target": null, "RetryAfterSeconds": null}}, "errorResponse": - null}, "additionalInfo": null}, "correlation": {"operation": "7a2f63d26bb5960b3563cbb34698cbe7", - "request": "495537cd607ab118"}, "environment": "eastus", "location": "eastus", - "time": "2024-04-17T09:15:18.9588393+00:00", "componentName": "PromptFlowService", + null}, "additionalInfo": null}, "correlation": {"operation": "bfc284380ea16e741380f73b29741ec3", + "request": "affdf8a0613d5769"}, "environment": "eastus", "location": "eastus", + "time": "2024-04-07T06:45:04.6153137+00:00", "componentName": "PromptFlowService", "statusCode": 404}' headers: connection: - keep-alive content-length: - - '7728' + - '7730' content-type: - application/json strict-transport-security: @@ -1252,7 +1377,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.261' + - '0.245' status: code: 404 message: Flow with id fake_flow_name not found diff --git a/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_bulk_with_remote_flow.yaml b/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_bulk_with_remote_flow.yaml index f4c78005637..f45a5aa5f71 100644 --- a/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_bulk_with_remote_flow.yaml +++ b/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_bulk_with_remote_flow.yaml @@ -9,8 +9,8 @@ interactions: Connection: - keep-alive User-Agent: - - promptflow-azure-sdk/0.1.0b1 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000 response: @@ -39,7 +39,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.029' + - '0.026' status: code: 200 message: OK @@ -53,8 +53,8 @@ interactions: Connection: - keep-alive User-Agent: - - promptflow-azure-sdk/0.1.0b1 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory response: @@ -91,7 +91,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.098' + - '0.728' status: code: 200 message: OK @@ -107,8 +107,8 @@ interactions: Content-Length: - '0' User-Agent: - - promptflow-azure-sdk/0.1.0b1 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceworkingdirectory/listSecrets response: @@ -132,7 +132,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.108' + - '0.211' status: code: 200 message: OK @@ -148,9 +148,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:26 GMT + - Sun, 07 Apr 2024 08:50:24 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -166,7 +166,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:8c817558-001a-0008-1caf-901783000000\nTime:2024-04-17T10:12:28.0620199Z" + specified resource already exists.\nRequestId:bc2fc032-301a-0085-0ac8-882051000000\nTime:2024-04-07T08:50:25.8766448Z" headers: content-length: - '228' @@ -193,9 +193,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:29 GMT + - Sun, 07 Apr 2024 08:50:26 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -211,7 +211,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:47b72a16-101a-0059-34af-908a0f000000\nTime:2024-04-17T10:12:30.4614907Z" + specified resource already exists.\nRequestId:470ffc2f-b01a-0032-14c8-880dfb000000\nTime:2024-04-07T08:50:27.8117094Z" headers: content-length: - '228' @@ -238,9 +238,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:30 GMT + - Sun, 07 Apr 2024 08:50:27 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -256,7 +256,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:36faa221-701a-00bb-18af-90b72e000000\nTime:2024-04-17T10:12:31.5159611Z" + specified resource already exists.\nRequestId:d04f81f8-d01a-000b-34c8-88f6e7000000\nTime:2024-04-07T08:50:28.5224116Z" headers: content-length: - '228' @@ -283,9 +283,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:31 GMT + - Sun, 07 Apr 2024 08:50:28 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -301,7 +301,7 @@ interactions: response: body: string: "\uFEFFResourceAlreadyExistsThe - specified resource already exists.\nRequestId:12b24c17-401a-0019-1baf-908d37000000\nTime:2024-04-17T10:12:32.5730168Z" + specified resource already exists.\nRequestId:ac1d2011-601a-00a7-68c8-88e54e000000\nTime:2024-04-07T08:50:29.2473200Z" headers: content-length: - '228' @@ -326,9 +326,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:32 GMT + - Sun, 07 Apr 2024 08:50:29 GMT x-ms-version: - '2023-11-03' method: GET @@ -336,7 +336,7 @@ interactions: response: body: string: "\uFEFFResourceNotFoundThe - specified resource does not exist.\nRequestId:1ced2c08-901a-0105-32af-90215a000000\nTime:2024-04-17T10:12:33.6731538Z" + specified resource does not exist.\nRequestId:b9cc1e5d-a01a-005c-75c8-8858d4000000\nTime:2024-04-07T08:50:29.9719845Z" headers: content-length: - '223' @@ -365,9 +365,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:33 GMT + - Sun, 07 Apr 2024 08:50:29 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -387,21 +387,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:34 GMT + - Sun, 07 Apr 2024 08:50:30 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T10:12:34.7705466Z' + - '2024-04-07T08:50:30.6649514Z' x-ms-file-creation-time: - - '2024-04-17T10:12:34.7705466Z' + - '2024-04-07T08:50:30.6649514Z' x-ms-file-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-file-last-write-time: - - '2024-04-17T10:12:34.7705466Z' + - '2024-04-07T08:50:30.6649514Z' x-ms-file-parent-id: - - '10088082484072808448' + - '13835071545774440448' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -421,9 +421,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:34 GMT + - Sun, 07 Apr 2024 08:50:30 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -435,7 +435,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory response: body: string: '' @@ -443,21 +443,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:35 GMT + - Sun, 07 Apr 2024 08:50:31 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T10:12:35.8408422Z' + - '2024-04-07T08:50:31.3917535Z' x-ms-file-creation-time: - - '2024-04-17T10:12:35.8408422Z' + - '2024-04-07T08:50:31.3917535Z' x-ms-file-id: - - '13835154696341291008' + - '13835074844309323776' x-ms-file-last-write-time: - - '2024-04-17T10:12:35.8408422Z' + - '2024-04-07T08:50:31.3917535Z' x-ms-file-parent-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -477,9 +477,9 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:35 GMT + - Sun, 07 Apr 2024 08:50:31 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -491,7 +491,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F__pycache__?restype=directory + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users%2Funknown_user%2Fpromptflow%2Fflow_name%2F.promptflow?restype=directory response: body: string: '' @@ -499,21 +499,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:36 GMT + - Sun, 07 Apr 2024 08:50:32 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Directory x-ms-file-change-time: - - '2024-04-17T10:12:36.8991889Z' + - '2024-04-07T08:50:32.1046156Z' x-ms-file-creation-time: - - '2024-04-17T10:12:36.8991889Z' + - '2024-04-07T08:50:32.1046156Z' x-ms-file-id: - - '11529236920336908288' + - '13835145213053501440' x-ms-file-last-write-time: - - '2024-04-17T10:12:36.8991889Z' + - '2024-04-07T08:50:32.1046156Z' x-ms-file-parent-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -533,11 +533,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '14' x-ms-date: - - Wed, 17 Apr 2024 10:12:36 GMT + - Sun, 07 Apr 2024 08:50:32 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -559,21 +559,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:37 GMT + - Sun, 07 Apr 2024 08:50:32 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T10:12:37.9515620Z' + - '2024-04-07T08:50:32.8274350Z' x-ms-file-creation-time: - - '2024-04-17T10:12:37.9515620Z' + - '2024-04-07T08:50:32.8274350Z' x-ms-file-id: - - '13835119511969202176' + - '13835110028681412608' x-ms-file-last-write-time: - - '2024-04-17T10:12:37.9515620Z' + - '2024-04-07T08:50:32.8274350Z' x-ms-file-parent-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -599,9 +599,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:38 GMT + - Sun, 07 Apr 2024 08:50:32 GMT x-ms-range: - bytes=0-13 x-ms-version: @@ -619,11 +619,11 @@ interactions: content-md5: - nYmkCopuDuFj82431amzZw== last-modified: - - Wed, 17 Apr 2024 10:12:39 GMT + - Sun, 07 Apr 2024 08:50:33 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T10:12:39.0059268Z' + - '2024-04-07T08:50:33.5203853Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -643,11 +643,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - - '372' + - '631' x-ms-date: - - Wed, 17 Apr 2024 10:12:39 GMT + - Sun, 07 Apr 2024 08:50:33 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -661,7 +661,7 @@ interactions: x-ms-version: - '2023-11-03' method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log response: body: string: '' @@ -669,21 +669,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:40 GMT + - Sun, 07 Apr 2024 08:50:34 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T10:12:40.0602916Z' + - '2024-04-07T08:50:34.2442003Z' x-ms-file-creation-time: - - '2024-04-17T10:12:40.0602916Z' + - '2024-04-07T08:50:34.2442003Z' x-ms-file-id: - - '16141008700671262720' + - '13835180397425590272' x-ms-file-last-write-time: - - '2024-04-17T10:12:40.0602916Z' + - '2024-04-07T08:50:34.2442003Z' x-ms-file-parent-id: - - '13835154696341291008' + - '13835145213053501440' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -692,12 +692,137 @@ interactions: code: 201 message: Created - request: - body: "{\n \"code\": {\n \"hello_world.py\": {\n \"type\": - \"python\",\n \"inputs\": {\n \"name\": {\n - \ \"type\": [\n \"string\"\n ]\n - \ }\n },\n \"source\": \"hello_world.py\",\n - \ \"function\": \"hello_world\"\n }\n },\n \"package\": - {}\n}" + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start executing + nodes in thread pool mode. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Start to run 1 + nodes with concurrency level 16. + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing node + hello_world. node run id: d32eef14-ba6e-44d7-9410-d9c8491fd4fb_hello_world_0 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + 2024-04-07 03:33:32 +0000 718308 execution.flow WARNING Error occurred + while force flush tracer provider: ''ProxyTracerProvider'' object has no attribute + ''force_flush'' + + ' + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '631' + Content-MD5: + - 4xvZisyz3aqT9bHeHwyeyA== + Content-Type: + - application/octet-stream + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-date: + - Sun, 07 Apr 2024 08:50:34 GMT + x-ms-range: + - bytes=0-630 + x-ms-version: + - '2023-11-03' + x-ms-write: + - update + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.log?comp=range + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - 4xvZisyz3aqT9bHeHwyeyA== + last-modified: + - Sun, 07 Apr 2024 08:50:34 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-last-write-time: + - '2024-04-07T08:50:34.9610448Z' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) + x-ms-content-length: + - '279' + x-ms-date: + - Sun, 07 Apr 2024 08:50:34 GMT + x-ms-file-attributes: + - none + x-ms-file-creation-time: + - now + x-ms-file-last-write-time: + - now + x-ms-file-permission: + - Inherit + x-ms-type: + - file + x-ms-version: + - '2023-11-03' + method: PUT + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log + response: + body: + string: '' + headers: + content-length: + - '0' + last-modified: + - Sun, 07 Apr 2024 08:50:35 GMT + server: + - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + x-ms-file-attributes: + - Archive + x-ms-file-change-time: + - '2024-04-07T08:50:35.7037755Z' + x-ms-file-creation-time: + - '2024-04-07T08:50:35.7037755Z' + x-ms-file-id: + - '11529274716049113088' + x-ms-file-last-write-time: + - '2024-04-07T08:50:35.7037755Z' + x-ms-file-parent-id: + - '13835145213053501440' + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: '2024-04-07 03:33:32 +0000 718308 execution.flow INFO Executing + node hello_world. node run id: f075dfe5-21f5-4d1b-84d1-46ac116bd4ab_hello_world_788fcf13-4cb3-4479-b4de-97a3b2ccd690 + + 2024-04-07 03:33:32 +0000 718308 execution.flow INFO Node hello_world + completes. + + ' headers: Accept: - application/xml @@ -706,23 +831,23 @@ interactions: Connection: - keep-alive Content-Length: - - '372' + - '279' Content-MD5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:40 GMT + - Sun, 07 Apr 2024 08:50:35 GMT x-ms-range: - - bytes=0-371 + - bytes=0-278 x-ms-version: - '2023-11-03' x-ms-write: - update method: PUT - uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/flow.tools.json?comp=range + uri: https://fake_account_name.file.core.windows.net/fake-file-share-name/Users/unknown_user/promptflow/flow_name/.promptflow/hello_world.node.log?comp=range response: body: string: '' @@ -730,13 +855,13 @@ interactions: content-length: - '0' content-md5: - - B9SwRStI08UJ7Rj8H6ST1A== + - hFC8nan3DR5KTPtD41njnw== last-modified: - - Wed, 17 Apr 2024 10:12:41 GMT + - Sun, 07 Apr 2024 08:50:36 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T10:12:41.2510565Z' + - '2024-04-07T08:50:36.4176342Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -756,11 +881,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '250' x-ms-date: - - Wed, 17 Apr 2024 10:12:41 GMT + - Sun, 07 Apr 2024 08:50:36 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -782,21 +907,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:42 GMT + - Sun, 07 Apr 2024 08:50:37 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T10:12:42.3253354Z' + - '2024-04-07T08:50:37.1653432Z' x-ms-file-creation-time: - - '2024-04-17T10:12:42.3253354Z' + - '2024-04-07T08:50:37.1653432Z' x-ms-file-id: - - '10376414371776561152' + - '13835092436495368192' x-ms-file-last-write-time: - - '2024-04-17T10:12:42.3253354Z' + - '2024-04-07T08:50:37.1653432Z' x-ms-file-parent-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -823,9 +948,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:42 GMT + - Sun, 07 Apr 2024 08:50:37 GMT x-ms-range: - bytes=0-249 x-ms-version: @@ -843,11 +968,11 @@ interactions: content-md5: - CT1FTZp5JScB8fq+HjnINw== last-modified: - - Wed, 17 Apr 2024 10:12:43 GMT + - Sun, 07 Apr 2024 08:50:37 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T10:12:43.3896552Z' + - '2024-04-07T08:50:37.9508866Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -867,11 +992,11 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-content-length: - '110' x-ms-date: - - Wed, 17 Apr 2024 10:12:43 GMT + - Sun, 07 Apr 2024 08:50:37 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -893,21 +1018,21 @@ interactions: content-length: - '0' last-modified: - - Wed, 17 Apr 2024 10:12:44 GMT + - Sun, 07 Apr 2024 08:50:38 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T10:12:44.4529803Z' + - '2024-04-07T08:50:38.6926221Z' x-ms-file-creation-time: - - '2024-04-17T10:12:44.4529803Z' + - '2024-04-07T08:50:38.6926221Z' x-ms-file-id: - - '13835189880713379840' + - '11529228536560746496' x-ms-file-last-write-time: - - '2024-04-17T10:12:44.4529803Z' + - '2024-04-07T08:50:38.6926221Z' x-ms-file-parent-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -932,9 +1057,9 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:44 GMT + - Sun, 07 Apr 2024 08:50:38 GMT x-ms-range: - bytes=0-109 x-ms-version: @@ -952,11 +1077,11 @@ interactions: content-md5: - 3CPKwiOwfwiEOJC0UpjR0Q== last-modified: - - Wed, 17 Apr 2024 10:12:45 GMT + - Sun, 07 Apr 2024 08:50:39 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-last-write-time: - - '2024-04-17T10:12:45.5332316Z' + - '2024-04-07T08:50:39.4423228Z' x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -976,31 +1101,31 @@ interactions: Connection: - keep-alive Content-Length: - - '282' + - '251' Content-Type: - application/json User-Agent: - - promptflow-azure-sdk/0.1.0b1 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/Flows response: body: - string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/8f768c0e-02f1-4275-98af-b94916325306/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", - "flowId": "8f768c0e-02f1-4275-98af-b94916325306", "flowName": "flow_display_name", + string: '{"eTag": {}, "studioPortalEndpoint": "https://ml.azure.com/prompts/flow/3e123da1-f9a5-4c91-9234-8d9ffbb39ff5/3295d11f-225c-42d8-9e99-10aac794991b/details?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "flowId": "3295d11f-225c-42d8-9e99-10aac794991b", "flowName": "flow_display_name", "description": "test flow description", "tags": {"owner": "sdk-test"}, "flowType": "Default", "experimentId": "00000000-0000-0000-0000-000000000000", "createdDate": - "2024-04-17T10:12:47.836358Z", "lastModifiedDate": "2024-04-17T10:12:47.8363837Z", + "2024-04-07T08:50:41.4291478Z", "lastModifiedDate": "2024-04-07T08:50:41.429166Z", "owner": {"userObjectId": "00000000-0000-0000-0000-000000000000", "userTenantId": - "00000000-0000-0000-0000-000000000000", "userName": "4cbd0e2e-aae4-4099-b4ba-94d3a4910587"}, - "flowResourceId": "azureml://locations/eastus/workspaces/00000/flows/8f768c0e-02f1-4275-98af-b94916325306", + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao"}, "flowResourceId": + "azureml://locations/eastus/workspaces/00000/flows/3295d11f-225c-42d8-9e99-10aac794991b", "isArchived": false, "flowDefinitionFilePath": "Users/unknown_user/promptflow/flow_name/flow.dag.yaml", "enableMultiContainer": false}' headers: connection: - keep-alive content-length: - - '1128' + - '1071' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1012,7 +1137,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.494' + - '0.646' status: code: 200 message: OK @@ -1026,9 +1151,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file-share/12.15.0 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-file-share/12.15.0 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:48 GMT + - Sun, 07 Apr 2024 08:50:41 GMT x-ms-version: - '2023-11-03' method: HEAD @@ -1042,7 +1167,7 @@ interactions: content-type: - application/octet-stream last-modified: - - Wed, 17 Apr 2024 10:12:43 GMT + - Sun, 07 Apr 2024 08:50:37 GMT server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 vary: @@ -1050,15 +1175,15 @@ interactions: x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2024-04-17T10:12:43.3896552Z' + - '2024-04-07T08:50:37.9508866Z' x-ms-file-creation-time: - - '2024-04-17T10:12:42.3253354Z' + - '2024-04-07T08:50:37.1653432Z' x-ms-file-id: - - '10376414371776561152' + - '13835092436495368192' x-ms-file-last-write-time: - - '2024-04-17T10:12:43.3896552Z' + - '2024-04-07T08:50:37.9508866Z' x-ms-file-parent-id: - - '13835084327597113344' + - '13835189193518612480' x-ms-type: - File x-ms-version: @@ -1076,8 +1201,8 @@ interactions: Connection: - keep-alive User-Agent: - - promptflow-azure-sdk/0.1.0b1 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores?count=30&isDefault=true&orderByAsc=false response: @@ -1114,7 +1239,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.057' + - '0.045' status: code: 200 message: OK @@ -1128,8 +1253,8 @@ interactions: Connection: - keep-alive User-Agent: - - promptflow-azure-sdk/0.1.0b1 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore response: @@ -1166,7 +1291,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.069' + - '0.086' status: code: 200 message: OK @@ -1182,8 +1307,8 @@ interactions: Content-Length: - '0' User-Agent: - - promptflow-azure-sdk/0.1.0b1 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore/listSecrets response: @@ -1207,7 +1332,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.098' + - '0.109' status: code: 200 message: OK @@ -1221,9 +1346,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-blob/12.19.1 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:52 GMT + - Sun, 07 Apr 2024 08:50:45 GMT x-ms-version: - '2023-11-03' method: HEAD @@ -1271,9 +1396,9 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + - azsdk-python-storage-blob/12.19.1 Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) x-ms-date: - - Wed, 17 Apr 2024 10:12:53 GMT + - Sun, 07 Apr 2024 08:50:45 GMT x-ms-version: - '2023-11-03' method: HEAD @@ -1299,10 +1424,9 @@ interactions: body: '{"flowDefinitionResourceId": "azureml://locations/fake-region/workspaces/00000/flows/00000000-0000-0000-0000-000000000000/", "runId": "name", "runDisplayName": "name", "sessionSetupMode": "SystemWait", "flowLineageId": "0000000000000000000000000000000000000000000000000000000000000000", - "runDisplayNameGenerationType": "UserProvidedMacro", "batchDataInput": {"dataUri": - "azureml://datastores/workspaceblobstore/paths/LocalUpload/000000000000000000000000000000000000/simple_hello_world.jsonl"}, - "inputsMapping": {"name": "${data.name}"}, "environmentVariables": {}, "connections": - {}, "runtimeName": "fake-runtime-name"}' + "runtimeName": "fake-runtime-name", "batchDataInput": {"dataUri": "azureml://datastores/workspaceblobstore/paths/LocalUpload/000000000000000000000000000000000000/simple_hello_world.jsonl"}, + "inputsMapping": {"name": "${data.name}"}, "connections": {}, "environmentVariables": + {}, "runDisplayNameGenerationType": "UserProvidedMacro"}' headers: Accept: - application/json @@ -1311,12 +1435,12 @@ interactions: Connection: - keep-alive Content-Length: - - '674' + - '675' Content-Type: - application/json User-Agent: - - promptflow-azure-sdk/0.1.0b1 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: POST uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/BulkRuns/submit response: @@ -1334,7 +1458,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '3.956' + - '9.458' status: code: 200 message: OK @@ -1348,35 +1472,334 @@ interactions: Connection: - keep-alive User-Agent: - - promptflow-azure-sdk/0.1.0b1 azsdk-python-azuremachinelearningdesignerserviceclient/unknown - Python/3.11.8 (Windows-10-10.0.22631-SP0) + - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown + Python/3.10.12 (Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35) method: GET uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/BulkRuns/name response: body: string: '{"flowGraph": {"nodes": [{"name": "hello_world", "type": "python", "source": {"type": "code", "path": "hello_world.py"}, "inputs": {"name": "${inputs.name}"}, - "tool": "hello_world.py", "reduce": false}], "tools": [{"name": "hello_world.py", - "type": "python", "inputs": {"name": {"type": ["string"], "allow_manual_entry": - false, "is_multi_select": false, "input_type": "default"}}, "source": "hello_world.py", - "function": "hello_world", "is_builtin": false, "enable_kwargs": false, "tool_state": + "tool": "hello_world.py", "reduce": false}], "tools": [{"name": "Azure OpenAI + GPT-4 Turbo with Vision", "type": "custom_llm", "inputs": {"connection": {"type": + ["AzureOpenAIConnection"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default", "ui_hints": {"index": 0}}, "deployment_name": + {"type": ["string"], "enabled_by": "connection", "dynamic_list": {"func_path": + "promptflow.tools.aoai_gpt4v.list_deployment_names", "func_kwargs": [{"name": + "connection", "reference": "${inputs.connection}", "type": ["AzureOpenAIConnection"]}]}, + "allow_manual_entry": true, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 1}}, "frequency_penalty": {"type": ["double"], "default": + 0, "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 7}}, "max_tokens": {"type": ["int"], "default": 512, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 4}}, "presence_penalty": {"type": ["double"], "default": + 0, "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 6}}, "seed": {"type": ["int"], "default": "", "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default", "ui_hints": {"index": + 8}}, "stop": {"type": ["list"], "default": "", "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default", "ui_hints": {"index": 5}}, + "temperature": {"type": ["double"], "default": 1, "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default", "ui_hints": {"index": 2}}, + "top_p": {"type": ["double"], "default": 1, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default", "ui_hints": {"index": 3}}}, "description": + "Use Azure OpenAI GPT-4 Turbo with Vision to leverage AOAI vision ability.", + "module": "promptflow.tools.aoai_gpt4v", "class_name": "AzureOpenAI", "function": + "chat", "icon": {"dark": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2ElEQVR4nJXSzW3CQBAF4DUSTjk+Al1AD0ikESslpBIEheRALhEpgAYSWV8OGUublf/yLuP3PPNmdndS+gdwXZrYDmh7fGE/W+wXbaYd8IYm4rxJPnZ0boI3wZcdJxs/n+AwV7DFK7aFyfQdYIMLPvES8YJNf5yp4jMeeEYdWh38gXOR35YGHe5xabvQdsHv6PLi8qV6gycc8YH3iMfQu6Lh4ASr+F5Hh3XwVWnQYzUkVlX1nccplAb1SN6Y/sfgmlK64VS8wimldIv/0yj2QLkHizG0iWP4AVAfQ34DVQONAAAAAElFTkSuQmCC", + "light": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVR4nJWSwQ2CQBBFX0jAcjgqXUgPJNiIsQQrIVCIFy8GC6ABDcGDX7Mus9n1Xz7zZ+fPsLPwH4bUg0dD2wMPcbR48Uxq4AKU4iSTDwZ1LhWXipN/B3V0J6hjBTvgLHZNonewBXrgDpzEvXSIjN0BE3AACmmF4kl5F6tNzcCoLpW0SvGovFvsb4oZ2AANcAOu4ka6axCcINN3rg654sww+CYsPD0OwjcozFNh/Qcd78tqVbCIW+n+Fky472Bh/Q6SYb1EEy8tDzd+9IsVPAAAAABJRU5ErkJggg=="}, + "is_builtin": true, "package": "promptflow-tools", "package_version": "1.4.0rc3", + "default_prompt": "# system:\nAs an AI assistant, your task involves interpreting + images and responding to questions about the image.\nRemember to provide accurate + answers based on the information present in the image.\n\n# user:\nCan you + tell me what the image depicts?\n![image]({{image_input}})\n", "enable_kwargs": + false, "tool_state": "preview"}, {"name": "Content Safety (Text Analyze)", + "type": "python", "inputs": {"connection": {"type": ["AzureContentSafetyConnection"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "hate_category": {"type": ["string"], "default": "medium_sensitivity", "enum": + ["disable", "low_sensitivity", "medium_sensitivity", "high_sensitivity"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "self_harm_category": {"type": ["string"], "default": "medium_sensitivity", + "enum": ["disable", "low_sensitivity", "medium_sensitivity", "high_sensitivity"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "sexual_category": {"type": ["string"], "default": "medium_sensitivity", "enum": + ["disable", "low_sensitivity", "medium_sensitivity", "high_sensitivity"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "text": {"type": ["string"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "violence_category": {"type": ["string"], + "default": "medium_sensitivity", "enum": ["disable", "low_sensitivity", "medium_sensitivity", + "high_sensitivity"], "allow_manual_entry": false, "is_multi_select": false, + "input_type": "default"}}, "description": "Use Azure Content Safety to detect + harmful content.", "module": "promptflow.tools.azure_content_safety", "function": + "analyze_text", "is_builtin": true, "package": "promptflow-tools", "package_version": + "1.4.0rc3", "enable_kwargs": false, "deprecated_tools": ["content_safety_text.tools.content_safety_text_tool.analyze_text"], + "tool_state": "stable"}, {"name": "Embedding", "type": "python", "inputs": + {"connection": {"type": ["AzureOpenAIConnection", "OpenAIConnection"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "deployment_name": + {"type": ["string"], "enabled_by": "connection", "enabled_by_type": ["AzureOpenAIConnection"], + "model_list": ["text-embedding-ada-002", "text-search-ada-doc-001", "text-search-ada-query-001"], + "capabilities": {"completion": false, "chat_completion": false, "embeddings": + true}, "allow_manual_entry": false, "is_multi_select": false, "input_type": + "default"}, "input": {"type": ["string"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "model": {"type": ["string"], "enum": ["text-embedding-ada-002", + "text-search-ada-doc-001", "text-search-ada-query-001"], "enabled_by": "connection", + "enabled_by_type": ["OpenAIConnection"], "allow_manual_entry": true, "is_multi_select": + false, "input_type": "default"}}, "description": "Use Open AI''s embedding + model to create an embedding vector representing the input text.", "module": + "promptflow.tools.embedding", "function": "embedding", "is_builtin": true, + "package": "promptflow-tools", "package_version": "1.4.0rc3", "enable_kwargs": + false, "tool_state": "stable"}, {"name": "Open Model LLM", "type": "custom_llm", + "inputs": {"api": {"type": ["string"], "enum": ["chat", "completion"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default", "ui_hints": {"index": + 2}}, "deployment_name": {"type": ["string"], "default": "", "dynamic_list": + {"func_path": "promptflow.tools.open_model_llm.list_deployment_names", "func_kwargs": + [{"name": "endpoint", "optional": true, "reference": "${inputs.endpoint}", + "type": ["string"]}]}, "allow_manual_entry": true, "is_multi_select": false, + "input_type": "default", "ui_hints": {"index": 1}}, "endpoint_name": {"type": + ["string"], "dynamic_list": {"func_path": "promptflow.tools.open_model_llm.list_endpoint_names"}, + "allow_manual_entry": true, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 0}}, "max_new_tokens": {"type": ["int"], "default": + 500, "allow_manual_entry": false, "is_multi_select": false, "input_type": + "default", "ui_hints": {"index": 4}}, "model_kwargs": {"type": ["object"], + "default": "{}", "allow_manual_entry": false, "is_multi_select": false, "input_type": + "default", "advanced": true, "ui_hints": {"index": 6}}, "temperature": {"type": + ["double"], "default": 1.0, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default", "ui_hints": {"index": 3}}, "top_p": {"type": + ["double"], "default": 1.0, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default", "advanced": true, "ui_hints": {"index": 5}}}, + "description": "Use an open model from the Azure Model catalog, deployed to + an AzureML Online Endpoint for LLM Chat or Completion API calls.", "module": + "promptflow.tools.open_model_llm", "class_name": "OpenModelLLM", "function": + "call", "icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACgElEQVR4nGWSz2vcVRTFP/e9NzOZ1KDGohASslLEH6VLV0ak4l/QpeDCrfQPcNGliODKnVm4EBdBsIjQIlhciKW0ycKFVCSNbYnjdDLtmPnmO/nO9917XcxMkjYX3uLx7nnn3HOuMK2Nix4fP78ZdrYXVkLVWjf3l3B1B+HpcjzGFtmqa6cePz7/x0dnn1n5qhj3iBJPYREIURAJuCtpY8PjReDbrf9WG7H1fuefwQU9qKztTcMJT+PNnEFvjGVDBDlSsH6p/9MLzy6+NxwVqI8RAg4IPmWedMckdLYP6O6UpIaQfvyyXG012+e79/ZfHukoS1ISMT2hGTB1RkUmNgQ5QZ0w+a2VWDq73MbdEWmfnnv6UWe7oNzPaLapl5CwuLTXK9WUGBuCjqekzhP+z52ZXOrKMD3OJg0Hh778aiOuvpnYvp05d6GJO4iAO4QAe/eV36/X5LFRV4Zmn+AdkqlL8Vjp3oVioOz+WTPzzYEgsN+fgPLYyJVheSbPPVl2ikeGZRjtG52/8rHuaV9VOlpP2OtKyVndcRVCSqOhsvxa4vW359i6OuKdD+aP8Q4SYPdOzS/flGjt1JUSaMqZ5nwa1Y8qWb/Ud/eZZkHisYezEM0m+fcelDr8F1SqW2LNK6r1jXQwyLzy1hxvrLXZulry7ocL+FS6G4QIu3fG/Px1gdYeW7LIgXU2P/115TOA5G7e3Rmj2aS/m7l5pThiZzrCcE/d1XHzbln373nw7y6veeoUm5KCNKT/IPPwbiY1hYd/l5MIT65BMFt87sU4v9D7/JMflr44uV6hGh1+L4RCkg6z5iK2tAhNLeLsNGwYA4fDYnC/drvuuFxe86NV/x+Ut27g0FvykgAAAABJRU5ErkJggg==", + "is_builtin": true, "package": "promptflow-tools", "package_version": "1.4.0rc3", + "enable_kwargs": false, "tool_state": "stable"}, {"name": "OpenAI GPT-4V", + "type": "custom_llm", "inputs": {"connection": {"type": ["OpenAIConnection"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 0}}, "frequency_penalty": {"type": ["double"], "default": + 0, "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 7}}, "max_tokens": {"type": ["int"], "default": 512, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 4}}, "model": {"type": ["string"], "enum": ["gpt-4-vision-preview"], + "allow_manual_entry": true, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 1}}, "presence_penalty": {"type": ["double"], "default": + 0, "allow_manual_entry": false, "is_multi_select": false, "input_type": "default", + "ui_hints": {"index": 6}}, "seed": {"type": ["int"], "default": "", "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default", "ui_hints": {"index": + 8}}, "stop": {"type": ["list"], "default": "", "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default", "ui_hints": {"index": 5}}, + "temperature": {"type": ["double"], "default": 1, "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default", "ui_hints": {"index": 2}}, + "top_p": {"type": ["double"], "default": 1, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default", "ui_hints": {"index": 3}}}, "description": + "Use OpenAI GPT-4V to leverage vision ability.", "module": "promptflow.tools.openai_gpt4v", + "class_name": "OpenAI", "function": "chat", "icon": {"dark": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2ElEQVR4nJXSzW3CQBAF4DUSTjk+Al1AD0ikESslpBIEheRALhEpgAYSWV8OGUublf/yLuP3PPNmdndS+gdwXZrYDmh7fGE/W+wXbaYd8IYm4rxJPnZ0boI3wZcdJxs/n+AwV7DFK7aFyfQdYIMLPvES8YJNf5yp4jMeeEYdWh38gXOR35YGHe5xabvQdsHv6PLi8qV6gycc8YH3iMfQu6Lh4ASr+F5Hh3XwVWnQYzUkVlX1nccplAb1SN6Y/sfgmlK64VS8wimldIv/0yj2QLkHizG0iWP4AVAfQ34DVQONAAAAAElFTkSuQmCC", + "light": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVR4nJWSwQ2CQBBFX0jAcjgqXUgPJNiIsQQrIVCIFy8GC6ABDcGDX7Mus9n1Xz7zZ+fPsLPwH4bUg0dD2wMPcbR48Uxq4AKU4iSTDwZ1LhWXipN/B3V0J6hjBTvgLHZNonewBXrgDpzEvXSIjN0BE3AACmmF4kl5F6tNzcCoLpW0SvGovFvsb4oZ2AANcAOu4ka6axCcINN3rg654sww+CYsPD0OwjcozFNh/Qcd78tqVbCIW+n+Fky472Bh/Q6SYb1EEy8tDzd+9IsVPAAAAABJRU5ErkJggg=="}, + "is_builtin": true, "package": "promptflow-tools", "package_version": "1.4.0rc3", + "default_prompt": "# system:\nAs an AI assistant, your task involves interpreting + images and responding to questions about the image.\nRemember to provide accurate + answers based on the information present in the image.\n\n# user:\nCan you + tell me what the image depicts?\n![image]({{image_input}})\n", "enable_kwargs": + false, "tool_state": "preview"}, {"name": "Serp API", "type": "python", "inputs": + {"connection": {"type": ["SerpConnection"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "engine": {"type": ["string"], "default": + "google", "enum": ["google", "bing"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "location": {"type": ["string"], "default": + "", "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "num": {"type": ["int"], "default": "10", "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "query": {"type": ["string"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "safe": {"type": + ["string"], "default": "off", "enum": ["active", "off"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}}, "description": + "Use Serp API to obtain search results from a specific search engine.", "module": + "promptflow.tools.serpapi", "class_name": "SerpAPI", "function": "search", + "is_builtin": true, "package": "promptflow-tools", "package_version": "1.4.0rc3", + "enable_kwargs": false, "tool_state": "stable"}, {"name": "Index Lookup", + "type": "python", "inputs": {"acs_content_field": {"type": ["string"], "enabled_by": + "index_type", "enabled_by_value": ["Azure AI Search"], "dynamic_list": {"func_path": + "promptflow_vectordb.tool.common_index_lookup_utils.list_acs_index_fields", + "func_kwargs": [{"name": "acs_connection", "optional": false, "reference": + "${inputs.acs_index_connection}", "type": ["CognitiveSearchConnection"]}, + {"name": "acs_index_name", "optional": false, "reference": "${inputs.acs_index_name}", + "type": ["string"]}, {"default": "Edm.String", "name": "field_data_type", + "optional": false, "type": ["string"]}]}, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "uionly_hidden"}, "acs_embedding_field": {"type": ["string"], + "enabled_by": "index_type", "enabled_by_value": ["Azure AI Search"], "dynamic_list": + {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_acs_index_fields", + "func_kwargs": [{"name": "acs_connection", "optional": false, "reference": + "${inputs.acs_index_connection}", "type": ["CognitiveSearchConnection"]}, + {"name": "acs_index_name", "optional": false, "reference": "${inputs.acs_index_name}", + "type": ["string"]}, {"default": "Collection(Edm.Single)", "name": "field_data_type", + "optional": false, "type": ["string"]}]}, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "uionly_hidden"}, "acs_index_connection": {"type": ["CognitiveSearchConnection"], + "enabled_by": "index_type", "enabled_by_value": ["Azure AI Search"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "uionly_hidden"}, "acs_index_name": + {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": ["Azure + AI Search"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_acs_indices", + "func_kwargs": [{"name": "acs_connection", "optional": false, "reference": + "${inputs.acs_index_connection}", "type": ["CognitiveSearchConnection"]}]}, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "uionly_hidden"}, + "acs_metadata_field": {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": + ["Azure AI Search"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_acs_index_fields", + "func_kwargs": [{"name": "acs_connection", "optional": false, "reference": + "${inputs.acs_index_connection}", "type": ["CognitiveSearchConnection"]}, + {"name": "acs_index_name", "optional": false, "reference": "${inputs.acs_index_name}", + "type": ["string"]}, {"default": "Edm.String", "name": "field_data_type", + "optional": false, "type": ["string"]}]}, "allow_manual_entry": false, "is_multi_select": + false, "input_type": "uionly_hidden"}, "aoai_embedding_connection": {"type": + ["AzureOpenAIConnection"], "enabled_by": "embedding_type", "enabled_by_value": + ["Azure OpenAI"], "allow_manual_entry": false, "is_multi_select": false, "input_type": + "uionly_hidden"}, "embedding_deployment": {"type": ["string"], "enabled_by": + "embedding_type", "enabled_by_value": ["Azure OpenAI"], "dynamic_list": {"func_path": + "promptflow_vectordb.tool.common_index_lookup_utils.list_aoai_embedding_deployments", + "func_kwargs": [{"name": "aoai_connection", "optional": false, "reference": + "${inputs.aoai_embedding_connection}", "type": ["AzurOpenAIConnection"]}]}, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "uionly_hidden"}, + "embedding_model": {"type": ["string"], "enabled_by": "embedding_type", "enabled_by_value": + ["OpenAI", "Hugging Face"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_embedding_models", + "func_kwargs": [{"name": "embedding_type", "optional": false, "reference": + "${inputs.embedding_type}", "type": ["string"]}]}, "allow_manual_entry": false, + "is_multi_select": false, "input_type": "uionly_hidden"}, "embedding_type": + {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": ["Azure + AI Search", "FAISS", "Pinecone"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_available_embedding_types", + "func_kwargs": [{"name": "index_type", "optional": false, "reference": "${inputs.index_type}", + "type": ["string"]}]}, "allow_manual_entry": false, "is_multi_select": false, + "input_type": "uionly_hidden"}, "faiss_index_path": {"type": ["string"], "enabled_by": + "index_type", "enabled_by_value": ["FAISS"], "allow_manual_entry": false, + "is_multi_select": false, "input_type": "uionly_hidden"}, "index_type": {"type": + ["string"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_available_index_types"}, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "uionly_hidden"}, + "mlindex_asset_id": {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": + ["Registered Index"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_registered_mlindices"}, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "uionly_hidden"}, + "mlindex_content": {"type": ["string"], "allow_manual_entry": false, "is_multi_select": + false, "generated_by": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.forward_mapping", + "func_kwargs": [{"name": "index_type", "reference": "${inputs.index_type}", + "type": ["string"]}, {"name": "mlindex_asset_id", "optional": true, "reference": + "${inputs.mlindex_asset_id}", "type": ["string"]}, {"name": "mlindex_path", + "optional": true, "reference": "${inputs.mlindex_path}", "type": ["string"]}, + {"name": "acs_index_connection", "optional": true, "reference": "${inputs.acs_index_connection}", + "type": ["CognitiveSearchConnection"]}, {"name": "acs_index_name", "optional": + true, "reference": "${inputs.acs_index_name}", "type": ["string"]}, {"name": + "acs_content_field", "optional": true, "reference": "${inputs.acs_content_field}", + "type": ["string"]}, {"name": "acs_embedding_field", "optional": true, "reference": + "${inputs.acs_embedding_field}", "type": ["string"]}, {"name": "acs_metadata_field", + "optional": true, "reference": "${inputs.acs_metadata_field}", "type": ["string"]}, + {"name": "semantic_configuration", "optional": true, "reference": "${inputs.semantic_configuration}", + "type": ["string"]}, {"name": "faiss_index_path", "optional": true, "reference": + "${inputs.faiss_index_path}", "type": ["string"]}, {"name": "pinecone_index_connection", + "optional": true, "reference": "${inputs.pinecone_index_connection}", "type": + ["string"]}, {"name": "pinecone_index_name", "optional": true, "reference": + "${inputs.pinecone_index_name}", "type": ["string"]}, {"name": "pinecone_content_field", + "optional": true, "reference": "${inputs.pinecone_content_field}", "type": + ["string"]}, {"name": "pinecone_metadata_field", "optional": true, "reference": + "${inputs.pinecone_metadata_field}", "type": ["string"]}, {"name": "embedding_type", + "optional": true, "reference": "${inputs.embedding_type}", "type": ["string"]}, + {"name": "aoai_embedding_connection", "optional": true, "reference": "${inputs.aoai_embedding_connection}", + "type": ["AzureOpenAIConnection"]}, {"name": "oai_embedding_connection", "optional": + true, "reference": "${inputs.oai_embedding_connection}", "type": ["string"]}, + {"name": "embedding_model", "optional": true, "reference": "${inputs.embedding_model}", + "type": ["string"]}, {"name": "embedding_deployment", "optional": true, "reference": + "${inputs.embedding_deployment}", "type": ["string"]}], "reverse_func_path": + "promptflow_vectordb.tool.common_index_lookup_utils.reverse_mapping"}, "input_type": + "default"}, "mlindex_path": {"type": ["string"], "enabled_by": "index_type", + "enabled_by_value": ["MLIndex file from path"], "allow_manual_entry": false, + "is_multi_select": false, "input_type": "uionly_hidden"}, "oai_embedding_connection": + {"type": ["OpenAIConnection"], "enabled_by": "embedding_type", "enabled_by_value": + ["OpenAI"], "allow_manual_entry": false, "is_multi_select": false, "input_type": + "uionly_hidden"}, "pinecone_content_field": {"type": ["string"], "enabled_by": + "index_type", "enabled_by_value": ["Pinecone"], "allow_manual_entry": false, + "is_multi_select": false, "input_type": "uionly_hidden"}, "pinecone_index_connection": + {"type": ["PineconeConnection"], "enabled_by": "index_type", "enabled_by_value": + ["Pinecone"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_pinecone_connections"}, + "allow_manual_entry": false, "is_multi_select": false, "input_type": "uionly_hidden"}, + "pinecone_index_name": {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": + ["Pinecone"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_pinecone_indices", + "func_kwargs": [{"name": "pinecone_connection_name", "optional": false, "reference": + "${inputs.pinecone_index_connection}", "type": ["string"]}]}, "allow_manual_entry": + false, "is_multi_select": false, "input_type": "uionly_hidden"}, "pinecone_metadata_field": + {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": ["Pinecone"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "uionly_hidden"}, + "queries": {"type": ["object"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "query_type": {"type": ["string"], "dynamic_list": + {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_available_query_types", + "func_kwargs": [{"name": "mlindex_content", "optional": false, "reference": + "${inputs.mlindex_content}", "type": ["string"]}]}, "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "semantic_configuration": + {"type": ["string"], "enabled_by": "index_type", "enabled_by_value": ["Azure + AI Search"], "dynamic_list": {"func_path": "promptflow_vectordb.tool.common_index_lookup_utils.list_acs_index_semantic_configurations", + "func_kwargs": [{"name": "acs_connection", "optional": false, "reference": + "${inputs.acs_index_connection}", "type": ["CognitiveSearchConnection"]}, + {"name": "acs_index_name", "optional": false, "reference": "${inputs.acs_index_name}", + "type": ["string"]}]}, "allow_manual_entry": false, "is_multi_select": false, + "input_type": "uionly_hidden"}, "top_k": {"type": ["int"], "default": 3, "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}}, "description": + "Search an AzureML Vector Index for relevant results using one or more text + queries.", "module": "promptflow_vectordb.tool.common_index_lookup", "function": + "search", "is_builtin": true, "package": "promptflow_vectordb", "package_version": + "0.2.6", "enable_kwargs": false, "tool_state": "preview"}, {"name": "Faiss + Index Lookup", "type": "python", "inputs": {"path": {"type": ["string"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "top_k": {"type": + ["int"], "default": "3", "allow_manual_entry": false, "is_multi_select": false, + "input_type": "default"}, "vector": {"type": ["list"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}}, "description": + "Search vector based query from the FAISS index file.", "module": "promptflow_vectordb.tool.faiss_index_lookup", + "class_name": "FaissIndexLookup", "function": "search", "is_builtin": true, + "package": "promptflow_vectordb", "package_version": "0.2.6", "enable_kwargs": + false, "tool_state": "archived"}, {"name": "Vector DB Lookup", "type": "python", + "inputs": {"class_name": {"type": ["string"], "enabled_by": "connection", + "enabled_by_type": ["WeaviateConnection"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}, "collection_name": {"type": ["string"], "enabled_by": + "connection", "enabled_by_type": ["QdrantConnection"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "connection": {"type": + ["CognitiveSearchConnection", "QdrantConnection", "WeaviateConnection"], "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "index_name": {"type": + ["string"], "enabled_by": "connection", "enabled_by_type": ["CognitiveSearchConnection"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "search_filters": {"type": ["object"], "enabled_by": "connection", "enabled_by_type": + ["CognitiveSearchConnection", "QdrantConnection"], "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default"}, "search_params": {"type": + ["object"], "enabled_by": "connection", "enabled_by_type": ["CognitiveSearchConnection", + "QdrantConnection"], "allow_manual_entry": false, "is_multi_select": false, + "input_type": "default"}, "text_field": {"type": ["string"], "enabled_by": + "connection", "enabled_by_type": ["CognitiveSearchConnection", "QdrantConnection", + "WeaviateConnection"], "allow_manual_entry": false, "is_multi_select": false, + "input_type": "default"}, "top_k": {"type": ["int"], "default": "3", "allow_manual_entry": + false, "is_multi_select": false, "input_type": "default"}, "vector": {"type": + ["list"], "allow_manual_entry": false, "is_multi_select": false, "input_type": + "default"}, "vector_field": {"type": ["string"], "enabled_by": "connection", + "enabled_by_type": ["CognitiveSearchConnection"], "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default"}}, "description": "Search + vector based query from existing Vector Database.", "module": "promptflow_vectordb.tool.vector_db_lookup", + "class_name": "VectorDBLookup", "function": "search", "is_builtin": true, + "package": "promptflow_vectordb", "package_version": "0.2.6", "enable_kwargs": + false, "tool_state": "archived"}, {"name": "Vector Index Lookup", "type": + "python", "inputs": {"path": {"type": ["string"], "allow_manual_entry": false, + "is_multi_select": false, "input_type": "default"}, "query": {"type": ["object"], + "allow_manual_entry": false, "is_multi_select": false, "input_type": "default"}, + "top_k": {"type": ["int"], "default": "3", "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}}, "description": "Search text or vector based + query from AzureML Vector Index.", "module": "promptflow_vectordb.tool.vector_index_lookup", + "class_name": "VectorIndexLookup", "function": "search", "is_builtin": true, + "package": "promptflow_vectordb", "package_version": "0.2.6", "enable_kwargs": + false, "tool_state": "archived"}, {"name": "hello_world.py", "type": "python", + "inputs": {"name": {"type": ["string"], "allow_manual_entry": false, "is_multi_select": + false, "input_type": "default"}}, "source": "hello_world.py", "function": + "hello_world", "is_builtin": false, "enable_kwargs": false, "tool_state": "stable"}], "inputs": {"name": {"type": "string", "default": "hod", "is_chat_input": false}}, "outputs": {"result": {"type": "string", "reference": "${hello_world.output}", "evaluation_only": false, "is_chat_output": false}}}, "flowRunResourceId": - "azureml://locations/eastus/workspaces/00000/flows/8f768c0e-02f1-4275-98af-b94916325306/flowRuns/name", + "azureml://locations/eastus/workspaces/00000/flows/3295d11f-225c-42d8-9e99-10aac794991b/flowRuns/name", "flowRunId": "name", "flowRunDisplayName": "name", "batchDataInput": {"dataUri": "azureml://datastores/workspaceblobstore/paths/LocalUpload/79f088fae0e502653c43146c9682f425/simple_hello_world.jsonl"}, - "flowRunType": "FlowRun", "flowType": "Default", "runtimeName": "test-runtime-ci", + "flowRunType": "FlowRun", "flowType": "Default", "runtimeName": "test-new-runtime", "inputsMapping": {"name": "${data.name}"}, "outputDatastoreName": "workspaceblobstore", - "childRunBasePath": "promptflow/PromptFlowArtifacts/8f768c0e-02f1-4275-98af-b94916325306/name/flow_artifacts", - "flowDagFileRelativePath": "flow.dag.yaml", "flowSnapshotId": "ab544c0b-e058-4afe-88e6-9d21c47db86e", - "sessionId": "8f768c0e-02f1-4275-98af-b94916325306", "studioPortalEndpoint": + "childRunBasePath": "promptflow/PromptFlowArtifacts/3295d11f-225c-42d8-9e99-10aac794991b/name/flow_artifacts", + "flowDagFileRelativePath": "flow.dag.yaml", "flowSnapshotId": "a00b8581-2379-46b1-a1d9-f013aa51a215", + "sessionId": "3295d11f-225c-42d8-9e99-10aac794991b", "studioPortalEndpoint": "https://ml.azure.com/runs/name?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000"}' headers: connection: - keep-alive content-length: - - '1799' + - '27289' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1388,7 +1811,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.156' + - '0.756' status: code: 200 message: OK @@ -1412,35 +1835,34 @@ interactions: uri: https://eastus.api.azureml.ms/history/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/rundata response: body: - string: '{"runMetadata": {"runNumber": 1713348778, "rootRunId": "name", "createdUtc": - "2024-04-17T10:12:58.4780888+00:00", "createdBy": {"userObjectId": "00000000-0000-0000-0000-000000000000", - "userPuId": null, "userIdp": "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", - "userAltSecId": null, "userIss": "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", - "userTenantId": "00000000-0000-0000-0000-000000000000", "userName": "4cbd0e2e-aae4-4099-b4ba-94d3a4910587", - "upn": null}, "userId": "00000000-0000-0000-0000-000000000000", "token": null, - "tokenExpiryTimeUtc": null, "error": null, "warnings": null, "revision": 3, - "statusRevision": 1, "runUuid": "4f761bd6-abdd-43c3-ac58-8b40b61a0e3d", "parentRunUuid": - null, "rootRunUuid": "4f761bd6-abdd-43c3-ac58-8b40b61a0e3d", "lastStartTimeUtc": + string: '{"runMetadata": {"runNumber": 1712479850, "rootRunId": "name", "createdUtc": + "2024-04-07T08:50:50.5657204+00:00", "createdBy": {"userObjectId": "00000000-0000-0000-0000-000000000000", + "userPuId": "1003BFFDAC523939", "userIdp": null, "userAltSecId": null, "userIss": + "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", "userTenantId": + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao", "upn": null}, + "userId": "00000000-0000-0000-0000-000000000000", "token": null, "tokenExpiryTimeUtc": + null, "error": null, "warnings": null, "revision": 3, "statusRevision": 1, + "runUuid": "3f1e5dca-d0e5-4f49-a315-681b6558d561", "parentRunUuid": null, + "rootRunUuid": "3f1e5dca-d0e5-4f49-a315-681b6558d561", "lastStartTimeUtc": null, "currentComputeTime": "00:00:00", "computeDuration": null, "effectiveStartTimeUtc": null, "lastModifiedBy": {"userObjectId": "00000000-0000-0000-0000-000000000000", - "userPuId": null, "userIdp": "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", - "userAltSecId": null, "userIss": "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", - "userTenantId": "00000000-0000-0000-0000-000000000000", "userName": "4cbd0e2e-aae4-4099-b4ba-94d3a4910587", - "upn": null}, "lastModifiedUtc": "2024-04-17T10:13:00.4682656+00:00", "duration": - null, "cancelationReason": null, "currentAttemptId": 1, "runId": "name", "parentRunId": - null, "experimentId": "c37563af-f0b0-4358-bf15-3f6847f3772d", "status": "Preparing", + "userPuId": "1003BFFDAC523939", "userIdp": null, "userAltSecId": null, "userIss": + "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", "userTenantId": + "00000000-0000-0000-0000-000000000000", "userName": "Philip Gao", "upn": null}, + "lastModifiedUtc": "2024-04-07T08:50:56.2521022+00:00", "duration": null, + "cancelationReason": null, "currentAttemptId": 1, "runId": "name", "parentRunId": + null, "experimentId": "529ac0f1-84f5-46cc-aa72-c8d2a3e1ce28", "status": "Preparing", "startTimeUtc": null, "endTimeUtc": null, "scheduleId": null, "displayName": "name", "name": null, "dataContainerId": "dcid.name", "description": null, "hidden": false, "runType": "azureml.promptflow.FlowRun", "runTypeV2": {"orchestrator": null, "traits": [], "attribution": "PromptFlow", "computeType": "AmlcDsi"}, - "properties": {"azureml.promptflow.runtime_name": "test-runtime-ci", "azureml.promptflow.runtime_version": - "20240411.v4", "azureml.promptflow.input_data": "azureml://datastores/workspaceblobstore/paths/LocalUpload/79f088fae0e502653c43146c9682f425/simple_hello_world.jsonl", - "azureml.promptflow.inputs_mapping": "{\"name\":\"${data.name}\"}", "azureml.promptflow.disable_trace": - "false", "azureml.promptflow.definition_file_name": "flow.dag.yaml", "azureml.promptflow.flow_lineage_id": - "8f768c0e-02f1-4275-98af-b94916325306", "azureml.promptflow.flow_definition_resource_id": - "azureml://locations/eastus/workspaces/00000/flows/8f768c0e-02f1-4275-98af-b94916325306", - "azureml.promptflow.flow_id": "8f768c0e-02f1-4275-98af-b94916325306", "_azureml.evaluation_run": - "promptflow.BatchRun", "azureml.promptflow.snapshot_id": "ab544c0b-e058-4afe-88e6-9d21c47db86e"}, + "properties": {"azureml.promptflow.runtime_name": "test-new-runtime", "azureml.promptflow.runtime_version": + "20240326.v2", "azureml.promptflow.input_data": "azureml://datastores/workspaceblobstore/paths/LocalUpload/79f088fae0e502653c43146c9682f425/simple_hello_world.jsonl", + "azureml.promptflow.inputs_mapping": "{\"name\":\"${data.name}\"}", "azureml.promptflow.definition_file_name": + "flow.dag.yaml", "azureml.promptflow.flow_lineage_id": "3295d11f-225c-42d8-9e99-10aac794991b", + "azureml.promptflow.flow_definition_resource_id": "azureml://locations/eastus/workspaces/00000/flows/3295d11f-225c-42d8-9e99-10aac794991b", + "azureml.promptflow.flow_id": "3295d11f-225c-42d8-9e99-10aac794991b", "_azureml.evaluation_run": + "promptflow.BatchRun", "azureml.promptflow.snapshot_id": "a00b8581-2379-46b1-a1d9-f013aa51a215"}, "parameters": {}, "actionUris": {}, "scriptName": null, "target": null, "uniqueChildRunComputeTargets": [], "tags": {}, "settings": {}, "services": {}, "inputDatasets": [], "outputDatasets": [], "runDefinition": null, "jobSpecification": null, "primaryMetricName": @@ -1452,7 +1874,7 @@ interactions: connection: - keep-alive content-length: - - '3902' + - '3710' content-type: - application/json; charset=utf-8 strict-transport-security: @@ -1464,7 +1886,7 @@ interactions: x-content-type-options: - nosniff x-request-time: - - '0.043' + - '0.045' status: code: 200 message: OK diff --git a/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_without_generate_tools_json.yaml b/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_without_generate_tools_json.yaml new file mode 100644 index 00000000000..c30a979f6d3 --- /dev/null +++ b/src/promptflow-recording/recordings/azure/test_run_operations_TestFlowRun_test_run_without_generate_tools_json.yaml @@ -0,0 +1,659 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000 + response: + body: + string: '{"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000", + "name": "00000", "type": "Microsoft.MachineLearningServices/workspaces", "location": + "eastus", "tags": {}, "etag": null, "kind": "Default", "sku": {"name": "Basic", + "tier": "Basic"}, "properties": {"discoveryUrl": "https://eastus.api.azureml.ms/discovery"}}' + headers: + cache-control: + - no-cache + content-length: + - '3678' + content-type: + - application/json; charset=utf-8 + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-request-time: + - '0.036' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores?count=30&isDefault=true&orderByAsc=false + response: + body: + string: '{"value": [{"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore", + "name": "workspaceblobstore", "type": "Microsoft.MachineLearningServices/workspaces/datastores", + "properties": {"description": null, "tags": null, "properties": null, "isDefault": + true, "credentials": {"credentialsType": "AccountKey"}, "intellectualProperty": + null, "subscriptionId": "00000000-0000-0000-0000-000000000000", "resourceGroup": + "00000", "datastoreType": "AzureBlob", "accountName": "fake_account_name", + "containerName": "fake-container-name", "endpoint": "core.windows.net", "protocol": + "https", "serviceDataAccessAuthIdentity": "WorkspaceSystemAssignedIdentity"}, + "systemData": {"createdAt": "2023-04-08T02:53:06.5886442+00:00", "createdBy": + "779301c0-18b2-4cdc-801b-a0a3368fee0a", "createdByType": "Application", "lastModifiedAt": + "2023-04-08T02:53:07.521127+00:00", "lastModifiedBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", + "lastModifiedByType": "Application"}}]}' + headers: + cache-control: + - no-cache + content-length: + - '1372' + content-type: + - application/json; charset=utf-8 + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-request-time: + - '0.056' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore + response: + body: + string: '{"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore", + "name": "workspaceblobstore", "type": "Microsoft.MachineLearningServices/workspaces/datastores", + "properties": {"description": null, "tags": null, "properties": null, "isDefault": + true, "credentials": {"credentialsType": "AccountKey"}, "intellectualProperty": + null, "subscriptionId": "00000000-0000-0000-0000-000000000000", "resourceGroup": + "00000", "datastoreType": "AzureBlob", "accountName": "fake_account_name", + "containerName": "fake-container-name", "endpoint": "core.windows.net", "protocol": + "https", "serviceDataAccessAuthIdentity": "WorkspaceSystemAssignedIdentity"}, + "systemData": {"createdAt": "2023-04-08T02:53:06.5886442+00:00", "createdBy": + "779301c0-18b2-4cdc-801b-a0a3368fee0a", "createdByType": "Application", "lastModifiedAt": + "2023-04-08T02:53:07.521127+00:00", "lastModifiedBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", + "lastModifiedByType": "Application"}}' + headers: + cache-control: + - no-cache + content-length: + - '1227' + content-type: + - application/json; charset=utf-8 + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-request-time: + - '0.157' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore/listSecrets + response: + body: + string: '{"secretsType": "AccountKey", "key": "dGhpcyBpcyBmYWtlIGtleQ=="}' + headers: + cache-control: + - no-cache + content-length: + - '134' + content-type: + - application/json; charset=utf-8 + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-request-time: + - '0.074' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + x-ms-date: + - Thu, 25 Apr 2024 01:14:37 GMT + x-ms-version: + - '2023-11-03' + method: HEAD + uri: https://fake_account_name.blob.core.windows.net/fake-container-name/LocalUpload/000000000000000000000000000000000000/simple_hello_world.jsonl + response: + body: + string: '' + headers: + accept-ranges: + - bytes + content-length: + - '22' + content-md5: + - SaVvJK8fXJzgPgQkmSaCGA== + content-type: + - application/octet-stream + last-modified: + - Thu, 23 Nov 2023 12:11:21 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + vary: + - Origin + x-ms-blob-type: + - BlockBlob + x-ms-creation-time: + - Thu, 23 Nov 2023 12:11:20 GMT + x-ms-meta-name: + - 74c8f1fa-9e14-4249-8fec-279efedeb400 + x-ms-meta-upload_status: + - completed + x-ms-meta-version: + - 2266d840-3ecd-4a91-9e63-8d57e7b0a62e + x-ms-version: + - '2023-11-03' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + x-ms-date: + - Thu, 25 Apr 2024 01:14:38 GMT + x-ms-version: + - '2023-11-03' + method: HEAD + uri: https://fake_account_name.blob.core.windows.net/fake-container-name/az-ml-artifacts/000000000000000000000000000000000000/simple_hello_world.jsonl + response: + body: + string: '' + headers: + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: + - chunked + vary: + - Origin + x-ms-error-code: + - BlobNotFound + x-ms-version: + - '2023-11-03' + status: + code: 404 + message: The specified blob does not exist. +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore + response: + body: + string: '{"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore", + "name": "workspaceblobstore", "type": "Microsoft.MachineLearningServices/workspaces/datastores", + "properties": {"description": null, "tags": null, "properties": null, "isDefault": + true, "credentials": {"credentialsType": "AccountKey"}, "intellectualProperty": + null, "subscriptionId": "00000000-0000-0000-0000-000000000000", "resourceGroup": + "00000", "datastoreType": "AzureBlob", "accountName": "fake_account_name", + "containerName": "fake-container-name", "endpoint": "core.windows.net", "protocol": + "https", "serviceDataAccessAuthIdentity": "WorkspaceSystemAssignedIdentity"}, + "systemData": {"createdAt": "2023-04-08T02:53:06.5886442+00:00", "createdBy": + "779301c0-18b2-4cdc-801b-a0a3368fee0a", "createdByType": "Application", "lastModifiedAt": + "2023-04-08T02:53:07.521127+00:00", "lastModifiedBy": "779301c0-18b2-4cdc-801b-a0a3368fee0a", + "lastModifiedByType": "Application"}}' + headers: + cache-control: + - no-cache + content-length: + - '1227' + content-type: + - application/json; charset=utf-8 + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + vary: + - Accept-Encoding + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-request-time: + - '0.073' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azure-ai-ml/1.15.0 azsdk-python-mgmt-machinelearningservices/0.1.0 + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/datastores/workspaceblobstore/listSecrets + response: + body: + string: '{"secretsType": "AccountKey", "key": "dGhpcyBpcyBmYWtlIGtleQ=="}' + headers: + cache-control: + - no-cache + content-length: + - '134' + content-type: + - application/json; charset=utf-8 + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-request-time: + - '0.120' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + x-ms-date: + - Thu, 25 Apr 2024 01:14:43 GMT + x-ms-version: + - '2023-11-03' + method: HEAD + uri: https://fake_account_name.blob.core.windows.net/fake-container-name/LocalUpload/000000000000000000000000000000000000/simple_hello_world/.gitattributes + response: + body: + string: '' + headers: + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: + - chunked + vary: + - Origin + x-ms-error-code: + - BlobNotFound + x-ms-version: + - '2023-11-03' + status: + code: 404 + message: The specified blob does not exist. +- request: + body: '* text eol=lf + + ' + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '14' + Content-MD5: + - nYmkCopuDuFj82431amzZw== + Content-Type: + - application/octet-stream + If-None-Match: + - '*' + User-Agent: + - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + x-ms-blob-type: + - BlockBlob + x-ms-date: + - Thu, 25 Apr 2024 01:14:44 GMT + x-ms-version: + - '2023-11-03' + method: PUT + uri: https://fake_account_name.blob.core.windows.net/fake-container-name/LocalUpload/000000000000000000000000000000000000/simple_hello_world/.gitattributes + response: + body: + string: '' + headers: + content-length: + - '0' + content-md5: + - nYmkCopuDuFj82431amzZw== + last-modified: + - Thu, 25 Apr 2024 01:14:46 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-content-crc64: + - 4HXPg1EDQ/4= + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/xml + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-storage-blob/12.19.1 Python/3.11.8 (Windows-10-10.0.22631-SP0) + x-ms-date: + - Thu, 25 Apr 2024 01:14:46 GMT + x-ms-meta-name: + - 678b4fe3-518b-4d57-8cc5-c44eb3a628ec + x-ms-meta-upload_status: + - completed + x-ms-meta-version: + - '1' + x-ms-version: + - '2023-11-03' + method: PUT + uri: https://fake_account_name.blob.core.windows.net/fake-container-name/LocalUpload/000000000000000000000000000000000000/simple_hello_world/.gitattributes?comp=metadata + response: + body: + string: '' + headers: + content-length: + - '0' + last-modified: + - Thu, 25 Apr 2024 01:14:48 GMT + server: + - Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0 + x-ms-request-server-encrypted: + - 'true' + x-ms-version: + - '2023-11-03' + status: + code: 200 + message: OK +- request: + body: '{"flowDefinitionDataStoreName": "workspaceblobstore", "flowDefinitionBlobPath": + "LocalUpload/000000000000000000000000000000000000/simple_hello_world/flow.dag.yaml", + "runId": "name", "runDisplayName": "name", "runExperimentName": "", "sessionId": + "000000000000000000000000000000000000000000000000", "sessionSetupMode": "SystemWait", + "flowLineageId": "0000000000000000000000000000000000000000000000000000000000000000", + "runDisplayNameGenerationType": "UserProvidedMacro", "batchDataInput": {"dataUri": + "azureml://datastores/workspaceblobstore/paths/LocalUpload/000000000000000000000000000000000000/simple_hello_world.jsonl"}, + "inputsMapping": {"name": "${data.name}"}, "environmentVariables": {}, "connections": + {}, "runtimeName": "fake-runtime-name"}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '815' + Content-Type: + - application/json + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: POST + uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/BulkRuns/submit + response: + body: + string: '"name"' + headers: + connection: + - keep-alive + content-length: + - '38' + content-type: + - application/json; charset=utf-8 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-content-type-options: + - nosniff + x-request-time: + - '3.559' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - promptflow-azure-sdk/1.8.0.dev0 azsdk-python-azuremachinelearningdesignerserviceclient/unknown + Python/3.11.8 (Windows-10-10.0.22631-SP0) + method: GET + uri: https://eastus.api.azureml.ms/flow/api/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/BulkRuns/name + response: + body: + string: '{"flowRunResourceId": "azureml://locations/eastus/workspaces/00000/flows/name/flowRuns/name", + "flowRunId": "name", "flowRunDisplayName": "name", "batchDataInput": {"dataUri": + "azureml://datastores/workspaceblobstore/paths/LocalUpload/79f088fae0e502653c43146c9682f425/simple_hello_world.jsonl"}, + "flowRunType": "FlowRun", "flowType": "Default", "runtimeName": "automatic", + "inputsMapping": {"name": "${data.name}"}, "outputDatastoreName": "workspaceblobstore", + "childRunBasePath": "promptflow/PromptFlowArtifacts/name/flow_artifacts", + "sessionId": "1462d572374990aaf8198687983d04a75bc2a5396594de54", "studioPortalEndpoint": + "https://ml.azure.com/runs/name?wsid=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000"}' + headers: + connection: + - keep-alive + content-length: + - '1010' + content-type: + - application/json; charset=utf-8 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-request-time: + - '0.185' + status: + code: 200 + message: OK +- request: + body: '{"runId": "name", "selectRunMetadata": true, "selectRunDefinition": true, + "selectJobSpecification": true}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '137' + Content-Type: + - application/json + User-Agent: + - python-requests/2.31.0 + method: POST + uri: https://eastus.api.azureml.ms/history/v1.0/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/00000/providers/Microsoft.MachineLearningServices/workspaces/00000/rundata + response: + body: + string: '{"runMetadata": {"runNumber": 1714007692, "rootRunId": "name", "createdUtc": + "2024-04-25T01:14:52.6563266+00:00", "createdBy": {"userObjectId": "00000000-0000-0000-0000-000000000000", + "userPuId": "10032001D9C91417", "userIdp": null, "userAltSecId": null, "userIss": + "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", "userTenantId": + "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang", "upn": + null}, "userId": "00000000-0000-0000-0000-000000000000", "token": null, "tokenExpiryTimeUtc": + null, "error": null, "warnings": null, "revision": 1, "statusRevision": 0, + "runUuid": "e46d5481-d25b-4182-91b4-17c00d0e6d06", "parentRunUuid": null, + "rootRunUuid": "e46d5481-d25b-4182-91b4-17c00d0e6d06", "lastStartTimeUtc": + null, "currentComputeTime": "00:00:00", "computeDuration": null, "effectiveStartTimeUtc": + null, "lastModifiedBy": {"userObjectId": "00000000-0000-0000-0000-000000000000", + "userPuId": "10032001D9C91417", "userIdp": null, "userAltSecId": null, "userIss": + "https://sts.windows.net/00000000-0000-0000-0000-000000000000/", "userTenantId": + "00000000-0000-0000-0000-000000000000", "userName": "Xingzhi Zhang", "upn": + null}, "lastModifiedUtc": "2024-04-25T01:14:52.6563266+00:00", "duration": + null, "cancelationReason": null, "currentAttemptId": 1, "runId": "name", "parentRunId": + null, "experimentId": "e57eb79e-3e83-45f1-810c-ee22c20b2ebd", "status": "NotStarted", + "startTimeUtc": null, "endTimeUtc": null, "scheduleId": null, "displayName": + "name", "name": null, "dataContainerId": "dcid.name", "description": null, + "hidden": false, "runType": "azureml.promptflow.FlowRun", "runTypeV2": {"orchestrator": + null, "traits": [], "attribution": "PromptFlow", "computeType": null}, "properties": + {"azureml.promptflow.inputs_mapping": "{\"name\":\"${data.name}\"}", "azureml.promptflow.runtime_name": + "automatic", "azureml.promptflow.disable_trace": "false", "azureml.promptflow.input_data": + "azureml://datastores/workspaceblobstore/paths/LocalUpload/79f088fae0e502653c43146c9682f425/simple_hello_world.jsonl", + "azureml.promptflow.session_id": "1462d572374990aaf8198687983d04a75bc2a5396594de54", + "azureml.promptflow.definition_file_name": "flow.dag.yaml", "azureml.promptflow.flow_lineage_id": + "02907dc1b09e504451e4792d069d2e3145ca10bbe3bfcbbc1750ea8aa051f6d6", "azureml.promptflow.flow_definition_datastore_name": + "workspaceblobstore", "azureml.promptflow.flow_definition_blob_path": "LocalUpload/ffc29a9907b3bd539677fbf107cd84c0/simple_hello_world/flow.dag.yaml", + "_azureml.evaluation_run": "promptflow.BatchRun"}, "parameters": {}, "actionUris": + {}, "scriptName": null, "target": null, "uniqueChildRunComputeTargets": [], + "tags": {}, "settings": {}, "services": {}, "inputDatasets": [], "outputDatasets": + [], "runDefinition": null, "jobSpecification": null, "primaryMetricName": + null, "createdFrom": null, "cancelUri": null, "completeUri": null, "diagnosticsUri": + null, "computeRequest": null, "compute": null, "retainForLifetimeOfWorkspace": + false, "queueingInfo": null, "inputs": null, "outputs": null}, "runDefinition": + null, "jobSpecification": null, "systemSettings": null}' + headers: + connection: + - keep-alive + content-length: + - '3699' + content-type: + - application/json; charset=utf-8 + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-content-type-options: + - nosniff + x-request-time: + - '0.030' + status: + code: 200 + message: OK +version: 1 From 5d24e12bf44f439a044ad9b5bdb54a0d56a5aa61 Mon Sep 17 00:00:00 2001 From: Peiwen Gao <111329184+PeiwenGaoMS@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:05:55 +0800 Subject: [PATCH 05/12] [Internal] Fix ci test test_invoke_sync_function_in_process_set_env (#3008) # Description fix test test_invoke_sync_function_in_process_set_env # All Promptflow Contribution checklist: - [x] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [x] Title of the pull request is clear and informative. - [x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [x] Pull request includes test coverage for the included changes. --- .../executor/_service/utils/test_process_utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/promptflow/tests/executor/unittests/executor/_service/utils/test_process_utils.py b/src/promptflow/tests/executor/unittests/executor/_service/utils/test_process_utils.py index 99bb16d28ad..dcebb5fd443 100644 --- a/src/promptflow/tests/executor/unittests/executor/_service/utils/test_process_utils.py +++ b/src/promptflow/tests/executor/unittests/executor/_service/utils/test_process_utils.py @@ -34,6 +34,10 @@ def target_function(request: int): return request +def target_function_get_env(environment_variable: str): + return os.getenv(environment_variable) + + @pytest.mark.unittest class TestProcessUtils: @pytest.mark.asyncio @@ -77,16 +81,13 @@ async def test_invoke_sync_function_in_process_unexpected_error(self): @pytest.mark.asyncio async def test_invoke_sync_function_in_process_set_env(self): - def target_function_get_env(environment_variable: str): - return os.getenv(environment_variable) - with patch("promptflow.executor._service.utils.process_utils.service_logger") as mock_logger: environment_variables = {"test_env_name": "test_env_value"} result = await invoke_sync_function_in_process( target_function_get_env, args=("test_env_name",), context_dict=MOCK_CONTEXT_DICT, - environment_variables=environment_variables + environment_variables=environment_variables, ) assert result == "test_env_value" assert mock_logger.info.call_count == 2 From 4c00cdb6dd51b453458183d8cd5a4a0bbb5a338d Mon Sep 17 00:00:00 2001 From: Brynn Yin <24237253+brynn-code@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:40:51 +0800 Subject: [PATCH 06/12] [PICKME] Fix prompty with workspace connection (#3011) # Description Please add an informative description that covers that changes made by the pull request and link all relevant issues. # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --------- Signed-off-by: Brynn Yin --- .../_local_azure_connection_operations.py | 12 +++++++++++- .../e2etests/test_global_config.py | 13 +++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/promptflow-devkit/promptflow/_sdk/operations/_local_azure_connection_operations.py b/src/promptflow-devkit/promptflow/_sdk/operations/_local_azure_connection_operations.py index d676d2a9661..df771dd3b92 100644 --- a/src/promptflow-devkit/promptflow/_sdk/operations/_local_azure_connection_operations.py +++ b/src/promptflow-devkit/promptflow/_sdk/operations/_local_azure_connection_operations.py @@ -105,7 +105,17 @@ def get(self, name: str, **kwargs) -> _Connection: :param name: Name of the connection. :type name: str - :return: connection object retrieved from the database. + :return: connection object retrieved from Azure. + :rtype: ~promptflow.sdk.entities._connection._Connection + """ + return self._get(name, **kwargs) + + def _get(self, name: str, **kwargs) -> _Connection: + """Get a connection entity. + + :param name: Name of the connection. + :type name: str + :return: connection object retrieved from Azure. :rtype: ~promptflow.sdk.entities._connection._Connection """ with_secrets = kwargs.get("with_secrets", False) diff --git a/src/promptflow-devkit/tests/sdk_cli_global_config_test/e2etests/test_global_config.py b/src/promptflow-devkit/tests/sdk_cli_global_config_test/e2etests/test_global_config.py index b7553962944..f0d0dee59a4 100644 --- a/src/promptflow-devkit/tests/sdk_cli_global_config_test/e2etests/test_global_config.py +++ b/src/promptflow-devkit/tests/sdk_cli_global_config_test/e2etests/test_global_config.py @@ -4,10 +4,13 @@ from promptflow._sdk._load_functions import load_flow from promptflow._sdk.entities._flows._flow_context_resolver import FlowContextResolver +from promptflow.core import Prompty from promptflow.core._connection_provider._workspace_connection_provider import WorkspaceConnectionProvider -FLOWS_DIR = PROMPTFLOW_ROOT / "tests" / "test_configs" / "flows" -DATAS_DIR = PROMPTFLOW_ROOT / "tests" / "test_configs" / "datas" +TEST_CONFIG_DIR = PROMPTFLOW_ROOT / "tests" / "test_configs" +FLOWS_DIR = TEST_CONFIG_DIR / "flows" +DATAS_DIR = TEST_CONFIG_DIR / "datas" +PROMPTY_DIR = TEST_CONFIG_DIR / "prompty" @pytest.mark.usefixtures("global_config") @@ -45,3 +48,9 @@ def assert_client(mock_self, provider, **kwargs): flow = load_flow(source=f"{FLOWS_DIR}/web_classification") with mock.patch("promptflow.core._serving.flow_invoker.FlowInvoker.resolve_connections", assert_client): FlowContextResolver.resolve(flow=flow) + + def test_prompty_callable(self, pf): + # Test prompty callable with global config ws connection + prompty = Prompty.load(source=f"{PROMPTY_DIR}/prompty_example.prompty") + result = prompty(question="what is the result of 1+1?") + assert "2" in result From 9f2bc059b2cff0a318e0812d30415afbd4edf48c Mon Sep 17 00:00:00 2001 From: Zhengfei Wang <38847871+zhengfeiwang@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:46:08 +0800 Subject: [PATCH 07/12] [trace][refactor] Move tracing related functions to a better place (#2990) # Description **Move tracing related functions** - `promptflow._sdk._tracing`: tracing related function import place, with unit tests covered and guarded - for `promptflow-tracing`: `start_trace_with_devkit`, `setup_exporter_to_pfs` - for OTLP collector, runtime and others: `process_otlp_trace_request` - parse span from Protocol Buffer - `promptflow._sdk._utils.tracing`: utilities for tracing Remove previous tracing utilities file `_tracing_utils.py`. **Pass function that gets credential** For `process_otlp_trace_request` usage, user should pass the function that how to get credential, instead of the credential itself. However, as the environment may not have Azure extension, so we cannot directly pass `AzureCliCredential` in outside; so add a default logic inside the function. # All Promptflow Contribution checklist: - [x] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [x] Title of the pull request is clear and informative. - [x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [x] Pull request includes test coverage for the included changes. --- .../promptflow/azure/_storage/blob/client.py | 17 +- .../azure/_storage/cosmosdb/client.py | 14 +- .../unittests/test_run_operations.py | 4 +- .../_sdk/_service/apis/collector.py | 37 ++- .../promptflow/_sdk/_tracing.py | 51 ++-- .../promptflow/_sdk/_tracing_utils.py | 145 --------- .../promptflow/_sdk/_utils/general_utils.py | 28 -- .../promptflow/_sdk/_utils/tracing.py | 285 ++++++++++++++++++ .../_sdk/operations/_trace_operations.py | 118 +------- .../sdk_cli_test/e2etests/test_flow_run.py | 5 +- .../sdk_cli_test/unittests/test_trace.py | 9 +- 11 files changed, 363 insertions(+), 350 deletions(-) delete mode 100644 src/promptflow-devkit/promptflow/_sdk/_tracing_utils.py create mode 100644 src/promptflow-devkit/promptflow/_sdk/_utils/tracing.py diff --git a/src/promptflow-azure/promptflow/azure/_storage/blob/client.py b/src/promptflow-azure/promptflow/azure/_storage/blob/client.py index 6f2085229d1..75f9e2bbb4c 100644 --- a/src/promptflow-azure/promptflow/azure/_storage/blob/client.py +++ b/src/promptflow-azure/promptflow/azure/_storage/blob/client.py @@ -2,7 +2,7 @@ import logging import threading import traceback -from typing import Optional, Tuple +from typing import Callable, Tuple from azure.ai.ml import MLClient from azure.ai.ml._azure_environments import _get_storage_endpoint_from_metadata @@ -25,17 +25,10 @@ def get_datastore_container_client( subscription_id: str, resource_group_name: str, workspace_name: str, - credential: Optional[object] = None, + get_credential: Callable, ) -> Tuple[ContainerClient, str]: try: - if credential is None: - # in cloud scenario, runtime will pass in credential - # so this is local to cloud only code, happens in prompt flow service - # which should rely on Azure CLI credential only - from azure.identity import AzureCliCredential - - credential = AzureCliCredential() - + credential = get_credential() datastore_definition, datastore_credential = _get_default_datastore( subscription_id, resource_group_name, workspace_name, credential ) @@ -68,7 +61,7 @@ def get_datastore_container_client( def _get_default_datastore( - subscription_id: str, resource_group_name: str, workspace_name: str, credential: Optional[object] + subscription_id: str, resource_group_name: str, workspace_name: str, credential ) -> Tuple[Datastore, str]: datastore_key = _get_datastore_client_key(subscription_id, resource_group_name, workspace_name) @@ -103,7 +96,7 @@ def _get_datastore_client_key(subscription_id: str, resource_group_name: str, wo def _get_aml_default_datastore( - subscription_id: str, resource_group_name: str, workspace_name: str, credential: Optional[object] + subscription_id: str, resource_group_name: str, workspace_name: str, credential ) -> Tuple[Datastore, str]: ml_client = MLClient( diff --git a/src/promptflow-azure/promptflow/azure/_storage/cosmosdb/client.py b/src/promptflow-azure/promptflow/azure/_storage/cosmosdb/client.py index 6e013ad7cfc..01a741da654 100644 --- a/src/promptflow-azure/promptflow/azure/_storage/cosmosdb/client.py +++ b/src/promptflow-azure/promptflow/azure/_storage/cosmosdb/client.py @@ -5,7 +5,7 @@ import ast import datetime import threading -from typing import Optional +from typing import Callable client_map = {} _thread_lock = threading.Lock() @@ -18,7 +18,7 @@ def get_client( subscription_id: str, resource_group_name: str, workspace_name: str, - credential: Optional[object] = None, + get_credential: Callable, ): client_key = _get_db_client_key(container_name, subscription_id, resource_group_name, workspace_name) container_client = _get_client_from_map(client_key) @@ -28,13 +28,7 @@ def get_client( with container_lock: container_client = _get_client_from_map(client_key) if container_client is None: - if credential is None: - # in cloud scenario, runtime will pass in credential - # so this is local to cloud only code, happens in prompt flow service - # which should rely on Azure CLI credential only - from azure.identity import AzureCliCredential - - credential = AzureCliCredential() + credential = get_credential() token = _get_resource_token( container_name, subscription_id, resource_group_name, workspace_name, credential ) @@ -77,7 +71,7 @@ def _get_resource_token( subscription_id: str, resource_group_name: str, workspace_name: str, - credential: Optional[object], + credential, ) -> object: from promptflow.azure import PFClient diff --git a/src/promptflow-azure/tests/sdk_cli_azure_test/unittests/test_run_operations.py b/src/promptflow-azure/tests/sdk_cli_azure_test/unittests/test_run_operations.py index f85ace022af..a334bc296d9 100644 --- a/src/promptflow-azure/tests/sdk_cli_azure_test/unittests/test_run_operations.py +++ b/src/promptflow-azure/tests/sdk_cli_azure_test/unittests/test_run_operations.py @@ -9,7 +9,7 @@ from sdk_cli_azure_test.conftest import DATAS_DIR, EAGER_FLOWS_DIR, FLOWS_DIR from promptflow._sdk._errors import RunOperationParameterError, UploadUserError, UserAuthenticationError -from promptflow._sdk._utils import parse_otel_span_status_code +from promptflow._sdk._utils.tracing import _parse_otel_span_status_code from promptflow._sdk.entities import Run from promptflow._sdk.operations._run_operations import RunOperations from promptflow._utils.async_utils import async_run_allowing_running_loop @@ -88,7 +88,7 @@ def test_flex_flow_with_imported_func(self, pf: PFClient): # TODO(3017093): won't support this for now with pytest.raises(UserErrorException) as e: pf.run( - flow=parse_otel_span_status_code, + flow=_parse_otel_span_status_code, data=f"{DATAS_DIR}/simple_eager_flow_data.jsonl", # set code folder to avoid snapshot too big code=f"{EAGER_FLOWS_DIR}/multiple_entries", diff --git a/src/promptflow-devkit/promptflow/_sdk/_service/apis/collector.py b/src/promptflow-devkit/promptflow/_sdk/_service/apis/collector.py index 766eef4ffcd..8820a11a168 100644 --- a/src/promptflow-devkit/promptflow/_sdk/_service/apis/collector.py +++ b/src/promptflow-devkit/promptflow/_sdk/_service/apis/collector.py @@ -13,7 +13,8 @@ from flask import request from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ExportTraceServiceRequest -from promptflow._sdk._tracing import process_otlp_trace_request +from promptflow._sdk._errors import MissingAzurePackage +from promptflow._sdk._tracing import _is_azure_ext_installed, process_otlp_trace_request def trace_collector( @@ -41,13 +42,33 @@ def trace_collector( if "application/x-protobuf" in content_type: trace_request = ExportTraceServiceRequest() trace_request.ParseFromString(request.data) - process_otlp_trace_request( - trace_request=trace_request, - get_created_by_info_with_cache=get_created_by_info_with_cache, - logger=logger, - cloud_trace_only=cloud_trace_only, - credential=credential, - ) + # this function will be called in some old runtime versions + # where runtime will pass either credential object, or the function to get credential + # as we need to be compatible with this, need to handle both cases + if credential is not None: + # local prompt flow service will not pass credential, so this is runtime scenario + get_credential = credential if callable(credential) else lambda: credential # noqa: F841 + process_otlp_trace_request( + trace_request=trace_request, + get_created_by_info_with_cache=get_created_by_info_with_cache, + logger=logger, + get_credential=get_credential, + cloud_trace_only=cloud_trace_only, + ) + else: + # if `promptflow-azure` is not installed, pass an exception class to the function + get_credential = MissingAzurePackage + if _is_azure_ext_installed(): + from azure.identity import AzureCliCredential + + get_credential = AzureCliCredential + process_otlp_trace_request( + trace_request=trace_request, + get_created_by_info_with_cache=get_created_by_info_with_cache, + logger=logger, + get_credential=get_credential, + cloud_trace_only=cloud_trace_only, + ) return "Traces received", 200 # JSON protobuf encoding diff --git a/src/promptflow-devkit/promptflow/_sdk/_tracing.py b/src/promptflow-devkit/promptflow/_sdk/_tracing.py index c8516c61d86..e167adc6c39 100644 --- a/src/promptflow-devkit/promptflow/_sdk/_tracing.py +++ b/src/promptflow-devkit/promptflow/_sdk/_tracing.py @@ -51,12 +51,8 @@ is_port_in_use, is_run_from_built_binary, ) -from promptflow._sdk._tracing_utils import get_workspace_kind -from promptflow._sdk._utils import ( - add_executable_script_to_env_path, - extract_workspace_triad_from_trace_provider, - parse_kv_from_pb_attribute, -) +from promptflow._sdk._utils import add_executable_script_to_env_path, extract_workspace_triad_from_trace_provider +from promptflow._sdk._utils.tracing import get_workspace_kind, parse_kv_from_pb_attribute, parse_protobuf_span from promptflow._utils.logger_utils import get_cli_sdk_logger from promptflow._utils.thread_utils import ThreadWithContextVars from promptflow.tracing._integrations._openai_injector import inject_openai_api @@ -559,8 +555,8 @@ def process_otlp_trace_request( trace_request: ExportTraceServiceRequest, get_created_by_info_with_cache: typing.Callable, logger: logging.Logger, + get_credential: typing.Callable, cloud_trace_only: bool = False, - credential: typing.Optional[object] = None, ): """Process ExportTraceServiceRequest and write data to local/remote storage. @@ -572,13 +568,12 @@ def process_otlp_trace_request( :type get_created_by_info_with_cache: Callable :param logger: The logger object used for logging. :type logger: logging.Logger + :param get_credential: A function that gets credential for Cosmos DB operation. + :type get_credential: Callable :param cloud_trace_only: If True, only write trace to cosmosdb and skip local trace. Default is False. :type cloud_trace_only: bool - :param credential: The credential object used to authenticate with cosmosdb. Default is None. - :type credential: Optional[object] """ from promptflow._sdk.entities._trace import Span - from promptflow._sdk.operations._trace_operations import TraceOperations all_spans = [] for resource_span in trace_request.resource_spans: @@ -596,7 +591,7 @@ def process_otlp_trace_request( for scope_span in resource_span.scope_spans: for span in scope_span.spans: # TODO: persist with batch - span: Span = TraceOperations._parse_protobuf_span(span, resource=resource, logger=logger) + span: Span = parse_protobuf_span(span, resource=resource, logger=logger) if not cloud_trace_only: all_spans.append(copy.deepcopy(span)) span._persist() @@ -606,12 +601,14 @@ def process_otlp_trace_request( if cloud_trace_only: # If we only trace to cloud, we should make sure the data writing is success before return. - _try_write_trace_to_cosmosdb(all_spans, get_created_by_info_with_cache, logger, credential, is_cloud_trace=True) + _try_write_trace_to_cosmosdb( + all_spans, get_created_by_info_with_cache, logger, get_credential, is_cloud_trace=True + ) else: # Create a new thread to write trace to cosmosdb to avoid blocking the main thread ThreadWithContextVars( target=_try_write_trace_to_cosmosdb, - args=(all_spans, get_created_by_info_with_cache, logger, credential, False), + args=(all_spans, get_created_by_info_with_cache, logger, get_credential, False), ).start() return @@ -621,7 +618,7 @@ def _try_write_trace_to_cosmosdb( all_spans: typing.List, get_created_by_info_with_cache: typing.Callable, logger: logging.Logger, - credential: typing.Optional[object] = None, + get_credential: typing.Callable, is_cloud_trace: bool = False, ): if not all_spans: @@ -649,19 +646,31 @@ def _try_write_trace_to_cosmosdb( # So, we load clients in parallel for warm up. span_client_thread = ThreadWithContextVars( target=get_client, - args=(CosmosDBContainerName.SPAN, subscription_id, resource_group_name, workspace_name, credential), + args=(CosmosDBContainerName.SPAN, subscription_id, resource_group_name, workspace_name, get_credential), ) span_client_thread.start() collection_client_thread = ThreadWithContextVars( target=get_client, - args=(CosmosDBContainerName.COLLECTION, subscription_id, resource_group_name, workspace_name, credential), + args=( + CosmosDBContainerName.COLLECTION, + subscription_id, + resource_group_name, + workspace_name, + get_credential, + ), ) collection_client_thread.start() line_summary_client_thread = ThreadWithContextVars( target=get_client, - args=(CosmosDBContainerName.LINE_SUMMARY, subscription_id, resource_group_name, workspace_name, credential), + args=( + CosmosDBContainerName.LINE_SUMMARY, + subscription_id, + resource_group_name, + workspace_name, + get_credential, + ), ) line_summary_client_thread.start() @@ -677,7 +686,7 @@ def _try_write_trace_to_cosmosdb( subscription_id=subscription_id, resource_group_name=resource_group_name, workspace_name=workspace_name, - credential=credential, + get_credential=get_credential, ) span_client_thread.join() @@ -687,7 +696,7 @@ def _try_write_trace_to_cosmosdb( created_by = get_created_by_info_with_cache() collection_client = get_client( - CosmosDBContainerName.COLLECTION, subscription_id, resource_group_name, workspace_name, credential + CosmosDBContainerName.COLLECTION, subscription_id, resource_group_name, workspace_name, get_credential ) collection_db = CollectionCosmosDB(first_span, is_cloud_trace, created_by) @@ -701,7 +710,7 @@ def _try_write_trace_to_cosmosdb( for span in all_spans: try: span_client = get_client( - CosmosDBContainerName.SPAN, subscription_id, resource_group_name, workspace_name, credential + CosmosDBContainerName.SPAN, subscription_id, resource_group_name, workspace_name, get_credential ) result = SpanCosmosDB(span, collection_id, created_by).persist( span_client, blob_container_client, blob_base_uri @@ -713,7 +722,7 @@ def _try_write_trace_to_cosmosdb( subscription_id, resource_group_name, workspace_name, - credential, + get_credential, ) Summary(span, collection_id, created_by, logger).persist(line_summary_client) except Exception as e: diff --git a/src/promptflow-devkit/promptflow/_sdk/_tracing_utils.py b/src/promptflow-devkit/promptflow/_sdk/_tracing_utils.py deleted file mode 100644 index b56848e652d..00000000000 --- a/src/promptflow-devkit/promptflow/_sdk/_tracing_utils.py +++ /dev/null @@ -1,145 +0,0 @@ -# --------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# --------------------------------------------------------- - -import datetime -import json -import logging -import typing -from dataclasses import dataclass -from pathlib import Path - -from promptflow._sdk._constants import HOME_PROMPT_FLOW_DIR, AzureMLWorkspaceTriad -from promptflow._sdk._utils import json_load -from promptflow._utils.logger_utils import get_cli_sdk_logger -from promptflow.core._errors import MissingRequiredPackage - -_logger = get_cli_sdk_logger() - - -# SCENARIO: local to cloud -# distinguish Azure ML workspace and AI project -@dataclass -class WorkspaceKindLocalCache: - subscription_id: str - resource_group_name: str - workspace_name: str - kind: typing.Optional[str] = None - timestamp: typing.Optional[datetime.datetime] = None - - SUBSCRIPTION_ID = "subscription_id" - RESOURCE_GROUP_NAME = "resource_group_name" - WORKSPACE_NAME = "workspace_name" - KIND = "kind" - TIMESTAMP = "timestamp" - # class-related constants - PF_DIR_TRACING = "tracing" - WORKSPACE_KIND_LOCAL_CACHE_EXPIRE_DAYS = 1 - - def __post_init__(self): - if self.is_cache_exists: - cache = json_load(self.cache_path) - self.kind = cache[self.KIND] - self.timestamp = datetime.datetime.fromisoformat(cache[self.TIMESTAMP]) - - @property - def cache_path(self) -> Path: - tracing_dir = HOME_PROMPT_FLOW_DIR / self.PF_DIR_TRACING - if not tracing_dir.exists(): - tracing_dir.mkdir(parents=True) - filename = f"{self.subscription_id}_{self.resource_group_name}_{self.workspace_name}.json" - return (tracing_dir / filename).resolve() - - @property - def is_cache_exists(self) -> bool: - return self.cache_path.is_file() - - @property - def is_expired(self) -> bool: - if not self.is_cache_exists: - return True - time_delta = datetime.datetime.now() - self.timestamp - return time_delta.days > self.WORKSPACE_KIND_LOCAL_CACHE_EXPIRE_DAYS - - def get_kind(self) -> str: - if not self.is_cache_exists or self.is_expired: - _logger.debug(f"refreshing local cache for resource {self.workspace_name}...") - self._refresh() - _logger.debug(f"local cache kind for resource {self.workspace_name}: {self.kind}") - return self.kind - - def _refresh(self) -> None: - self.kind = self._get_workspace_kind_from_azure() - self.timestamp = datetime.datetime.now() - cache = { - self.SUBSCRIPTION_ID: self.subscription_id, - self.RESOURCE_GROUP_NAME: self.resource_group_name, - self.WORKSPACE_NAME: self.workspace_name, - self.KIND: self.kind, - self.TIMESTAMP: self.timestamp.isoformat(), - } - with open(self.cache_path, "w") as f: - f.write(json.dumps(cache)) - - def _get_workspace_kind_from_azure(self) -> str: - try: - from azure.ai.ml import MLClient - - from promptflow.azure._cli._utils import get_credentials_for_cli - except ImportError: - error_message = "Please install 'promptflow-azure' to use Azure related tracing features." - raise MissingRequiredPackage(message=error_message) - - _logger.debug("trying to get workspace from Azure...") - ml_client = MLClient( - credential=get_credentials_for_cli(), - subscription_id=self.subscription_id, - resource_group_name=self.resource_group_name, - workspace_name=self.workspace_name, - ) - ws = ml_client.workspaces.get(name=self.workspace_name) - return ws._kind - - -def get_workspace_kind(ws_triad: AzureMLWorkspaceTriad) -> str: - """Get workspace kind. - - Note that we will cache this result locally with timestamp, so that we don't - really need to request every time, but need to check timestamp. - """ - return WorkspaceKindLocalCache( - subscription_id=ws_triad.subscription_id, - resource_group_name=ws_triad.resource_group_name, - workspace_name=ws_triad.workspace_name, - ).get_kind() - - -# SCENARIO: local trace UI search experience -# append condition(s) to user specified query -def append_conditions( - expression: str, - collection: typing.Optional[str] = None, - runs: typing.Optional[typing.Union[str, typing.List[str]]] = None, - session_id: typing.Optional[str] = None, - logger: typing.Optional[logging.Logger] = None, -) -> str: - if logger is None: - logger = _logger - logger.debug("received original search expression: %s", expression) - if collection is not None: - logger.debug("received search parameter collection: %s", collection) - expression += f" and collection == '{collection}'" - if runs is not None: - logger.debug("received search parameter runs: %s", runs) - if isinstance(runs, str): - expression += f" and run == '{runs}'" - elif len(runs) == 1: - expression += f" and run == '{runs[0]}'" - else: - runs_expr = " or ".join([f"run == '{run}'" for run in runs]) - expression += f" and ({runs_expr})" - if session_id is not None: - logger.debug("received search parameter session_id: %s", session_id) - expression += f" and session_id == '{session_id}'" - logger.debug("final search expression: %s", expression) - return expression diff --git a/src/promptflow-devkit/promptflow/_sdk/_utils/general_utils.py b/src/promptflow-devkit/promptflow/_sdk/_utils/general_utils.py index d332a63fa66..afb33415baf 100644 --- a/src/promptflow-devkit/promptflow/_sdk/_utils/general_utils.py +++ b/src/promptflow-devkit/promptflow/_sdk/_utils/general_utils.py @@ -909,34 +909,6 @@ def convert_time_unix_nano_to_timestamp(time_unix_nano: str) -> datetime.datetim return datetime.datetime.utcfromtimestamp(seconds) -def parse_kv_from_pb_attribute(attribute: Dict) -> Tuple[str, str]: - attr_key = attribute["key"] - # suppose all values are flattened here - # so simply regard the first value as the attribute value - attr_value = list(attribute["value"].values())[0] - return attr_key, attr_value - - -def flatten_pb_attributes(attributes: List[Dict]) -> Dict: - flattened_attributes = {} - for attribute in attributes: - attr_key, attr_value = parse_kv_from_pb_attribute(attribute) - flattened_attributes[attr_key] = attr_value - return flattened_attributes - - -def parse_otel_span_status_code(value: int) -> str: - # map int value to string - # https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/trace/api.md#set-status - # https://github.com/open-telemetry/opentelemetry-python/blob/v1.22.0/opentelemetry-api/src/opentelemetry/trace/status.py#L22-L32 - if value == 0: - return "Unset" - elif value == 1: - return "Ok" - else: - return "Error" - - def extract_workspace_triad_from_trace_provider(trace_provider: str) -> AzureMLWorkspaceTriad: match = re.match(AZURE_WORKSPACE_REGEX_FORMAT, trace_provider) if not match or len(match.groups()) != 5: diff --git a/src/promptflow-devkit/promptflow/_sdk/_utils/tracing.py b/src/promptflow-devkit/promptflow/_sdk/_utils/tracing.py new file mode 100644 index 00000000000..2bbf6058988 --- /dev/null +++ b/src/promptflow-devkit/promptflow/_sdk/_utils/tracing.py @@ -0,0 +1,285 @@ +# --------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# --------------------------------------------------------- + +import datetime +import json +import logging +import typing +from dataclasses import dataclass +from pathlib import Path + +from google.protobuf.json_format import MessageToJson +from opentelemetry.proto.trace.v1.trace_pb2 import Span as PBSpan +from opentelemetry.trace.span import format_span_id as otel_format_span_id +from opentelemetry.trace.span import format_trace_id as otel_format_trace_id + +from promptflow._constants import ( + SpanContextFieldName, + SpanEventFieldName, + SpanFieldName, + SpanLinkFieldName, + SpanStatusFieldName, +) +from promptflow._sdk._constants import HOME_PROMPT_FLOW_DIR, AzureMLWorkspaceTriad +from promptflow._sdk._utils import convert_time_unix_nano_to_timestamp, json_load +from promptflow._sdk.entities._trace import Span +from promptflow._utils.logger_utils import get_cli_sdk_logger +from promptflow.core._errors import MissingRequiredPackage + +_logger = get_cli_sdk_logger() + + +# SCENARIO: OTLP trace collector +# prompt flow service, runtime parse OTLP trace +def format_span_id(span_id: bytes) -> str: + """Format span id to hex string. + Note that we need to add 0x since it is how opentelemetry-sdk does. + Reference: https://github.com/open-telemetry/opentelemetry-python/blob/ + 642f8dd18eea2737b4f8cd2f6f4d08a7e569c4b2/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L505 + """ + return f"0x{otel_format_span_id(int.from_bytes(span_id, byteorder='big', signed=False))}" + + +def format_trace_id(trace_id: bytes) -> str: + """Format trace_id id to hex string. + Note that we need to add 0x since it is how opentelemetry-sdk does. + Reference: https://github.com/open-telemetry/opentelemetry-python/blob/ + 642f8dd18eea2737b4f8cd2f6f4d08a7e569c4b2/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L505 + """ + return f"0x{otel_format_trace_id(int.from_bytes(trace_id, byteorder='big', signed=False))}" + + +def parse_kv_from_pb_attribute(attribute: typing.Dict) -> typing.Tuple[str, str]: + attr_key = attribute["key"] + # suppose all values are flattened here + # so simply regard the first value as the attribute value + attr_value = list(attribute["value"].values())[0] + return attr_key, attr_value + + +def _flatten_pb_attributes(attributes: typing.List[typing.Dict]) -> typing.Dict: + flattened_attributes = {} + for attribute in attributes: + attr_key, attr_value = parse_kv_from_pb_attribute(attribute) + flattened_attributes[attr_key] = attr_value + return flattened_attributes + + +def _parse_otel_span_status_code(value: int) -> str: + # map int value to string + # https://github.com/open-telemetry/opentelemetry-specification/blob/v1.22.0/specification/trace/api.md#set-status + # https://github.com/open-telemetry/opentelemetry-python/blob/v1.22.0/opentelemetry-api/src/opentelemetry/trace/status.py#L22-L32 + if value == 0: + return "Unset" + elif value == 1: + return "Ok" + else: + return "Error" + + +def parse_protobuf_events(obj: typing.List[PBSpan.Event], logger: logging.Logger) -> typing.List[typing.Dict]: + events = [] + if len(obj) == 0: + logger.debug("No events found in span") + return events + for pb_event in obj: + event_dict: dict = json.loads(MessageToJson(pb_event)) + logger.debug("Received event: %s", json.dumps(event_dict)) + event = { + SpanEventFieldName.NAME: pb_event.name, + # .isoformat() here to make this dumpable to JSON + SpanEventFieldName.TIMESTAMP: convert_time_unix_nano_to_timestamp(pb_event.time_unix_nano).isoformat(), + SpanEventFieldName.ATTRIBUTES: _flatten_pb_attributes( + event_dict.get(SpanEventFieldName.ATTRIBUTES, dict()) + ), + } + events.append(event) + return events + + +def parse_protobuf_links(obj: typing.List[PBSpan.Link], logger: logging.Logger) -> typing.List[typing.Dict]: + links = [] + if len(obj) == 0: + logger.debug("No links found in span") + return links + for pb_link in obj: + link_dict: dict = json.loads(MessageToJson(pb_link)) + logger.debug("Received link: %s", json.dumps(link_dict)) + link = { + SpanLinkFieldName.CONTEXT: { + SpanContextFieldName.TRACE_ID: format_trace_id(pb_link.trace_id), + SpanContextFieldName.SPAN_ID: format_span_id(pb_link.span_id), + SpanContextFieldName.TRACE_STATE: pb_link.trace_state, + }, + SpanLinkFieldName.ATTRIBUTES: _flatten_pb_attributes(link_dict.get(SpanLinkFieldName.ATTRIBUTES, dict())), + } + links.append(link) + return links + + +def parse_protobuf_span(span: PBSpan, resource: typing.Dict, logger: logging.Logger) -> Span: + # Open Telemetry does not provide official way to parse Protocol Buffer Span object + # so we need to parse it manually relying on `MessageToJson` + # reference: https://github.com/open-telemetry/opentelemetry-python/issues/3700#issuecomment-2010704554 + span_dict: dict = json.loads(MessageToJson(span)) + logger.debug("Received span: %s, resource: %s", json.dumps(span_dict), json.dumps(resource)) + span_id = format_span_id(span.span_id) + trace_id = format_trace_id(span.trace_id) + parent_id = format_span_id(span.parent_span_id) if span.parent_span_id else None + # we have observed in some scenarios, there is not `attributes` field + attributes = _flatten_pb_attributes(span_dict.get(SpanFieldName.ATTRIBUTES, dict())) + logger.debug("Parsed attributes: %s", json.dumps(attributes)) + links = parse_protobuf_links(span.links, logger) + events = parse_protobuf_events(span.events, logger) + + return Span( + trace_id=trace_id, + span_id=span_id, + name=span.name, + context={ + SpanContextFieldName.TRACE_ID: trace_id, + SpanContextFieldName.SPAN_ID: span_id, + SpanContextFieldName.TRACE_STATE: span.trace_state, + }, + kind=span.kind, + parent_id=parent_id if parent_id else None, + start_time=convert_time_unix_nano_to_timestamp(span.start_time_unix_nano), + end_time=convert_time_unix_nano_to_timestamp(span.end_time_unix_nano), + status={ + SpanStatusFieldName.STATUS_CODE: _parse_otel_span_status_code(span.status.code), + SpanStatusFieldName.DESCRIPTION: span.status.message, + }, + attributes=attributes, + links=links, + events=events, + resource=resource, + ) + + +# SCENARIO: local to cloud +# distinguish Azure ML workspace and AI project +@dataclass +class WorkspaceKindLocalCache: + subscription_id: str + resource_group_name: str + workspace_name: str + kind: typing.Optional[str] = None + timestamp: typing.Optional[datetime.datetime] = None + + SUBSCRIPTION_ID = "subscription_id" + RESOURCE_GROUP_NAME = "resource_group_name" + WORKSPACE_NAME = "workspace_name" + KIND = "kind" + TIMESTAMP = "timestamp" + # class-related constants + PF_DIR_TRACING = "tracing" + WORKSPACE_KIND_LOCAL_CACHE_EXPIRE_DAYS = 1 + + def __post_init__(self): + if self.is_cache_exists: + cache = json_load(self.cache_path) + self.kind = cache[self.KIND] + self.timestamp = datetime.datetime.fromisoformat(cache[self.TIMESTAMP]) + + @property + def cache_path(self) -> Path: + tracing_dir = HOME_PROMPT_FLOW_DIR / self.PF_DIR_TRACING + if not tracing_dir.exists(): + tracing_dir.mkdir(parents=True) + filename = f"{self.subscription_id}_{self.resource_group_name}_{self.workspace_name}.json" + return (tracing_dir / filename).resolve() + + @property + def is_cache_exists(self) -> bool: + return self.cache_path.is_file() + + @property + def is_expired(self) -> bool: + if not self.is_cache_exists: + return True + time_delta = datetime.datetime.now() - self.timestamp + return time_delta.days > self.WORKSPACE_KIND_LOCAL_CACHE_EXPIRE_DAYS + + def get_kind(self) -> str: + if not self.is_cache_exists or self.is_expired: + _logger.debug(f"refreshing local cache for resource {self.workspace_name}...") + self._refresh() + _logger.debug(f"local cache kind for resource {self.workspace_name}: {self.kind}") + return self.kind + + def _refresh(self) -> None: + self.kind = self._get_workspace_kind_from_azure() + self.timestamp = datetime.datetime.now() + cache = { + self.SUBSCRIPTION_ID: self.subscription_id, + self.RESOURCE_GROUP_NAME: self.resource_group_name, + self.WORKSPACE_NAME: self.workspace_name, + self.KIND: self.kind, + self.TIMESTAMP: self.timestamp.isoformat(), + } + with open(self.cache_path, "w") as f: + f.write(json.dumps(cache)) + + def _get_workspace_kind_from_azure(self) -> str: + try: + from azure.ai.ml import MLClient + + from promptflow.azure._cli._utils import get_credentials_for_cli + except ImportError: + error_message = "Please install 'promptflow-azure' to use Azure related tracing features." + raise MissingRequiredPackage(message=error_message) + + _logger.debug("trying to get workspace from Azure...") + ml_client = MLClient( + credential=get_credentials_for_cli(), + subscription_id=self.subscription_id, + resource_group_name=self.resource_group_name, + workspace_name=self.workspace_name, + ) + ws = ml_client.workspaces.get(name=self.workspace_name) + return ws._kind + + +def get_workspace_kind(ws_triad: AzureMLWorkspaceTriad) -> str: + """Get workspace kind. + + Note that we will cache this result locally with timestamp, so that we don't + really need to request every time, but need to check timestamp. + """ + return WorkspaceKindLocalCache( + subscription_id=ws_triad.subscription_id, + resource_group_name=ws_triad.resource_group_name, + workspace_name=ws_triad.workspace_name, + ).get_kind() + + +# SCENARIO: local trace UI search experience +# append condition(s) to user specified query +def append_conditions( + expression: str, + collection: typing.Optional[str] = None, + runs: typing.Optional[typing.Union[str, typing.List[str]]] = None, + session_id: typing.Optional[str] = None, + logger: typing.Optional[logging.Logger] = None, +) -> str: + if logger is None: + logger = _logger + logger.debug("received original search expression: %s", expression) + if collection is not None: + logger.debug("received search parameter collection: %s", collection) + expression += f" and collection == '{collection}'" + if runs is not None: + logger.debug("received search parameter runs: %s", runs) + if isinstance(runs, str): + expression += f" and run == '{runs}'" + elif len(runs) == 1: + expression += f" and run == '{runs[0]}'" + else: + runs_expr = " or ".join([f"run == '{run}'" for run in runs]) + expression += f" and ({runs_expr})" + if session_id is not None: + logger.debug("received search parameter session_id: %s", session_id) + expression += f" and session_id == '{session_id}'" + logger.debug("final search expression: %s", expression) + return expression diff --git a/src/promptflow-devkit/promptflow/_sdk/operations/_trace_operations.py b/src/promptflow-devkit/promptflow/_sdk/operations/_trace_operations.py index 2bafffbaaa6..228ec836d3e 100644 --- a/src/promptflow-devkit/promptflow/_sdk/operations/_trace_operations.py +++ b/src/promptflow-devkit/promptflow/_sdk/operations/_trace_operations.py @@ -3,21 +3,8 @@ # --------------------------------------------------------- import datetime -import json -import logging import typing -from google.protobuf.json_format import MessageToJson -from opentelemetry.proto.trace.v1.trace_pb2 import Span as PBSpan -from opentelemetry.trace.span import format_span_id, format_trace_id - -from promptflow._constants import ( - SpanContextFieldName, - SpanEventFieldName, - SpanFieldName, - SpanLinkFieldName, - SpanStatusFieldName, -) from promptflow._sdk._constants import TRACE_DEFAULT_COLLECTION, TRACE_LIST_DEFAULT_LIMIT from promptflow._sdk._orm.retry import sqlite_retry from promptflow._sdk._orm.session import trace_mgmt_db_session @@ -25,12 +12,7 @@ from promptflow._sdk._orm.trace import LineRun as ORMLineRun from promptflow._sdk._orm.trace import Span as ORMSpan from promptflow._sdk._telemetry import ActivityType, monitor_operation -from promptflow._sdk._tracing_utils import append_conditions -from promptflow._sdk._utils import ( - convert_time_unix_nano_to_timestamp, - flatten_pb_attributes, - parse_otel_span_status_code, -) +from promptflow._sdk._utils.tracing import append_conditions from promptflow._sdk.entities._trace import Event, LineRun, Span from promptflow._utils.logger_utils import get_cli_sdk_logger from promptflow.exceptions import UserErrorException @@ -40,104 +22,6 @@ class TraceOperations: def __init__(self): self._logger = get_cli_sdk_logger() - def _parse_protobuf_events(obj: typing.List[PBSpan.Event], logger: logging.Logger) -> typing.List[typing.Dict]: - events = [] - if len(obj) == 0: - logger.debug("No events found in span") - return events - for pb_event in obj: - event_dict: dict = json.loads(MessageToJson(pb_event)) - logger.debug("Received event: %s", json.dumps(event_dict)) - event = { - SpanEventFieldName.NAME: pb_event.name, - # .isoformat() here to make this dumpable to JSON - SpanEventFieldName.TIMESTAMP: convert_time_unix_nano_to_timestamp(pb_event.time_unix_nano).isoformat(), - SpanEventFieldName.ATTRIBUTES: flatten_pb_attributes( - event_dict.get(SpanEventFieldName.ATTRIBUTES, dict()) - ), - } - events.append(event) - return events - - @staticmethod - def _parse_protobuf_links(obj: typing.List[PBSpan.Link], logger: logging.Logger) -> typing.List[typing.Dict]: - links = [] - if len(obj) == 0: - logger.debug("No links found in span") - return links - for pb_link in obj: - link_dict: dict = json.loads(MessageToJson(pb_link)) - logger.debug("Received link: %s", json.dumps(link_dict)) - link = { - SpanLinkFieldName.CONTEXT: { - SpanContextFieldName.TRACE_ID: TraceOperations.format_trace_id(pb_link.trace_id), - SpanContextFieldName.SPAN_ID: TraceOperations.format_span_id(pb_link.span_id), - SpanContextFieldName.TRACE_STATE: pb_link.trace_state, - }, - SpanLinkFieldName.ATTRIBUTES: flatten_pb_attributes( - link_dict.get(SpanLinkFieldName.ATTRIBUTES, dict()) - ), - } - links.append(link) - return links - - @staticmethod - def format_span_id(span_id: bytes) -> str: - """Format span id to hex string. - Note that we need to add 0x since it is how opentelemetry-sdk does. - Reference: https://github.com/open-telemetry/opentelemetry-python/blob/ - 642f8dd18eea2737b4f8cd2f6f4d08a7e569c4b2/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L505 - """ - return f"0x{format_span_id(int.from_bytes(span_id, byteorder='big', signed=False))}" - - @staticmethod - def format_trace_id(trace_id: bytes) -> str: - """Format trace_id id to hex string. - Note that we need to add 0x since it is how opentelemetry-sdk does. - Reference: https://github.com/open-telemetry/opentelemetry-python/blob/ - 642f8dd18eea2737b4f8cd2f6f4d08a7e569c4b2/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L505 - """ - return f"0x{format_trace_id(int.from_bytes(trace_id, byteorder='big', signed=False))}" - - @staticmethod - def _parse_protobuf_span(span: PBSpan, resource: typing.Dict, logger: logging.Logger) -> Span: - # Open Telemetry does not provide official way to parse Protocol Buffer Span object - # so we need to parse it manually relying on `MessageToJson` - # reference: https://github.com/open-telemetry/opentelemetry-python/issues/3700#issuecomment-2010704554 - span_dict: dict = json.loads(MessageToJson(span)) - logger.debug("Received span: %s, resource: %s", json.dumps(span_dict), json.dumps(resource)) - span_id = TraceOperations.format_span_id(span.span_id) - trace_id = TraceOperations.format_trace_id(span.trace_id) - parent_id = TraceOperations.format_span_id(span.parent_span_id) if span.parent_span_id else None - # we have observed in some scenarios, there is not `attributes` field - attributes = flatten_pb_attributes(span_dict.get(SpanFieldName.ATTRIBUTES, dict())) - logger.debug("Parsed attributes: %s", json.dumps(attributes)) - links = TraceOperations._parse_protobuf_links(span.links, logger) - events = TraceOperations._parse_protobuf_events(span.events, logger) - - return Span( - trace_id=trace_id, - span_id=span_id, - name=span.name, - context={ - SpanContextFieldName.TRACE_ID: trace_id, - SpanContextFieldName.SPAN_ID: span_id, - SpanContextFieldName.TRACE_STATE: span.trace_state, - }, - kind=span.kind, - parent_id=parent_id if parent_id else None, - start_time=convert_time_unix_nano_to_timestamp(span.start_time_unix_nano), - end_time=convert_time_unix_nano_to_timestamp(span.end_time_unix_nano), - status={ - SpanStatusFieldName.STATUS_CODE: parse_otel_span_status_code(span.status.code), - SpanStatusFieldName.DESCRIPTION: span.status.message, - }, - attributes=attributes, - links=links, - events=events, - resource=resource, - ) - def get_event(self, event_id: str) -> typing.Dict: return Event.get(event_id=event_id) diff --git a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py index be0e213f4a4..53c77bc7311 100644 --- a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py +++ b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py @@ -33,7 +33,8 @@ from promptflow._sdk._load_functions import load_flow, load_run from promptflow._sdk._orchestrator.utils import SubmitterHelper from promptflow._sdk._run_functions import create_yaml_run -from promptflow._sdk._utils import _get_additional_includes, parse_otel_span_status_code +from promptflow._sdk._utils import _get_additional_includes +from promptflow._sdk._utils.tracing import _parse_otel_span_status_code from promptflow._sdk.entities import Run from promptflow._sdk.operations._local_storage_operations import LocalStorageOperations from promptflow._utils.context_utils import _change_working_dir, inject_sys_path @@ -1409,7 +1410,7 @@ def test_flex_flow_with_local_imported_func(self, pf): def test_flex_flow_with_imported_func(self, pf): # run eager flow against a function from module run = pf.run( - flow=parse_otel_span_status_code, + flow=_parse_otel_span_status_code, data=f"{DATAS_DIR}/simple_eager_flow_data.jsonl", # set code folder to avoid snapshot too big code=f"{EAGER_FLOWS_DIR}/multiple_entries", diff --git a/src/promptflow-devkit/tests/sdk_cli_test/unittests/test_trace.py b/src/promptflow-devkit/tests/sdk_cli_test/unittests/test_trace.py index 0f8c6577e45..0ab655fdcfe 100644 --- a/src/promptflow-devkit/tests/sdk_cli_test/unittests/test_trace.py +++ b/src/promptflow-devkit/tests/sdk_cli_test/unittests/test_trace.py @@ -33,8 +33,7 @@ ContextAttributeKey, ) from promptflow._sdk._tracing import start_trace_with_devkit -from promptflow._sdk._tracing_utils import WorkspaceKindLocalCache, append_conditions -from promptflow._sdk.operations._trace_operations import TraceOperations +from promptflow._sdk._utils.tracing import WorkspaceKindLocalCache, append_conditions, parse_protobuf_span from promptflow.client import PFClient from promptflow.exceptions import UserErrorException from promptflow.tracing._operation_context import OperationContext @@ -150,7 +149,7 @@ def test_trace_without_attributes_collection(self, mock_resource: Dict) -> None: pb_span.parent_span_id = base64.b64decode("C+++WS+OuxI=") pb_span.kind = PBSpan.SpanKind.SPAN_KIND_INTERNAL # below line should execute successfully - span = TraceOperations._parse_protobuf_span(pb_span, resource=mock_resource, logger=logging.getLogger(__name__)) + span = parse_protobuf_span(pb_span, resource=mock_resource, logger=logging.getLogger(__name__)) # as the above span do not have any attributes, so the parsed span should not have any attributes assert isinstance(span.attributes, dict) assert len(span.attributes) == 0 @@ -265,7 +264,7 @@ def test_no_cache(self): # mock `WorkspaceKindLocalCache._get_workspace_kind_from_azure` mock_kind = str(uuid.uuid4()) with patch( - "promptflow._sdk._tracing_utils.WorkspaceKindLocalCache._get_workspace_kind_from_azure" + "promptflow._sdk._utils.tracing.WorkspaceKindLocalCache._get_workspace_kind_from_azure" ) as mock_get_kind: mock_get_kind.return_value = mock_kind assert ws_local_cache.get_kind() == mock_kind @@ -306,7 +305,7 @@ def test_expired_cache(self): # mock `WorkspaceKindLocalCache._get_workspace_kind_from_azure` kind = str(uuid.uuid4()) with patch( - "promptflow._sdk._tracing_utils.WorkspaceKindLocalCache._get_workspace_kind_from_azure" + "promptflow._sdk._utils.tracing.WorkspaceKindLocalCache._get_workspace_kind_from_azure" ) as mock_get_kind: mock_get_kind.return_value = kind assert ws_local_cache.get_kind() == kind From 600d0bfee9f6a3236ca0fd26aa0e68b6b551b6a4 Mon Sep 17 00:00:00 2001 From: zhen Date: Thu, 25 Apr 2024 18:07:36 +0800 Subject: [PATCH 08/12] [changelog] Add prompty to changelog (#3003) # Description Please add an informative description that covers that changes made by the pull request and link all relevant issues. # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --- src/promptflow-core/CHANGELOG.md | 5 +++++ src/promptflow-devkit/CHANGELOG.md | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/promptflow-core/CHANGELOG.md b/src/promptflow-core/CHANGELOG.md index 5d5c9c645f4..b5762a04501 100644 --- a/src/promptflow-core/CHANGELOG.md +++ b/src/promptflow-core/CHANGELOG.md @@ -1,6 +1,11 @@ # promptflow-core package ## v1.10.0 (Upcoming) + +### Features Added +- Add prompty feature to simplify the development of prompt templates for customers, reach [here](https://microsoft.github.io/promptflow/how-to-guides/develop-a-prompty/index.html) for more details. + +### Others - Add fastapi serving engine support. ## v1.9.0 (2024.04.17) diff --git a/src/promptflow-devkit/CHANGELOG.md b/src/promptflow-devkit/CHANGELOG.md index 465076bc662..1f2f0da1275 100644 --- a/src/promptflow-devkit/CHANGELOG.md +++ b/src/promptflow-devkit/CHANGELOG.md @@ -7,6 +7,8 @@ - The `pf config set ` support set the folder where the config is saved by `--path config_folder` parameter, and the config will take effect when **os.getcwd** is a subdirectory of the specified folder. - Local serving container support using fastapi engine and tuning worker/thread num via environment variables, reach [here](https://microsoft.github.io/promptflow/how-to-guides/deploy-a-flow/deploy-using-docker.html) for more details. +- Prompty supports to flow test and batch run, reach [here](https://microsoft.github.io/promptflow/how-to-guides/develop-a-prompty/index.html#testing-prompty) for more details. + ## v1.9.0 (2024.04.17) From 6399905a0f4073e222d5b3c4a9c6707be649681f Mon Sep 17 00:00:00 2001 From: Honglin Date: Thu, 25 Apr 2024 18:39:23 +0800 Subject: [PATCH 09/12] [SDK/CLI] Write instance_results.jsonl path in run properties (#3014) # Description Please add an informative description that covers that changes made by the pull request and link all relevant issues. # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --- .../e2etests/test_run_upload.py | 27 +++++-------------- .../promptflow/_sdk/_constants.py | 2 +- .../promptflow/_sdk/entities/_run.py | 6 ++++- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py index 699517ea992..74600c144a9 100644 --- a/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py +++ b/src/promptflow-azure/tests/sdk_cli_azure_test/e2etests/test_run_upload.py @@ -51,6 +51,7 @@ def check_local_to_cloud_run(pf: PFClient, run: Run, check_run_details_in_cloud: assert cloud_run.properties["azureml.promptflow.local_to_cloud"] == "true" assert cloud_run.properties["azureml.promptflow.snapshot_id"] assert cloud_run.properties[Local2CloudProperties.TOTAL_TOKENS] + assert cloud_run.properties[Local2CloudProperties.EVAL_ARTIFACTS] # if no description or tags, skip the check, since one could be {} but the other is None if run.description: @@ -74,12 +75,12 @@ def check_local_to_cloud_run(pf: PFClient, run: Run, check_run_details_in_cloud: "mock_set_headers_with_user_aml_token", "single_worker_thread_pool", "vcr_recording", + "mock_isinstance_for_mock_datastore", + "mock_get_azure_pf_client", + "mock_trace_destination_to_cloud", ) class TestFlowRunUpload: @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_run( self, pf: PFClient, @@ -103,9 +104,6 @@ def test_upload_run( Local2CloudTestHelper.check_local_to_cloud_run(pf, run, check_run_details_in_cloud=True) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_flex_flow_run_with_yaml(self, pf: PFClient, randstr: Callable[[str], str]): name = randstr("flex_run_name_with_yaml_for_upload") local_pf = Local2CloudTestHelper.get_local_pf(name) @@ -125,9 +123,6 @@ def test_upload_flex_flow_run_with_yaml(self, pf: PFClient, randstr: Callable[[s Local2CloudTestHelper.check_local_to_cloud_run(pf, run) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_flex_flow_run_without_yaml(self, pf: PFClient, randstr: Callable[[str], str]): name = randstr("flex_run_name_without_yaml_for_upload") local_pf = Local2CloudTestHelper.get_local_pf(name) @@ -148,9 +143,6 @@ def test_upload_flex_flow_run_without_yaml(self, pf: PFClient, randstr: Callable Local2CloudTestHelper.check_local_to_cloud_run(pf, run) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_prompty_run(self, pf: PFClient, randstr: Callable[[str], str]): # currently prompty run is skipped for upload, this test should be finished without error name = randstr("prompty_run_name_for_upload") @@ -167,9 +159,6 @@ def test_upload_prompty_run(self, pf: PFClient, randstr: Callable[[str], str]): Local2CloudTestHelper.check_local_to_cloud_run(pf, run) @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_run_with_customized_run_properties(self, pf: PFClient, randstr: Callable[[str], str]): name = randstr("batch_run_name_for_upload_with_customized_properties") local_pf = Local2CloudTestHelper.get_local_pf(name) @@ -200,9 +189,6 @@ def test_upload_run_with_customized_run_properties(self, pf: PFClient, randstr: assert cloud_run.properties[Local2CloudUserProperties.EVAL_ARTIFACTS] == eval_artifacts @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures( - "mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client", "mock_trace_destination_to_cloud" - ) def test_upload_eval_run(self, pf: PFClient, randstr: Callable[[str], str]): main_run_name = randstr("main_run_name_for_test_upload_eval_run") local_pf = Local2CloudTestHelper.get_local_pf(main_run_name) @@ -216,8 +202,8 @@ def test_upload_eval_run(self, pf: PFClient, randstr: Callable[[str], str]): # run an evaluation run eval_run_name = randstr("eval_run_name_for_test_upload_eval_run") - local_lpf = Local2CloudTestHelper.get_local_pf(eval_run_name) - eval_run = local_lpf.run( + local_pf = Local2CloudTestHelper.get_local_pf(eval_run_name) + eval_run = local_pf.run( flow=f"{FLOWS_DIR}/simple_hello_world", data=f"{DATAS_DIR}/webClassification3.jsonl", run=main_run_name, @@ -229,7 +215,6 @@ def test_upload_eval_run(self, pf: PFClient, randstr: Callable[[str], str]): assert eval_run.properties["azureml.promptflow.variant_run_id"] == main_run_name @pytest.mark.skipif(condition=not pytest.is_live, reason="Bug - 3089145 Replay failed for test 'test_upload_run'") - @pytest.mark.usefixtures("mock_isinstance_for_mock_datastore", "mock_get_azure_pf_client") def test_upload_flex_flow_run_with_global_azureml(self, pf: PFClient, randstr: Callable[[str], str]): with patch("promptflow._sdk._configuration.Configuration.get_config", return_value="azureml"): name = randstr("flex_run_name_with_global_azureml_for_upload") diff --git a/src/promptflow-devkit/promptflow/_sdk/_constants.py b/src/promptflow-devkit/promptflow/_sdk/_constants.py index f4dc2ec4b24..a90ac6df468 100644 --- a/src/promptflow-devkit/promptflow/_sdk/_constants.py +++ b/src/promptflow-devkit/promptflow/_sdk/_constants.py @@ -483,13 +483,13 @@ class Local2CloudProperties: """Run properties that server needs when uploading local run to cloud.""" TOTAL_TOKENS = "azureml.promptflow.total_tokens" + EVAL_ARTIFACTS = "_azureml.evaluate_artifacts" class Local2CloudUserProperties: """Run properties that user can specify when uploading local run to cloud.""" RUN_TYPE = "runType" - EVAL_ARTIFACTS = "_azureml.evaluate_artifacts" @staticmethod def get_all_values(): diff --git a/src/promptflow-devkit/promptflow/_sdk/entities/_run.py b/src/promptflow-devkit/promptflow/_sdk/entities/_run.py index bb91d25d3ca..ef593597fd4 100644 --- a/src/promptflow-devkit/promptflow/_sdk/entities/_run.py +++ b/src/promptflow-devkit/promptflow/_sdk/entities/_run.py @@ -711,7 +711,11 @@ def _to_rest_object_for_local_to_cloud(self, local_to_cloud_info: dict, variant_ # extract properties that needs to be passed to the request total_tokens = self.properties[FlowRunProperties.SYSTEM_METRICS].get("total_tokens", 0) - properties = {Local2CloudProperties.TOTAL_TOKENS: total_tokens} + properties = { + Local2CloudProperties.TOTAL_TOKENS: total_tokens, + # add instance_results.jsonl path to run properties, which is required by UI feature. + Local2CloudProperties.EVAL_ARTIFACTS: '[{"path": "instance_results.jsonl", "type": "table"}]', + } for property_key in Local2CloudUserProperties.get_all_values(): value = self.properties.get(property_key, None) if value is not None: From b4c9f37999d05d833806d59de26bb263b8a8b220 Mon Sep 17 00:00:00 2001 From: chjinche <49483542+chjinche@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:08:32 +0800 Subject: [PATCH 10/12] [Bugfix] Support parsing chat prompt if role property has \r around colon (#3007) # Description ## Issue: UX may add extra '\r' to user input, which may throw confusing error to user because user does not write '\r' explicitly. - user input ![image](https://github.com/microsoft/promptflow/assets/49483542/727be9b3-a8d5-42fc-ab98-592816f85f91) - ux adding extra '\r' ![image](https://github.com/microsoft/promptflow/assets/49483542/2628a0d5-2cec-4bd1-a4ef-8149f05db51d) - confusing error ![image](https://github.com/microsoft/promptflow/assets/49483542/27bab56a-e318-47ae-b377-842061e4928d) ## Solution: Handling '\r' around role property colon. The same way as '\r' around role colon. # All Promptflow Contribution checklist: - [X] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [X] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [X] Title of the pull request is clear and informative. - [X] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [X] Pull request includes test coverage for the included changes. --- .../promptflow/tools/common.py | 4 +-- src/promptflow-tools/tests/test_common.py | 27 ++++++++++++++++++- .../tests/test_handle_openai_error.py | 1 + 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/promptflow-tools/promptflow/tools/common.py b/src/promptflow-tools/promptflow/tools/common.py index f957f55f6f6..1737c114328 100644 --- a/src/promptflow-tools/promptflow/tools/common.py +++ b/src/promptflow-tools/promptflow/tools/common.py @@ -222,7 +222,7 @@ def validate_tools(tools): def try_parse_name_and_content(role_prompt): # customer can add ## in front of name/content for markdown highlight. # and we still support name/content without ## prefix for backward compatibility. - pattern = r"\n*#{0,2}\s*name:\n+\s*(\S+)\s*\n*#{0,2}\s*content:\n?(.*)" + pattern = r"\n*#{0,2}\s*name\s*:\s*\n+\s*(\S+)\s*\n*#{0,2}\s*content\s*:\s*\n?(.*)" match = re.search(pattern, role_prompt, re.DOTALL) if match: return match.group(1), match.group(2) @@ -232,7 +232,7 @@ def try_parse_name_and_content(role_prompt): def try_parse_tool_call_id_and_content(role_prompt): # customer can add ## in front of tool_call_id/content for markdown highlight. # and we still support tool_call_id/content without ## prefix for backward compatibility. - pattern = r"\n*#{0,2}\s*tool_call_id:\n+\s*(\S+)\s*\n*#{0,2}\s*content:\n?(.*)" + pattern = r"\n*#{0,2}\s*tool_call_id\s*:\s*\n+\s*(\S+)\s*\n*#{0,2}\s*content\s*:\s*\n?(.*)" match = re.search(pattern, role_prompt, re.DOTALL) if match: return match.group(1), match.group(2) diff --git a/src/promptflow-tools/tests/test_common.py b/src/promptflow-tools/tests/test_common.py index 78f30790b0c..97373babdaa 100644 --- a/src/promptflow-tools/tests/test_common.py +++ b/src/promptflow-tools/tests/test_common.py @@ -214,7 +214,10 @@ def test_success_parse_role_prompt(self, chat_str, images, image_detail, expecte ("\nsystem:\nname:\n\n content:\nfirst", [ {'role': 'system', 'content': 'name:\n\n content:\nfirst'}]), ("\nsystem:\nname:\n\n", [ - {'role': 'system', 'content': 'name:'}]) + {'role': 'system', 'content': 'name:'}]), + # portal may add extra \r to new line character. + ("function:\r\nname:\r\n AI\ncontent :\r\nfirst", [ + {'role': 'function', 'name': 'AI', 'content': 'first'}]), ], ) def test_parse_chat_with_name_in_role_prompt(self, chat_str, expected_result): @@ -240,6 +243,20 @@ def test_try_parse_chat_with_tools(self, example_prompt_template_with_tool, pars actual_result = parse_chat(example_prompt_template_with_tool) assert actual_result == parsed_chat_with_tools + @pytest.mark.parametrize( + "chat_str, expected_result", + [ + ("\n#tool:\n## tool_call_id:\nid \n content:\nfirst\n\n#user:\nsecond", [ + {'role': 'tool', 'tool_call_id': 'id', 'content': 'first'}, {'role': 'user', 'content': 'second'}]), + # portal may add extra \r to new line character. + ("\ntool:\ntool_call_id :\r\nid\n content:\r\n", [ + {'role': 'tool', 'tool_call_id': 'id', 'content': ''}]), + ], + ) + def test_parse_tool_call_id_and_content(self, chat_str, expected_result): + actual_result = parse_chat(chat_str) + assert actual_result == expected_result + @pytest.mark.parametrize("chunk, error_msg, success", [ (""" ## tool_calls: @@ -275,6 +292,14 @@ def test_try_parse_chat_with_tools(self, example_prompt_template_with_tool, pars "function": {"name": "func1", "arguments": ""} }] """, "", True), + # portal may add extra \r to new line character. + (""" + ## tool_calls:\r + [{ + "id": "tool_call_id", "type": "function", + "function": {"name": "func1", "arguments": ""} + }] + """, "", True), ]) def test_parse_tool_calls_for_assistant(self, chunk: str, error_msg: str, success: bool): last_message = {'role': 'assistant'} diff --git a/src/promptflow-tools/tests/test_handle_openai_error.py b/src/promptflow-tools/tests/test_handle_openai_error.py index 686a2c7a8a2..cfad9281161 100644 --- a/src/promptflow-tools/tests/test_handle_openai_error.py +++ b/src/promptflow-tools/tests/test_handle_openai_error.py @@ -261,6 +261,7 @@ def test_input_invalid_function_role_prompt(self, azure_open_ai_connection): ) assert "'name' is required if role is function," in exc_info.value.message + @pytest.mark.skip(reason="Skip temporarily because there is something issue with test AOAI resource response.") def test_completion_with_chat_model(self, azure_open_ai_connection): with pytest.raises(UserErrorException) as exc_info: completion(connection=azure_open_ai_connection, prompt="hello", deployment_name="gpt-35-turbo") From 40c054d56c1ecf3dde841f8f047f49d2f385a66a Mon Sep 17 00:00:00 2001 From: Xingzhi Zhang <37076709+elliotzh@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:32:41 +0800 Subject: [PATCH 11/12] hotfix: extra string at the beginning of yaml in snapshot (#3006) # Description Fix a bug that !!omap tag will generated at the beginning of `flow.flex.yaml` in snapshot and break local to cloud # All Promptflow Contribution checklist: - [x] **The pull request does not introduce [breaking changes].** - [x] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [x] Title of the pull request is clear and informative. - [x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [x] Pull request includes test coverage for the included changes. --- .cspell.json | 5 ++- .../promptflow/_utils/flow_utils.py | 5 ++- .../promptflow/_utils/utils.py | 45 +++++++++++++++++++ .../sdk_cli_test/e2etests/test_flow_run.py | 2 + 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/.cspell.json b/.cspell.json index 1d97d3c469d..b13c4312bc2 100644 --- a/.cspell.json +++ b/.cspell.json @@ -217,10 +217,11 @@ "dcid", "piezo", "Piezo", - "cmpop" + "cmpop", + "omap" ], "flagWords": [ "Prompt Flow" ], "allowCompoundWords": true -} \ No newline at end of file +} diff --git a/src/promptflow-core/promptflow/_utils/flow_utils.py b/src/promptflow-core/promptflow/_utils/flow_utils.py index 0962a675de8..58fb7839edc 100644 --- a/src/promptflow-core/promptflow/_utils/flow_utils.py +++ b/src/promptflow-core/promptflow/_utils/flow_utils.py @@ -21,7 +21,7 @@ ) from promptflow._core._errors import MetaFileNotFound, MetaFileReadError from promptflow._utils.logger_utils import LoggerFactory -from promptflow._utils.utils import strip_quotation +from promptflow._utils.utils import convert_ordered_dict_to_dict, strip_quotation from promptflow._utils.yaml_utils import dump_yaml, load_yaml from promptflow.contracts.flow import Flow as ExecutableFlow from promptflow.exceptions import ErrorTarget, UserErrorException, ValidationException @@ -157,7 +157,8 @@ def dump_flow_dag(flow_dag: dict, flow_path: Path): flow_dir, flow_filename = resolve_flow_path(flow_path, check_flow_exist=False) flow_path = flow_dir / flow_filename with open(flow_path, "w", encoding=DEFAULT_ENCODING) as f: - dump_yaml(flow_dag, f) + # directly dumping ordered dict will bring !!omap tag in yaml + dump_yaml(convert_ordered_dict_to_dict(flow_dag, remove_empty=False), f) return flow_path diff --git a/src/promptflow-core/promptflow/_utils/utils.py b/src/promptflow-core/promptflow/_utils/utils.py index 7af01b61774..26f52e3fabd 100644 --- a/src/promptflow-core/promptflow/_utils/utils.py +++ b/src/promptflow-core/promptflow/_utils/utils.py @@ -434,3 +434,48 @@ def strip_quotation(value): return value[1:-1] else: return value + + +def is_empty_target(obj: Optional[Dict]) -> bool: + """Determines if it's empty target + + :param obj: The object to check + :type obj: Optional[Dict] + :return: True if obj is None or an empty Dict + :rtype: bool + """ + return ( + obj is None + # some objs have overloaded "==" and will cause error. e.g CommandComponent obj + or (isinstance(obj, dict) and len(obj) == 0) + ) + + +def convert_ordered_dict_to_dict(target_object: Union[Dict, List], remove_empty: bool = True) -> Union[Dict, List]: + """Convert ordered dict to dict. Remove keys with None value. + This is a workaround for rest request must be in dict instead of + ordered dict. + + :param target_object: The object to convert + :type target_object: Union[Dict, List] + :param remove_empty: Whether to omit values that are None or empty dictionaries. Defaults to True. + :type remove_empty: bool + :return: Converted ordered dict with removed None values + :rtype: Union[Dict, List] + """ + # OrderedDict can appear nested in a list + if isinstance(target_object, list): + new_list = [] + for item in target_object: + item = convert_ordered_dict_to_dict(item, remove_empty=remove_empty) + if not is_empty_target(item) or not remove_empty: + new_list.append(item) + return new_list + if isinstance(target_object, dict): + new_dict = {} + for key, value in target_object.items(): + value = convert_ordered_dict_to_dict(value, remove_empty=remove_empty) + if not is_empty_target(value) or not remove_empty: + new_dict[key] = value + return new_dict + return target_object diff --git a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py index 53c77bc7311..3539d113d0f 100644 --- a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py +++ b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_flow_run.py @@ -1376,6 +1376,8 @@ def test_flex_flow_run( yaml_dict = load_yaml(local_storage._dag_path) assert yaml_dict == expected_snapshot_yaml + assert not local_storage._dag_path.read_text().startswith("!!omap") + # actual result will be entry2:my_flow2 details = pf.get_details(run.name) # convert DataFrame to dict From 935176fa65b9959deeda44d0f3fffa0900503652 Mon Sep 17 00:00:00 2001 From: Xingzhi Zhang <37076709+elliotzh@users.noreply.github.com> Date: Thu, 25 Apr 2024 20:07:11 +0800 Subject: [PATCH 12/12] fix: csharp executor proxy ci failure (#3018) # Description fix 2 test on Windows: promptflow-devkit/tests/sdk_cli_test/e2etests/test_csharp_sdk.py - test_destroy_with_terminates_gracefully - test_destroy_with_force_kill # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --- .../tests/sdk_cli_test/e2etests/test_csharp_sdk.py | 8 ++++++-- .../unittests/batch/test_csharp_executor_proxy.py | 12 ++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_csharp_sdk.py b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_csharp_sdk.py index 0d66d21bd2e..0261997a2df 100644 --- a/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_csharp_sdk.py +++ b/src/promptflow-devkit/tests/sdk_cli_test/e2etests/test_csharp_sdk.py @@ -31,7 +31,11 @@ class TestCSharpSdk: "language": {"default": "chinese", "type": "string"}, "topic": {"default": "ocean", "type": "string"}, }, - "outputs": {"output": {"type": "object"}}, + "outputs": { + "Answer": {"type": "string"}, + "AnswerLength": {"type": "int"}, + "PoemLanguage": {"type": "string"}, + }, }, id="function_mode_basic", ), @@ -39,7 +43,7 @@ class TestCSharpSdk: { "init": {"connection": {"type": "AzureOpenAIConnection"}, "name": {"type": "string"}}, "inputs": {"question": {"default": "What is Promptflow?", "type": "string"}}, - "outputs": {"output": {"type": "object"}}, + "outputs": {"output": {"type": "string"}}, }, id="class_init_flex_flow", ), diff --git a/src/promptflow/tests/executor/unittests/batch/test_csharp_executor_proxy.py b/src/promptflow/tests/executor/unittests/batch/test_csharp_executor_proxy.py index dcc22683270..0e36f198ca0 100644 --- a/src/promptflow/tests/executor/unittests/batch/test_csharp_executor_proxy.py +++ b/src/promptflow/tests/executor/unittests/batch/test_csharp_executor_proxy.py @@ -1,4 +1,6 @@ import json +import platform +import signal import socket import subprocess from pathlib import Path @@ -62,7 +64,10 @@ async def test_destroy_with_terminates_gracefully(self): await executor_proxy.destroy() mock_process.poll.assert_called_once() - mock_process.terminate.assert_called_once() + if platform.system() != "Windows": + mock_process.terminate.assert_called_once() + else: + mock_process.send_signal.assert_called_once_with(signal.CTRL_BREAK_EVENT) mock_process.wait.assert_called_once_with(timeout=5) mock_process.kill.assert_not_called() @@ -77,7 +82,10 @@ async def test_destroy_with_force_kill(self): await executor_proxy.destroy() mock_process.poll.assert_called_once() - mock_process.terminate.assert_called_once() + if platform.system() != "Windows": + mock_process.terminate.assert_called_once() + else: + mock_process.send_signal.assert_called_once_with(signal.CTRL_BREAK_EVENT) mock_process.wait.assert_called_once_with(timeout=5) mock_process.kill.assert_called_once()