Skip to content

Commit 72c4e8e

Browse files
Python Refactoring (#103)
1 parent 503fdfd commit 72c4e8e

Some content is hidden

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

63 files changed

+4682
-3136
lines changed

.devcontainer/README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,22 +160,22 @@ Our devcontainer uses two key lifecycle commands optimized for prebuild:
160160
#### `onCreateCommand` (Container Creation)
161161
```bash
162162
# Creates Python virtual environment and registers Jupyter kernel
163-
echo '🚀 Creating Python virtual environment in workspace...' &&
164-
/usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies &&
165-
source /workspaces/Apim-Samples/.venv/bin/activate &&
166-
pip install --upgrade pip setuptools wheel ipykernel &&
163+
echo '🚀 Creating Python virtual environment in workspace...' &&
164+
/usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies &&
165+
source /workspaces/Apim-Samples/.venv/bin/activate &&
166+
pip install --upgrade pip setuptools wheel ipykernel &&
167167
python -m ipykernel install --user --name=apim-samples --display-name='APIM Samples Python 3.12'
168168
```
169169

170170
#### `updateContentCommand` (Content Updates)
171171
```bash
172172
# Installs Python packages and configures environment
173-
source /workspaces/Apim-Samples/.venv/bin/activate &&
174-
pip install -r requirements.txt &&
175-
pip install pytest pytest-cov coverage &&
176-
python setup/setup_python_path.py --generate-env &&
177-
az config set core.login_experience_v2=off &&
178-
az extension add --name containerapp --only-show-errors &&
173+
source /workspaces/Apim-Samples/.venv/bin/activate &&
174+
pip install -r requirements.txt &&
175+
pip install pytest pytest-cov coverage &&
176+
python setup/setup_python_path.py --generate-env &&
177+
az config set core.login_experience_v2=off &&
178+
az extension add --name containerapp --only-show-errors &&
179179
az extension add --name front-door --only-show-errors
180180
```
181181

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,4 @@
157157
"runArgs": [
158158
"--init"
159159
]
160-
}
160+
}

.devcontainer/post-start-setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ echo " - Wait for all extensions to install"
7777
echo " --> ✅ (.venv) prefix will appear when you open a new terminal"
7878
echo ""
7979
echo " 3. Start using the infrastructures and samples!"
80-
echo " - You may initially need to select the kernel (top-right above the"
80+
echo " - You may initially need to select the kernel (top-right above the"
8181
echo " Jupyter notebook). If so, select the '.venv' Python environment."
8282
echo ""
8383
echo "============================================================================"

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
# Markdown files should use LF
2727
*.md text eol=lf
2828

29+
# Python files should use LF
30+
*.py text eol=lf
31+
2932
# Windows batch files should use CRLF
3033
*.bat text eol=crlf
3134
*.cmd text eol=crlf
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
applyTo: "**/*.bicep"
3+
---
4+
5+
# Copilot Instructions (Bicep)
6+
7+
## Goals
8+
9+
- Prefer modern Bicep syntax and patterns.
10+
- Keep templates readable and easy to extend.
11+
- Keep deployments cross-platform (Windows, Linux, macOS).
12+
13+
## Conventions
14+
15+
- Use `@description` for all parameters and variables.
16+
- Prefer consistent naming:
17+
- Enums: `SNAKE_CASE` + uppercase.
18+
- Resources/variables: `camelCase`.
19+
- Use the repo's standard top parameters when authoring standalone Bicep files:
20+
21+
```bicep
22+
@description('Location to be used for resources. Defaults to the resource group location')
23+
param location string = resourceGroup().location
24+
25+
@description('The unique suffix to append. Defaults to a unique string based on subscription and resource group IDs.')
26+
param resourceSuffix string = uniqueString(subscription().id, resourceGroup().id)
27+
```
28+
29+
## Structure
30+
31+
- Prefer visible section headers:
32+
33+
```bicep
34+
// ------------------------------
35+
// PARAMETERS
36+
// ------------------------------
37+
```
38+
39+
- Keep two blank lines before a section header and one blank line after.
40+
- Suggested order (when applicable): Parameters, Constants, Variables, Resources, Outputs.
41+
42+
## Docs
43+
44+
- Add a Microsoft Learn template reference comment above each resource, e.g.:
45+
46+
```bicep
47+
// https://learn.microsoft.com/azure/templates/microsoft.network/virtualnetworks
48+
resource vnet 'Microsoft.Network/virtualNetworks@<apiVersion>' = {
49+
...
50+
}
51+
```

.github/copilot-instructions.md

