arnmatch 2026.2.0__tar.gz → 2026.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/.github/workflows/workflow.yml +1 -1
  2. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/CLAUDE.md +12 -11
  3. arnmatch-2026.2.1/LICENSE +182 -0
  4. arnmatch-2026.2.1/PKG-INFO +134 -0
  5. arnmatch-2026.2.1/README.md +124 -0
  6. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/pyproject.toml +1 -0
  7. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/src/arnmatch/__init__.py +1 -1
  8. arnmatch-2026.2.0/AGENTS.md +0 -299
  9. arnmatch-2026.2.0/PKG-INFO +0 -121
  10. arnmatch-2026.2.0/README.md +0 -113
  11. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/.gitignore +0 -0
  12. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/.python-version +0 -0
  13. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/Makefile +0 -0
  14. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/.gitignore +0 -0
  15. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/Makefile +0 -0
  16. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/cache/CloudFormationResourceSpecification.json +0 -0
  17. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/cache/CloudFormationResources.json +0 -0
  18. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/cache/CloudFormationServices.json +0 -0
  19. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/cache/SDKServices.json +0 -0
  20. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/codegen.py +0 -0
  21. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/codegen_python.py +0 -0
  22. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/index_arn.py +0 -0
  23. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/index_cfn.py +0 -0
  24. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/index_cfn_resources.py +0 -0
  25. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/index_sdk.py +0 -0
  26. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/index_sdk_resources.py +0 -0
  27. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/arn_excludes.json +0 -0
  28. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/arn_excludes_resources.json +0 -0
  29. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/arn_includes.json +0 -0
  30. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/arn_overrides.json +0 -0
  31. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/cfn_excludes.json +0 -0
  32. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/cfn_overrides.json +0 -0
  33. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/cfn_resources_excludes.json +0 -0
  34. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/cfn_resources_overrides.json +0 -0
  35. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/lowercase_transforms.json +0 -0
  36. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/sdk_excludes.json +0 -0
  37. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/sdk_overrides.json +0 -0
  38. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/sdk_resources_defaults.json +0 -0
  39. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/rules/sdk_resources_overrides.json +0 -0
  40. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/scraper.py +0 -0
  41. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/transform.py +0 -0
  42. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/codegen/utils.py +0 -0
  43. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/docs/CloudFormation.md +0 -0
  44. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/src/arnmatch/arn_patterns.py +0 -0
  45. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/tests/integration/test_resource_explorer.py +0 -0
  46. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/tests/test_arnmatch.py +0 -0
  47. {arnmatch-2026.2.0 → arnmatch-2026.2.1}/uv.lock +0 -0
@@ -3,7 +3,7 @@ name: Release
3
3
  on:
4
4
  push:
5
5
  tags:
6
- - "v*"
6
+ - "20[0-9][0-9].[0-9]*.[0-9]*"
7
7
 
8
8
  jobs:
9
9
  release:
@@ -12,14 +12,13 @@ arnmatch is a zero-dependency Python library that parses AWS ARNs into structure
12
12
  make lint # Run ruff linter
13
13
  make test # Run pytest tests
14
14
  make check # Run lint and test
15
+ make generate # Regenerate patterns from AWS docs (runs codegen pipeline)
15
16
  make build # Copy generated patterns to src + build wheel/tarball
16
17
  make publish # Build and upload to PyPI
17
18
  make clean # Remove build artifacts
