Skip to content

Commit 5708d64

Browse files
Feature/refactor python (#38)
1 parent 7b75315 commit 5708d64

File tree

16 files changed

+424
-402
lines changed

16 files changed

+424
-402
lines changed

.github/.copilot-instructions.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This instructions file is designed to guide GitHub Copilot's behavior specifical
1010

1111
**In case of any conflict, instructions from other individualized or project-specific files (such as `my-copilot.instructions.md`) take precedence over this file.**
1212

13-
## Repo Context
13+
## Repository Context
1414

1515
- This repository provides a playground to safely experiment with and learn Azure API Management (APIM) policies in various architectures.
1616
- The primary technologies are Python, Bicep, Jupyter notebooks, Azure CLI, APIM policy XML, and Markdown.
@@ -53,6 +53,17 @@ In case of any conflicting instructions, the following hierarchy shall apply. If
5353
- Use type annotations and docstrings where appropriate.
5454
- Prefer standard libraries and well-maintained dependencies.
5555

56+
## Repository Structure
57+
58+
- `/`: Root directory containing the main files and folders. Bicep configuration is stored in `bicepconfig.json`.
59+
- The following folders are all at the root level:
60+
- `assets/`: PlantUML diagrams and images. Static assets such as these should be placed here. Any diagrams should be placed in the /diagrams/src subfolder.
61+
- `infrastructure/`: Contains Jupyter notebooks for setting up various API Management infrastructures. When modifying samples, these notebooks should not need to be modified.
62+
- `samples/`: Various policy and scenario samples that can be applied to the infrastructures.
63+
- `setup/`: General setup scripts and configurations for the repository and dev environment setup.
64+
- `shared/`: Shared resources, such as Bicep modules, Python libraries, and other reusable components.
65+
- `tests/`: Contains unit tests for Python code and Bicep modules. This folder should contain all tests for all code in the repository.
66+
5667
## Formatting and Style
5768

5869
- Maintain consistent indentation and whitespace but consider Editor Config settings, etc, for the repository.
@@ -117,6 +128,7 @@ param resourceSuffix string = uniqueString(subscription().id, resourceGroup().id
117128
- Prefer Python 3.12+ syntax and features unless otherwise specified.
118129
- When inserting a comment to describe a method, insert a blank line after the comment section.
119130
- 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.
131+
- 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.
120132
- 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:
121133

122134
```python

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ __pycache__/
55
.venv/
66
venv/
77
env/
8+
.pytest_cache/
89

910
# Jupyter
1011
.ipynb_checkpoints/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ The first time you run a Jupyter notebook, you'll be asked to install the Jupyte
4949

5050
| Sample Name | Description | Supported Infrastructure(s) |
5151
|:----------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------|:------------------------------|
52-
| [General](./samples/general/create.ipynb) | Basic demo of APIM sample setup and policy usage. | All infrastructures |
53-
| [Load Balancing](./samples/load-balancing/create.ipynb) | Priority and weighted load balancing across backends. | apim-aca, afd-apim (with ACA) |
5452
| [AuthX](./samples/authx/create.ipynb) | Authentication and role-based authorization in a mock HR API. | All infrastructures |
5553
| [AuthX Pro](./samples/authx-pro/create.ipynb) | Authentication and role-based authorization in a mock product with multiple APIs and policy fragments. | All infrastructures |
54+
| [General](./samples/general/create.ipynb) | Basic demo of APIM sample setup and policy usage. | All infrastructures |
55+
| [Load Balancing](./samples/load-balancing/create.ipynb) | Priority and weighted load balancing across backends. | apim-aca, afd-apim (with ACA) |
5656
| [Secure Blob Access](./samples/secure-blob-access/create.ipynb) | Secure blob access via the [valet key pattern](https://learn.microsoft.com/azure/architecture/patterns/valet-key). | All infrastructures |
5757

5858
### ▶️ Running a Sample

TEMPLATE_PARAMETERS_USAGE.md

Lines changed: 0 additions & 69 deletions
This file was deleted.

examples/template_parameters_usage.py

Lines changed: 0 additions & 197 deletions
This file was deleted.

samples/authX-pro/create.ipynb

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@
107107
"# 3) Set up the named values\n",
108108
"nvs: List[NamedValue] = [\n",
109109
" NamedValue(jwt_key_name, jwt_key_value_bytes_b64, True),\n",
110-
" NamedValue('HRMemberRoleId', HR_MEMBER_ROLE_ID),\n",
111-
" NamedValue('HRAssociateRoleId', HR_ASSOCIATE_ROLE_ID),\n",
112-
" NamedValue('HRAdministratorRoleId', HR_ADMINISTRATOR_ROLE_ID)\n",
110+
" NamedValue('HRMemberRoleId', Role.HR_MEMBER),\n",
111+
" NamedValue('HRAssociateRoleId', Role.HR_ASSOCIATE),\n",
112+
" NamedValue('HRAdministratorRoleId', Role.HR_ADMINISTRATOR)\n",
113113
"]\n",
114114
"\n",
115115
"# 4) Set up the policy fragments\n",
@@ -226,25 +226,17 @@
226226
"source": [
227227
"import utils\n",
228228
"from apimrequests import ApimRequests\n",
229-
"from apimjwt import JwtPayload, SymmetricJwtToken\n",
230-
"from apimtypes import HR_MEMBER_ROLE_ID, HR_ADMINISTRATOR_ROLE_ID, HR_ASSOCIATE_ROLE_ID\n",
229+
"from apimtypes import Role\n",
230+
"from users import UserHelper\n",
231+
"from authfactory import AuthFactory\n",
231232
"\n",
232233
"# Preflight: Check if the infrastructure architecture deployment uses Azure Front Door. If so, assume that APIM is not directly accessible and use the Front Door URL instead.\n",
233-
"endpoint_url = apim_gateway_url\n",
234-
"utils.print_message('Checking if the infrastructure architecture deployment uses Azure Front Door.', blank_above = True)\n",
235-
"afd_endpoint_url = utils.get_frontdoor_url(deployment, rg_name)\n",
236-
"\n",
237-
"if afd_endpoint_url:\n",
238-
" endpoint_url = afd_endpoint_url\n",
239-
" utils.print_message(f'Using Azure Front Door URL: {afd_endpoint_url}', blank_above = True)\n",
240-
"else:\n",
241-
" utils.print_message(f'Using APIM Gateway URL: {apim_gateway_url}', blank_above = True)\n",
234+
"endpoint_url = utils.test_url_preflight_check(deployment, rg_name, apim_gateway_url)\n",
242235
"\n",
243236
"# 1) HR Administrator\n",
244237
"# Create a JSON Web Token with a payload and sign it with the symmetric key from above.\n",
245-
"jwt_payload_hr_admin = JwtPayload(subject = 'user123', name = 'Angie Administrator', roles = [HR_MEMBER_ROLE_ID, HR_ADMINISTRATOR_ROLE_ID])\n",
246-
"encoded_jwt_token_hr_admin = SymmetricJwtToken(jwt_key_value, jwt_payload_hr_admin).encode()\n",
247-
"print(f'\\nJWT token HR Admin: {encoded_jwt_token_hr_admin}') # this value is used to call the APIs via APIM\n",
238+
"encoded_jwt_token_hr_admin = AuthFactory.create_symmetric_jwt_token_for_user(UserHelper.get_user_by_role(Role.HR_ADMINISTRATOR), jwt_key_value)\n",
239+
"print(f'\\nJWT token for HR Admin:\\n{encoded_jwt_token_hr_admin}') # this value is used to call the APIs via APIM\n",
248240
"\n",
249241
"# Set up an APIM requests object with the JWT token\n",
250242
"reqsApimAdmin = ApimRequests(endpoint_url)\n",
@@ -258,9 +250,8 @@
258250
"\n",
259251
"# 2) HR Associate\n",
260252
"# Create a JSON Web Token with a payload and sign it with the symmetric key from above.\n",
261-
"jwt_payload_hr_associate = JwtPayload(subject = 'user789', name = 'Aaron Associate', roles = [HR_MEMBER_ROLE_ID, HR_ASSOCIATE_ROLE_ID])\n",
262-
"encoded_jwt_token_hr_associate = SymmetricJwtToken(jwt_key_value, jwt_payload_hr_associate).encode()\n",
263-
"print(f'\\nJWT token HR Associate: {encoded_jwt_token_hr_associate}') # this value is used to call the APIs via APIM\n",
253+
"encoded_jwt_token_hr_associate = AuthFactory.create_symmetric_jwt_token_for_user(UserHelper.get_user_by_role(Role.HR_ASSOCIATE), jwt_key_value)\n",
254+
"print(f'\\nJWT token for HR Associate:\\n{encoded_jwt_token_hr_associate}') # this value is used to call the APIs via APIM\n",
264255
"\n",
265256
"# Set up an APIM requests object with the JWT token\n",
266257
"reqsApimAssociate = ApimRequests(endpoint_url)\n",

0 commit comments

Comments
 (0)