Lines changed: 6 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ In case of any conflicting instructions, the following hierarchy shall apply. If
6464
- `shared/`: Shared resources, such as Bicep modules, Python libraries, and other reusable components.
6565
- `tests/`: Contains unit tests for Python code and Bicep modules. This folder should contain all tests for all code in the repository.
6666

67+
## Language-specific Instructions
68+
69+
- Python: see `.github/copilot-instructions.python.md`
70+
- Bicep: see `.github/copilot-instructions.bicep.md`
71+
6772
## Formatting and Style
6873

6974
- Maintain consistent indentation and whitespace but consider Editor Config settings, etc, for the repository.
@@ -85,110 +90,7 @@ In case of any conflicting instructions, the following hierarchy shall apply. If
8590
- Ensure that Jupyter notebooks do not contain any cell output.
8691
- Ensure that Jupyter notebooks have `index` assigned to `1` in the first cell.
8792

88-
## Language-specific Instructions
89-
90-
### Bicep Instructions
91-
- Prefer latest Bicep syntax and features.
92-
- Generated Bicep files should work with Windows, Linux, and macOS.
93-
- Reference latest available module versions. These may be newer than what you were trained on.
94-
- Add a link to each Bicep module immediately above the resource declaration (e.g., // https://learn.microsoft.com/azure/templates/microsoft.network/virtualnetworks)
95-
- Use `@description` for all parameters and variables.
96-
- Use snake-case and uppercase for all enum declarations.
97-
- Use camel care for resource and variables names.
98-
- `location` and `resourceSuffix` parameters do not need to be included when referencing modules in the current workspace unless the values differ from the defaults set in their parameters.
99-
- If a script must be used, default to cross-platform shell (not bash) scripts. Avoid PowerShell scripts.
100-
- Always add these two parameters at the top of Bicep files:
101-
102-
```Bicep
103-
@description('Location to be used for resources. Defaults to the resource group location')
104-
param location string = resourceGroup().location
105-
106-
@description('The unique suffix to append. Defaults to a unique string based on subscription and resource group IDs.')
107-
param resourceSuffix string = uniqueString(subscription().id, resourceGroup().id)
108-
```
109-
110-
- Overall layout of a Bicep file should be:
111-
- Visible sections of code with the following format should be used:
112-
113-
```bicep
114-
// ------------------------------
115-
// <SECTION HEADER>
116-
// ------------------------------
117-
```
118-
119-
- <SECTION HEADER> should be indented three spaces and be in all caps.
120-
- Section headers should have only two blank lines before and only one blank line after.
121-
- Top-to-bottom, the following comma-separated section headers should be inserted unless the section is empty:
122-
- Parameters
123-
- Constants
124-
- Variables
125-
- Resources
126-
- Outputs
127-
128-
### Python Instructions
129-
130-
- Prefer Python 3.12+ syntax and features unless otherwise specified.
131-
- Respect the repository's `.pylintrc` file for linting rules. The file is found in the `tests/python/` folder.
132-
- When inserting a comment to describe a method, insert a blank line after the comment section.
133-
- Never leave a blank line at the very top of a Python file. The file must start immediately with the module docstring or code. Always remove any leading blank line at the top.
134-
- Do not have imports such as `from shared.python import Foo`. The /shared/python directory is covered by a root `.env` file. Just use `import Foo` or `from Foo import Bar` as appropriate.
135-
- After the module docstring, all import statements must come before any section headers (e.g., CONSTANTS, VARIABLES, etc.). Section headers should only appear after the imports. Here is a more explicit example:
136-
137-
```python
138-
"""
139-
Module docstring.
140-
"""
141-
142-
import ...
143-
...
144-
145-
146-
# ------------------------------
147-
# CONSTANTS
148-
# ------------------------------
149-
...
150-
```
151-
152-
- Overall layout of a Python file should be:
153-
- Visible sections of code with the following format should be used:
154-
155-
```python
156-
# ------------------------------
157-
# <SECTION HEADER>
158-
# ------------------------------
159-
```
160-
161-
- <SECTION HEADER> should be indented three spaces and be in all caps.
162-
- Section headers should have only two blank lines before and only one blank line after.
163-
- Top-to-bottom, the following comma-separated section headers should be inserted unless the section is empty:
164-
- Constants
165-
- Variables
166-
- Private Methods
167-
- Public Methods
168-
169-
- If using classes, the following section headers should be used:
170-
- Classes
171-
- Constants
172-
- Variables
173-
- Constructor
174-
- Private Methods
175-
- Public Methods
176-
177-
- Python Docstring/Class Formatting Rule:
178-
- Always insert a single blank line after a class docstring and before any class attributes or methods.
179-
- Never place class attributes or decorators on the same line as the docstring. Example:
180-
181-
```python
182-
class MyClass:
183-
"""
184-
This is the class docstring.
185-
"""
186-
187-
attribute: str
188-
...
189-
```
190-
191-
### Jupyter Notebook Instructions
93+
## Jupyter Notebook Instructions
19294

19395
- Use these [configuration settings](https://github.com/microsoft/vscode-jupyter/blob/dd568fde/package.nls.json) as a reference for the VS Code Jupyter extension configuration.
19496

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
applyTo: "**/*.py"
3+
---
4+
5+
# Copilot Instructions (Python)
6+
7+
## Goals
8+
9+
- Make changes that are easy to review, test, and maintain.
10+
- Keep scripts cross-platform (Windows, Linux, macOS).
11+
- Prefer minimal, working implementations (MVP), then iterate.
12+
13+
## Project Context
14+
15+
- Python code lives primarily under `shared/python/`, `setup/`, `infrastructure/`, and `tests/python/`.
16+
- The repository uses Azure CLI from Python for many operations.
17+
18+
## Style and Conventions
19+
20+
- Prefer Python 3.12+ features unless otherwise required.
21+
- Keep all imports at the top of the file.
22+
- Use type hints and concise docstrings (PEP 257).
23+
- Use 4-space indentation and PEP 8 conventions.
24+
- Use only straight quotes (U+0027 and U+0022), not typographic quotes.
25+
- Use whitespace to separate logical sections and add a blank line before `return` statements.
26+
27+
## Import Style Guidelines
28+
29+
- Imports from this repo should be grouped, be imported last, and have a group header called `# APIM Samples imports`
30+
- Only use multi-line imports when a single-line is too long
31+
- Avoid mixing patterns: Don't use both `import module` and `from module import ...` for the same module
32+
- Parentheses in imports: Only use parentheses for multi-line imports, not for single-line imports:
33+
- Good: `from console import print_error, print_val`
34+
- Bad: `from console import (print_error, print_val)`
35+
- Good (multi-line):
36+
```python
37+
from console import (
38+
print_error,
39+
print_info,
40+
print_ok
41+
)
42+
```
43+
- Order within APIM Samples imports section:
44+
1. Module imports with aliases (e.g., `import azure_resources as az`)
45+
2. Specific type/constant imports (e.g., `from apimtypes import INFRASTRUCTURE`)
46+
3. Specific function imports (e.g., `from console import print_error`)
47+
48+
## Linting (pylint)
49+
50+
- Respect the repository pylint configuration at `tests/python/.pylintrc`.
51+
- When changing Python code, run pylint and ensure changes do not worsen the pylint rating unexpectedly.
52+
- Prefer fixing root causes (e.g., import structure, error handling) over suppressions.
53+
54+
## Testing
55+
56+
- Add or update pytest unit tests when changing behavior.
57+
- Prefer focused tests for the code being changed.
58+
- Avoid tests that require live Azure access; mock Azure CLI interactions and `azure_resources` helpers.
59+
60+
## Azure Helper Imports
61+
62+
- Prefer calling Azure resource helper functions via `import azure_resources as az`.
63+
- Avoid calling Azure-resource helpers through `utils` re-exports in new code.
64+
- When patching in tests, patch the symbol actually used by the module under test (e.g., `module.az.does_resource_group_exist`).

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@ tests/python/$TextReport
3636
shared/bicep/modules/**/*.json
3737
main.json
3838

39-
Test-Matrix.html
39+
Test-Matrix.html
40+
41+
$JsonReport
42+
$TextReport

.vscode/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@
1313
"files.trimTrailingWhitespace": true,
1414
"files.insertFinalNewline": true,
1515
"files.trimFinalNewlines": true,
16+
"files.eol": "\n",
1617
"editor.renderWhitespace": "trailing",
1718
"python.defaultInterpreterPath": "./.venv/Scripts/python.exe",
1819
"python.pythonPath": "./.venv/Scripts/python.exe",
1920
"python.envFile": "${workspaceFolder}/.env",
21+
"[python]": {
22+
"editor.codeActionsOnSave": {
23+
"source.organizeImports": "explicit",
24+
"source.unusedImports": "explicit"
25+
},
26+
"editor.formatOnSave": true
27+
},
2028
"notebook.defaultLanguage": "python",
2129
"notebook.kernelPickerType": "mru",
2230
"terminal.integrated.defaultProfile.windows": "PowerShell",

0 commit comments

Comments
 (0)