Skip to content

Commit c8c4f33

Browse files
Nagkumar ArkalgudNagkumar Arkalgud
authored andcommitted
Merge remote-tracking branch 'origin/main'
2 parents 8363637 + 8405014 commit c8c4f33

File tree

205 files changed

+28880
-239
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

205 files changed

+28880
-239
lines changed

.github/CODEOWNERS

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,20 @@
44

55
# Default owner for everything, unless overridden by a more specific rule.
66
* @Azure-Samples/azure-ai-samples-maintainers
7+
8+
9+
#### files referenced in docs (DO NOT EDIT, except for Docs team!!!) ###################
10+
/scenarios/projects/basic/chat-simple.py @azure-samples/AI-Platform-Docs
11+
/scenarios/projects/basic/chat-template.py @azure-samples/AI-Platform-Docs
12+
/scenarios/rag/custom-rag-app/assets/chat_eval_data.jsonl @azure-samples/AI-Platform-Docs
13+
/scenarios/rag/custom-rag-app/assets/grounded_chat.prompty @azure-samples/AI-Platform-Docs
14+
/scenarios/rag/custom-rag-app/assets/intent_mapping.prompty @azure-samples/AI-Platform-Docs
15+
/scenarios/rag/custom-rag-app/assets/products.csv @azure-samples/AI-Platform-Docs
16+
/scenarios/rag/custom-rag-app/chat_with_products.py @azure-samples/AI-Platform-Docs
17+
/scenarios/rag/custom-rag-app/config.py @azure-samples/AI-Platform-Docs
18+
/scenarios/rag/custom-rag-app/create_search_index.py @azure-samples/AI-Platform-Docs
19+
/scenarios/rag/custom-rag-app/evaluate.py @azure-samples/AI-Platform-Docs
20+
/scenarios/rag/custom-rag-app/get_product_documents.py @azure-samples/AI-Platform-Docs
21+
/scenarios/rag/custom-rag-app/requirements.txt @azure-samples/AI-Platform-Docs
22+
/scenarios/langchain/getting-started-with-langchain-chat-models.ipynb @azure-samples/AI-Platform-Docs
23+
/scenarios/langchain/getting-started-with-langchain-embeddings.ipynb @azure-samples/AI-Platform-Docs
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import os
2+
import sys
3+
from pathlib import Path
4+
from azure.cli.core import get_default_cli
5+
from typing import List, Union
6+
7+
8+
def run_az_command(*args: Union[str, Path]) -> None:
9+
"""Runs an Azure CLI command using the Azure CLI Python SDK."""
10+
cli = get_default_cli()
11+
command = list(args)
12+
exit_code = cli.invoke(command)
13+
14+
if exit_code != 0:
15+
print(f"❌ Failed to execute: {' '.join(command)}")
16+
sys.exit(exit_code)
17+
18+
19+
def get_main_bicep_files(modified_files: List[Path]) -> List[Path]:
20+
"""Finds unique folders with modified files and ensures 'main.bicep' exists in each."""
21+
modified_folders = {Path(f).parent for f in modified_files}
22+
return [folder / "main.bicep" for folder in modified_folders if (folder / "main.bicep").exists()]
23+
24+
25+
def build_bicep_file(bicep_file: Path) -> None:
26+
"""Builds a Bicep file using Azure CLI Python SDK and ensures azuredeploy.json is created."""
27+
output_file = bicep_file.with_name("azuredeploy.json")
28+
29+
print(f"🔹 Building Bicep: {bicep_file} -> {output_file}")
30+
os.environ.update({"AZURE_BICEP_USE_BINARY_FROM_PATH": "false", "AZURE_BICEP_CHECK_VERSION": "false"})
31+
32+
# Pin the bicep CLI to minimize pre-commit failures due to modified metadata in files.
33+
run_az_command("bicep", "install", "--version", "v0.33.93")
34+
35+
# Run az bicep build using Azure CLI SDK
36+
run_az_command("bicep", "build", "--file", str(bicep_file), "--outfile", str(output_file))
37+
38+
# Verify if azuredeploy.json was created
39+
if not output_file.exists():
40+
print(f"❌ Build succeeded, but {output_file} was not created!")
41+
sys.exit(1)
42+
43+
print(f"✅ Successfully built: {bicep_file} -> {output_file}")
44+
45+
46+
def main() -> None:
47+
"""Main script execution."""
48+
print("🚀 Running Bicep build using Azure CLI SDK...")
49+
50+
# Get modified Bicep files from pre-commit
51+
modified_files = [Path(f) for f in sys.argv[1:]]
52+
53+
if not modified_files:
54+
print("✅ No modified Bicep files detected. Skipping build.")
55+
sys.exit(0)
56+
57+
# Run Bicep build on each modified file
58+
bicep_files = get_main_bicep_files(modified_files)
59+
60+
for bicep_file in bicep_files:
61+
build_bicep_file(bicep_file)
62+
63+
print("🎉 All Bicep files successfully built!")
64+
sys.exit(0)
65+
66+
67+
if __name__ == "__main__":
68+
main()