18
- ```
19
19
 
20
- Run codegen to regenerate patterns from AWS docs:
21
- ```bash
22
- uv run codegen/codegen.py
20
+ # Integration test (requires AWS credentials + Resource Explorer)
21
+ make test-integration
23
22
  ```
24
23
 
25
24
  Test locally:
@@ -32,30 +31,32 @@ uv run arnmatch <arn>
32
31
  ### Core Library (`src/arnmatch/`)
33
32
 
34
33
  - `__init__.py` - Main module with `arnmatch(arn)` function and `ARN` dataclass
35
- - `arn_patterns.py` - Generated file containing compiled regex patterns indexed by service and AWS SDK services mapping
34
+ - `arn_patterns.py` - Generated file containing compiled regex patterns indexed by service, SDK services mapping, and CloudFormation resource types
36
35
 
37
- The `arnmatch()` function splits the ARN, looks up patterns by service, and returns an `ARN` with partition, service, region, account, resource_type, and captured groups. The `resource_id` and `resource_name` properties use heuristics (prefer groups ending in "Id" or "Name"). The `aws_sdk_services` property returns boto3 client names for the service.
36
+ The `arnmatch()` function splits the ARN, looks up patterns by service, and returns an `ARN` with partition, service, region, account, resource_type, and captured groups. Key properties: `resource_id`/`resource_name` use heuristics (prefer groups ending in "Id" or "Name"), `aws_sdk_service` returns the specific boto3 client for this resource type, `cloudformation_resource` returns the CFN type (e.g., `AWS::Lambda::Function`).
38
37
 
39
38
  ### Code Generation (`codegen/`)
40
39
 
41
40
  - `scraper.py` - Scrapes AWS service authorization reference pages, caches results with joblib
42
- - `codegen.py` - Processes resources and generates `arn_patterns.py`
43
- - `index_sdk.py` - Maps ARN service names to AWS SDK (boto3) client names
41
+ - `codegen.py` - Main orchestrator: processes resources and generates `arn_patterns.yaml`
42
+ - `codegen_python.py` - Converts YAML to Python with compiled regex patterns
43
+ - `index_*.py` - Indexers for ARN patterns, SDK clients, and CloudFormation types
44
+ - `transform.py` - Normalizes resource type names (e.g., `loadbalancer/app/` → `loadbalancer-app`)
44
45
 
45
- Data flow: AWS docs → `scraper.py` → raw resources → `codegen.py` + `index_sdk.py` → `codegen/build/arn_patterns.py` → (copied by `make build`) → `src/arnmatch/arn_patterns.py`
46
+ Data flow: AWS docs → `scraper.py` → raw resources → `codegen.py` `arn_patterns.yaml` → `codegen_python.py` → `codegen/build/arn_patterns.py` → (copied by `make build`) → `src/arnmatch/arn_patterns.py`
46
47
 
47
48
  ### Key Design Decisions
48
49
 
49
50
  1. **Pattern ordering**: Patterns sorted by specificity (more literal segments first) for correct matching
50
51
  2. **Service index**: O(1) lookup by service before pattern matching
51
52
  3. **Overrides in codegen.py**: `PATTERN_OVERRIDES` fixes AWS docs that use wildcards instead of capture groups; `PATTERN_INCLUDES` adds patterns not in docs (EKS k8s resources, Inspector legacy)
52
- 4. **SDK service mapping**: `index_sdk.py` maps ARN service names to boto3 client names using botocore metadata (signingName/endpointPrefix), with manual overrides for edge cases and excludes for discontinued/console-only services
53
+ 4. **SDK service mapping**: `index_sdk.py` maps ARN service names to boto3 client names using botocore metadata (signingName/endpointPrefix), with manual overrides for edge cases and excludes for discontinued/console-only services. Rules are stored in `codegen/rules/*.json`
53
54
  5. **Zero runtime dependencies**: Only codegen has external deps (requests, beautifulsoup4, joblib, boto3)
54
55
 
55
56
  ## Build Notes
56
57
 
57
58
  - Uses `uv` for package management (not pip)
58
59
  - Build system is hatchling with dynamic version from `src/arnmatch/__init__.py`
59
- - **Versioning**: CalVer format `YYYY.0M.MICRO` (e.g., `2026.01.0`)
60
+ - **Versioning**: CalVer format `YYYY.MM.MICRO` (e.g., `2026.2.0`)
60
61
  - Always run `make build` before publishing to ensure patterns are current
61
62
  - Scraper cache lives in `.cache/` - delete if AWS docs change significantly
@@ -0,0 +1,182 @@
1
+ Copyright 2026 Andrey Gubarev
2
+
3
+ Apache License
4
+ Version 2.0, January 2004
5
+ http://www.apache.org/licenses/
6
+
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
+
9
+ 1. Definitions.
10
+
11
+ "License" shall mean the terms and conditions for use, reproduction, and
12
+ distribution as defined by Sections 1 through 9 of this document.
13
+
14
+ "Licensor" shall mean the copyright owner or entity authorized by the
15
+ copyright owner that is granting the License.
16
+
17
+ "Legal Entity" shall mean the union of the acting entity and all other
18
+ entities that control, are controlled by, or are under common control with
19
+ that entity. For the purposes of this definition, "control" means (i) the
20
+ power, direct or indirect, to cause the direction or management of such
21
+ entity, whether by contract or otherwise, or (ii) ownership of fifty percent
22
+ (50%) or more of the outstanding shares, or (iii) beneficial ownership of
23
+ such entity.
24
+
25
+ "You" (or "Your") shall mean an individual or Legal Entity exercising
26
+ permissions granted by this License.
27
+
28
+ "Source" form shall mean the preferred form for making modifications,
29
+ including but not limited to software source code, documentation source,
30
+ and configuration files.
31
+
32
+ "Object" form shall mean any form resulting from mechanical transformation
33
+ or translation of a Source form, including but not limited to compiled
34
+ object code, generated documentation, and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or Object form,
37
+ made available under the License, as indicated by a copyright notice that
38
+ is included in or attached to the work (an example is provided in the
39
+ Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object form,
42
+ that is based on (or derived from) the Work and for which the editorial
43
+ revisions, annotations, elaborations, or other modifications represent, as
44
+ a whole, an original work of authorship. For the purposes of this License,
45
+ Derivative Works shall not include works that remain separable from, or
46
+ merely link (or bind by name) to the interfaces of, the Work and Derivative
47
+ Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including the original
50
+ version of the Work and any modifications or additions to that Work or
51
+ Derivative Works thereof, that is intentionally submitted to Licensor for
52
+ inclusion in the Work by the copyright owner or by an individual or Legal
53
+ Entity authorized to submit on behalf of the copyright owner. For the
54
+ purposes of this definition, "submitted" means any form of electronic,
55
+ verbal, or written communication sent to the Licensor or its
56
+ representatives, including but not limited to communication on electronic
57
+ mailing lists, source code control systems, and issue tracking systems that
58
+ are managed by, or on behalf of, the Licensor for the purpose of discussing
59
+ and improving the Work, but excluding communication that is conspicuously
60
+ marked or otherwise designated in writing by the copyright owner as
61
+ "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity on
64
+ behalf of whom a Contribution has been received by Licensor and subsequently
65
+ incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License.
68
+
69
+ Subject to the terms and conditions of this License, each Contributor hereby
70
+ grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
71
+ irrevocable copyright license to reproduce, prepare Derivative Works of,
72
+ publicly display, publicly perform, sublicense, and distribute the Work and
73
+ such Derivative Works in Source or Object form.
74
+
75
+ 3. Grant of Patent License.
76
+
77
+ Subject to the terms and conditions of this License, each Contributor hereby
78
+ grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
79
+ irrevocable (except as stated in this section) patent license to make, have
80
+ made, use, offer to sell, sell, import, and otherwise transfer the Work,
81
+ where such license applies only to those patent claims licensable by such
82
+ Contributor that are necessarily infringed by their Contribution(s) alone
83
+ or by combination of their Contribution(s) with the Work to which such
84
+ Contribution(s) was submitted. If You institute patent litigation against
85
+ any entity (including a cross-claim or counterclaim in a lawsuit) alleging
86
+ that the Work or a Contribution incorporated within the Work constitutes
87
+ direct or contributory patent infringement, then any patent licenses granted
88
+ to You under this License for that Work shall terminate as of the date such
89
+ litigation is filed.
90
+
91
+ 4. Redistribution.
92
+
93
+ You may reproduce and distribute copies of the Work or Derivative Works
94
+ thereof in any medium, with or without modifications, and in Source or
95
+ Object form, provided that You meet the following conditions:
96
+
97
+ (a) You must give any other recipients of the Work or Derivative Works a
98
+ copy of this License; and
99
+
100
+ (b) You must cause any modified files to carry prominent notices stating
101
+ that You changed the files; and
102
+
103
+ (c) You must retain, in the Source form of any Derivative Works that You
104
+ distribute, all copyright, patent, trademark, and attribution notices
105
+ from the Source form of the Work, excluding those notices that do not
106
+ pertain to any part of the Derivative Works; and
107
+
108
+ (d) If the Work includes a "NOTICE" text file as part of its distribution,
109
+ then any Derivative Works that You distribute must include a readable
110
+ copy of the attribution notices contained within such NOTICE file,
111
+ excluding those notices that do not pertain to any part of the
112
+ Derivative Works, in at least one of the following places: within a
113
+ NOTICE text file distributed as part of the Derivative Works; within
114
+ the Source form or documentation, if provided along with the Derivative
115
+ Works; or, within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents of the
117
+ NOTICE file are for informational purposes only and do not modify the
118
+ License. You may add Your own attribution notices within Derivative
119
+ Works that You distribute, alongside or as an addendum to the NOTICE
120
+ text from the Work, provided that such additional attribution notices
121
+ cannot be construed as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and may
124
+ provide additional or different license terms and conditions for use,
125
+ reproduction, or distribution of Your modifications, or for any such
126
+ Derivative Works as a whole, provided Your use, reproduction, and
127
+ distribution of the Work otherwise complies with the conditions stated
128
+ in this License.
129
+
130
+ 5. Submission of Contributions.
131
+
132
+ Unless You explicitly state otherwise, any Contribution intentionally
133
+ submitted for inclusion in the Work by You to the Licensor shall be under
134
+ the terms and conditions of this License, without any additional terms or
135
+ conditions. Notwithstanding the above, nothing herein shall supersede or
136
+ modify the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks.
140
+
141
+ This License does not grant permission to use the trade names, trademarks,
142
+ service marks, or product names of the Licensor, except as required for
143
+ reasonable and customary use in describing the origin of the Work and
144
+ reproducing the content of the NOTICE file.
145
+
146
+ 7. Disclaimer of Warranty.
147
+
148
+ Unless required by applicable law or agreed to in writing, Licensor provides
149
+ the Work (and each Contributor provides its Contributions) on an "AS IS"
150
+ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
151
+ implied, including, without limitation, any warranties or conditions of
152
+ TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
153
+ PURPOSE. You are solely responsible for determining the appropriateness of
154
+ using or redistributing the Work and assume any risks associated with Your
155
+ exercise of permissions under this License.
156
+
157
+ 8. Limitation of Liability.
158
+
159
+ In no event and under no legal theory, whether in tort (including
160
+ negligence), contract, or otherwise, unless required by applicable law
161
+ (such as deliberate and grossly negligent acts) or agreed to in writing,
162
+ shall any Contributor be liable to You for damages, including any direct,
163
+ indirect, special, incidental, or consequential damages of any character
164
+ arising as a result of this License or out of the use or inability to use
165
+ the Work (including but not limited to damages for loss of goodwill, work
166
+ stoppage, computer failure or malfunction, or any and all other commercial
167
+ damages or losses), even if such Contributor has been advised of the
168
+ possibility of such damages.
169
+
170
+ 9. Accepting Warranty or Additional Liability.
171
+
172
+ While redistributing the Work or Derivative Works thereof, You may choose
173
+ to offer, and charge a fee for, acceptance of support, warranty, indemnity,
174
+ or other liability obligations and/or rights consistent with this License.
175
+ However, in accepting such obligations, You may act only on Your own behalf
176
+ and on Your sole responsibility, not on behalf of any other Contributor,
177
+ and only if You agree to indemnify, defend, and hold each Contributor
178
+ harmless for any liability incurred by, or claims asserted against, such
179
+ Contributor by reason of your accepting any such warranty or additional
180
+ liability.
181
+
182
+ END OF TERMS AND CONDITIONS
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: arnmatch
3
+ Version: 2026.2.1
4
+ Summary: Parse AWS ARNs into structured data (2000+ resource types)
5
+ Author-email: Andrey Gubarev <andrey@andreygubarev.com>
6
+ License-Expression: Apache-2.0
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+
11
+ # arnmatch
12
+
13
+ Parse AWS ARNs into structured data.
14
+
15
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
16
+ [![PyPI](https://img.shields.io/pypi/v/arnmatch)](https://pypi.org/project/arnmatch/)
17
+
18
+ ## Overview
19
+
20
+ Working with AWS at scale raises questions that are surprisingly hard to answer:
21
+
22
+ 1. **What resource does this ARN represent?** - ARN formats vary across services with no consistent parsing rules
23
+ 2. **What ARN formats exist?** - No single source documents all valid ARN patterns
24
+ 3. **What resource types exist on AWS?** - Scattered across 300+ service documentation pages
25
+ 4. **What CloudFormation type maps to this ARN?** - No direct ARN-to-CFN mapping exists
26
+
27
+ arnmatch answers these questions by:
28
+ - Parsing ARNs into structured components (service, region, account, resource type, resource ID)
29
+ - Providing a complete index of 2000+ resource types from 300+ AWS services
30
+ - Mapping ARNs to CloudFormation resource types (e.g., `arn:aws:lambda:...:function:X` → `AWS::Lambda::Function`)
31
+
32
+ Patterns are auto-generated from [AWS Service Authorization Reference](https://docs.aws.amazon.com/service-authorization/latest/reference/).
33
+
34
+ ## Features
35
+
36
+ - Zero runtime dependencies
37
+ - 300+ AWS services, 2000+ resource types
38
+ - Patterns auto-generated from AWS official documentation
39
+ - CLI and library interface
40
+ - CloudFormation resource type mapping
41
+ - Boto3 SDK service name mapping
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install arnmatch
47
+ ```
48
+
49
+ ## Quick Start
50
+
51
+ ### CLI
52
+
53
+ ```bash
54
+ $ arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
55
+ aws_service: lambda
56
+ aws_sdk_service: lambda
57
+ aws_sdk_services: lambda
58
+ aws_region: us-east-1
59
+ aws_account: 123456789012
60
+ resource_type: function
61
+ resource_id: my-function
62
+ resource_name: my-function
63
+ cloudformation_resource: AWS::Lambda::Function
64
+ ```
65
+
66
+ ### Library
67
+
68
+ ```python
69
+ from arnmatch import arnmatch
70
+
71
+ result = arnmatch("arn:aws:lambda:us-east-1:123456789012:function:my-function")
72
+
73
+ result.aws_service # "lambda"
74
+ result.aws_region # "us-east-1"
75
+ result.aws_account # "123456789012"
76
+ result.resource_type # "function"
77
+ result.resource_id # "my-function"
78
+ result.resource_name # "my-function"
79
+ result.cloudformation_resource # "AWS::Lambda::Function"
80
+ result.aws_sdk_service # "lambda"
81
+ ```
82
+
83
+ ## API Reference
84
+
85
+ ### `arnmatch(arn: str) -> ARN`
86
+
87
+ Parse an ARN string and return structured data.
88
+
89
+ Raises `ARNError` if the ARN format is invalid or no pattern matches.
90
+
91
+ ### `ARN`
92
+
93
+ Dataclass with parsed ARN components:
94
+
95
+ | Field | Type | Description |
96
+ |-------|------|-------------|
97
+ | `aws_partition` | `str` | AWS partition (aws, aws-cn, aws-us-gov) |
98
+ | `aws_service` | `str` | AWS service name |
99
+ | `aws_region` | `str` | AWS region (may be empty for global resources) |
100
+ | `aws_account` | `str` | AWS account ID |
101
+ | `resource_type` | `str` | Canonical resource type from AWS docs |
102
+ | `resource_types` | `list[str]` | All known names for this resource type |
103
+ | `attributes` | `dict[str, str]` | All captured attributes from the ARN |
104
+ | `aws_sdk_service` | `str \| None` | Primary boto3 client name |
105
+ | `cloudformation_resource` | `str \| None` | CloudFormation resource type |
106
+
107
+ Properties:
108
+
109
+ | Property | Description |
110
+ |----------|-------------|
111
+ | `resource_id` | Resource identifier (prefers attributes ending in `Id`, then `Name`, then last attribute) |
112
+ | `resource_name` | Resource name (prefers attributes ending in `Name`, falls back to `resource_id`) |
113
+ | `aws_sdk_services` | List of boto3 client names (e.g., `['elb', 'elbv2']` for elasticloadbalancing) |
114
+
115
+ ### `ARNError`
116
+
117
+ Exception raised when ARN parsing fails. Inherits from `ValueError`.
118
+
119
+ ## Development
120
+
121
+ Prerequisites: [uv](https://github.com/astral-sh/uv)
122
+
123
+ ```bash
124
+ make lint # Run ruff linter
125
+ make test # Run pytest tests
126
+ make check # Run lint and test
127
+ make generate # Regenerate patterns from AWS docs
128
+ make build # Build wheel and tarball
129
+ make publish # Build and upload to PyPI
130
+ ```
131
+
132
+ ## Versioning
133
+
134
+ [CalVer](https://calver.org/) format `YYYY.MM.MICRO` (e.g., `2026.2.0`).
@@ -0,0 +1,124 @@
1
+ # arnmatch
2
+
3
+ Parse AWS ARNs into structured data.
4
+
5
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
6
+ [![PyPI](https://img.shields.io/pypi/v/arnmatch)](https://pypi.org/project/arnmatch/)
7
+
8
+ ## Overview
9
+
10
+ Working with AWS at scale raises questions that are surprisingly hard to answer:
11
+
12
+ 1. **What resource does this ARN represent?** - ARN formats vary across services with no consistent parsing rules
13
+ 2. **What ARN formats exist?** - No single source documents all valid ARN patterns
14
+ 3. **What resource types exist on AWS?** - Scattered across 300+ service documentation pages
15
+ 4. **What CloudFormation type maps to this ARN?** - No direct ARN-to-CFN mapping exists
16
+
17
+ arnmatch answers these questions by:
18
+ - Parsing ARNs into structured components (service, region, account, resource type, resource ID)
19
+ - Providing a complete index of 2000+ resource types from 300+ AWS services
20
+ - Mapping ARNs to CloudFormation resource types (e.g., `arn:aws:lambda:...:function:X` → `AWS::Lambda::Function`)
21
+
22
+ Patterns are auto-generated from [AWS Service Authorization Reference](https://docs.aws.amazon.com/service-authorization/latest/reference/).
23
+
24
+ ## Features
25
+
26
+ - Zero runtime dependencies
27
+ - 300+ AWS services, 2000+ resource types
28
+ - Patterns auto-generated from AWS official documentation
29
+ - CLI and library interface
30
+ - CloudFormation resource type mapping
31
+ - Boto3 SDK service name mapping
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pip install arnmatch
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ### CLI
42
+
43
+ ```bash
44
+ $ arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
45
+ aws_service: lambda
46
+ aws_sdk_service: lambda
47
+ aws_sdk_services: lambda
48
+ aws_region: us-east-1
49
+ aws_account: 123456789012
50
+ resource_type: function
51
+ resource_id: my-function
52
+ resource_name: my-function
53
+ cloudformation_resource: AWS::Lambda::Function
54
+ ```
55
+
56
+ ### Library
57
+
58
+ ```python
59
+ from arnmatch import arnmatch
60
+
61
+ result = arnmatch("arn:aws:lambda:us-east-1:123456789012:function:my-function")
62
+
63
+ result.aws_service # "lambda"
64
+ result.aws_region # "us-east-1"
65
+ result.aws_account # "123456789012"
66
+ result.resource_type # "function"
67
+ result.resource_id # "my-function"
68
+ result.resource_name # "my-function"
69
+ result.cloudformation_resource # "AWS::Lambda::Function"
70
+ result.aws_sdk_service # "lambda"
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ ### `arnmatch(arn: str) -> ARN`
76
+
77
+ Parse an ARN string and return structured data.
78
+
79
+ Raises `ARNError` if the ARN format is invalid or no pattern matches.
80
+
81
+ ### `ARN`
82
+
83
+ Dataclass with parsed ARN components:
84
+
85
+ | Field | Type | Description |
86
+ |-------|------|-------------|
87
+ | `aws_partition` | `str` | AWS partition (aws, aws-cn, aws-us-gov) |
88
+ | `aws_service` | `str` | AWS service name |
89
+ | `aws_region` | `str` | AWS region (may be empty for global resources) |
90
+ | `aws_account` | `str` | AWS account ID |
91
+ | `resource_type` | `str` | Canonical resource type from AWS docs |
92
+ | `resource_types` | `list[str]` | All known names for this resource type |
93
+ | `attributes` | `dict[str, str]` | All captured attributes from the ARN |
94
+ | `aws_sdk_service` | `str \| None` | Primary boto3 client name |
95
+ | `cloudformation_resource` | `str \| None` | CloudFormation resource type |
96
+
97
+ Properties:
98
+
99
+ | Property | Description |
100
+ |----------|-------------|
101
+ | `resource_id` | Resource identifier (prefers attributes ending in `Id`, then `Name`, then last attribute) |
102
+ | `resource_name` | Resource name (prefers attributes ending in `Name`, falls back to `resource_id`) |
103
+ | `aws_sdk_services` | List of boto3 client names (e.g., `['elb', 'elbv2']` for elasticloadbalancing) |
104
+
105
+ ### `ARNError`
106
+
107
+ Exception raised when ARN parsing fails. Inherits from `ValueError`.
108
+
109
+ ## Development
110
+
111
+ Prerequisites: [uv](https://github.com/astral-sh/uv)
112
+
113
+ ```bash
114
+ make lint # Run ruff linter
115
+ make test # Run pytest tests
116
+ make check # Run lint and test
117
+ make generate # Regenerate patterns from AWS docs
118
+ make build # Build wheel and tarball
119
+ make publish # Build and upload to PyPI
120
+ ```
121
+
122
+ ## Versioning
123
+
124
+ [CalVer](https://calver.org/) format `YYYY.MM.MICRO` (e.g., `2026.2.0`).
@@ -7,6 +7,7 @@ authors = [
7
7
  { name = "Andrey Gubarev", email = "andrey@andreygubarev.com" }
8
8
  ]
9
9
  requires-python = ">=3.10"
10
+ license = "Apache-2.0"
10
11
  dependencies = []
11
12
 
12
13
  [project.scripts]
@@ -1,6 +1,6 @@
1
1
  """ARN pattern matching using regex patterns."""
2
2
 
3
- __version__ = "2026.02.0"
3
+ __version__ = "2026.2.1"
4
4
 
5
5
  import sys
6
6
  from dataclasses import dataclass
@@ -1,299 +0,0 @@
1
- # arnmatch - AI Agent Guide
2
-
3
- ## Project Overview
4
-
5
- arnmatch is a zero-dependency Python library that parses AWS ARNs (Amazon Resource Names) into structured data. It supports 300+ AWS services and 2000+ resource types. The library provides both a programmatic API and a CLI interface.
6
-
7
- Key characteristics:
8
- - **Zero runtime dependencies** - only standard library
9
- - **Auto-generated patterns** - scraped from AWS official documentation
10
- - **Dual interface** - CLI (`arnmatch <arn>`) and library (`arnmatch.arnmatch()`)
11
- - **Versioning** - CalVer format `YYYY.0M.MICRO` (e.g., `2026.01.3`)
12
-
13
- ## Technology Stack
14
-
15
- - **Language**: Python 3.10+
16
- - **Build System**: [hatchling](https://hatch.pypa.io/)
17
- - **Package Manager**: [uv](https://github.com/astral-sh/uv) (required for development)
18
- - **Linter**: [ruff](https://docs.astral.sh/ruff/)
19
- - **Testing**: pytest
20
-
21
- ## Project Structure
22
-
23
- ```
24
- ├── src/arnmatch/ # Core library (zero runtime deps)
25
- │ ├── __init__.py # Main module: ARN dataclass, arnmatch() function
26
- │ └── arn_patterns.py # GENERATED FILE - compiled regex patterns
27
- ├── codegen/ # Code generation (has external deps)
28
- │ ├── scraper.py # Scrapes AWS service authorization reference pages
29
- │ ├── codegen.py # Main code generator
30
- │ ├── index_arn.py # Processes raw ARN resources, applies overrides
31
- │ ├── index_sdk.py # Maps ARN service names to boto3 client names
32
- │ ├── index_sdk_resources.py # Resource-level SDK client mappings
33
- │ ├── index_cfn.py # Maps services to CloudFormation resource types
34
- │ ├── index_cfn_resources.py # Maps ARN resources to CFN resource types
35
- │ ├── utils.py # Shared utilities (botocore metadata loader)
36
- │ └── build/ # Build output (generated patterns)
37
- │ └── arn_patterns.py # Generated patterns (copied to src/)
38
- ├── tests/ # pytest test suite
39
- │ └── test_arnmatch.py # Tests for various AWS services
40
- ├── Makefile # Build automation
41
- ├── pyproject.toml # Project configuration
42
- └── .cache/ # Scraper cache (joblib)
43
- ```
44
-
45
- ## Build and Development Commands
46
-
47
- All commands use `make` and require `uv` to be installed:
48
-
49
- ```bash
50
- # Linting
51
- make lint # Run ruff linter
52
-
53
- # Testing
54
- make test # Run pytest tests
55
- make check # Run both lint and test
56
-
57
- # Building
58
- make build # Copy generated patterns + build wheel/tarball
59
- # NOTE: This copies codegen/build/arn_patterns.py to src/arnmatch/
60
-
61
- # Publishing
62
- make publish # Build and upload to PyPI (requires credentials)
63
-
64
- # Cleanup
65
- make clean # Remove build artifacts
66
- ```
67
-
68
- ## Code Generation Workflow
69
-
70
- The ARN patterns are auto-generated from AWS documentation. To regenerate:
71
-
72
- ```bash
73
- cd codegen && uv run codegen.py
74
- ```
75
-
76
- This will:
77
- 1. Scrape AWS service authorization reference pages (cached with joblib)
78
- 2. Process resources, apply overrides, filter, deduplicate
79
- 3. Build SDK service mappings using botocore metadata
80
- 4. Build CloudFormation resource mappings
81
- 5. Generate `codegen/build/arn_patterns.py`
82
-
83
- After regeneration, run `make build` to copy the patterns to `src/arnmatch/`.
84
-
85
- ### Code Generation Architecture
86
-
87
- **Data Flow:**
88
- ```
89
- AWS Docs → scraper.py → raw resources → index_arn.py → processed resources
90
-
91
- botocore metadata → index_sdk.py → SDK mappings → codegen.py
92
-
93
- CFN spec → index_cfn.py → CFN mappings → index_cfn_resources.py
94
-
95
- codegen/build/arn_patterns.py
96
-
97
- make build
98
-
99
- src/arnmatch/arn_patterns.py
100
- ```
101
-
102
- **Key Components:**
103
-
104
- | File | Purpose |
105
- |------|---------|
106
- | `scraper.py` | Fetches AWS docs, extracts service prefixes and resource patterns |
107
- | `index_arn.py` | Processes resources: deduplicates, sorts by specificity, applies `PATTERN_OVERRIDES` and `PATTERN_INCLUDES` |
108
- | `index_sdk.py` | Maps ARN service names to boto3 client names using botocore metadata |
109
- | `index_sdk_resources.py` | Defines `DEFAULT_SERVICE` and `OVERRIDE_SERVICE` for multi-SDK services |
110
- | `index_cfn.py` | Maps services to CloudFormation resource types using CFN spec |
111
- | `index_cfn_resources.py` | Maps ARN resource types to CFN resource types |
112
- | `codegen.py` | Main generator, produces Python file with compiled regex patterns |
113
-
114
- ### Important Override Files
115
-
116
- When AWS docs have errors or omissions, edit these in `codegen/`:
117
-
118
- - **`index_arn.py:PATTERN_OVERRIDES`** - Fix incorrect ARN patterns in AWS docs
119
- - **`index_arn.py:PATTERN_INCLUDES`** - Add patterns not in AWS docs (e.g., EKS k8s resources)
120
- - **`index_sdk.py:OVERRIDES`** - Manual ARN service → SDK client mappings
121
- - **`index_sdk.py:EXCLUDES_*`** - Services to exclude (discontinued, console-only, no SDK)
122
- - **`index_sdk_resources.py:DEFAULT_SERVICE`** - Default SDK for multi-SDK services
123
- - **`index_sdk_resources.py:OVERRIDE_SERVICE`** - Resource-level SDK overrides
124
- - **`index_cfn.py:OVERRIDES`** - Manual CFN service → SDK service mappings
125
-
126
- ## Core Library Architecture
127
-
128
- ### Main API (`src/arnmatch/__init__.py`)
129
-
130
- ```python
131
- from arnmatch import arnmatch
132
-
133
- result = arnmatch("arn:aws:lambda:us-east-1:123456789012:function:my-function")
134
-
135
- # Available attributes:
136
- result.aws_partition # "aws"
137
- result.aws_service # "lambda"
138
- result.aws_region # "us-east-1"
139
- result.aws_account # "123456789012"
140
- result.resource_type # "function" (canonical)
141
- result.resource_types # ["function"] (all known names)
142
- result.attributes # {"FunctionName": "my-function", ...}
143
-
144
- # Properties (computed):
145
- result.resource_id # "my-function" (heuristic: prefers *Id, then *Name)
146
- result.resource_name # "my-function" (heuristic: prefers *Name, falls back to resource_id)
147
- result.aws_sdk_services # ["lambda"] (all possible boto3 clients)
148
- result.aws_sdk_service # "lambda" (specific client for this resource)
149
- result.cloudformation_resource # "AWS::Lambda::Function" or None
150
- ```
151
-
152
- ### ARN Dataclass
153
-
154
- The `ARN` dataclass is frozen and stores:
155
- - `aws_partition`, `aws_service`, `aws_region`, `aws_account` - ARN components
156
- - `resource_type` - canonical type from AWS docs
157
- - `resource_types` - all known aliases for this type
158
- - `attributes` - dict of all regex capture groups
159
-
160
- Properties use `@cached_property` for lazy evaluation.
161
-
162
- ### Pattern Matching Algorithm
163
-
164
- 1. Split ARN by `:` into 6 parts (arn, partition, service, region, account, resource)
165
- 2. Look up service in `ARN_PATTERNS` dict (O(1))
166
- 3. Iterate through patterns for that service (most specific first)
167
- 4. Return first match with all capture groups
168
-
169
- Pattern ordering is critical - patterns are sorted by specificity:
170
- - More segments come first
171
- - Literal segments come before wildcards
172
- - Variables come before wildcards
173
-
174
- ## Testing Strategy
175
-
176
- Tests are in `tests/test_arnmatch.py` and use pytest:
177
-
178
- ```bash
179
- make test
180
- ```
181
-
182
- Test patterns:
183
- - Each major service has a test function (e.g., `test_lambda()`, `test_s3()`)
184
- - Tests verify: resource_type, attributes, SDK mappings, CFN mappings
185
- - Edge cases: multi-SDK services, resource-level overrides
186
-
187
- When adding new features or fixing bugs, add corresponding test cases.
188
-
189
- ## Development Guidelines
190
-
191
- ### Code Style
192
-
193
- - Follow existing code style (ruff enforces this)
194
- - Run `make lint` before committing
195
- - Use type hints where appropriate
196
- - Document public APIs with docstrings
197
-
198
- ### Adding New Patterns
199
-
200
- If AWS docs are missing a pattern:
201
-
202
- 1. Add to `codegen/index_arn.py:PATTERN_INCLUDES`:
203
- ```python
204
- PATTERN_INCLUDES = [
205
- # (service, arn_pattern, resource_type)
206
- ("eks", "arn:${Partition}:eks:${Region}:${Account}:pod/${ClusterName}/${Namespace}/${PodName}/${UUID}", "pod"),
207
- ]
208
- ```
209
-
210
- 2. Regenerate: `cd codegen && uv run codegen.py`
211
- 3. Rebuild: `make build`
212
- 4. Test: `make test`
213
-
214
- ### Fixing Pattern Issues
215
-
216
- If AWS docs have incorrect patterns (e.g., wildcards instead of capture groups):
217
-
218
- 1. Add to `codegen/index_arn.py:PATTERN_OVERRIDES`:
219
- ```python
220
- PATTERN_OVERRIDES = {
221
- ("service", "resource-type"): "arn:${Partition}:service:${Region}:${Account}:resource/${ResourceId}",
222
- }
223
- ```
224
-
225
- ### Version Updates
226
-
227
- Version is in `src/arnmatch/__init__.py:__version__` (CalVer format).
228
-
229
- Update this when:
230
- - Regenerating patterns (if AWS docs changed)
231
- - Adding new features
232
- - Fixing bugs
233
-
234
- ## Key Design Decisions
235
-
236
- 1. **Zero runtime dependencies** - Only standard library in `src/arnmatch/`
237
- 2. **Compiled regex patterns** - Generated once, not parsed at runtime
238
- 3. **Service-indexed patterns** - O(1) lookup before pattern matching
239
- 4. **Specificity-based sorting** - More specific patterns match first
240
- 5. **Multi-SDK support** - Some services map to multiple boto3 clients (e.g., `rds` → `["rds", "docdb", "neptune"]`)
241
-
242
- ## Common Tasks
243
-
244
- ### Test a specific ARN locally
245
-
246
- ```bash
247
- uv run arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
248
- ```
249
-
250
- ### Regenerate all patterns from AWS docs
251
-
252
- ```bash
253
- cd codegen && uv run codegen.py
254
- make build
255
- make test
256
- ```
257
-
258
- ### Clear scraper cache
259
-
260
- If AWS docs changed significantly and caching causes issues:
261
-
262
- ```bash
263
- rm -rf .cache/
264
- ```
265
-
266
- ### Add support for a new service
267
-
268
- Usually automatic via code generation. If the service has special cases:
269
-
270
- 1. Check `codegen/index_sdk.py` - add override if SDK name differs
271
- 2. Check `codegen/index_sdk_resources.py` - add to `DEFAULT_SERVICE` or `OVERRIDE_SERVICE` if multi-SDK
272
- 3. Check `codegen/index_cfn.py` - add to `OVERRIDES` if CFN service name differs
273
- 4. Regenerate and test
274
-
275
- ## Security Considerations
276
-
277
- - The library only parses ARN strings, never makes AWS API calls
278
- - No credentials or sensitive data is handled
279
- - Generated patterns come from official AWS documentation
280
- - The scraper only reads public AWS documentation pages
281
-
282
- ## Troubleshooting
283
-
284
- **Issue**: Pattern not matching
285
- - Check if pattern exists in `codegen/build/arn_resources.json`
286
- - Check `PATTERN_OVERRIDES` if AWS docs use wildcards
287
- - Check `PATTERN_INCLUDES` if pattern is missing from docs
288
-
289
- **Issue**: Wrong SDK client returned
290
- - Check `index_sdk.py:OVERRIDES` for service-level mapping
291
- - Check `index_sdk_resources.py:OVERRIDE_SERVICE` for resource-level mapping
292
-
293
- **Issue**: Tests fail after regeneration
294
- - AWS docs may have changed - verify changes are correct
295
- - Some services may have been discontinued - check `EXCLUDES_*` sets
296
-
297
- **Issue**: Import errors
298
- - Ensure `make build` was run (copies patterns to src/)
299
- - Check that `uv sync` was run to install dependencies
@@ -1,121 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: arnmatch
3
- Version: 2026.2.0
4
- Summary: Parse AWS ARNs into structured data (2000+ resource types)
5
- Author-email: Andrey Gubarev <andrey@andreygubarev.com>
6
- Requires-Python: >=3.10
7
- Description-Content-Type: text/markdown
8
-
9
- # arnmatch
10
-
11
- Parse AWS ARNs into structured data.
12
-
13
- ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
14
-
15
- ## Why
16
-
17
- AWS ARN formats are inconsistent. This problem was unsolved. Now it's solved (for 2000+ resource types from 300+ services). You're welcome.
18
-
19
- ## Features
20
-
21
- - Zero runtime dependencies
22
- - 300+ AWS services, 2000+ resource types supported
23
- - Patterns auto-generated from AWS official documentation
24
- - CLI and library interface
25
- - Extracts resource type, ID, and name with smart heuristics
26
-
27
- ## Installation
28
-
29
- ```bash
30
- pip install arnmatch
31
- ```
32
-
33
- ## Quick Start
34
-
35
- ### CLI
36
-
37
- ```bash
38
- $ uvx arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
39
- aws_service: lambda
40
- aws_sdk_services: lambda
41
- aws_region: us-east-1
42
- aws_account: 123456789012
43
- resource_type: function
44
- resource_id: my-function
45
- resource_name: my-function
46
- ```
47
-
48
- ### Library
49
-
50
- ```python
51
- from arnmatch import arnmatch
52
-
53
- arn = "arn:aws:lambda:us-east-1:123456789012:function:my-function"
54
- result = arnmatch(arn)
55
-
56
- print(result.aws_service) # lambda
57
- print(result.aws_sdk_services) # ['lambda']
58
- print(result.aws_region) # us-east-1
59
- print(result.aws_account) # 123456789012
60
- print(result.resource_type) # function
61
- print(result.resource_id) # my-function
62
- print(result.resource_name) # my-function
63
- print(result.attributes) # {'Partition': 'aws', 'Region': 'us-east-1', ...}
64
- ```
65
-
66
- ## API Reference
67
-
68
- ### `arnmatch(arn: str) -> ARN`
69
-
70
- Parse an ARN string and return structured data.
71
-
72
- Raises `ARNError` if the ARN format is invalid or no pattern matches.
73
-
74
- ### `ARN`
75
-
76
- Dataclass with parsed ARN components:
77
-
78
- | Field | Type | Description |
79
- |-------|------|-------------|
80
- | `aws_partition` | `str` | AWS partition (aws, aws-cn, aws-us-gov) |
81
- | `aws_service` | `str` | AWS service name |
82
- | `aws_region` | `str` | AWS region (may be empty for global resources) |
83
- | `aws_account` | `str` | AWS account ID |
84
- | `resource_type` | `str` | Canonical resource type from AWS docs |
85
- | `resource_types` | `list[str]` | All known names for this resource type |
86
- | `attributes` | `dict[str, str]` | All captured attributes from the pattern |
87
-
88
- Properties:
89
-
90
- | Property | Description |
91
- |----------|-------------|
92
- | `resource_id` | Resource identifier (prefers groups ending in `Id`, falls back to `Name`, then last group) |
93
- | `resource_name` | Resource name (prefers groups ending in `Name`, falls back to `resource_id`) |
94
- | `aws_sdk_services` | List of boto3 client names for this service (e.g., `['elb', 'elbv2']` for elasticloadbalancing) |
95
-
96
- ### `ARNError`
97
-
98
- Exception raised when ARN parsing fails. Inherits from `ValueError`.
99
-
100
- ## Versioning
101
-
102
- This project uses [CalVer](https://calver.org/) with format `YYYY.0M.MICRO` (e.g., `2026.01.0`).
103
-
104
- ## Development
105
-
106
- Prerequisites: [uv](https://github.com/astral-sh/uv)
107
-
108
- ```bash
109
- make lint # Run ruff linter
110
- make test # Run pytest tests
111
- make check # Run lint and test
112
- make build # Build wheel and tarball
113
- make publish # Build and upload to PyPI
114
- make clean # Remove build artifacts
115
- ```
116
-
117
- Regenerate patterns from AWS docs:
118
-
119
- ```bash
120
- cd codegen && uv run codegen.py
121
- ```
@@ -1,113 +0,0 @@
1
- # arnmatch
2
-
3
- Parse AWS ARNs into structured data.
4
-
5
- ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
6
-
7
- ## Why
8
-
9
- AWS ARN formats are inconsistent. This problem was unsolved. Now it's solved (for 2000+ resource types from 300+ services). You're welcome.
10
-
11
- ## Features
12
-
13
- - Zero runtime dependencies
14
- - 300+ AWS services, 2000+ resource types supported
15
- - Patterns auto-generated from AWS official documentation
16
- - CLI and library interface
17
- - Extracts resource type, ID, and name with smart heuristics
18
-
19
- ## Installation
20
-
21
- ```bash
22
- pip install arnmatch
23
- ```
24
-
25
- ## Quick Start
26
-
27
- ### CLI
28
-
29
- ```bash
30
- $ uvx arnmatch "arn:aws:lambda:us-east-1:123456789012:function:my-function"
31
- aws_service: lambda
32
- aws_sdk_services: lambda
33
- aws_region: us-east-1
34
- aws_account: 123456789012
35
- resource_type: function
36
- resource_id: my-function
37
- resource_name: my-function
38
- ```
39
-
40
- ### Library
41
-
42
- ```python
43
- from arnmatch import arnmatch
44
-
45
- arn = "arn:aws:lambda:us-east-1:123456789012:function:my-function"
46
- result = arnmatch(arn)
47
-
48
- print(result.aws_service) # lambda
49
- print(result.aws_sdk_services) # ['lambda']
50
- print(result.aws_region) # us-east-1
51
- print(result.aws_account) # 123456789012
52
- print(result.resource_type) # function
53
- print(result.resource_id) # my-function
54
- print(result.resource_name) # my-function
55
- print(result.attributes) # {'Partition': 'aws', 'Region': 'us-east-1', ...}
56
- ```
57
-
58
- ## API Reference
59
-
60
- ### `arnmatch(arn: str) -> ARN`
61
-
62
- Parse an ARN string and return structured data.
63
-
64
- Raises `ARNError` if the ARN format is invalid or no pattern matches.
65
-
66
- ### `ARN`
67
-
68
- Dataclass with parsed ARN components:
69
-
70
- | Field | Type | Description |
71
- |-------|------|-------------|
72
- | `aws_partition` | `str` | AWS partition (aws, aws-cn, aws-us-gov) |
73
- | `aws_service` | `str` | AWS service name |
74
- | `aws_region` | `str` | AWS region (may be empty for global resources) |
75
- | `aws_account` | `str` | AWS account ID |
76
- | `resource_type` | `str` | Canonical resource type from AWS docs |
77
- | `resource_types` | `list[str]` | All known names for this resource type |
78
- | `attributes` | `dict[str, str]` | All captured attributes from the pattern |
79
-
80
- Properties:
81
-
82
- | Property | Description |
83
- |----------|-------------|
84
- | `resource_id` | Resource identifier (prefers groups ending in `Id`, falls back to `Name`, then last group) |
85
- | `resource_name` | Resource name (prefers groups ending in `Name`, falls back to `resource_id`) |
86
- | `aws_sdk_services` | List of boto3 client names for this service (e.g., `['elb', 'elbv2']` for elasticloadbalancing) |
87
-
88
- ### `ARNError`
89
-
90
- Exception raised when ARN parsing fails. Inherits from `ValueError`.
91
-
92
- ## Versioning
93
-
94
- This project uses [CalVer](https://calver.org/) with format `YYYY.0M.MICRO` (e.g., `2026.01.0`).
95
-
96
- ## Development
97
-
98
- Prerequisites: [uv](https://github.com/astral-sh/uv)
99
-
100
- ```bash
101
- make lint # Run ruff linter
102
- make test # Run pytest tests
103
- make check # Run lint and test
104
- make build # Build wheel and tarball
105
- make publish # Build and upload to PyPI
106
- make clean # Remove build artifacts
107
- ```
108
-
109
- Regenerate patterns from AWS docs:
110
-
111
- ```bash
112
- cd codegen && uv run codegen.py
113
- ```
File without changes
File without changes
File without changes
File without changes