From 449d67998945bf9ecc3e698cb37114cced8407d9 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Thu, 7 Dec 2023 12:45:33 +0800 Subject: [PATCH] [Sample] Create CI for sample service (#1334) This pull request includes various updates to documentation files and workflow files for improved organization and triggering conditions. The most important changes include renaming and updating the content of a readme file, updating triggering conditions for multiple workflow files, and adding a new workflow file for running daily and on pull requests. Documentation updates: * `examples/tutorials/flow-deploy/create-service-with-flow/README.md`: Renamed `readme.md` to `README.md` and updated its content to include instructions on starting the service and testing it with a request. * `examples/README.md`: Added a new entry for the `create-service-with-flow` example, including a badge for the workflow and a brief description. Workflow updates: * `.github/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml`: Added a new workflow file that runs daily and on pull requests, with various steps including generating config files, setting up environments, running scripts, and uploading artifacts. * `.github/workflows/samples_tutorials_flow_deploy_kubernetes.yml`: Updated triggering conditions to include the `examples/flows/integrations/**` path on pull requests. * `.github/workflows/samples_tutorials_flow_deploy_distribute_flow_as_executable_app.yml`: Updated workflow file to remove the exclusion of the `examples/flows/integrations/**` path from triggering the workflow on pull requests. * `.github/workflows/samples_tutorials_e2e_development_chat_with_pdf.yml`: Updated triggering conditions to remove the exclusion of the `examples/flows/integrations/**` path from triggering the workflow on pull requests. * `.github/workflows/samples_configuration.yml`: Updated triggering conditions to remove the exclusion of `examples/flows/integrations/**` and add an exclusion for files ending with `requirements.txt`. * `.github/workflows/samples_tutorials_flow_deploy_azure_app_service.yml`: Updated triggering conditions to remove the exclusion of the `examples/flows/integrations/**` path. * `.github/workflows/samples_tutorials_flow_deploy_docker.yml`: Updated triggering conditions to remove the exclusion of the `examples/flows/integrations/**` path from triggering the workflow on pull requests. * `.github/workflows/samples_tutorials_flow_fine_tuning_evaluation_promptflow_quality_improvement.yml`: Updated triggering conditions to remove the exclusion of the `examples/flows/integrations/**` path from triggering the workflow on pull requests.# 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. --- .cspell.json | 1 + ...s_flow_deploy_create_service_with_flow.yml | 96 +++++++++++++++++++ examples/README.md | 3 +- examples/dev_requirements.txt | 2 +- .../create-service-with-flow/README.md | 38 ++++++++ .../create-service-with-flow/readme.md | 12 --- .../readme/ghactions_driver/readme_step.py | 15 ++- 7 files changed, 148 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml create mode 100644 examples/tutorials/flow-deploy/create-service-with-flow/README.md delete mode 100644 examples/tutorials/flow-deploy/create-service-with-flow/readme.md diff --git a/.cspell.json b/.cspell.json index c16170d0e7e..3f29fa0bd3a 100644 --- a/.cspell.json +++ b/.cspell.json @@ -154,6 +154,7 @@ "restx", "httpx", "tiiuae", + "nohup", "metagenai" ], "flagWords": [ diff --git a/.github/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml b/.github/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml new file mode 100644 index 00000000000..2e9fc02748a --- /dev/null +++ b/.github/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml @@ -0,0 +1,96 @@ +# This code is autogenerated. +# Code is generated by running custom script: python3 readme.py +# Any manual changes to this file may cause incorrect behavior. +# Any manual changes will be overwritten if the code is regenerated. + +name: samples_tutorials_flow_deploy_create_service_with_flow +on: + schedule: + - cron: "49 22 * * *" # Every day starting at 6:49 BJT + pull_request: + branches: [ main ] + paths: [ examples/**, .github/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml ] + workflow_dispatch: + +env: + IS_IN_CI_PIPELINE: "true" + +jobs: + samples_readme_ci: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Python 3.9 environment + uses: actions/setup-python@v4 + with: + python-version: "3.9" + - name: Generate config.json for canary workspace (scheduled runs only) + if: github.event_name == 'schedule' + run: echo '${{ secrets.TEST_WORKSPACE_CONFIG_JSON_CANARY }}' > ${{ github.workspace }}/examples/config.json + - name: Generate config.json for production workspace + if: github.event_name != 'schedule' + run: echo '${{ secrets.EXAMPLE_WORKSPACE_CONFIG_JSON_PROD }}' > ${{ github.workspace }}/examples/config.json + - name: Prepare requirements + working-directory: examples + run: | + if [[ -e requirements.txt ]]; then + python -m pip install --upgrade pip + pip install -r requirements.txt + fi + - name: Prepare dev requirements + working-directory: examples + run: | + python -m pip install --upgrade pip + pip install -r dev_requirements.txt + - name: Refine .env file + working-directory: examples/tutorials/flow-deploy/create-service-with-flow + run: | + AOAI_API_KEY=${{ secrets.AOAI_API_KEY_TEST }} + AOAI_API_ENDPOINT=${{ secrets.AOAI_API_ENDPOINT_TEST }} + AOAI_API_ENDPOINT=$(echo ${AOAI_API_ENDPOINT//\//\\/}) + if [[ -e .env.example ]]; then + echo "env replacement" + sed -i -e "s//$AOAI_API_KEY/g" -e "s//$AOAI_API_ENDPOINT/g" .env.example + mv .env.example .env + fi + - name: Create run.yml + working-directory: examples/tutorials/flow-deploy/create-service-with-flow + run: | + gpt_base=${{ secrets.AOAI_API_ENDPOINT_TEST }} + gpt_base=$(echo ${gpt_base//\//\\/}) + if [[ -e run.yml ]]; then + sed -i -e "s/\${azure_open_ai_connection.api_key}/${{ secrets.AOAI_API_KEY_TEST }}/g" -e "s/\${azure_open_ai_connection.api_base}/$gpt_base/g" run.yml + fi + - name: Azure Login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Extract Steps examples/tutorials/flow-deploy/create-service-with-flow/README.md + working-directory: ${{ github.workspace }} + run: | + python scripts/readme/extract_steps_from_readme.py -f examples/tutorials/flow-deploy/create-service-with-flow/README.md -o examples/tutorials/flow-deploy/create-service-with-flow + - name: Cat script + working-directory: examples/tutorials/flow-deploy/create-service-with-flow + run: | + cat bash_script.sh + - name: Run scripts + working-directory: examples/tutorials/flow-deploy/create-service-with-flow + run: | + export aoai_api_key=${{secrets.AOAI_API_KEY_TEST }} + export aoai_api_endpoint=${{ secrets.AOAI_API_ENDPOINT_TEST }} + export test_workspace_sub_id=${{ secrets.TEST_WORKSPACE_SUB_ID }} + export test_workspace_rg=${{ secrets.TEST_WORKSPACE_RG }} + export test_workspace_name=${{ secrets.TEST_WORKSPACE_NAME_CANARY }} + bash bash_script.sh + - name: Pip List for Debug + if : ${{ always() }} + working-directory: examples/tutorials/flow-deploy/create-service-with-flow + run: | + pip list + - name: Upload artifact + if: ${{ always() }} + uses: actions/upload-artifact@v3 + with: + name: artifact + path: examples/tutorials/flow-deploy/create-service-with-flow/bash_script.sh \ No newline at end of file diff --git a/examples/README.md b/examples/README.md index e7299e2fa95..6780acbc9c2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -28,6 +28,7 @@ ------|--------|------------- | [chat-with-pdf](tutorials/e2e-development/chat-with-pdf.md) | [![samples_tutorials_e2e_development_chat_with_pdf](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_e2e_development_chat_with_pdf.yml/badge.svg?branch=main)](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_e2e_development_chat_with_pdf.yml) | Retrieval Augmented Generation (or RAG) has become a prevalent pattern to build intelligent application with Large Language Models (or LLMs) since it can infuse external knowledge into the model, which is not trained with those up-to-date or proprietary information | | [azure-app-service](tutorials/flow-deploy/azure-app-service/README.md) | [![samples_tutorials_flow_deploy_azure_app_service](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_azure_app_service.yml/badge.svg?branch=main)](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_azure_app_service.yml) | This example demos how to deploy a flow using Azure App Service | +| [create-service-with-flow](tutorials/flow-deploy/create-service-with-flow/README.md) | [![samples_tutorials_flow_deploy_create_service_with_flow](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml/badge.svg?branch=main)](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_create_service_with_flow.yml) | This example shows how to create a simple service with flow | | [distribute-flow-as-executable-app](tutorials/flow-deploy/distribute-flow-as-executable-app/README.md) | [![samples_tutorials_flow_deploy_distribute_flow_as_executable_app](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_distribute_flow_as_executable_app.yml/badge.svg?branch=main)](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_distribute_flow_as_executable_app.yml) | This example demos how to package flow as a executable app | | [docker](tutorials/flow-deploy/docker/README.md) | [![samples_tutorials_flow_deploy_docker](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_docker.yml/badge.svg?branch=main)](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_docker.yml) | This example demos how to deploy flow as a docker app | | [kubernetes](tutorials/flow-deploy/kubernetes/README.md) | [![samples_tutorials_flow_deploy_kubernetes](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_kubernetes.yml/badge.svg?branch=main)](https://github.com/microsoft/promptflow/actions/workflows/samples_tutorials_flow_deploy_kubernetes.yml) | This example demos how to deploy flow as a Kubernetes app | @@ -122,4 +123,4 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope ## Reference -* [Promptflow documentation](https://microsoft.github.io/promptflow/) +* [Promptflow documentation](https://microsoft.github.io/promptflow/) \ No newline at end of file diff --git a/examples/dev_requirements.txt b/examples/dev_requirements.txt index 1c53472949d..727dfa0d0eb 100644 --- a/examples/dev_requirements.txt +++ b/examples/dev_requirements.txt @@ -8,4 +8,4 @@ black-nb pypandoc # for markdown reader pypandoc_binary # pypandoc pandoc backend panflute # for pandoc filters -jinja2 # for readme generations \ No newline at end of file +jinja2 # for readme generations diff --git a/examples/tutorials/flow-deploy/create-service-with-flow/README.md b/examples/tutorials/flow-deploy/create-service-with-flow/README.md new file mode 100644 index 00000000000..24e451b6115 --- /dev/null +++ b/examples/tutorials/flow-deploy/create-service-with-flow/README.md @@ -0,0 +1,38 @@ +# Create service with flow + +This example shows how to create a simple service with flow. + +You can create your own service by utilize `flow-as-function`. + +This folder contains a example on how to build a service with a flow. +Reference [here](./simple_score.py) for a minimal service example. +The output of score.py will be a json serialized dictionary. +You can use json parser to parse the output. + +## 1. Start the service and put in background + +```bash +nohup python simple_score.py & +# Note: added this to run in our CI pipeline, not needed for user. +sleep 10 +``` + +## 2. Test the service with request + +Executing the following command to send a request to execute a flow. + +```bash +curl -X POST http://127.0.0.1:5000/score --header "Content-Type: application/json" --data '{"flow_input": "some_flow_input", "node_input": "some_node_input"}' +``` + +Sample output of the request: + +```json +{ + "output": { + "value": "some_flow_input" + } +} +``` + +Reference [here](./simple_score.py) for more. diff --git a/examples/tutorials/flow-deploy/create-service-with-flow/readme.md b/examples/tutorials/flow-deploy/create-service-with-flow/readme.md deleted file mode 100644 index 151eeedb82d..00000000000 --- a/examples/tutorials/flow-deploy/create-service-with-flow/readme.md +++ /dev/null @@ -1,12 +0,0 @@ -# Create service with flow - -You can create your own service with a flow. -This folder contains a example on how to build a service with a flow. -Reference [here](./simple_score.py) for a minimal service example. -The output of score.py will be a json serialized dictionary. -You can use json parser to parse the output. -For example, in powershell: - -```powershell -curl -X POST http://127.0.0.1:5000/score --header "Content-Type: application/json" --data '{"flow_input": "some_flow_input", "node_input": "some_node_input"}' | ConvertFrom-Json | ConvertTo-Json -``` diff --git a/scripts/readme/ghactions_driver/readme_step.py b/scripts/readme/ghactions_driver/readme_step.py index b13003bda0b..03dbb301c9f 100644 --- a/scripts/readme/ghactions_driver/readme_step.py +++ b/scripts/readme/ghactions_driver/readme_step.py @@ -266,11 +266,16 @@ def git_base_dir() -> str: Get the base directory of the git repo """ if ReadmeStepsManage.repo_base_dir == "": - ReadmeStepsManage.repo_base_dir = ( - subprocess.check_output(["git", "rev-parse", "--show-toplevel"]) - .decode("utf-8") - .strip() - ) + try: + ReadmeStepsManage.repo_base_dir = ( + subprocess.check_output(["git", "rev-parse", "--show-toplevel"]) + .decode("utf-8") + .strip() + ) + raise Exception("Not in git repo") + except Exception: + ReadmeStepsManage.repo_base_dir = Path(__file__).parent.parent.parent.parent.resolve() + print(ReadmeStepsManage.repo_base_dir) return ReadmeStepsManage.repo_base_dir @staticmethod