.infra/pytest_plugins/changed_samples/src/pytest_changed_samples/plugin.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
PR_CHANGES_OPTION = "--changed-samples-only-from"
1414

1515

16+
def is_plugin_active(config: pytest.Config) -> bool:
17+
"""Return whether any of the plugin provided options were provided on commandline."""
18+
return get_diff_paths_function(config) is not None
19+
20+
1621
def pytest_addoption(parser: pytest.Parser) -> None:
1722
parser.addoption(
1823
WORKING_TREE_CHANGES_OPTION,
@@ -42,10 +47,18 @@ def pytest_configure(config: pytest.Config) -> None:
4247

4348
@pytest.hookimpl(hookwrapper=True)
4449
def pytest_collection(session: pytest.Session) -> None:
50+
"""Set up path filtering based on git diff."""
4551
config = session.config
4652
diff_path_trie = Trie()
4753

48-
for p in get_diff_paths_function(config)():
54+
paths_filter = get_diff_paths_function(config)
55+
56+
if paths_filter is None:
57+
# Exit early if there's no path filter
58+
yield
59+
return
60+
61+
for p in paths_filter():
4962
diff_path_trie.insert(p.parts)
5063

5164
config.stash[DIFF_PATH_TRIE_KEY] = diff_path_trie
@@ -56,8 +69,9 @@ def pytest_collection(session: pytest.Session) -> None:
5669

5770

5871
def pytest_ignore_collect(collection_path: Path, config: pytest.Config) -> Optional[bool]:
72+
"""Ignore paths that were not touched by the current git diff."""
5973
if DIFF_PATH_TRIE_KEY not in config.stash:
60-
# Occures when calling `pytest --fixtures`
74+
# Occurs when calling `pytest --fixtures`
6175
return None
6276

6377
diff_path_trie = config.stash[DIFF_PATH_TRIE_KEY]
@@ -72,7 +86,16 @@ def pytest_ignore_collect(collection_path: Path, config: pytest.Config) -> Optio
7286
return (not diff_path_trie.is_prefix(ignore_dir.resolve().parts)) or None
7387

7488

75-
def get_diff_paths_function(config: pytest.Config) -> Callable[[], Iterable[Path]]:
89+
@pytest.hookimpl(trylast=True)
90+
def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None:
91+
if not is_plugin_active(session.config):
92+
return
93+
94+
if exitstatus == pytest.ExitCode.NO_TESTS_COLLECTED:
95+
session.exitstatus = pytest.ExitCode.OK
96+
97+
98+
def get_diff_paths_function(config: pytest.Config) -> Optional[Callable[[], Iterable[Path]]]:
7699
"""Get the function that returns paths present in a diff specfied by cmdline arguments
77100
78101
:param pytest.Config config: The pytest config
@@ -87,7 +110,7 @@ def get_diff_paths_function(config: pytest.Config) -> Callable[[], Iterable[Path
87110
if ref := config.getoption(opt_var(PR_CHANGES_OPTION)):
88111
return lambda: get_branch_diff_paths(ref)
89112

90-
return lambda: ()
113+
return None
91114

92115

93116
def opt_var(s: str) -> str:

.pre-commit-config.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ repos:
1515
language: system
1616
types_or: [jupyter]
1717
minimum_pre_commit_version: 2.9.2
18-
args: ["-m", "tox", "-qqq", "run", "-e", "nb-clean", "--", "clean", "--preserve-cell-metadata", "tags", "--"]
18+
args: ["-m", "tox", "-qqq", "run", "-e", "nb-clean", "--", "clean", "--preserve-cell-metadata", "tags", "name", "--"]
1919
- id: ruff
2020
name: ruff
2121
description: "Run 'ruff' for extremely fast Python linting"
@@ -40,3 +40,13 @@ repos:
4040
entry: python .github/scripts/detect_azure_secrets.py
4141
language: python
4242
types: [file]
43+
- id: bicep-build
44+
name: Regenerate azuredeploy.json for Agent samples
45+
description: "Automatically build Bicep files into azuredeploy.json before commit"
46+
types: [text]
47+
files: ^scenarios/Agents/setup/.*\.bicep$
48+
require_serial: true
49+
pass_filenames: true
50+
entry: python
51+
language: system
52+
args: ["-m", "tox", "-qqq", "run", "-e", "build-agent-bicep", "--"]

CONTRIBUTING.md

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,17 @@ python -m pip install -r dev-requirements.txt
6464
[pre-commit](https://pre-commit.com/) is a tool that enables us to run code when committing to a local repository. We
6565
use this to automate running code formatters, linters, etc...
6666

67-
To install pre-commit in the repository, run the following from the root of the repository:
67+
To enable `pre-commit`, run the following from the root of the repository:
6868

6969
```shell
7070
pre-commit install
7171
```
7272

73-
`pre-commit` will run automatically when you commit changes, but you can also manually run it using
74-
`pre-commit run --all-files`.
73+
`pre-commit` will now automatically run a series of code quality checks when you commit changes, which
74+
will accelerate the identification of issues that will be flagged when the PR is submitted.
75+
76+
If needed, you can manually run `pre-commit` against all files with `pre-commit run --all-files`. See
77+
[the documentation for `pre-commit run`](https://pre-commit.com/#pre-commit-run) for more information.
7578

7679
Note:
7780

@@ -115,8 +118,6 @@ Note that samples are organized by scenario, find the one best-suited for your s
115118
git push -f
116119
```
117120

118-
That's it! Thank you for your contribution!
119-
120121
> [!IMPORTANT]
121122
>
122123
> You should expect to budget time to engage with reviewers (responding to comments, fixing PR checks) before your PR is merged in. This is especially
@@ -125,6 +126,45 @@ That's it! Thank you for your contribution!
125126
> Adhering to the guidance in this document (i.e [using pre-commit](#3-set-up-pre-commit), [using provided templates](#write-your-contribution)) ***will***
126127
> help expedite the review process.
127128

129+
#### Resolve Failing Pull Request Checks
130+
131+
132+
> [!IMPORTANT]
133+
>
134+
> This repository requires approval from someone with write access for pull request checks
135+
> to run against a PR, to avoid abuse of live resources.
136+
>
137+
> All of the PR checks can also be run from developers machine, which should prevent the approval
138+
> processes from unnecessarily lengthening the feedback cycle.
139+
140+
> [!NOTE]
141+
> If you are a Microsoft employee, you can skip the approval process for PR checks by:
142+
>
143+
> * Joining the "[Azure-Samples](https://github.com/Azure-Samples)" organization
144+
> * [Setting your org membership visibility to public](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-your-membership-in-organizations/publicizing-or-hiding-organization-membership#changing-the-visibility-of-your-organization-membership)
145+
>
146+
147+
##### pre-commit
148+
149+
###### black
150+
151+
[black](https://github.com/psf/black) is a code formatter for Python and Jupyter notebooks.
152+
153+
**How to Fix**: If the `pre-commit` check is failing on your PR because of `black`, just run `pre-commit run black --all-files` and commit the changes.
154+
155+
###### nb-clean
156+
157+
[nb-clean](https://github.com/srstevenson/nb-clean) that removes metadata from Jupyter Notebooks to make them more ammenable to version control.
158+
159+
**How to Fix**: If the `nb-clean` check is failing on your PR because of `nb-clean`, just run `pre-commit run nb-clean --all-files` and commit the changes.
160+
161+
###### ruff
162+
163+
[ruff](https://github.com/astral-sh/ruff) is a linter for Python and Jupyter Notebooks.
164+
165+
**How to Fix**: If the `pre-commit` step is failing on your PR because of `ruff`:
166+
* ruff makes an attempt to automatically fix issues it detects. You can run `pre-commit run ruff --all-files` and commit any changes.
167+
* Issues that ruff can't fix should be manually updated and committed. See ruff's [rule list](https://docs.astral.sh/ruff/rules/) for more info on issues it reports.
128168

129169
### Discoverability
130170

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ Use the samples in this repository to try out Azure AI scenarios on your local m
1515

1616
### Other Sample Repositories
1717

18-
#### Azure AI Studio
18+
#### Azure AI Agent Service
19+
20+
* **[Azure/azure-sdk-for-python](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/ai/azure-ai-projects/samples/agents)** - Repo containing Python SDK samples for the Azure AI Agent Service.
21+
* **[Azure/azure-sdk-for-net](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/ai/Azure.AI.Projects/tests/Samples/Agent)** - Repo containing .NET SDK samples for the Azure AI Agent Service.
22+
* **[Azure-Samples/azureai-travel-agent-python](https://github.com/Azure-Samples/azureai-travel-agent-python/tree/main)** - Sample showing how to build a travel agent using the Azure AI Agent Service in Python.
23+
* **[Azure-Samples/azure-ai-projects-file-search](https://github.com/Azure-Samples/azure-ai-projects-file-search)** - A simple Python Quart app that streams responses from Azure AI Agents to an HTML/JS frontend using Server-Sent Events (SSEs).
24+
25+
#### Azure AI Foundry
1926

2027
* **[Azure/aistudio-copilot-sample]** - Quickstart repo for building an enterprise chat copilot in Azure AI Studio.
2128
* **[Azure-Samples/contoso-chat](https://github.com/Azure-Samples/contoso-chat)** - End-to-end solution sample for a custom RAG-based retail copilot built code-first with Prompty & Azure AI Studio.

conftest.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
REPO_ROOT = Path(__file__).parent.resolve()
99

1010

11-
@pytest.fixture()
11+
@pytest.fixture
1212
def notebook_path(
1313
# Create and activate a new venv for each test that requests `notebook_path`
1414
venv: types.SimpleNamespace, # noqa: ARG001
@@ -18,7 +18,7 @@ def notebook_path(
1818
return notebook_path
1919

2020

21-
@pytest.fixture()
21+
@pytest.fixture
2222
def deployment_outputs() -> Dict[str, str]:
2323
"""The outputs of the deployment used to setup resources for testing samples.
2424
@@ -43,7 +43,7 @@ def deployment_outputs() -> Dict[str, str]:
4343
return {output_name: output["value"] for output_name, output in outputs.items()}
4444

4545

46-
@pytest.fixture()
46+
@pytest.fixture
4747
def azure_ai_project(deployment_outputs: Dict[str, str]) -> Dict[str, str]:
4848
"""Azure ai project dictionary."""
4949
return {
@@ -53,7 +53,7 @@ def azure_ai_project(deployment_outputs: Dict[str, str]) -> Dict[str, str]:
5353
}
5454

5555

56-
@pytest.fixture()
56+
@pytest.fixture
5757
def azure_ai_project_connection_string(deployment_outputs: Dict[str, str]) -> str:
5858
"""The connection string for the azure ai project"""
5959
return ";".join(
@@ -66,19 +66,19 @@ def azure_ai_project_connection_string(deployment_outputs: Dict[str, str]) -> st
6666
)
6767

6868

69-
@pytest.fixture()
69+
@pytest.fixture
7070
def azure_openai_endpoint(deployment_outputs: Dict[str, str]) -> str:
7171
"""The azure openai endpoint for the azure ai project."""
7272
return deployment_outputs["azure_openai_endpoint"]
7373

7474

75-
@pytest.fixture()
75+
@pytest.fixture
7676
def azure_openai_gpt4_deployment(deployment_outputs: Dict[str, str]) -> str:
7777
"""The deployment name of the gpt-4 deployment."""
7878
return deployment_outputs["azure_openai_gpt4_deployment_name"]
7979

8080

81-
@pytest.fixture()
81+
@pytest.fixture
8282
def azure_openai_gpt4_api_version(deployment_outputs: Dict[str, str]) -> str:
8383
"""The api version of the gpt-4 deployment."""
8484
return deployment_outputs["azure_openai_gpt4_api_version"]

dev-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ python-dotenv ~= 1.0
44
pytest ~= 8.0
55
pytest-iovis[papermill] == 0.1.0
66
ipykernel ~= 6.0
7+
azure-cli ~= 2.69
78
.infra/pytest_plugins/changed_samples

pyproject.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ extend-select = [
1818
"ANN",
1919
"RUF",
2020
]
21-
ignore = [
22-
"ANN101", # missing-type-self: This can be inferred and will be deprecated by ruff
23-
]
2421

2522
[tool.ruff.lint.extend-per-file-ignores]
2623
"*.ipynb" = [

0 commit comments

Comments
 (0)