diff --git a/c7n/filters/iamaccess.py b/c7n/filters/iamaccess.py index 022a7c74cc6..c38bf5a1f94 100644 --- a/c7n/filters/iamaccess.py +++ b/c7n/filters/iamaccess.py @@ -257,7 +257,7 @@ def normalize_conditions(self, s): 'ArnLike', 'IpAddress', 'NotIpAddress') - set_conditions = ('ForAllValues', 'ForAnyValues') + set_conditions = ('ForAllValues', 'ForAnyValue') for s_cond_op in list(s['Condition'].keys()): if s_cond_op not in conditions: diff --git a/c7n/filters/waf.py b/c7n/filters/waf.py index 076be6f4b2c..dec64a67456 100644 --- a/c7n/filters/waf.py +++ b/c7n/filters/waf.py @@ -223,8 +223,14 @@ def _legacy_match(self, r_acl): # based on the scope def _get_web_acls(self, scope): if self._cached_web_acls is None: - self._cached_web_acls = self.manager.get_resource_manager('wafv2').resources( - query=dict(Scope=scope), + # Scope must be supplied as resource manager data rather than a query + # kwarg. The wafv2 manager derives both the API Scope and the region + # used for the call from its own data (CLOUDFRONT web acls are global + # and must be addressed via us-east-1), and a Scope passed via + # resources(query=...) is overwritten by the manager's own value. + wafv2 = self.manager.get_resource_manager( + 'wafv2', {'query': [{'Scope': scope}]}) + self._cached_web_acls = wafv2.resources( # required to get the additional detail needed for this filter (e.g. Rules), but # the legacy mode does not require additional detail augment=(not self._is_legacy) diff --git a/c7n/lookup.py b/c7n/lookup.py index 123d5659e4b..46cf6d0aa21 100644 --- a/c7n/lookup.py +++ b/c7n/lookup.py @@ -6,28 +6,52 @@ import copy +class Skip: + """Sentinel returned by Lookup.resolve_value to omit a value entirely.""" + + __slots__ = () + + def __repr__(self): + return 'Lookup.SKIP' + + class Lookup: RESOURCE_SOURCE = 'resource' + SKIP = Skip() + + # A lookup needs a key, a fallback, or both. With a key it resolves against + # the resource and falls back to 'default-value' when the path yields + # nothing. With no key it is just the fallback -- which callers that pass a + # name to resolve_value treat as a conditional default, writing it only + # when that name is not already present on the resource. schema = { 'type': 'object', - 'oneOf': [ - { - 'properties': { - 'type': {'type': 'string', 'enum': [RESOURCE_SOURCE]}, - 'key': {'type': 'string'} - }, - 'additionalProperties': False, - 'required': ['type', 'key'] - } + 'properties': { + 'type': {'type': 'string', 'enum': [RESOURCE_SOURCE]}, + 'key': {'type': 'string'}, + 'default-value': {}, + }, + 'additionalProperties': False, + 'required': ['type'], + 'anyOf': [ + {'required': ['key']}, + {'required': ['default-value']}, ] } @staticmethod - def lookup_type(schema): + def lookup_type(schema, default_schema=None): + """Schema for a value that may be given directly or looked up. + + ``default_schema`` types the lookup's fallback, and defaults to + ``schema``. Pass it when the fallback is narrower than the value -- + tag values, for instance, accept unquoted YAML scalars for backwards + compatibility, but a fallback is always written as a string. + """ lookup_schema = copy.deepcopy(Lookup.schema) - for lookup in lookup_schema['oneOf']: - lookup['properties']['default-value'] = schema + lookup_schema['properties']['default-value'] = ( + schema if default_schema is None else default_schema) return { 'oneOf': [ @@ -36,6 +60,30 @@ def lookup_type(schema): ] } + @staticmethod + def resolve_value(spec, resource, name=None, current_names=()): + """Resolve a value spec against a resource. + + Handles both lookup forms and plain scalars: + + - a scalar is returned unchanged + - ``{type: resource, key: }`` resolves against the resource, + falling back to ``default-value`` when the path yields nothing + - ``{type: resource, default-value: }`` (no key) is a conditional + default: it resolves to ``x`` only when ``name`` is absent from + ``current_names``, and to ``Lookup.SKIP`` otherwise. + """ + if not Lookup.is_lookup(spec): + return spec + if 'key' not in spec and name in current_names: + return Lookup.SKIP + return Lookup.extract(spec, resource) + + @staticmethod + def has_lookups(spec_map): + """True if any value in the mapping is a lookup rather than a scalar.""" + return any(Lookup.is_lookup(v) for v in spec_map.values()) + @staticmethod def extract(source, data=None): if Lookup.is_lookup(source): @@ -54,10 +102,11 @@ def get_value(source, data=None): @staticmethod def get_value_from_resource(source, resource): - value = jmespath_search(source['key'], resource) + if 'key' in source: + value = jmespath_search(source['key'], resource) + if value is not None: + return value - if value is not None: - return value if 'default-value' not in source: raise Exception('Lookup for key, {}, returned None'.format(source['key'])) else: diff --git a/c7n/query.py b/c7n/query.py index 73d6101afde..a0357e803f8 100644 --- a/c7n/query.py +++ b/c7n/query.py @@ -461,13 +461,14 @@ class QueryResourceManager(ResourceManager, metaclass=QueryMeta): retry = staticmethod( get_retry(( - 'TooManyRequestsException', - 'ThrottlingException', + 'Client.RequestLimitExceeded', + 'InternalServerException', 'RequestLimitExceeded', 'Throttled', 'ThrottledException', 'Throttling', - 'Client.RequestLimitExceeded'))) + 'ThrottlingException', + 'TooManyRequestsException'))) source_mapping = sources diff --git a/c7n/resources/asg.py b/c7n/resources/asg.py index ca18a28e1b4..c6fc0bfcf61 100644 --- a/c7n/resources/asg.py +++ b/c7n/resources/asg.py @@ -20,9 +20,11 @@ from c7n.manager import resources from c7n import query from c7n.resources.securityhub import PostFinding -from c7n.tags import TagActionFilter, DEFAULT_TAG, TagCountFilter, TagTrim, TagDelayedAction +from c7n.tags import ( + TagActionFilter, DEFAULT_TAG, TagCountFilter, TagTrim, TagDelayedAction, + TagValueResolver, has_dynamic_tag_values, tag_value_schema) from c7n.utils import ( - FormatDate, local_session, type_schema, chunks, get_retry, select_keys) + local_session, type_schema, chunks, get_retry, select_keys) from .ec2 import deserialize_user_data @@ -1104,7 +1106,7 @@ def process_resource_set(self, client, asgs, tags): @ASG.action_registry.register('tag') @ASG.action_registry.register('mark') -class Tag(Action): +class Tag(TagValueResolver, Action): """Action to add a tag to an ASG The *propagate* parameter can be used to specify that the tag being added @@ -1125,13 +1127,32 @@ class Tag(Action): key: OwnerName value: OwnerName propagate: true + + Tag values may also be looked up per-asg from the asg's attributes: + + .. code-block:: yaml + + policies: + - name: asg-tag-owner + resource: asg + actions: + - type: tag + propagate: true + tags: + Owner: + type: resource + key: "Tags[?Key=='Team'].Value | [0]" # from the Team tag + default-value: unknown + CostCenter: + type: resource + default-value: unassigned # set only if CostCenter absent """ schema = type_schema( 'tag', key={'type': 'string'}, - value={'type': 'string'}, - tags={'type': 'object'}, + value=tag_value_schema(), + tags={'type': 'object', 'additionalProperties': tag_value_schema()}, # Backwards compatibility tag={'type': 'string'}, msg={'type': 'string'}, @@ -1141,34 +1162,57 @@ class Tag(Action): permissions = ('autoscaling:CreateOrUpdateTags',) batch_size = 1 - def get_tag_set(self): - tags = [] + def get_tag_spec_map(self): + spec_map = {} + tags = self.data.get('tags', {}) key = self.data.get('key', self.data.get('tag', DEFAULT_TAG)) - value = self.data.get( - 'value', self.data.get( - 'msg', 'AutoScaleGroup does not meet policy guidelines')) + value = self.data.get('value', self.data.get('msg')) + # The mark default only applies to the single-tag form. A policy that + # spells out a tags mapping gets that mapping and nothing else -- + # otherwise every asg picks up a marker tag it never asked for, and a + # conditional default can never resolve to an empty payload. + if value is None and not tags: + value = 'AutoScaleGroup does not meet policy guidelines' if key and value: - tags.append({'Key': key, 'Value': value}) + spec_map[key] = value + + spec_map.update(tags) - for k, v in self.data.get('tags', {}).items(): - tags.append({'Key': k, 'Value': v}) + return spec_map - return tags + def resolve_tag_sets(self, asgs, spec_map): + """Yield (asg_set, tags) pairs to submit. + + Static values are shared by every asg, so they go out in batches. + Dynamic values are resolved per asg and then regrouped, so asgs that + land on the same payload still batch together, and an asg whose tags + all resolve to skip drops out entirely. + """ + if not has_dynamic_tag_values(spec_map): + tags = [{'Key': k, 'Value': v} for k, v in spec_map.items()] + self.interpolate_values(tags) + for asg_set in chunks(asgs, self.batch_size): + yield asg_set, tags + return + + for asg_set, resolved in self.resolve_and_group(asgs, spec_map): + tags = [{'Key': k, 'Value': v} for k, v in resolved.items()] + for chunk in chunks(asg_set, self.batch_size): + yield chunk, tags def process(self, asgs): - tags = self.get_tag_set() + spec_map = self.get_tag_spec_map() error = None - self.interpolate_values(tags) - client = self.get_client() with self.executor_factory(max_workers=2) as w: futures = {} - for asg_set in chunks(asgs, self.batch_size): + for asg_set, tags in self.resolve_tag_sets(asgs, spec_map): futures[w.submit( - self.process_resource_set, client, asg_set, tags)] = asg_set + self.process_resource_set, client, asg_set, tags)] = ( + asg_set, tags) for f in as_completed(futures): - asg_set = futures[f] + asg_set, tags = futures[f] if f.exception(): self.log.exception( "Exception tagging tag:%s error:%s asg:%s" % ( @@ -1194,14 +1238,6 @@ def process_resource_set(self, client, asgs, tags): a.setdefault('Tags', []).append(atags) self.manager.retry(client.create_or_update_tags, Tags=tag_params) - def interpolate_values(self, tags): - params = { - 'account_id': self.manager.config.account_id, - 'now': FormatDate.utcnow(), - 'region': self.manager.config.region} - for t in tags: - t['Value'] = t['Value'].format(**params) - def get_client(self): return local_session(self.manager.session_factory).client('autoscaling') diff --git a/c7n/resources/aws.py b/c7n/resources/aws.py index feb11628f72..7d29350db6b 100644 --- a/c7n/resources/aws.py +++ b/c7n/resources/aws.py @@ -726,12 +726,22 @@ def transfer(self): self.ctx.session_factory(region=bucket_region, assume=False).client('s3')) return self._transfer + def get_sse_args(self): + # encryption configurable via output url query params, eg + # s3://bucket/prefix?sse=aws:kms&kms-key=alias/custodian + kms_key = self.config.get('kms-key') + sse = self.config.get('sse') or (kms_key and 'aws:kms') or 'AES256' + args = {'ServerSideEncryption': sse} + if sse == 'aws:kms' and kms_key: + args['SSEKMSKeyId'] = kms_key + return args + def upload_file(self, path, key): + extra_args = {'ACL': 'bucket-owner-full-control'} + extra_args.update(self.get_sse_args()) self.transfer.upload_file( path, self.bucket, key, - extra_args={ - 'ACL': 'bucket-owner-full-control', - 'ServerSideEncryption': 'AES256'}) + extra_args=extra_args) @clouds.register('aws') diff --git a/c7n/resources/cleanrooms.py b/c7n/resources/cleanrooms.py index a581f364bc0..1a477a76a7c 100644 --- a/c7n/resources/cleanrooms.py +++ b/c7n/resources/cleanrooms.py @@ -1,10 +1,12 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +from c7n.filters import ListItemFilter from c7n.manager import resources from c7n.query import ( ChildResourceManager, QueryResourceManager, TypeInfo, DescribeWithResourceTags) +from c7n.utils import local_session, type_schema @resources.register('cleanrooms-collaboration') @@ -27,6 +29,53 @@ class resource_type(TypeInfo): source_mapping = {'describe': DescribeWithResourceTags} +@CleanRoomsCollaboration.filter_registry.register('members') +class CleanRoomsCollaborationMemberFilter(ListItemFilter): + """Filter Clean Rooms collaborations on their members details. + + :example: + + .. code-block:: yaml + + policies: + - name: cleanrooms-collaboration-with-members + resource: cleanrooms-collaboration + filters: + - type: members + attrs: + - type: value + key: status + value: ACTIVE + - type: value + key: abilities + op: intersect + value: [CAN_QUERY, CAN_RECEIVE] + """ + + schema = type_schema('members', + attrs={"$ref": "#/definitions/filters_common/list_item_attrs"}, + count={"type": "number"}, + count_op={"$ref": "#/definitions/filters_common/comparison_operators"}) + + annotation_key = 'c7n:Members' + permissions = ('cleanrooms:ListMembers',) + + def __init__(self, data, manager=None): + super().__init__(data, manager) + data['key'] = f'"{self.annotation_key}"' + + def get_item_values(self, collaboration): + if self.annotation_key in collaboration: + return collaboration[self.annotation_key] + client = local_session(self.manager.session_factory).client('cleanrooms') + members = self.manager.retry( + client.get_paginator('list_members').paginate, + collaborationIdentifier=collaboration['id'] + ).build_full_result().get('memberSummaries', []) + collaboration[self.annotation_key] = members + return members + + @resources.register('cleanrooms-membership') class CleanRoomsMembership(QueryResourceManager): """AWS Clean Rooms Membership""" diff --git a/c7n/resources/emr.py b/c7n/resources/emr.py index 53ebd054a67..f778f96de7a 100644 --- a/c7n/resources/emr.py +++ b/c7n/resources/emr.py @@ -383,6 +383,7 @@ class EMRServerless(QueryResourceManager): class resource_type(TypeInfo): service = 'emr-serverless' enum_spec = ('list_applications', 'applications', None) + detail_spec = ('get_application', 'applicationId', 'id', 'application') arn = 'arn' arn_type = '/applications' name = 'name' diff --git a/c7n/resources/iam.py b/c7n/resources/iam.py index 4813e0a4700..689245b6853 100644 --- a/c7n/resources/iam.py +++ b/c7n/resources/iam.py @@ -36,7 +36,7 @@ from c7n.resolver import ValuesFrom from c7n.tags import TagActionFilter, TagDelayedAction, Tag, RemoveTag, universal_augment from c7n.utils import ( - get_partition, local_session, type_schema, chunks, filter_empty, QueryParser, + get_partition, get_retry, local_session, type_schema, chunks, filter_empty, QueryParser, select_keys ) @@ -44,6 +44,18 @@ from c7n.resources.securityhub import OtherResourcePostFinding +_iam_tag_retry = get_retry(( + 'ConcurrentModification', + 'TooManyRequestsException', + 'ThrottlingException', + 'RequestLimitExceeded', + 'Throttled', + 'ThrottledException', + 'Throttling', + 'Client.RequestLimitExceeded', +)) + + class DescribeGroup(DescribeSource): def get_resources(self, resource_ids, cache=True): @@ -149,8 +161,7 @@ class RoleTag(Tag): def process_resource_set(self, client, roles, tags): for role in roles: try: - self.manager.retry( - client.tag_role, RoleName=role['RoleName'], Tags=tags) + _iam_tag_retry(client.tag_role, RoleName=role['RoleName'], Tags=tags) except client.exceptions.NoSuchEntityException: continue @@ -164,8 +175,7 @@ class RoleRemoveTag(RemoveTag): def process_resource_set(self, client, roles, tags): for role in roles: try: - self.manager.retry( - client.untag_role, RoleName=role['RoleName'], TagKeys=tags) + _iam_tag_retry(client.untag_role, RoleName=role['RoleName'], TagKeys=tags) except client.exceptions.NoSuchEntityException: continue @@ -281,8 +291,7 @@ class UserTag(Tag): def process_resource_set(self, client, users, tags): for u in users: try: - self.manager.retry( - client.tag_user, UserName=u['UserName'], Tags=tags) + _iam_tag_retry(client.tag_user, UserName=u['UserName'], Tags=tags) except client.exceptions.NoSuchEntityException: continue @@ -296,8 +305,7 @@ class UserRemoveTag(RemoveTag): def process_resource_set(self, client, users, tags): for u in users: try: - self.manager.retry( - client.untag_user, UserName=u['UserName'], TagKeys=tags) + _iam_tag_retry(client.untag_user, UserName=u['UserName'], TagKeys=tags) except client.exceptions.NoSuchEntityException: continue diff --git a/c7n/resources/lattice.py b/c7n/resources/lattice.py index bd773d85f15..af855329d02 100644 --- a/c7n/resources/lattice.py +++ b/c7n/resources/lattice.py @@ -1,18 +1,25 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import logging +import re + from c7n.filters import ValueFilter from c7n.filters.iamaccess import CrossAccountAccessFilter from c7n.manager import resources from c7n.query import ( ChildDescribeSource, ChildResourceManager, + ChildResourceQuery, DescribeWithResourceTags, QueryResourceManager, + sources, TypeInfo, ) from c7n.tags import universal_augment from c7n.utils import local_session, type_schema +log = logging.getLogger('custodian.lattice') + @resources.register('vpc-lattice-service-network') class VPCLatticeServiceNetwork(QueryResourceManager): @@ -117,6 +124,139 @@ class resource_type(TypeInfo): permissions_enum = ('vpc-lattice:ListListeners',) +class VPCLatticeRuleQuery(ChildResourceQuery): + def _list_listeners(self, service_id=None): + listener_manager = self.manager.get_resource_manager('vpc-lattice-listener') + + # If service is specified, only get listeners for that service. + if service_id: + query = {'serviceIdentifier': service_id} + listeners = listener_manager.resources(query, augment=False) + return [{**l, **query} for l in listeners] + + # Otherwise, get all listeners and parse the service id from the arn. + listeners = [] + for l in listener_manager.resources(augment=False): + match = re.search(r":service/(svc-[^/]+)/listener/", l['arn']) + service_id = match.group(1) if match else None + listeners.append({**l, 'serviceIdentifier': service_id}) + return listeners + + def filter(self, resource_manager, parent_ids=None, **params): + if parent_ids: + raise ValueError( + 'This query is dependent on more than one ancestor id, so do not pass parent_ids.' + ) + + m = self.resolve(resource_manager.resource_type) + client = local_session(self.session_factory).client(m.service) + enum_op, path, extra_args = m.enum_spec + + def list_rules(service_id, listener_id): + ids = {'serviceIdentifier': service_id, 'listenerIdentifier': listener_id} + rules = self._invoke_client_enum( + client, + enum_op, + {**params, **(extra_args or {}), **ids}, + path, + retry=self.manager.retry + ) + return [{**r, **ids} for r in rules] # Augment rules with service and listener ids + + service_id = params.get('serviceIdentifier') + listener_id = params.get('listenerIdentifier') + if service_id and listener_id: + # Query the rules directly + rules = list_rules(service_id, listener_id) + else: + # Query listeners and then rules + if listener_id: + raise ValueError( + 'Do not pass listenerIdentifier without serviceIdentifier in the query block.' + ' Either pass serviceIdentifier too or use listenerIdentifier as a filter.' + ) + listeners = self._list_listeners(service_id) + rules = [] + for l in listeners: + rules.extend(list_rules(l['serviceIdentifier'], l['id'])) + return rules + + +@sources.register('vpc-lattice-rule') +class VPCLatticeRuleSource(ChildDescribeSource): + resource_query_factory = VPCLatticeRuleQuery + + def augment(self, resources): + return universal_augment(self.manager, resources) + + def get_query_params(self, query): + """Pass serviceIdentifier and listenerIdentifier through to `filter`""" + supported = ('serviceIdentifier', 'listenerIdentifier') + query = query or {} + for q in self.manager.data.get('query', []): + for k in q: + if k in supported: + query[k] = q[k] + else: + log.warning(f'"{k}" is not a supported query parameter for this resource.') + return query + + +@resources.register('vpc-lattice-rule') +class VPCLatticeRule(ChildResourceManager): + """VPC Lattice listener rule resource. + + Rules are enumerated through listeners and require both + ``serviceIdentifier`` and ``listenerIdentifier`` for direct API queries. + This resource supports a custom ``query`` block with those keys to narrow + enumeration before filters are applied. + + If only ``serviceIdentifier`` is provided in the query, Custodian will + enumerate listeners for that service and then list rules for each listener. + If both identifiers are provided, Custodian queries the rule API directly. + A query with ``listenerIdentifier`` alone is rejected because the VPC + Lattice API also requires the parent service identifier. + + :example: + + .. code-block:: yaml + + policies: + - name: lattice-rule-by-service + resource: aws.vpc-lattice-rule + query: + - serviceIdentifier: svc-0123456789abcdef0 + filters: + - isDefault: false + + - name: lattice-rule-by-service-and-listener + resource: aws.vpc-lattice-rule + query: + - serviceIdentifier: svc-0123456789abcdef0 + - listenerIdentifier: listener-0123456789abcdef0 + filters: + - type: value + key: priority + value: 10 + """ + + child_source = 'vpc-lattice-rule' + class resource_type(TypeInfo): + service = 'vpc-lattice' + enum_spec = ('list_rules', 'items', None) + parent_spec = ('vpc-lattice-listener', 'listenerIdentifier', True) + arn = 'arn' + id = 'id' + name = 'name' + universal_taggable = object() + permissions_enum = ( + 'vpc-lattice:ListRules', + 'vpc-lattice:ListListeners', + 'vpc-lattice:ListServices', + ) + permissions_augment = ('vpc-lattice:ListTagsForResource',) + + class DescribeServiceNetworkAssociation(ChildDescribeSource): def augment(self, resources): return universal_augment(self.manager, resources) diff --git a/c7n/resources/resource_map.py b/c7n/resources/resource_map.py index 18f29531a1c..a9e46514500 100644 --- a/c7n/resources/resource_map.py +++ b/c7n/resources/resource_map.py @@ -307,6 +307,7 @@ "aws.s3-access-point": "c7n.resources.s3control.AccessPoint", "aws.s3-access-point-multi": "c7n.resources.s3control.MultiRegionAccessPoint", "aws.s3-storage-lens": "c7n.resources.s3control.StorageLens", + "aws.sagemaker-app": "c7n.resources.sagemaker.SagemakerApp", "aws.sagemaker-auto-ml-job": "c7n.resources.sagemaker.SagemakerAutoMLJob", "aws.sagemaker-cluster": "c7n.resources.sagemaker.Cluster", "aws.sagemaker-compilation-job": "c7n.resources.sagemaker.SagemakerCompilationJob", @@ -323,7 +324,9 @@ "aws.sagemaker-job": "c7n.resources.sagemaker.SagemakerJob", "aws.sagemaker-model": "c7n.resources.sagemaker.Model", "aws.sagemaker-notebook": "c7n.resources.sagemaker.NotebookInstance", + "aws.sagemaker-space": "c7n.resources.sagemaker.SagemakerSpace", "aws.sagemaker-transform-job": "c7n.resources.sagemaker.SagemakerTransformJob", + "aws.sagemaker-user-profile": "c7n.resources.sagemaker.SagemakerUserProfile", "aws.sagemaker-hyperparameter-tuning-job": "c7n.resources.sagemaker.SagemakerHyperParameterTuningJob", "aws.sagemaker-model-bias-job-definition": @@ -389,6 +392,7 @@ "c7n.resources.lattice.VPCLatticeServiceNetworkAssociation", "aws.vpc-lattice-target-group": "c7n.resources.lattice.VPCLatticeTargetGroup", "aws.vpc-lattice-listener": "c7n.resources.lattice.VPCLatticeListener", + "aws.vpc-lattice-rule": "c7n.resources.lattice.VPCLatticeRule", "aws.client-vpn-endpoint": "c7n.resources.vpc.ClientVpnEndpoint", "aws.vpn-connection": "c7n.resources.vpc.VPNConnection", "aws.vpn-gateway": "c7n.resources.vpc.VPNGateway", diff --git a/c7n/resources/sagemaker.py b/c7n/resources/sagemaker.py index 96b93c540ef..222124ac96c 100644 --- a/c7n/resources/sagemaker.py +++ b/c7n/resources/sagemaker.py @@ -1261,3 +1261,140 @@ class resource_type(TypeInfo): @SagemakerDomain.filter_registry.register('kms-key') class SagemakerDomainKmsFilter(KmsRelatedFilter): RelatedIdsExpression = 'KmsKeyId' + + +class SagemakerUserProfileDescribe(DescribeSource): + + def augment(self, resources): + client = local_session(self.manager.session_factory).client('sagemaker') + resources = [ + self.manager.retry( + client.describe_user_profile, + DomainId=r['DomainId'], + UserProfileName=r['UserProfileName'], + ignore_err_codes=('ResourceNotFound',)) + for r in resources] + resources = [r for r in resources if r] + return universal_augment(self.manager, resources) + + +@resources.register('sagemaker-user-profile') +class SagemakerUserProfile(QueryResourceManager): + """AWS SageMaker Studio User Profile + + :example: + + .. code-block:: yaml + + policies: + - name: sagemaker-user-profile-untagged + resource: aws.sagemaker-user-profile + filters: + - tag:favorite-color: absent + """ + + class resource_type(TypeInfo): + service = 'sagemaker' + enum_spec = ('list_user_profiles', 'UserProfiles', None) + arn = id = 'UserProfileArn' + name = 'UserProfileName' + date = 'CreationTime' + cfn_type = 'AWS::SageMaker::UserProfile' + permission_prefix = 'sagemaker' + permissions_augment = ("sagemaker:DescribeUserProfile",) + universal_taggable = object() + + source_mapping = {'describe': SagemakerUserProfileDescribe} + + +class SagemakerSpaceDescribe(DescribeSource): + + def augment(self, resources): + client = local_session(self.manager.session_factory).client('sagemaker') + resources = [ + self.manager.retry( + client.describe_space, + DomainId=r['DomainId'], + SpaceName=r['SpaceName'], + ignore_err_codes=('ResourceNotFound',)) + for r in resources] + resources = [r for r in resources if r] + return universal_augment(self.manager, resources) + + +@resources.register('sagemaker-space') +class SagemakerSpace(QueryResourceManager): + """AWS SageMaker Studio Space + + :example: + + .. code-block:: yaml + + policies: + - name: sagemaker-space-untagged + resource: aws.sagemaker-space + filters: + - tag:favorite-color: absent + """ + + class resource_type(TypeInfo): + service = 'sagemaker' + enum_spec = ('list_spaces', 'Spaces', None) + arn = id = 'SpaceArn' + name = 'SpaceName' + date = 'CreationTime' + cfn_type = 'AWS::SageMaker::Space' + permission_prefix = 'sagemaker' + permissions_augment = ("sagemaker:DescribeSpace",) + universal_taggable = object() + + source_mapping = {'describe': SagemakerSpaceDescribe} + + +class SagemakerAppDescribe(DescribeSource): + + def augment(self, resources): + client = local_session(self.manager.session_factory).client('sagemaker') + + def _describe(r): + kw = dict( + DomainId=r['DomainId'], AppType=r['AppType'], AppName=r['AppName']) + if r.get('UserProfileName'): + kw['UserProfileName'] = r['UserProfileName'] + if r.get('SpaceName'): + kw['SpaceName'] = r['SpaceName'] + return self.manager.retry( + client.describe_app, ignore_err_codes=('ResourceNotFound',), **kw) + + resources = [_describe(r) for r in resources] + resources = [r for r in resources if r] + return universal_augment(self.manager, resources) + + +@resources.register('sagemaker-app') +class SagemakerApp(QueryResourceManager): + """AWS SageMaker Studio App + + :example: + + .. code-block:: yaml + + policies: + - name: sagemaker-app-untagged + resource: aws.sagemaker-app + filters: + - tag:favorite-color: absent + """ + + class resource_type(TypeInfo): + service = 'sagemaker' + enum_spec = ('list_apps', 'Apps', None) + arn = id = 'AppArn' + name = 'AppName' + date = 'CreationTime' + cfn_type = 'AWS::SageMaker::App' + permission_prefix = 'sagemaker' + permissions_augment = ("sagemaker:DescribeApp",) + universal_taggable = object() + + source_mapping = {'describe': SagemakerAppDescribe} diff --git a/c7n/resources/waf.py b/c7n/resources/waf.py index eb586f474bd..0580a078f08 100644 --- a/c7n/resources/waf.py +++ b/c7n/resources/waf.py @@ -249,6 +249,15 @@ def get_permissions(self): # set REGIONAL for Scope as default def get_query_params(self, query_params): query_params = query_params or {} + # Scope is owned by the resource manager, since it also determines which + # region the wafv2 API is called in. Fail loudly rather than silently + # discarding a conflicting Scope supplied by the caller. + requested_scope = query_params.get('Scope') + if requested_scope is not None and requested_scope != self.manager.scope: + raise PolicyValidationError( + "wafv2 Scope conflict: %s was requested but the resource manager " + "scope is %s. Pass Scope via the resource manager's 'query' data." + % (requested_scope, self.manager.scope)) # Parse query from policy data queries = self.manager.data.get('query', []) for q in queries: diff --git a/c7n/tags.py b/c7n/tags.py index 2ecb97235d0..443b76f327d 100644 --- a/c7n/tags.py +++ b/c7n/tags.py @@ -30,7 +30,7 @@ # Sentinel: the resolver returns this to omit a tag from a resource's payload. -TAG_VALUE_SKIP = object() +TAG_VALUE_SKIP = Lookup.SKIP def tag_value_schema(): @@ -38,35 +38,18 @@ def tag_value_schema(): Accepts a scalar, a resource lookup by key (with optional fallback), or a conditional default with no key (write only when the tag is absent). + + Tag values are strings, but unquoted YAML scalars have always been + accepted here and coerced on the way out, so the scalar form stays wide. + A fallback has no such history and is held to a string. """ - return { - 'oneOf': [ - {'type': ['string', 'number', 'boolean']}, - { - 'type': 'object', - 'additionalProperties': False, - 'required': ['type', 'key'], - 'properties': { - 'type': {'enum': [Lookup.RESOURCE_SOURCE]}, - 'key': {'type': 'string'}, - 'default-value': {'type': 'string'}, - }, - }, - { - 'type': 'object', - 'additionalProperties': False, - 'required': ['type', 'default-value'], - 'properties': { - 'type': {'enum': [Lookup.RESOURCE_SOURCE]}, - 'default-value': {'type': 'string'}, - }, - }, - ] - } + return Lookup.lookup_type( + {'type': ['string', 'number', 'boolean']}, + default_schema={'type': 'string'}) def has_dynamic_tag_values(spec_map): - return any(Lookup.is_lookup(v) for v in spec_map.values()) + return Lookup.has_lookups(spec_map) def resource_tag_keys(resource): @@ -85,14 +68,76 @@ def resolve_tag_value(spec, tag_name, resource, current_tag_keys): Returns the resolved value, or TAG_VALUE_SKIP to omit the tag. """ - if not Lookup.is_lookup(spec): - return spec - if 'key' in spec: - return Lookup.extract(spec, resource) - # Conditional default (no key): write only if the tag is absent. - if tag_name in current_tag_keys: - return TAG_VALUE_SKIP - return spec['default-value'] + return Lookup.resolve_value(spec, resource, tag_name, current_tag_keys) + + +class TagValueResolver: + """Turn a mapping of tag value specs into concrete tags for a resource. + + A mixin rather than part of Tag itself because the asg tag action isn't a + Tag subclass, but resolves the same per-resource lookups and writes the + same {account_id}/{now}/{region} placeholders. + """ + + def get_interpolation_params(self): + """Placeholder values shared by every tag in a run. + + None of these depend on the resource being tagged, so a caller + resolving values per resource builds them once and passes them back + in rather than re-deriving a fresh {now} for each one. + """ + return { + 'account_id': self.manager.config.account_id, + 'now': utils.FormatDate.utcnow(), + 'region': self.manager.config.region} + + def resolve_and_group(self, resources, spec_map): + """Resolve tag values per resource and group by identical payload. + + Returns a list of (resource_set, resolved_dict). Resources whose + payload is empty (all tags conditionally skipped) are dropped. + """ + groups = {} + # {now} and friends don't vary per resource, so fix them once for the + # whole run -- otherwise a large resource set drifts across seconds and + # splits into a group per timestamp. + params = self.get_interpolation_params() + for r in resources: + resolved = self.resolve_resource_tags(spec_map, r, params) + if not resolved: + continue + sig = tuple(sorted(resolved.items())) + groups.setdefault(sig, ([], resolved))[0].append(r) + return list(groups.values()) + + def resolve_resource_tags(self, spec_map, resource, params): + """Resolve a spec mapping against one resource. + + Returns {name: value} of the tags to write - a conditional default the + resource already carries is left out, so the mapping comes back empty + when there's nothing to do for this resource. + """ + current = resource_tag_keys(resource) + resolved = {} + for name, spec in spec_map.items(): + value = resolve_tag_value(spec, name, resource, current) + if value is TAG_VALUE_SKIP: + continue + resolved[name] = self.interpolate_single_value(value, params) + return resolved + + def interpolate_single_value(self, value, params=None): + """Interpolate placeholders in a single tag value.""" + if params is None: + params = self.get_interpolation_params() + return str(value).format(**params) + + def interpolate_values(self, tags, params=None): + """Interpolate in a list of tags - 'old' ec2 format""" + if params is None: + params = self.get_interpolation_params() + for t in tags: + t['Value'] = self.interpolate_single_value(t['Value'], params) def register_ec2_tags(filters, actions): @@ -424,7 +469,7 @@ def __call__(self, i): return op(tag_count, count) -class Tag(Action): +class Tag(TagValueResolver, Action): """Tag an ec2 resource. Tag values may be looked up per-resource from resource attributes: @@ -499,33 +544,12 @@ def process(self, resources): self.process_resource_set, self.id_key, resources, tags, self.log) return - for resource_set, resolved in self._resolve_and_group(resources, spec_map): + for resource_set, resolved in self.resolve_and_group(resources, spec_map): tags = [{'Key': k, 'Value': v} for k, v in resolved.items()] _common_tag_processer( self.executor_factory, batch_size, self.concurrency, client, self.process_resource_set, self.id_key, resource_set, tags, self.log) - def _resolve_and_group(self, resources, spec_map): - """Resolve tag values per resource and group by identical payload. - - Returns a list of (resource_set, resolved_dict). Resources whose - payload is empty (all tags conditionally skipped) are dropped. - """ - groups = {} - for r in resources: - current = resource_tag_keys(r) - resolved = {} - for name, spec in spec_map.items(): - value = resolve_tag_value(spec, name, r, current) - if value is TAG_VALUE_SKIP: - continue - resolved[name] = self.interpolate_single_value(value) - if not resolved: - continue - sig = tuple(sorted(resolved.items())) - groups.setdefault(sig, ([], resolved))[0].append(r) - return list(groups.values()) - def process_resource_set(self, client, resource_set, tags): mid = self.manager.get_model().id self.manager.retry( @@ -534,21 +558,6 @@ def process_resource_set(self, client, resource_set, tags): Tags=tags, DryRun=self.manager.config.dryrun) - def interpolate_single_value(self, tag): - """Interpolate in a single tag value. - """ - params = { - 'account_id': self.manager.config.account_id, - 'now': utils.FormatDate.utcnow(), - 'region': self.manager.config.region} - return str(tag).format(**params) - - def interpolate_values(self, tags): - """Interpolate in a list of tags - 'old' ec2 format - """ - for t in tags: - t['Value'] = self.interpolate_single_value(t['Value']) - def get_client(self): return utils.local_session(self.manager.session_factory).client( self.manager.resource_type.service) @@ -986,7 +995,7 @@ def process(self, resources): self.process_resource_set, self.id_key, resources, tags, self.log) return - for resource_set, resolved in self._resolve_and_group(resources, spec_map): + for resource_set, resolved in self.resolve_and_group(resources, spec_map): _common_tag_processer( self.executor_factory, batch_size, self.concurrency, client, self.process_resource_set, self.id_key, resource_set, resolved, @@ -999,11 +1008,13 @@ def process_resource_set(self, client, resource_set, tags): return universal_retry( client.tag_resources, ResourceARNList=arns, Tags=tags) - def interpolate_values(self, tags): + def interpolate_values(self, tags, params=None): """Interpolate in a list of tags - 'new' resourcegroupstaggingapi format """ + if params is None: + params = self.get_interpolation_params() for key in list(tags.keys()): - tags[key] = self.interpolate_single_value(tags[key]) + tags[key] = self.interpolate_single_value(tags[key], params) def get_client(self): # For global resources, manage tags from us-east-1 diff --git a/c7n/version.py b/c7n/version.py index dbfa72e41c2..dea98299b11 100644 --- a/c7n/version.py +++ b/c7n/version.py @@ -1,2 +1,2 @@ # Generated via tools/dev/devpkg.py -version = "0.9.52a5+a83dda5c9" +version = "0.9.53a1+e4c099e03" diff --git a/docs/source/gcp/examples/audit-event-recording.rst b/docs/source/gcp/examples/audit-event-recording.rst new file mode 100644 index 00000000000..ec50606b3d1 --- /dev/null +++ b/docs/source/gcp/examples/audit-event-recording.rst @@ -0,0 +1,213 @@ +.. _gcp_audit_event_recording: + +Recording gcp-audit Event Fixtures +==================================== + +Tests for ``gcp-audit`` mode policies run +``exec_mode.run(event_data("some-event.json"), None)`` against a +fixture event -- a Cloud Audit Log ``LogEntry``. The test helper, +``audit_event_recorder``, in ``tools/c7n_gcp/tests/gcp_common.py``, +records those fixtures from real GCP Cloud Audit Log entries instead +of hand-writing synthetic event JSON, which easily drifts from what +GCP actually sends. + +Normally, when running ``gcp-audit`` mode policies, cloud resources are +created to invoke the policies when configured events occur, as +indicated by log entries. The test helper avoids that by capturing +log entries directly. + +Basic usage +------------ + +Recording is gated on ``test.recording``: it needs a live Cloud Logging +client, so it can't run against replayed flight data. Loading the fixture +for assertions always goes through ``event_data(...)``, regardless of mode. + +API calls made by a recording run to *set up* an event, such as +triggering a resource change and polling Cloud Logging, are not +the behavior under test, and should not go through the test flight +recorder. For that reason, a separate setup session is used. + +Cloud Logging returns whole ``LogEntry`` objects, which include +sensitive developer data, such as email and IP addresses and +development project IDs. These are sanitized by the event recorder. + +.. code-block:: python + + import functools + + from c7n_gcp.client import Session + from gcp_common import audit_event_recorder, event_data + + @terraform("firestore_database") + def test_firestore_backup_schedule_update(test, firestore_database): + resource_name = firestore_database.resources[ + "google_firestore_backup_schedule"]["c7n"]["id"] + + policy_session_factory = test.replay_flight_data( + "firestore-backup-schedule-update", project_id=project_id) + + if test.recording: + # Use a separate session for event recording: + setup_session_factory = functools.partial( + Session, project_id=project_id) + setup_session = setup_session_factory() + + # trigger the real change here, e.g. + # setup_session.client(...).execute_command("patch", ...) + + audit_event_recorder( + setup_session_factory, + + # Base name for recorded event-data files: + "firestore-backup-schedule-update.json", + + # Required event operation method-name to record: + method="UpdateBackupSchedule", + + # Additional filters + resource_name=resource_name, + labels={"database_id": database_id}, + + # Use a large skew to capture create events performed + # by Terraform. + start_time_skew_seconds=900, + + ).record() + + # Prevent the cached setup session from being reused: + test.cleanUp() + + policy = test.load_policy( + {...}, session_factory=policy_session_factory) + [resource] = policy.get_execution_mode().run( + event_data("firestore-backup-schedule-update.json"), None) + +The recorder takes a session *factory*, not a session, which is why +``setup_session_factory`` is kept around after being called. + +``test.cleanUp()`` at the end of the block is required, not tidiness. A +session (keyed by region, in ``c7n.utils.CONN_CACHE``) and its http +transport (keyed by thread, by ``Session.http``) are both cached globally, +ignoring the factory the caller asked for. Without it the policy below +reuses ``setup_session``, so nothing is written to flight data -- and the +test still passes, against the live api. For the same reason, build the +setup session directly rather than through ``local_session()``. + +The ``start_time_skew_seconds`` parameter, as its name implies, is normally +used to adjust for clock skew and defaults to 60 seconds. It can also +be used to work around the fact that the event recorder is created in +the test body, after Terraform has created test resources. Future +versions of the test helper will make this unnecessary. + +While actually recording, the flight-data and Terraform decorators take +their recording forms -- ``test.record_flight_data(...)`` and +``@terraform("firestore_database", replay=False)``. Once recorded, commit +the generated fixture(s) under ``tools/c7n_gcp/tests/data/events/`` and +switch both back, same as any other flight-data test. + +``test_disk_audit_mode``, in ``tools/c7n_gcp/tests/test_compute.py``, is a +worked example. + +Filtering options +------------------- + +``audit_event_recorder`` takes arguments to filter desired log events: + +- ``method`` (required) -- a substring match against + ``protoPayload.methodName``, e.g. ``"UpdateBackupSchedule"`` rather than + the full ``google.firestore.admin.v1.FirestoreAdmin.UpdateBackupSchedule``. +- ``resource_name`` (optional) -- a substring match against + ``protoPayload.resourceName``. +- ``labels`` (optional) -- an exact-match mapping against + ``resource.labels``, e.g. ``{"database_id": database_id}``. +- ``start_time_skew_seconds`` (default 60) -- how far before construction + time to set the query's lower time bound. The default covers clock skew + between the test host and Cloud Logging, assuming the recorder is constructed + around the time the event is triggered. Raise it when the event happened + earlier -- notably for a resource a ``@terraform`` fixture created before + the test body ran. +- ``timeout`` / ``poll_interval`` (default 120s/5s) -- how long, and how often, to poll + before giving up. + +``record()`` polls until every matching operation is complete (or the +timeout elapses), rather than issuing a single query -- Cloud Logging +entries can take a few seconds to become queryable after the underlying +API call completes. On timeout it raises, naming any operation still +missing its ``last`` entry; that usually means the filter is too loose and +swept up an unrelated operation, so narrow ``resource_name`` or ``labels``. + +Files created +-------------- + +Some GCP operations have multiple log entries. These log entries have +an ``operation`` field with an ``id`` field used to group them together. + +For a call with no ``operation`` field, the matching entry is +written under the requested name, e.g. ``foo.json``. + +If an entry has an ``operation`` field, the +filename reflects that: + +- entries are grouped by ``operation.id``, and each distinct operation + seen is assigned an index in the order first encountered (0, 1, 2, ...); + index 0 is omitted from the filename, so the common single-operation + case doesn't get a numeric suffix at all +- ``-first`` is appended when ``operation.first`` is set, + ``-last`` when ``operation.last`` is set +- polling stops once *every* operation seen so far has produced its + ``last`` entry -- one operation completing doesn't cut short another + operation the same filter matched + +So the common case for an operation with multiple log entries produces +exactly two files: ``foo-first.json`` and ``foo-last.json``. A second, +distinct operation swept up by the same filter (rare, but possible +with a loose or no ``resource_name`` substring) would produce +``foo-1-first.json`` / ``foo-1-last.json``. + +If a computed filename already exists on disk (e.g. a stale fixture from +an earlier recording run, or two truly ambiguous matches), a numeric +suffix is appended *after* the extension instead -- +``foo.json``, then ``foo.json-1``, ``foo.json-2``, and so on -- and a +warning is logged. These extra files are left in place rather than +cleaned up automatically, so they show up in the diff for the developer +to sort out (rename, merge, or delete as appropriate). + +Sanitization +------------- + +Recorded entries are rewritten before being written to disk: + +- the recording account's project id becomes ``cloud-custodian``, the same + placeholder ``recorder.py`` uses for flight data -- an event naming the + real project would resolve its resource against a project that has no + recorded responses +- any email address becomes ``user@example.com`` +- ``protoPayload.requestMetadata.callerIp`` becomes ``198.51.100.1`` + +Other projects an entry refers to (a public image project, say) are left +alone, as is the ``oauthClientId``, which identifies the client +application rather than the caller. + +Caveats +------- + +Multiple log entries cause multiple policy invocations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned earlier, an operation may have multiple log entries. A +matching policy will be invoked for each entry. + +Creation events don't always identify what was created +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For "update" audit events, ``protoPayload.resourceName`` +reliably names the specific resource being changed, since it already +exists and already has an assigned id. + +For "create" audit events, that isn't reliable. Whether the +event identifies the *created* resource depends on the resource type. +For some resources, ``resourceName`` names some other resource that +serves the role of a factory. In some, but not all, cases, the +identity of the created resource occurs somewhere in log entries in a +resource-type dependent way. diff --git a/pyproject.toml b/pyproject.toml index 74928da9cf4..c8cea784f48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ dependencies = [ "urllib3>2", ] name = "c7n" -version = "0.9.52a5+a83dda5c9" +version = "0.9.53a1+e4c099e03" description = "Cloud Custodian - Policy Rules Engine" readme = "README.md" classifiers = [ diff --git a/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.GetCollaboration_1.json b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.GetCollaboration_1.json new file mode 100644 index 00000000000..8263327cd75 --- /dev/null +++ b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.GetCollaboration_1.json @@ -0,0 +1,49 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "collaboration": { + "id": "62647862-bee9-42e8-8c07-99b0fc492f3a", + "arn": "arn:aws:cleanrooms:us-east-1:644160558196:collaboration/62647862-bee9-42e8-8c07-99b0fc492f3a", + "name": "Compliant Collaboration", + "description": "Compliant Collaboration", + "creatorAccountId": "644160558196", + "creatorDisplayName": "Compliant Member", + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 2, + "second": 3, + "microsecond": 366000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 2, + "second": 3, + "microsecond": 366000 + }, + "memberStatus": "ACTIVE", + "membershipId": "c5773151-1c6c-40ff-86f2-543d68654295", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/c5773151-1c6c-40ff-86f2-543d68654295", + "dataEncryptionMetadata": { + "allowCleartext": false, + "allowDuplicates": false, + "allowJoinsOnColumnsWithDifferentNames": false, + "preserveNulls": false + }, + "queryLogStatus": "ENABLED", + "analyticsEngine": "SPARK", + "allowedResultRegions": [ + "us-east-1" + ], + "isMetricsEnabled": false + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.GetCollaboration_2.json b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.GetCollaboration_2.json new file mode 100644 index 00000000000..a9133b9f722 --- /dev/null +++ b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.GetCollaboration_2.json @@ -0,0 +1,49 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "collaboration": { + "id": "8326c03e-8c92-4cc0-9d84-3be7208e1528", + "arn": "arn:aws:cleanrooms:us-east-1:644160558196:collaboration/8326c03e-8c92-4cc0-9d84-3be7208e1528", + "name": "Noncompliant Collaboration", + "description": "Noncompliant CollaborationFor", + "creatorAccountId": "644160558196", + "creatorDisplayName": "Noncompliant Test creator", + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "memberStatus": "ACTIVE", + "membershipId": "471d06d5-b382-4d18-9ad5-8e61ffe2bfac", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/471d06d5-b382-4d18-9ad5-8e61ffe2bfac", + "dataEncryptionMetadata": { + "allowCleartext": true, + "allowDuplicates": false, + "allowJoinsOnColumnsWithDifferentNames": false, + "preserveNulls": false + }, + "queryLogStatus": "DISABLED", + "analyticsEngine": "SPARK", + "allowedResultRegions": [ + "us-east-1" + ], + "isMetricsEnabled": false + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListCollaborations_1.json b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListCollaborations_1.json new file mode 100644 index 00000000000..6856c0ab160 --- /dev/null +++ b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListCollaborations_1.json @@ -0,0 +1,70 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "collaborationList": [ + { + "id": "62647862-bee9-42e8-8c07-99b0fc492f3a", + "arn": "arn:aws:cleanrooms:us-east-1:644160558196:collaboration/62647862-bee9-42e8-8c07-99b0fc492f3a", + "name": "Compliant Collaboration", + "creatorAccountId": "644160558196", + "creatorDisplayName": "Compliant Member", + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 2, + "second": 3, + "microsecond": 366000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 2, + "second": 3, + "microsecond": 366000 + }, + "memberStatus": "ACTIVE", + "membershipId": "c5773151-1c6c-40ff-86f2-543d68654295", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/c5773151-1c6c-40ff-86f2-543d68654295", + "analyticsEngine": "SPARK" + }, + { + "id": "8326c03e-8c92-4cc0-9d84-3be7208e1528", + "arn": "arn:aws:cleanrooms:us-east-1:644160558196:collaboration/8326c03e-8c92-4cc0-9d84-3be7208e1528", + "name": "Noncompliant Collaboration", + "creatorAccountId": "644160558196", + "creatorDisplayName": "Noncompliant Test creator", + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "memberStatus": "ACTIVE", + "membershipId": "471d06d5-b382-4d18-9ad5-8e61ffe2bfac", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/471d06d5-b382-4d18-9ad5-8e61ffe2bfac", + "analyticsEngine": "SPARK" + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListMembers_1.json b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListMembers_1.json new file mode 100644 index 00000000000..441609d3f07 --- /dev/null +++ b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListMembers_1.json @@ -0,0 +1,58 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "memberSummaries": [ + { + "accountId": "644160558196", + "status": "ACTIVE", + "displayName": "Compliant Member", + "abilities": [ + "CAN_QUERY", + "CAN_RECEIVE_RESULTS" + ], + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 2, + "second": 3, + "microsecond": 366000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 2, + "second": 4, + "microsecond": 210000 + }, + "membershipId": "c5773151-1c6c-40ff-86f2-543d68654295", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/c5773151-1c6c-40ff-86f2-543d68654295", + "paymentConfiguration": { + "queryCompute": { + "isResponsible": true + }, + "machineLearning": { + "modelTraining": { + "isResponsible": false + }, + "modelInference": { + "isResponsible": false + }, + "syntheticDataGeneration": { + "isResponsible": false + } + }, + "jobCompute": { + "isResponsible": false + } + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListMembers_2.json b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListMembers_2.json new file mode 100644 index 00000000000..8c79e3a849a --- /dev/null +++ b/tests/data/placebo/test_cleanrooms_collaboration_members/cleanrooms.ListMembers_2.json @@ -0,0 +1,106 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "memberSummaries": [ + { + "accountId": "644160558196", + "status": "INVITED", + "displayName": "Noncompliant Test Member", + "abilities": [ + "CAN_QUERY" + ], + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "membershipId": "786a4a30-7dfb-4917-a08d-d06fd6b191a0", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/786a4a30-7dfb-4917-a08d-d06fd6b191a0", + "paymentConfiguration": { + "queryCompute": { + "isResponsible": false + }, + "machineLearning": { + "modelTraining": { + "isResponsible": false + }, + "modelInference": { + "isResponsible": false + }, + "syntheticDataGeneration": { + "isResponsible": false + } + }, + "jobCompute": { + "isResponsible": false + } + } + }, + { + "accountId": "644160558196", + "status": "ACTIVE", + "displayName": "Noncompliant Test creator", + "abilities": [ + "CAN_RECEIVE_RESULTS" + ], + "createTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 43, + "microsecond": 53000 + }, + "updateTime": { + "__class__": "datetime", + "year": 2026, + "month": 6, + "day": 9, + "hour": 2, + "minute": 19, + "second": 55, + "microsecond": 367000 + }, + "membershipId": "471d06d5-b382-4d18-9ad5-8e61ffe2bfac", + "membershipArn": "arn:aws:cleanrooms:us-east-1:644160558196:membership/471d06d5-b382-4d18-9ad5-8e61ffe2bfac", + "paymentConfiguration": { + "queryCompute": { + "isResponsible": true + }, + "machineLearning": { + "modelTraining": { + "isResponsible": false + }, + "modelInference": { + "isResponsible": false + }, + "syntheticDataGeneration": { + "isResponsible": false + } + }, + "jobCompute": { + "isResponsible": false + } + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_cleanrooms_collaboration_members/tagging.GetResources_1.json b/tests/data/placebo/test_cleanrooms_collaboration_members/tagging.GetResources_1.json new file mode 100644 index 00000000000..4a7b0f53076 --- /dev/null +++ b/tests/data/placebo/test_cleanrooms_collaboration_members/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:cleanrooms:us-east-1:644160558196:collaboration/62647862-bee9-42e8-8c07-99b0fc492f3a", + "Tags": [ + { + "Key": "ASV", + "Value": "PolicyTestASV" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_distribution_wafv2_filter_scope/cloudfront.ListDistributions_1.json b/tests/data/placebo/test_distribution_wafv2_filter_scope/cloudfront.ListDistributions_1.json new file mode 100644 index 00000000000..594e78a7bdc --- /dev/null +++ b/tests/data/placebo/test_distribution_wafv2_filter_scope/cloudfront.ListDistributions_1.json @@ -0,0 +1,72 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "DistributionList": { + "Marker": "", + "MaxItems": 100, + "IsTruncated": false, + "Quantity": 1, + "Items": [ + { + "Id": "E1EXAMPLE1234", + "ARN": "arn:aws:cloudfront::123456789012:distribution/E1EXAMPLE1234", + "Status": "Deployed", + "LastModifiedTime": { + "hour": 0, + "microsecond": 0, + "second": 0, + "year": 2024, + "month": 1, + "day": 1, + "minute": 0 + }, + "DomainName": "d111111abcdef8.cloudfront.net", + "Aliases": { + "Quantity": 0, + "Items": [] + }, + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-example", + "DomainName": "example-bucket.s3.amazonaws.com", + "OriginPath": "" + } + ] + }, + "DefaultCacheBehavior": { + "TargetOriginId": "S3-example", + "ViewerProtocolPolicy": "redirect-to-https" + }, + "CacheBehaviors": { + "Quantity": 0, + "Items": [] + }, + "CustomErrorResponses": { + "Quantity": 0, + "Items": [] + }, + "Comment": "", + "PriceClass": "PriceClass_All", + "Enabled": true, + "ViewerCertificate": { + "CloudFrontDefaultCertificate": true, + "MinimumProtocolVersion": "TLSv1", + "CertificateSource": "cloudfront" + }, + "Restrictions": { + "GeoRestriction": { + "RestrictionType": "none", + "Quantity": 0 + } + }, + "WebACLId": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/example-cloudfront-acl/11111111-2222-3333-4444-555555555555", + "HttpVersion": "http2", + "IsIPV6Enabled": true + } + ] + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_distribution_wafv2_filter_scope/tagging.GetResources_1.json b/tests/data/placebo/test_distribution_wafv2_filter_scope/tagging.GetResources_1.json new file mode 100644 index 00000000000..e20312f86da --- /dev/null +++ b/tests/data/placebo/test_distribution_wafv2_filter_scope/tagging.GetResources_1.json @@ -0,0 +1,13 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:cloudfront::123456789012:distribution/E1EXAMPLE1234", + "Tags": [] + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_distribution_wafv2_filter_scope/wafv2.ListWebACLs_1.json b/tests/data/placebo/test_distribution_wafv2_filter_scope/wafv2.ListWebACLs_1.json new file mode 100644 index 00000000000..6baff824a4b --- /dev/null +++ b/tests/data/placebo/test_distribution_wafv2_filter_scope/wafv2.ListWebACLs_1.json @@ -0,0 +1,16 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "NextMarker": "", + "WebACLs": [ + { + "Name": "example-cloudfront-acl", + "Id": "11111111-2222-3333-4444-555555555555", + "Description": "", + "LockToken": "22222222-3333-4444-5555-666666666666", + "ARN": "arn:aws:wafv2:us-east-1:123456789012:global/webacl/example-cloudfront-acl/11111111-2222-3333-4444-555555555555" + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.GetApplication_1.json b/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.GetApplication_1.json new file mode 100644 index 00000000000..f6d63779d7d --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.GetApplication_1.json @@ -0,0 +1,52 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "application": { + "applicationId": "00g7c4jplrhduu09", + "name": "c7n-test-emr-serverless-autostop-disabled", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4jplrhduu09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 713000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 713000 + }, + "tags": {}, + "autoStartConfiguration": { + "enabled": true + }, + "autoStopConfiguration": { + "enabled": false, + "idleTimeoutMinutes": 15 + }, + "architecture": "X86_64", + "monitoringConfiguration": { + "managedPersistenceMonitoringConfiguration": { + "enabled": true + } + }, + "jobLevelCostAllocationConfiguration": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.GetApplication_2.json b/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.GetApplication_2.json new file mode 100644 index 00000000000..b2a496b5114 --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.GetApplication_2.json @@ -0,0 +1,52 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "application": { + "applicationId": "00g7c4jplnn1si09", + "name": "c7n-test-emr-serverless-autostop-enabled", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4jplnn1si09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 701000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 701000 + }, + "tags": {}, + "autoStartConfiguration": { + "enabled": true + }, + "autoStopConfiguration": { + "enabled": true, + "idleTimeoutMinutes": 15 + }, + "architecture": "X86_64", + "monitoringConfiguration": { + "managedPersistenceMonitoringConfiguration": { + "enabled": true + } + }, + "jobLevelCostAllocationConfiguration": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.ListApplications_1.json b/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.ListApplications_1.json new file mode 100644 index 00000000000..0dadc7a50d7 --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_autostop_filter/emr-serverless.ListApplications_1.json @@ -0,0 +1,68 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "applications": [ + { + "id": "00g7c4jplrhduu09", + "name": "c7n-test-emr-serverless-autostop-disabled", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4jplrhduu09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 713000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 713000 + }, + "architecture": "X86_64" + }, + { + "id": "00g7c4jplnn1si09", + "name": "c7n-test-emr-serverless-autostop-enabled", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4jplnn1si09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 701000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 6, + "second": 49, + "microsecond": 701000 + }, + "architecture": "X86_64" + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_autostop_filter/tagging.GetResources_1.json b/tests/data/placebo/test_emr_serverless_autostop_filter/tagging.GetResources_1.json new file mode 100644 index 00000000000..8b704d1852a --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_autostop_filter/tagging.GetResources_1.json @@ -0,0 +1,8 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_delete/emr-serverless.GetApplication_1.json b/tests/data/placebo/test_emr_serverless_delete/emr-serverless.GetApplication_1.json new file mode 100644 index 00000000000..a8aae7dd24b --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_delete/emr-serverless.GetApplication_1.json @@ -0,0 +1,52 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "application": { + "applicationId": "00g7c4tup58h2u09", + "name": "c7n-test-emr-serverless-delete", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4tup58h2u09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 24, + "second": 35, + "microsecond": 12000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 24, + "second": 35, + "microsecond": 12000 + }, + "tags": {}, + "autoStartConfiguration": { + "enabled": true + }, + "autoStopConfiguration": { + "enabled": true, + "idleTimeoutMinutes": 15 + }, + "architecture": "X86_64", + "monitoringConfiguration": { + "managedPersistenceMonitoringConfiguration": { + "enabled": true + } + }, + "jobLevelCostAllocationConfiguration": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_delete/emr-serverless.ListApplications_1.json b/tests/data/placebo/test_emr_serverless_delete/emr-serverless.ListApplications_1.json index d874c9cbb7a..2680579e919 100644 --- a/tests/data/placebo/test_emr_serverless_delete/emr-serverless.ListApplications_1.json +++ b/tests/data/placebo/test_emr_serverless_delete/emr-serverless.ListApplications_1.json @@ -4,32 +4,32 @@ "ResponseMetadata": {}, "applications": [ { - "id": "00f7bp174ejqb109", - "name": "test-emr-serverless", - "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bp174ejqb109", + "id": "00g7c4tup58h2u09", + "name": "c7n-test-emr-serverless-delete", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4tup58h2u09", "releaseLabel": "emr-6.9.0", "type": "Spark", "state": "CREATED", "stateDetails": "Application created by user.", "createdAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 19, - "second": 48, - "microsecond": 859000 + "minute": 24, + "second": 35, + "microsecond": 12000 }, "updatedAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 19, - "second": 48, - "microsecond": 859000 + "minute": 24, + "second": 35, + "microsecond": 12000 }, "architecture": "X86_64" } diff --git a/tests/data/placebo/test_emr_serverless_delete/tagging.GetResources_1.json b/tests/data/placebo/test_emr_serverless_delete/tagging.GetResources_1.json index 76f0a5b5d97..8b704d1852a 100644 --- a/tests/data/placebo/test_emr_serverless_delete/tagging.GetResources_1.json +++ b/tests/data/placebo/test_emr_serverless_delete/tagging.GetResources_1.json @@ -2,17 +2,7 @@ "status_code": 200, "data": { "PaginationToken": "", - "ResourceTagMappingList": [ - { - "ResourceARN": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bp174ejqb109", - "Tags": [ - { - "Key": "foo", - "Value": "Resource does not meet policy: notify@2023/01/26" - } - ] - } - ], + "ResourceTagMappingList": [], "ResponseMetadata": {} } } \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_markop/emr-serverless.GetApplication_1.json b/tests/data/placebo/test_emr_serverless_markop/emr-serverless.GetApplication_1.json new file mode 100644 index 00000000000..f564ca92373 --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_markop/emr-serverless.GetApplication_1.json @@ -0,0 +1,52 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "application": { + "applicationId": "00g7c4slugdoti09", + "name": "c7n-test-emr-serverless-markop", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4slugdoti09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 22, + "second": 21, + "microsecond": 210000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 22, + "second": 21, + "microsecond": 210000 + }, + "tags": {}, + "autoStartConfiguration": { + "enabled": true + }, + "autoStopConfiguration": { + "enabled": true, + "idleTimeoutMinutes": 15 + }, + "architecture": "X86_64", + "monitoringConfiguration": { + "managedPersistenceMonitoringConfiguration": { + "enabled": true + } + }, + "jobLevelCostAllocationConfiguration": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListApplications_1.json b/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListApplications_1.json index d874c9cbb7a..bca6a1d9516 100644 --- a/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListApplications_1.json +++ b/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListApplications_1.json @@ -4,32 +4,32 @@ "ResponseMetadata": {}, "applications": [ { - "id": "00f7bp174ejqb109", - "name": "test-emr-serverless", - "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bp174ejqb109", + "id": "00g7c4slugdoti09", + "name": "c7n-test-emr-serverless-markop", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4slugdoti09", "releaseLabel": "emr-6.9.0", "type": "Spark", "state": "CREATED", "stateDetails": "Application created by user.", "createdAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 19, - "second": 48, - "microsecond": 859000 + "minute": 22, + "second": 21, + "microsecond": 210000 }, "updatedAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 19, - "second": 48, - "microsecond": 859000 + "minute": 22, + "second": 21, + "microsecond": 210000 }, "architecture": "X86_64" } diff --git a/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListTagsForResource_1.json b/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListTagsForResource_1.json index 4ce9eaa6b51..8f649ee8d2f 100644 --- a/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListTagsForResource_1.json +++ b/tests/data/placebo/test_emr_serverless_markop/emr-serverless.ListTagsForResource_1.json @@ -3,7 +3,7 @@ "data": { "ResponseMetadata": {}, "tags": { - "foo": "Resource does not meet policy: notify@2023/01/26" + "foo": "Resource does not meet policy: notify@2026/07/22" } } } \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.GetApplication_1.json b/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.GetApplication_1.json new file mode 100644 index 00000000000..9b304cfb7d7 --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.GetApplication_1.json @@ -0,0 +1,54 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "application": { + "applicationId": "00g7c4rdj2nvis09", + "name": "c7n-test-emr-serverless-remove-tag", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4rdj2nvis09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 20, + "second": 9, + "microsecond": 79000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 20, + "second": 9, + "microsecond": 79000 + }, + "tags": { + "foo": "bar" + }, + "autoStartConfiguration": { + "enabled": true + }, + "autoStopConfiguration": { + "enabled": true, + "idleTimeoutMinutes": 15 + }, + "architecture": "X86_64", + "monitoringConfiguration": { + "managedPersistenceMonitoringConfiguration": { + "enabled": true + } + }, + "jobLevelCostAllocationConfiguration": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.ListApplications_1.json b/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.ListApplications_1.json index 23088dbf1c8..0811895ce5b 100644 --- a/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.ListApplications_1.json +++ b/tests/data/placebo/test_emr_serverless_remove_tag/emr-serverless.ListApplications_1.json @@ -4,32 +4,32 @@ "ResponseMetadata": {}, "applications": [ { - "id": "00f7bot3h1dbr009", - "name": "test-emr-serverless", - "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bot3h1dbr009", + "id": "00g7c4rdj2nvis09", + "name": "c7n-test-emr-serverless-remove-tag", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4rdj2nvis09", "releaseLabel": "emr-6.9.0", "type": "Spark", "state": "CREATED", "stateDetails": "Application created by user.", "createdAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 12, - "second": 37, - "microsecond": 610000 + "minute": 20, + "second": 9, + "microsecond": 79000 }, "updatedAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 12, - "second": 37, - "microsecond": 610000 + "minute": 20, + "second": 9, + "microsecond": 79000 }, "architecture": "X86_64" } diff --git a/tests/data/placebo/test_emr_serverless_remove_tag/tagging.GetResources_1.json b/tests/data/placebo/test_emr_serverless_remove_tag/tagging.GetResources_1.json index 6abb9b7f420..8b3afaca35d 100644 --- a/tests/data/placebo/test_emr_serverless_remove_tag/tagging.GetResources_1.json +++ b/tests/data/placebo/test_emr_serverless_remove_tag/tagging.GetResources_1.json @@ -4,7 +4,7 @@ "PaginationToken": "", "ResourceTagMappingList": [ { - "ResourceARN": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bot3h1dbr009", + "ResourceARN": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4rdj2nvis09", "Tags": [ { "Key": "foo", diff --git a/tests/data/placebo/test_emr_serverless_tag/emr-serverless.GetApplication_1.json b/tests/data/placebo/test_emr_serverless_tag/emr-serverless.GetApplication_1.json new file mode 100644 index 00000000000..f6057e14603 --- /dev/null +++ b/tests/data/placebo/test_emr_serverless_tag/emr-serverless.GetApplication_1.json @@ -0,0 +1,52 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "application": { + "applicationId": "00g7c4q56puk5q09", + "name": "c7n-test-emr-serverless-tag", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4q56puk5q09", + "releaseLabel": "emr-6.9.0", + "type": "Spark", + "state": "CREATED", + "stateDetails": "Application created by user.", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 17, + "second": 56, + "microsecond": 639000 + }, + "updatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 20, + "hour": 13, + "minute": 17, + "second": 56, + "microsecond": 639000 + }, + "tags": {}, + "autoStartConfiguration": { + "enabled": true + }, + "autoStopConfiguration": { + "enabled": true, + "idleTimeoutMinutes": 15 + }, + "architecture": "X86_64", + "monitoringConfiguration": { + "managedPersistenceMonitoringConfiguration": { + "enabled": true + } + }, + "jobLevelCostAllocationConfiguration": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_emr_serverless_tag/emr-serverless.ListApplications_1.json b/tests/data/placebo/test_emr_serverless_tag/emr-serverless.ListApplications_1.json index 23088dbf1c8..a47146b9cf0 100644 --- a/tests/data/placebo/test_emr_serverless_tag/emr-serverless.ListApplications_1.json +++ b/tests/data/placebo/test_emr_serverless_tag/emr-serverless.ListApplications_1.json @@ -4,32 +4,32 @@ "ResponseMetadata": {}, "applications": [ { - "id": "00f7bot3h1dbr009", - "name": "test-emr-serverless", - "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bot3h1dbr009", + "id": "00g7c4q56puk5q09", + "name": "c7n-test-emr-serverless-tag", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4q56puk5q09", "releaseLabel": "emr-6.9.0", "type": "Spark", "state": "CREATED", "stateDetails": "Application created by user.", "createdAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 12, - "second": 37, - "microsecond": 610000 + "minute": 17, + "second": 56, + "microsecond": 639000 }, "updatedAt": { "__class__": "datetime", - "year": 2023, - "month": 1, - "day": 24, + "year": 2026, + "month": 7, + "day": 20, "hour": 13, - "minute": 12, - "second": 37, - "microsecond": 610000 + "minute": 17, + "second": 56, + "microsecond": 639000 }, "architecture": "X86_64" } diff --git a/tests/data/placebo/test_emr_serverless_tag/tagging.GetResources_1.json b/tests/data/placebo/test_emr_serverless_tag/tagging.GetResources_1.json index 111e71ad05b..8b704d1852a 100644 --- a/tests/data/placebo/test_emr_serverless_tag/tagging.GetResources_1.json +++ b/tests/data/placebo/test_emr_serverless_tag/tagging.GetResources_1.json @@ -2,12 +2,7 @@ "status_code": 200, "data": { "PaginationToken": "", - "ResourceTagMappingList": [ - { - "ResourceARN": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00f7bot3h1dbr009", - "Tags": [] - } - ], + "ResourceTagMappingList": [], "ResponseMetadata": {} } } \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_filter_listener/tagging.GetResources_1.json b/tests/data/placebo/test_lattice_rule_filter_listener/tagging.GetResources_1.json new file mode 100644 index 00000000000..21bce90027c --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_filter_listener/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0/listener/listener-0aea8cb5e967c8493/rule/rule-0d6e45a66600da527", + "Tags": [ + { + "Key": "ExistingKey", + "Value": "ExistingValue" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListListeners_1.json b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListListeners_1.json new file mode 100644 index 00000000000..c8d6032237d --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListListeners_1.json @@ -0,0 +1,35 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d/listener/listener-0bab637e7fe24d8f1", + "id": "listener-0bab637e7fe24d8f1", + "name": "test-listener2", + "protocol": "HTTP", + "port": 80, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 36, + "microsecond": 542000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 36, + "microsecond": 542000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListListeners_2.json b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListListeners_2.json new file mode 100644 index 00000000000..ae425e3d203 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListListeners_2.json @@ -0,0 +1,35 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0/listener/listener-0aea8cb5e967c8493", + "id": "listener-0aea8cb5e967c8493", + "name": "test-listener", + "protocol": "HTTP", + "port": 80, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 35, + "microsecond": 132000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 35, + "microsecond": 132000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListRules_1.json b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListRules_1.json new file mode 100644 index 00000000000..b34909ccb88 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListRules_1.json @@ -0,0 +1,62 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d/listener/listener-0bab637e7fe24d8f1/rule/rule-05bf91b4822600d9f", + "id": "rule-05bf91b4822600d9f", + "name": "default", + "isDefault": true, + "priority": 99999, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 36, + "microsecond": 542000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 36, + "microsecond": 542000 + } + }, + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d/listener/listener-0bab637e7fe24d8f1/rule/rule-07cc81379b2259d4d", + "id": "rule-07cc81379b2259d4d", + "name": "test-rule2", + "isDefault": false, + "priority": 10, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 36, + "microsecond": 945000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 36, + "microsecond": 945000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListRules_2.json b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListRules_2.json new file mode 100644 index 00000000000..20851863d5b --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListRules_2.json @@ -0,0 +1,62 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0/listener/listener-0aea8cb5e967c8493/rule/rule-0d8595a67c5ce95e8", + "id": "rule-0d8595a67c5ce95e8", + "name": "default", + "isDefault": true, + "priority": 99999, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 35, + "microsecond": 132000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 35, + "microsecond": 132000 + } + }, + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0/listener/listener-0aea8cb5e967c8493/rule/rule-0d6e45a66600da527", + "id": "rule-0d6e45a66600da527", + "name": "test-rule", + "isDefault": false, + "priority": 10, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 35, + "microsecond": 542000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 35, + "microsecond": 542000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListServices_1.json b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListServices_1.json new file mode 100644 index 00000000000..e8951b9e0de --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_filter_listener/vpc-lattice.ListServices_1.json @@ -0,0 +1,68 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "id": "svc-0a1e45b6464d1be4d", + "name": "test-service2", + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 33, + "microsecond": 395000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 33, + "microsecond": 395000 + }, + "dnsEntry": { + "domainName": "test-service2-0a1e45b6464d1be4d.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hostedZoneId": "Z0681547Z82L3THDFSCZ" + }, + "status": "ACTIVE" + }, + { + "id": "svc-0b853eda0579935b0", + "name": "test-service", + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 33, + "microsecond": 153000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 33, + "microsecond": 153000 + }, + "dnsEntry": { + "domainName": "test-service-0b853eda0579935b0.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hostedZoneId": "Z0681547Z82L3THDFSCZ" + }, + "status": "ACTIVE" + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_query/tagging.GetResources_1.json b/tests/data/placebo/test_lattice_rule_query/tagging.GetResources_1.json new file mode 100644 index 00000000000..188ab1c1897 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query/tagging.GetResources_1.json @@ -0,0 +1,22 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0123456789abcdef0/listener/listener-0123456789abcdef0/rule/rule-0123456789abcdef0", + "Tags": [ + { + "Key": "Env", + "Value": "Test" + } + ] + }, + { + "ResourceARN": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0123456789abcdef0/listener/listener-0123456789abcdef0/rule/rule-default", + "Tags": [] + } + ], + "ResponseMetadata": {} + } +} diff --git a/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListListeners_1.json b/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListListeners_1.json new file mode 100644 index 00000000000..babe658b66c --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListListeners_1.json @@ -0,0 +1,35 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0123456789abcdef0/listener/listener-0123456789abcdef0", + "createdAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 31, + "second": 5, + "microsecond": 789000 + }, + "id": "listener-0123456789abcdef0", + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 31, + "second": 9, + "microsecond": 101000 + }, + "name": "test-listener", + "port": 80, + "protocol": "HTTP" + } + ] + } +} diff --git a/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListRules_1.json b/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListRules_1.json new file mode 100644 index 00000000000..fa78404f975 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListRules_1.json @@ -0,0 +1,62 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0123456789abcdef0/listener/listener-0123456789abcdef0/rule/rule-0123456789abcdef0", + "createdAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 32, + "second": 11, + "microsecond": 222000 + }, + "id": "rule-0123456789abcdef0", + "isDefault": false, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 32, + "second": 18, + "microsecond": 333000 + }, + "name": "test-rule", + "priority": 10 + }, + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0123456789abcdef0/listener/listener-0123456789abcdef0/rule/rule-default", + "createdAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 32, + "second": 0, + "microsecond": 0 + }, + "id": "rule-default", + "isDefault": true, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 32, + "second": 0, + "microsecond": 0 + }, + "name": "default-rule", + "priority": 1 + } + ] + } +} diff --git a/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListServices_1.json b/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListServices_1.json new file mode 100644 index 00000000000..5c321853754 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query/vpc-lattice.ListServices_1.json @@ -0,0 +1,38 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0123456789abcdef0", + "createdAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 30, + "second": 15, + "microsecond": 123000 + }, + "dnsEntry": { + "domainName": "test-service-0123456789abcdef0.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hostedZoneId": "Z0681547Z82L3THDFSCZ" + }, + "id": "svc-0123456789abcdef0", + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2025, + "month": 10, + "day": 1, + "hour": 12, + "minute": 30, + "second": 20, + "microsecond": 456000 + }, + "name": "test-service", + "status": "ACTIVE" + } + ] + } +} diff --git a/tests/data/placebo/test_lattice_rule_query_service/tagging.GetResources_1.json b/tests/data/placebo/test_lattice_rule_query_service/tagging.GetResources_1.json new file mode 100644 index 00000000000..4ca4b210800 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query_service/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a/listener/listener-02e6d6e4b198fd51a/rule/rule-0aa60409d67d5ea6f", + "Tags": [ + { + "Key": "ExistingKey", + "Value": "ExistingValue" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListListeners_1.json b/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListListeners_1.json new file mode 100644 index 00000000000..1849edaee96 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListListeners_1.json @@ -0,0 +1,35 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a/listener/listener-02e6d6e4b198fd51a", + "id": "listener-02e6d6e4b198fd51a", + "name": "test-listener", + "protocol": "HTTP", + "port": 80, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 14, + "microsecond": 158000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 14, + "microsecond": 158000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListRules_1.json b/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListRules_1.json new file mode 100644 index 00000000000..7b4afb09fda --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListRules_1.json @@ -0,0 +1,62 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a/listener/listener-02e6d6e4b198fd51a/rule/rule-02b5c5d3306505d14", + "id": "rule-02b5c5d3306505d14", + "name": "default", + "isDefault": true, + "priority": 99999, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 14, + "microsecond": 158000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 14, + "microsecond": 158000 + } + }, + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a/listener/listener-02e6d6e4b198fd51a/rule/rule-0aa60409d67d5ea6f", + "id": "rule-0aa60409d67d5ea6f", + "name": "test-rule", + "isDefault": false, + "priority": 10, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 14, + "microsecond": 592000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 44, + "second": 14, + "microsecond": 592000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListServices_1.json b/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListServices_1.json new file mode 100644 index 00000000000..2fec88d6f1f --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query_service/vpc-lattice.ListServices_1.json @@ -0,0 +1,68 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "id": "svc-02e81f6c1e61ddcfe", + "name": "test-service2", + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-02e81f6c1e61ddcfe", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 43, + "second": 39, + "microsecond": 891000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 43, + "second": 39, + "microsecond": 891000 + }, + "dnsEntry": { + "domainName": "test-service2-02e81f6c1e61ddcfe.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hostedZoneId": "Z0681547Z82L3THDFSCZ" + }, + "status": "ACTIVE" + }, + { + "id": "svc-0861b4cd69650046a", + "name": "test-service", + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a", + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 43, + "second": 40, + "microsecond": 102000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 43, + "second": 40, + "microsecond": 102000 + }, + "dnsEntry": { + "domainName": "test-service-0861b4cd69650046a.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hostedZoneId": "Z0681547Z82L3THDFSCZ" + }, + "status": "ACTIVE" + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_query_service_listener/tagging.GetResources_1.json b/tests/data/placebo/test_lattice_rule_query_service_listener/tagging.GetResources_1.json new file mode 100644 index 00000000000..1168e4f9c9e --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query_service_listener/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06/listener/listener-09d4c687748f5183d/rule/rule-0d1442e6612b77614", + "Tags": [ + { + "Key": "ExistingKey", + "Value": "ExistingValue" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_query_service_listener/vpc-lattice.ListRules_1.json b/tests/data/placebo/test_lattice_rule_query_service_listener/vpc-lattice.ListRules_1.json new file mode 100644 index 00000000000..c1deebddf80 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_query_service_listener/vpc-lattice.ListRules_1.json @@ -0,0 +1,62 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06/listener/listener-09d4c687748f5183d/rule/rule-0cf9342f9b4e093f9", + "id": "rule-0cf9342f9b4e093f9", + "name": "default", + "isDefault": true, + "priority": 99999, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 45, + "second": 19, + "microsecond": 727000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 45, + "second": 19, + "microsecond": 727000 + } + }, + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06/listener/listener-09d4c687748f5183d/rule/rule-0d1442e6612b77614", + "id": "rule-0d1442e6612b77614", + "name": "test-rule", + "isDefault": false, + "priority": 10, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 45, + "second": 20, + "microsecond": 142000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 45, + "second": 20, + "microsecond": 142000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_tagging/tagging.GetResources_1.json b/tests/data/placebo/test_lattice_rule_tagging/tagging.GetResources_1.json new file mode 100644 index 00000000000..61074f8d1e1 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_tagging/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537/listener/listener-010148a46dc5dfa6f/rule/rule-07e791dc458a1967f", + "Tags": [ + { + "Key": "ExistingKey", + "Value": "ExistingValue" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_tagging/tagging.TagResources_1.json b/tests/data/placebo/test_lattice_rule_tagging/tagging.TagResources_1.json new file mode 100644 index 00000000000..bd2dead8598 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_tagging/tagging.TagResources_1.json @@ -0,0 +1,7 @@ +{ + "status_code": 200, + "data": { + "FailedResourcesMap": {}, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_tagging/vpc-lattice.ListRules_1.json b/tests/data/placebo/test_lattice_rule_tagging/vpc-lattice.ListRules_1.json new file mode 100644 index 00000000000..7bf8b413681 --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_tagging/vpc-lattice.ListRules_1.json @@ -0,0 +1,62 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "items": [ + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537/listener/listener-010148a46dc5dfa6f/rule/rule-0f191013ad64dd340", + "id": "rule-0f191013ad64dd340", + "name": "default", + "isDefault": true, + "priority": 99999, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 46, + "second": 13, + "microsecond": 76000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 46, + "second": 13, + "microsecond": 76000 + } + }, + { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537/listener/listener-010148a46dc5dfa6f/rule/rule-07e791dc458a1967f", + "id": "rule-07e791dc458a1967f", + "name": "test-rule", + "isDefault": false, + "priority": 10, + "createdAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 46, + "second": 13, + "microsecond": 610000 + }, + "lastUpdatedAt": { + "__class__": "datetime", + "year": 2026, + "month": 3, + "day": 13, + "hour": 15, + "minute": 46, + "second": 13, + "microsecond": 610000 + } + } + ] + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_lattice_rule_tagging/vpc-lattice.ListTagsForResource_1.json b/tests/data/placebo/test_lattice_rule_tagging/vpc-lattice.ListTagsForResource_1.json new file mode 100644 index 00000000000..3e54195aaba --- /dev/null +++ b/tests/data/placebo/test_lattice_rule_tagging/vpc-lattice.ListTagsForResource_1.json @@ -0,0 +1,10 @@ +{ + "status_code": 200, + "data": { + "ResponseMetadata": {}, + "tags": { + "ExistingKey": "ExistingValue", + "NewKey": "NewValue" + } + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_1.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_1.json new file mode 100644 index 00000000000..2e1eaeb9364 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_1.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-comic-chicken/JupyterServer/c7n-app-comic-chicken", + "AppType": "JupyterServer", + "AppName": "c7n-app-comic-chicken", + "DomainId": "d-szjlsjfyqmaq", + "UserProfileName": "c7n-profile-comic-chicken", + "Status": "InService", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 484000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 484000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 484000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_2.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_2.json new file mode 100644 index 00000000000..6ba38dee9f0 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_2.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken/JupyterServer/c7n-app-untagged-comic-chicken", + "AppType": "JupyterServer", + "AppName": "c7n-app-untagged-comic-chicken", + "DomainId": "d-szjlsjfyqmaq", + "UserProfileName": "c7n-profile-untagged-comic-chicken", + "Status": "InService", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 477000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 477000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 477000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_3.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_3.json new file mode 100644 index 00000000000..6013ae63ea4 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_3.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-a056u6jhtsnr/c7n-profile-sound-beetle/JupyterServer/c7n-app-sound-beetle", + "AppType": "JupyterServer", + "AppName": "c7n-app-sound-beetle", + "DomainId": "d-a056u6jhtsnr", + "UserProfileName": "c7n-profile-sound-beetle", + "Status": "Deleted", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 12, + "second": 21, + "microsecond": 878000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 12, + "second": 21, + "microsecond": 878000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 8, + "second": 1, + "microsecond": 160000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_4.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_4.json new file mode 100644 index 00000000000..1e45c603caf --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_4.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-a056u6jhtsnr/c7n-profile-sound-beetle/JupyterServer/c7n-app-untagged-sound-beetle", + "AppType": "JupyterServer", + "AppName": "c7n-app-untagged-sound-beetle", + "DomainId": "d-a056u6jhtsnr", + "UserProfileName": "c7n-profile-sound-beetle", + "Status": "Deleted", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 8, + "second": 1, + "microsecond": 159000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 8, + "second": 1, + "microsecond": 159000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 8, + "second": 1, + "microsecond": 159000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_5.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_5.json new file mode 100644 index 00000000000..b0329e8b564 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_5.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-cdvywlci9fz9/c7n-profile-relative-satyr/JupyterServer/c7n-app-relative-satyr", + "AppType": "JupyterServer", + "AppName": "c7n-app-relative-satyr", + "DomainId": "d-cdvywlci9fz9", + "UserProfileName": "c7n-profile-relative-satyr", + "Status": "Deleted", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 36, + "second": 15, + "microsecond": 690000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 36, + "second": 15, + "microsecond": 690000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 36, + "second": 15, + "microsecond": 690000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_6.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_6.json new file mode 100644 index 00000000000..852e98ccdba --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_6.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-8qju6kwhkbxw/c7n-profile-literate-dingo/JupyterServer/c7n-app-literate-dingo", + "AppType": "JupyterServer", + "AppName": "c7n-app-literate-dingo", + "DomainId": "d-8qju6kwhkbxw", + "UserProfileName": "c7n-profile-literate-dingo", + "Status": "Deleted", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 25, + "second": 56, + "microsecond": 736000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 25, + "second": 56, + "microsecond": 736000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 25, + "second": 56, + "microsecond": 736000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_7.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_7.json new file mode 100644 index 00000000000..63ccb59c22e --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_7.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-1gl8yb9eznhn/c7n-profile-super-monkfish/JupyterServer/c7n-app-super-monkfish", + "AppType": "JupyterServer", + "AppName": "c7n-app-super-monkfish", + "DomainId": "d-1gl8yb9eznhn", + "UserProfileName": "c7n-profile-super-monkfish", + "Status": "Deleted", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 16, + "second": 5, + "microsecond": 663000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 16, + "second": 5, + "microsecond": 663000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 16, + "second": 5, + "microsecond": 663000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_8.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_8.json new file mode 100644 index 00000000000..1139c1ec856 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.DescribeApp_8.json @@ -0,0 +1,48 @@ +{ + "status_code": 200, + "data": { + "AppArn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-hdmmj0w5a3de/c7n-profile-nice-pangolin/JupyterServer/c7n-app-nice-pangolin", + "AppType": "JupyterServer", + "AppName": "c7n-app-nice-pangolin", + "DomainId": "d-hdmmj0w5a3de", + "UserProfileName": "c7n-profile-nice-pangolin", + "Status": "Deleted", + "EffectiveTrustedIdentityPropagationStatus": "DISABLED", + "RecoveryMode": false, + "LastHealthCheckTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 14, + "minute": 24, + "second": 16, + "microsecond": 333000 + }, + "LastUserActivityTimestamp": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 14, + "minute": 24, + "second": 16, + "microsecond": 333000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 14, + "minute": 24, + "second": 16, + "microsecond": 333000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/api.sagemaker.ListApps_1.json b/tests/data/placebo/test_sagemaker_app/api.sagemaker.ListApps_1.json new file mode 100644 index 00000000000..046e31d5cac --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/api.sagemaker.ListApps_1.json @@ -0,0 +1,176 @@ +{ + "status_code": 200, + "data": { + "Apps": [ + { + "DomainId": "d-szjlsjfyqmaq", + "UserProfileName": "c7n-profile-comic-chicken", + "AppType": "JupyterServer", + "AppName": "c7n-app-comic-chicken", + "Status": "InService", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 484000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-szjlsjfyqmaq", + "UserProfileName": "c7n-profile-untagged-comic-chicken", + "AppType": "JupyterServer", + "AppName": "c7n-app-untagged-comic-chicken", + "Status": "InService", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 51, + "microsecond": 477000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-a056u6jhtsnr", + "UserProfileName": "c7n-profile-sound-beetle", + "AppType": "JupyterServer", + "AppName": "c7n-app-sound-beetle", + "Status": "Deleted", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 8, + "second": 1, + "microsecond": 160000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-a056u6jhtsnr", + "UserProfileName": "c7n-profile-sound-beetle", + "AppType": "JupyterServer", + "AppName": "c7n-app-untagged-sound-beetle", + "Status": "Deleted", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 8, + "second": 1, + "microsecond": 159000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-cdvywlci9fz9", + "UserProfileName": "c7n-profile-relative-satyr", + "AppType": "JupyterServer", + "AppName": "c7n-app-relative-satyr", + "Status": "Deleted", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 36, + "second": 15, + "microsecond": 690000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-8qju6kwhkbxw", + "UserProfileName": "c7n-profile-literate-dingo", + "AppType": "JupyterServer", + "AppName": "c7n-app-literate-dingo", + "Status": "Deleted", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 25, + "second": 56, + "microsecond": 736000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-1gl8yb9eznhn", + "UserProfileName": "c7n-profile-super-monkfish", + "AppType": "JupyterServer", + "AppName": "c7n-app-super-monkfish", + "Status": "Deleted", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 15, + "minute": 16, + "second": 5, + "microsecond": 663000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + }, + { + "DomainId": "d-hdmmj0w5a3de", + "UserProfileName": "c7n-profile-nice-pangolin", + "AppType": "JupyterServer", + "AppName": "c7n-app-nice-pangolin", + "Status": "Deleted", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 14, + "hour": 14, + "minute": 24, + "second": 16, + "microsecond": 333000 + }, + "ResourceSpec": { + "SageMakerImageArn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "InstanceType": "system" + } + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_app/tagging.GetResources_1.json b/tests/data/placebo/test_sagemaker_app/tagging.GetResources_1.json new file mode 100644 index 00000000000..5ac495f8028 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_app/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-comic-chicken/JupyterServer/c7n-app-comic-chicken", + "Tags": [ + { + "Key": "favorite-color", + "Value": "c7n" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_space/api.sagemaker.DescribeSpace_1.json b/tests/data/placebo/test_sagemaker_space/api.sagemaker.DescribeSpace_1.json new file mode 100644 index 00000000000..9b8f9db92c2 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_space/api.sagemaker.DescribeSpace_1.json @@ -0,0 +1,32 @@ +{ + "status_code": 200, + "data": { + "DomainId": "d-szjlsjfyqmaq", + "SpaceArn": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspacecomicchicken", + "SpaceName": "c7nspacecomicchicken", + "HomeEfsFileSystemUid": "200015", + "Status": "InService", + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 50, + "microsecond": 150000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 367000 + }, + "Url": "https://fmbqtou3xkfhnso.studio.us-east-1.sagemaker.aws", + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_space/api.sagemaker.DescribeSpace_2.json b/tests/data/placebo/test_sagemaker_space/api.sagemaker.DescribeSpace_2.json new file mode 100644 index 00000000000..7f776fb48b1 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_space/api.sagemaker.DescribeSpace_2.json @@ -0,0 +1,32 @@ +{ + "status_code": 200, + "data": { + "DomainId": "d-szjlsjfyqmaq", + "SpaceArn": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspaceuntaggedcomicchicken", + "SpaceName": "c7nspaceuntaggedcomicchicken", + "HomeEfsFileSystemUid": "200005", + "Status": "InService", + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 49, + "microsecond": 379000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 199000 + }, + "Url": "https://yri67bja2mhi76a.studio.us-east-1.sagemaker.aws", + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_space/api.sagemaker.ListSpaces_1.json b/tests/data/placebo/test_sagemaker_space/api.sagemaker.ListSpaces_1.json new file mode 100644 index 00000000000..e072eb4a887 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_space/api.sagemaker.ListSpaces_1.json @@ -0,0 +1,58 @@ +{ + "status_code": 200, + "data": { + "Spaces": [ + { + "DomainId": "d-szjlsjfyqmaq", + "SpaceName": "c7nspacecomicchicken", + "Status": "InService", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 367000 + }, + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 50, + "microsecond": 150000 + } + }, + { + "DomainId": "d-szjlsjfyqmaq", + "SpaceName": "c7nspaceuntaggedcomicchicken", + "Status": "InService", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 199000 + }, + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 49, + "microsecond": 379000 + } + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_space/tagging.GetResources_1.json b/tests/data/placebo/test_sagemaker_space/tagging.GetResources_1.json new file mode 100644 index 00000000000..108525c98cc --- /dev/null +++ b/tests/data/placebo/test_sagemaker_space/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspacecomicchicken", + "Tags": [ + { + "Key": "favorite-color", + "Value": "c7n" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.DescribeUserProfile_1.json b/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.DescribeUserProfile_1.json new file mode 100644 index 00000000000..cee61ec8274 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.DescribeUserProfile_1.json @@ -0,0 +1,36 @@ +{ + "status_code": 200, + "data": { + "DomainId": "d-szjlsjfyqmaq", + "UserProfileArn": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-comic-chicken", + "UserProfileName": "c7n-profile-comic-chicken", + "HomeEfsFileSystemUid": "200020", + "Status": "InService", + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 50, + "microsecond": 915000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 527000 + }, + "UserSettings": { + "ExecutionRole": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "CustomFileSystemConfigs": [], + "AutoMountHomeEFS": "DefaultAsDomain" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.DescribeUserProfile_2.json b/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.DescribeUserProfile_2.json new file mode 100644 index 00000000000..c812f9a07b1 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.DescribeUserProfile_2.json @@ -0,0 +1,36 @@ +{ + "status_code": 200, + "data": { + "DomainId": "d-szjlsjfyqmaq", + "UserProfileArn": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken", + "UserProfileName": "c7n-profile-untagged-comic-chicken", + "HomeEfsFileSystemUid": "200010", + "Status": "InService", + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 50, + "microsecond": 755000 + }, + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 510000 + }, + "UserSettings": { + "ExecutionRole": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "CustomFileSystemConfigs": [], + "AutoMountHomeEFS": "DefaultAsDomain" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.ListUserProfiles_1.json b/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.ListUserProfiles_1.json new file mode 100644 index 00000000000..0d3a97231d7 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_user_profile/api.sagemaker.ListUserProfiles_1.json @@ -0,0 +1,58 @@ +{ + "status_code": 200, + "data": { + "UserProfiles": [ + { + "DomainId": "d-szjlsjfyqmaq", + "UserProfileName": "c7n-profile-comic-chicken", + "Status": "InService", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 527000 + }, + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 50, + "microsecond": 915000 + } + }, + { + "DomainId": "d-szjlsjfyqmaq", + "UserProfileName": "c7n-profile-untagged-comic-chicken", + "Status": "InService", + "CreationTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 47, + "microsecond": 510000 + }, + "LastModifiedTime": { + "__class__": "datetime", + "year": 2026, + "month": 7, + "day": 15, + "hour": 12, + "minute": 20, + "second": 50, + "microsecond": 755000 + } + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sagemaker_user_profile/tagging.GetResources_1.json b/tests/data/placebo/test_sagemaker_user_profile/tagging.GetResources_1.json new file mode 100644 index 00000000000..8941c79fa74 --- /dev/null +++ b/tests/data/placebo/test_sagemaker_user_profile/tagging.GetResources_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [ + { + "ResourceARN": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-comic-chicken", + "Tags": [ + { + "Key": "favorite-color", + "Value": "c7n" + } + ] + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sns_cross_account_for_any_value/sns.GetTopicAttributes_1.json b/tests/data/placebo/test_sns_cross_account_for_any_value/sns.GetTopicAttributes_1.json new file mode 100644 index 00000000000..16425e4970c --- /dev/null +++ b/tests/data/placebo/test_sns_cross_account_for_any_value/sns.GetTopicAttributes_1.json @@ -0,0 +1,18 @@ +{ + "status_code": 200, + "data": { + "Attributes": { + "Policy": "{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:Publish\",\"SNS:RemovePermission\",\"SNS:SetTopicAttributes\",\"SNS:DeleteTopic\",\"SNS:ListSubscriptionsByTopic\",\"SNS:GetTopicAttributes\",\"SNS:AddPermission\",\"SNS:Subscribe\"],\"Resource\":\"arn:aws:sns:us-east-1:644160558196:c7n-test\",\"Condition\":{\"StringEquals\":{\"AWS:SourceAccount\":\"644160558196\"}}},{\"Sid\":\"OrgPathStatement\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:Publish\",\"SNS:RemovePermission\",\"SNS:SetTopicAttributes\",\"SNS:DeleteTopic\",\"SNS:ListSubscriptionsByTopic\",\"SNS:GetTopicAttributes\",\"SNS:AddPermission\",\"SNS:Subscribe\"],\"Resource\":\"arn:aws:sns:us-east-1:644160558196:c7n-test\",\"Condition\":{\"ForAnyValue:StringLike\":{\"aws:PrincipalOrgPaths\":\"o-abcd123456/r-xyz789/ou-xyz789-qrstuvwx/*\"}}}]}", + "Owner": "644160558196", + "SubscriptionsPending": "0", + "KmsMasterKeyId": "alias/aws/sns", + "TopicArn": "arn:aws:sns:us-east-1:644160558196:c7n-test", + "TracingConfig": "PassThrough", + "EffectiveDeliveryPolicy": "{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false,\"defaultRequestPolicy\":{\"headerContentType\":\"text/plain; charset=UTF-8\"}}}", + "SubscriptionsConfirmed": "0", + "DisplayName": "", + "SubscriptionsDeleted": "0" + }, + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sns_cross_account_for_any_value/sns.ListTopics_1.json b/tests/data/placebo/test_sns_cross_account_for_any_value/sns.ListTopics_1.json new file mode 100644 index 00000000000..3557f976950 --- /dev/null +++ b/tests/data/placebo/test_sns_cross_account_for_any_value/sns.ListTopics_1.json @@ -0,0 +1,11 @@ +{ + "status_code": 200, + "data": { + "Topics": [ + { + "TopicArn": "arn:aws:sns:us-east-1:644160558196:c7n-test" + } + ], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/data/placebo/test_sns_cross_account_for_any_value/tagging.GetResources_1.json b/tests/data/placebo/test_sns_cross_account_for_any_value/tagging.GetResources_1.json new file mode 100644 index 00000000000..8b704d1852a --- /dev/null +++ b/tests/data/placebo/test_sns_cross_account_for_any_value/tagging.GetResources_1.json @@ -0,0 +1,8 @@ +{ + "status_code": 200, + "data": { + "PaginationToken": "", + "ResourceTagMappingList": [], + "ResponseMetadata": {} + } +} \ No newline at end of file diff --git a/tests/terraform/emr_serverless_app_autostop/main.tf b/tests/terraform/emr_serverless_app_autostop/main.tf new file mode 100644 index 00000000000..718bd137aad --- /dev/null +++ b/tests/terraform/emr_serverless_app_autostop/main.tf @@ -0,0 +1,20 @@ +resource "aws_emrserverless_application" "autostop_enabled" { + name = "c7n-test-emr-serverless-autostop-enabled" + release_label = "emr-6.9.0" + type = "Spark" + + auto_stop_configuration { + enabled = true + idle_timeout_minutes = 15 + } +} + +resource "aws_emrserverless_application" "autostop_disabled" { + name = "c7n-test-emr-serverless-autostop-disabled" + release_label = "emr-6.9.0" + type = "Spark" + + auto_stop_configuration { + enabled = false + } +} diff --git a/tests/terraform/emr_serverless_app_autostop/tf_resources.json b/tests/terraform/emr_serverless_app_autostop/tf_resources.json new file mode 100644 index 00000000000..16354e9e38c --- /dev/null +++ b/tests/terraform/emr_serverless_app_autostop/tf_resources.json @@ -0,0 +1,134 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_emrserverless_application": { + "autostop_disabled": { + "architecture": "X86_64", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4jplrhduu09", + "auto_start_configuration": [ + { + "enabled": true + } + ], + "auto_stop_configuration": [ + { + "enabled": false, + "idle_timeout_minutes": 15 + } + ], + "id": "00g7c4jplrhduu09", + "image_configuration": [], + "initial_capacity": [], + "interactive_configuration": [ + { + "livy_endpoint_enabled": null, + "studio_enabled": null + } + ], + "job_level_cost_allocation_configuration": [ + { + "enabled": false + } + ], + "maximum_capacity": [ + { + "cpu": null, + "disk": null, + "memory": null + } + ], + "monitoring_configuration": [ + { + "cloudwatch_logging_configuration": [], + "managed_persistence_monitoring_configuration": [ + { + "enabled": true, + "encryption_key_arn": "" + } + ], + "prometheus_monitoring_configuration": [], + "s3_monitoring_configuration": [] + } + ], + "name": "c7n-test-emr-serverless-autostop-disabled", + "network_configuration": [ + { + "security_group_ids": null, + "subnet_ids": null + } + ], + "region": "us-east-1", + "release_label": "emr-6.9.0", + "runtime_configuration": [], + "scheduler_configuration": [], + "tags": null, + "tags_all": {}, + "type": "spark" + }, + "autostop_enabled": { + "architecture": "X86_64", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4jplnn1si09", + "auto_start_configuration": [ + { + "enabled": true + } + ], + "auto_stop_configuration": [ + { + "enabled": true, + "idle_timeout_minutes": 15 + } + ], + "id": "00g7c4jplnn1si09", + "image_configuration": [], + "initial_capacity": [], + "interactive_configuration": [ + { + "livy_endpoint_enabled": null, + "studio_enabled": null + } + ], + "job_level_cost_allocation_configuration": [ + { + "enabled": false + } + ], + "maximum_capacity": [ + { + "cpu": null, + "disk": null, + "memory": null + } + ], + "monitoring_configuration": [ + { + "cloudwatch_logging_configuration": [], + "managed_persistence_monitoring_configuration": [ + { + "enabled": true, + "encryption_key_arn": "" + } + ], + "prometheus_monitoring_configuration": [], + "s3_monitoring_configuration": [] + } + ], + "name": "c7n-test-emr-serverless-autostop-enabled", + "network_configuration": [ + { + "security_group_ids": null, + "subnet_ids": null + } + ], + "region": "us-east-1", + "release_label": "emr-6.9.0", + "runtime_configuration": [], + "scheduler_configuration": [], + "tags": null, + "tags_all": {}, + "type": "spark" + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/emr_serverless_app_delete/main.tf b/tests/terraform/emr_serverless_app_delete/main.tf new file mode 100644 index 00000000000..000c32b2945 --- /dev/null +++ b/tests/terraform/emr_serverless_app_delete/main.tf @@ -0,0 +1,5 @@ +resource "aws_emrserverless_application" "test" { + name = "c7n-test-emr-serverless-delete" + release_label = "emr-6.9.0" + type = "Spark" +} diff --git a/tests/terraform/emr_serverless_app_delete/tf_resources.json b/tests/terraform/emr_serverless_app_delete/tf_resources.json new file mode 100644 index 00000000000..165b6ffbe9e --- /dev/null +++ b/tests/terraform/emr_serverless_app_delete/tf_resources.json @@ -0,0 +1,71 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_emrserverless_application": { + "test": { + "architecture": "X86_64", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4tup58h2u09", + "auto_start_configuration": [ + { + "enabled": true + } + ], + "auto_stop_configuration": [ + { + "enabled": true, + "idle_timeout_minutes": 15 + } + ], + "id": "00g7c4tup58h2u09", + "image_configuration": [], + "initial_capacity": [], + "interactive_configuration": [ + { + "livy_endpoint_enabled": null, + "studio_enabled": null + } + ], + "job_level_cost_allocation_configuration": [ + { + "enabled": false + } + ], + "maximum_capacity": [ + { + "cpu": null, + "disk": null, + "memory": null + } + ], + "monitoring_configuration": [ + { + "cloudwatch_logging_configuration": [], + "managed_persistence_monitoring_configuration": [ + { + "enabled": true, + "encryption_key_arn": "" + } + ], + "prometheus_monitoring_configuration": [], + "s3_monitoring_configuration": [] + } + ], + "name": "c7n-test-emr-serverless-delete", + "network_configuration": [ + { + "security_group_ids": null, + "subnet_ids": null + } + ], + "region": "us-east-1", + "release_label": "emr-6.9.0", + "runtime_configuration": [], + "scheduler_configuration": [], + "tags": null, + "tags_all": {}, + "type": "spark" + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/emr_serverless_app_markop/main.tf b/tests/terraform/emr_serverless_app_markop/main.tf new file mode 100644 index 00000000000..0e4534658e5 --- /dev/null +++ b/tests/terraform/emr_serverless_app_markop/main.tf @@ -0,0 +1,5 @@ +resource "aws_emrserverless_application" "test" { + name = "c7n-test-emr-serverless-markop" + release_label = "emr-6.9.0" + type = "Spark" +} diff --git a/tests/terraform/emr_serverless_app_markop/tf_resources.json b/tests/terraform/emr_serverless_app_markop/tf_resources.json new file mode 100644 index 00000000000..56721fa06fa --- /dev/null +++ b/tests/terraform/emr_serverless_app_markop/tf_resources.json @@ -0,0 +1,71 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_emrserverless_application": { + "test": { + "architecture": "X86_64", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4slugdoti09", + "auto_start_configuration": [ + { + "enabled": true + } + ], + "auto_stop_configuration": [ + { + "enabled": true, + "idle_timeout_minutes": 15 + } + ], + "id": "00g7c4slugdoti09", + "image_configuration": [], + "initial_capacity": [], + "interactive_configuration": [ + { + "livy_endpoint_enabled": null, + "studio_enabled": null + } + ], + "job_level_cost_allocation_configuration": [ + { + "enabled": false + } + ], + "maximum_capacity": [ + { + "cpu": null, + "disk": null, + "memory": null + } + ], + "monitoring_configuration": [ + { + "cloudwatch_logging_configuration": [], + "managed_persistence_monitoring_configuration": [ + { + "enabled": true, + "encryption_key_arn": "" + } + ], + "prometheus_monitoring_configuration": [], + "s3_monitoring_configuration": [] + } + ], + "name": "c7n-test-emr-serverless-markop", + "network_configuration": [ + { + "security_group_ids": null, + "subnet_ids": null + } + ], + "region": "us-east-1", + "release_label": "emr-6.9.0", + "runtime_configuration": [], + "scheduler_configuration": [], + "tags": null, + "tags_all": {}, + "type": "spark" + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/emr_serverless_app_remove_tag/main.tf b/tests/terraform/emr_serverless_app_remove_tag/main.tf new file mode 100644 index 00000000000..93f09f0d743 --- /dev/null +++ b/tests/terraform/emr_serverless_app_remove_tag/main.tf @@ -0,0 +1,9 @@ +resource "aws_emrserverless_application" "test" { + name = "c7n-test-emr-serverless-remove-tag" + release_label = "emr-6.9.0" + type = "Spark" + + tags = { + foo = "bar" + } +} diff --git a/tests/terraform/emr_serverless_app_remove_tag/tf_resources.json b/tests/terraform/emr_serverless_app_remove_tag/tf_resources.json new file mode 100644 index 00000000000..f8e09016fcf --- /dev/null +++ b/tests/terraform/emr_serverless_app_remove_tag/tf_resources.json @@ -0,0 +1,75 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_emrserverless_application": { + "test": { + "architecture": "X86_64", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4rdj2nvis09", + "auto_start_configuration": [ + { + "enabled": true + } + ], + "auto_stop_configuration": [ + { + "enabled": true, + "idle_timeout_minutes": 15 + } + ], + "id": "00g7c4rdj2nvis09", + "image_configuration": [], + "initial_capacity": [], + "interactive_configuration": [ + { + "livy_endpoint_enabled": null, + "studio_enabled": null + } + ], + "job_level_cost_allocation_configuration": [ + { + "enabled": false + } + ], + "maximum_capacity": [ + { + "cpu": null, + "disk": null, + "memory": null + } + ], + "monitoring_configuration": [ + { + "cloudwatch_logging_configuration": [], + "managed_persistence_monitoring_configuration": [ + { + "enabled": true, + "encryption_key_arn": "" + } + ], + "prometheus_monitoring_configuration": [], + "s3_monitoring_configuration": [] + } + ], + "name": "c7n-test-emr-serverless-remove-tag", + "network_configuration": [ + { + "security_group_ids": null, + "subnet_ids": null + } + ], + "region": "us-east-1", + "release_label": "emr-6.9.0", + "runtime_configuration": [], + "scheduler_configuration": [], + "tags": { + "foo": "bar" + }, + "tags_all": { + "foo": "bar" + }, + "type": "spark" + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/emr_serverless_app_tag/main.tf b/tests/terraform/emr_serverless_app_tag/main.tf new file mode 100644 index 00000000000..d5013f7ec96 --- /dev/null +++ b/tests/terraform/emr_serverless_app_tag/main.tf @@ -0,0 +1,5 @@ +resource "aws_emrserverless_application" "test" { + name = "c7n-test-emr-serverless-tag" + release_label = "emr-6.9.0" + type = "Spark" +} diff --git a/tests/terraform/emr_serverless_app_tag/tf_resources.json b/tests/terraform/emr_serverless_app_tag/tf_resources.json new file mode 100644 index 00000000000..8503c177093 --- /dev/null +++ b/tests/terraform/emr_serverless_app_tag/tf_resources.json @@ -0,0 +1,71 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_emrserverless_application": { + "test": { + "architecture": "X86_64", + "arn": "arn:aws:emr-serverless:us-east-1:644160558196:/applications/00g7c4q56puk5q09", + "auto_start_configuration": [ + { + "enabled": true + } + ], + "auto_stop_configuration": [ + { + "enabled": true, + "idle_timeout_minutes": 15 + } + ], + "id": "00g7c4q56puk5q09", + "image_configuration": [], + "initial_capacity": [], + "interactive_configuration": [ + { + "livy_endpoint_enabled": null, + "studio_enabled": null + } + ], + "job_level_cost_allocation_configuration": [ + { + "enabled": false + } + ], + "maximum_capacity": [ + { + "cpu": null, + "disk": null, + "memory": null + } + ], + "monitoring_configuration": [ + { + "cloudwatch_logging_configuration": [], + "managed_persistence_monitoring_configuration": [ + { + "enabled": true, + "encryption_key_arn": "" + } + ], + "prometheus_monitoring_configuration": [], + "s3_monitoring_configuration": [] + } + ], + "name": "c7n-test-emr-serverless-tag", + "network_configuration": [ + { + "security_group_ids": null, + "subnet_ids": null + } + ], + "region": "us-east-1", + "release_label": "emr-6.9.0", + "runtime_configuration": [], + "scheduler_configuration": [], + "tags": null, + "tags_all": {}, + "type": "spark" + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/lattice_rule_filter_listener/main.tf b/tests/terraform/lattice_rule_filter_listener/main.tf new file mode 100644 index 00000000000..0ec8396120b --- /dev/null +++ b/tests/terraform/lattice_rule_filter_listener/main.tf @@ -0,0 +1,85 @@ +resource "aws_vpclattice_service" "test_service" { + name = "test-service" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener" { + name = "test-listener" + service_identifier = aws_vpclattice_service.test_service.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule" { + name = "test-rule" + service_identifier = aws_vpclattice_service.test_service.id + listener_identifier = aws_vpclattice_listener.test_listener.listener_id + priority = 10 + tags = { + ExistingKey = "ExistingValue" + } + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} + + +resource "aws_vpclattice_service" "test_service2" { + name = "test-service2" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener2" { + name = "test-listener2" + service_identifier = aws_vpclattice_service.test_service2.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule2" { + name = "test-rule2" + service_identifier = aws_vpclattice_service.test_service2.id + listener_identifier = aws_vpclattice_listener.test_listener2.listener_id + priority = 10 + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} diff --git a/tests/terraform/lattice_rule_filter_listener/tf_resources.json b/tests/terraform/lattice_rule_filter_listener/tf_resources.json new file mode 100644 index 00000000000..cf751ded087 --- /dev/null +++ b/tests/terraform/lattice_rule_filter_listener/tf_resources.json @@ -0,0 +1,194 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_vpclattice_listener": { + "test_listener": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0/listener/listener-0aea8cb5e967c8493", + "created_at": "2026-03-13 15:44:35.132 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0b853eda0579935b0/listener-0aea8cb5e967c8493", + "last_updated_at": "2026-03-13 15:44:35.132 +0000 UTC", + "listener_id": "listener-0aea8cb5e967c8493", + "name": "test-listener", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0", + "service_identifier": "svc-0b853eda0579935b0", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_listener2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d/listener/listener-0bab637e7fe24d8f1", + "created_at": "2026-03-13 15:44:36.542 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0a1e45b6464d1be4d/listener-0bab637e7fe24d8f1", + "last_updated_at": "2026-03-13 15:44:36.542 +0000 UTC", + "listener_id": "listener-0bab637e7fe24d8f1", + "name": "test-listener2", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d", + "service_identifier": "svc-0a1e45b6464d1be4d", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_listener_rule": { + "test_rule": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0/listener/listener-0aea8cb5e967c8493/rule/rule-0d6e45a66600da527", + "id": "svc-0b853eda0579935b0/listener-0aea8cb5e967c8493/rule-0d6e45a66600da527", + "listener_identifier": "listener-0aea8cb5e967c8493", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0d6e45a66600da527", + "service_identifier": "svc-0b853eda0579935b0", + "tags": { + "ExistingKey": "ExistingValue" + }, + "tags_all": { + "ExistingKey": "ExistingValue" + }, + "timeouts": null + }, + "test_rule2": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d/listener/listener-0bab637e7fe24d8f1/rule/rule-07cc81379b2259d4d", + "id": "svc-0a1e45b6464d1be4d/listener-0bab637e7fe24d8f1/rule-07cc81379b2259d4d", + "listener_identifier": "listener-0bab637e7fe24d8f1", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule2", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-07cc81379b2259d4d", + "service_identifier": "svc-0a1e45b6464d1be4d", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_service": { + "test_service": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0b853eda0579935b0", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service-0b853eda0579935b0.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0b853eda0579935b0", + "name": "test-service", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_service2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0a1e45b6464d1be4d", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service2-0a1e45b6464d1be4d.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0a1e45b6464d1be4d", + "name": "test-service2", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/lattice_rule_query_listener/main.tf b/tests/terraform/lattice_rule_query_listener/main.tf new file mode 100644 index 00000000000..0ec8396120b --- /dev/null +++ b/tests/terraform/lattice_rule_query_listener/main.tf @@ -0,0 +1,85 @@ +resource "aws_vpclattice_service" "test_service" { + name = "test-service" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener" { + name = "test-listener" + service_identifier = aws_vpclattice_service.test_service.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule" { + name = "test-rule" + service_identifier = aws_vpclattice_service.test_service.id + listener_identifier = aws_vpclattice_listener.test_listener.listener_id + priority = 10 + tags = { + ExistingKey = "ExistingValue" + } + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} + + +resource "aws_vpclattice_service" "test_service2" { + name = "test-service2" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener2" { + name = "test-listener2" + service_identifier = aws_vpclattice_service.test_service2.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule2" { + name = "test-rule2" + service_identifier = aws_vpclattice_service.test_service2.id + listener_identifier = aws_vpclattice_listener.test_listener2.listener_id + priority = 10 + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} diff --git a/tests/terraform/lattice_rule_query_listener/tf_resources.json b/tests/terraform/lattice_rule_query_listener/tf_resources.json new file mode 100644 index 00000000000..ad565bc0720 --- /dev/null +++ b/tests/terraform/lattice_rule_query_listener/tf_resources.json @@ -0,0 +1,194 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_vpclattice_listener": { + "test_listener": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-030ab283855fcf4c2/listener/listener-0c714b70206e5aef8", + "created_at": "2026-03-13 15:44:58.785 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-030ab283855fcf4c2/listener-0c714b70206e5aef8", + "last_updated_at": "2026-03-13 15:44:58.785 +0000 UTC", + "listener_id": "listener-0c714b70206e5aef8", + "name": "test-listener", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-030ab283855fcf4c2", + "service_identifier": "svc-030ab283855fcf4c2", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_listener2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d1ea894ca7ba9bf8/listener/listener-00d375a6df37459f3", + "created_at": "2026-03-13 15:44:59.049 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0d1ea894ca7ba9bf8/listener-00d375a6df37459f3", + "last_updated_at": "2026-03-13 15:44:59.049 +0000 UTC", + "listener_id": "listener-00d375a6df37459f3", + "name": "test-listener2", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d1ea894ca7ba9bf8", + "service_identifier": "svc-0d1ea894ca7ba9bf8", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_listener_rule": { + "test_rule": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-030ab283855fcf4c2/listener/listener-0c714b70206e5aef8/rule/rule-073ef7848bfdf7b87", + "id": "svc-030ab283855fcf4c2/listener-0c714b70206e5aef8/rule-073ef7848bfdf7b87", + "listener_identifier": "listener-0c714b70206e5aef8", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-073ef7848bfdf7b87", + "service_identifier": "svc-030ab283855fcf4c2", + "tags": { + "ExistingKey": "ExistingValue" + }, + "tags_all": { + "ExistingKey": "ExistingValue" + }, + "timeouts": null + }, + "test_rule2": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d1ea894ca7ba9bf8/listener/listener-00d375a6df37459f3/rule/rule-0b053660a8f9217dc", + "id": "svc-0d1ea894ca7ba9bf8/listener-00d375a6df37459f3/rule-0b053660a8f9217dc", + "listener_identifier": "listener-00d375a6df37459f3", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule2", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0b053660a8f9217dc", + "service_identifier": "svc-0d1ea894ca7ba9bf8", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_service": { + "test_service": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-030ab283855fcf4c2", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service-030ab283855fcf4c2.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-030ab283855fcf4c2", + "name": "test-service", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_service2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d1ea894ca7ba9bf8", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service2-0d1ea894ca7ba9bf8.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0d1ea894ca7ba9bf8", + "name": "test-service2", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/lattice_rule_query_service/main.tf b/tests/terraform/lattice_rule_query_service/main.tf new file mode 100644 index 00000000000..0ec8396120b --- /dev/null +++ b/tests/terraform/lattice_rule_query_service/main.tf @@ -0,0 +1,85 @@ +resource "aws_vpclattice_service" "test_service" { + name = "test-service" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener" { + name = "test-listener" + service_identifier = aws_vpclattice_service.test_service.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule" { + name = "test-rule" + service_identifier = aws_vpclattice_service.test_service.id + listener_identifier = aws_vpclattice_listener.test_listener.listener_id + priority = 10 + tags = { + ExistingKey = "ExistingValue" + } + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} + + +resource "aws_vpclattice_service" "test_service2" { + name = "test-service2" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener2" { + name = "test-listener2" + service_identifier = aws_vpclattice_service.test_service2.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule2" { + name = "test-rule2" + service_identifier = aws_vpclattice_service.test_service2.id + listener_identifier = aws_vpclattice_listener.test_listener2.listener_id + priority = 10 + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} diff --git a/tests/terraform/lattice_rule_query_service/tf_resources.json b/tests/terraform/lattice_rule_query_service/tf_resources.json new file mode 100644 index 00000000000..b8dff929eb8 --- /dev/null +++ b/tests/terraform/lattice_rule_query_service/tf_resources.json @@ -0,0 +1,194 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_vpclattice_listener": { + "test_listener": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a/listener/listener-02e6d6e4b198fd51a", + "created_at": "2026-03-13 15:44:14.158 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0861b4cd69650046a/listener-02e6d6e4b198fd51a", + "last_updated_at": "2026-03-13 15:44:14.158 +0000 UTC", + "listener_id": "listener-02e6d6e4b198fd51a", + "name": "test-listener", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a", + "service_identifier": "svc-0861b4cd69650046a", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_listener2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-02e81f6c1e61ddcfe/listener/listener-05fd18c3764b26259", + "created_at": "2026-03-13 15:44:14.244 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-02e81f6c1e61ddcfe/listener-05fd18c3764b26259", + "last_updated_at": "2026-03-13 15:44:14.244 +0000 UTC", + "listener_id": "listener-05fd18c3764b26259", + "name": "test-listener2", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-02e81f6c1e61ddcfe", + "service_identifier": "svc-02e81f6c1e61ddcfe", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_listener_rule": { + "test_rule": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a/listener/listener-02e6d6e4b198fd51a/rule/rule-0aa60409d67d5ea6f", + "id": "svc-0861b4cd69650046a/listener-02e6d6e4b198fd51a/rule-0aa60409d67d5ea6f", + "listener_identifier": "listener-02e6d6e4b198fd51a", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0aa60409d67d5ea6f", + "service_identifier": "svc-0861b4cd69650046a", + "tags": { + "ExistingKey": "ExistingValue" + }, + "tags_all": { + "ExistingKey": "ExistingValue" + }, + "timeouts": null + }, + "test_rule2": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-02e81f6c1e61ddcfe/listener/listener-05fd18c3764b26259/rule/rule-0e14d63e5ad9b7034", + "id": "svc-02e81f6c1e61ddcfe/listener-05fd18c3764b26259/rule-0e14d63e5ad9b7034", + "listener_identifier": "listener-05fd18c3764b26259", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule2", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0e14d63e5ad9b7034", + "service_identifier": "svc-02e81f6c1e61ddcfe", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_service": { + "test_service": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0861b4cd69650046a", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service-0861b4cd69650046a.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0861b4cd69650046a", + "name": "test-service", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_service2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-02e81f6c1e61ddcfe", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service2-02e81f6c1e61ddcfe.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-02e81f6c1e61ddcfe", + "name": "test-service2", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/lattice_rule_query_service_listener/main.tf b/tests/terraform/lattice_rule_query_service_listener/main.tf new file mode 100644 index 00000000000..0ec8396120b --- /dev/null +++ b/tests/terraform/lattice_rule_query_service_listener/main.tf @@ -0,0 +1,85 @@ +resource "aws_vpclattice_service" "test_service" { + name = "test-service" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener" { + name = "test-listener" + service_identifier = aws_vpclattice_service.test_service.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule" { + name = "test-rule" + service_identifier = aws_vpclattice_service.test_service.id + listener_identifier = aws_vpclattice_listener.test_listener.listener_id + priority = 10 + tags = { + ExistingKey = "ExistingValue" + } + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} + + +resource "aws_vpclattice_service" "test_service2" { + name = "test-service2" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener2" { + name = "test-listener2" + service_identifier = aws_vpclattice_service.test_service2.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule2" { + name = "test-rule2" + service_identifier = aws_vpclattice_service.test_service2.id + listener_identifier = aws_vpclattice_listener.test_listener2.listener_id + priority = 10 + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} diff --git a/tests/terraform/lattice_rule_query_service_listener/tf_resources.json b/tests/terraform/lattice_rule_query_service_listener/tf_resources.json new file mode 100644 index 00000000000..15aec6f9c5f --- /dev/null +++ b/tests/terraform/lattice_rule_query_service_listener/tf_resources.json @@ -0,0 +1,194 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_vpclattice_listener": { + "test_listener": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06/listener/listener-09d4c687748f5183d", + "created_at": "2026-03-13 15:45:19.727 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-04c7fac0d29f77a06/listener-09d4c687748f5183d", + "last_updated_at": "2026-03-13 15:45:19.727 +0000 UTC", + "listener_id": "listener-09d4c687748f5183d", + "name": "test-listener", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06", + "service_identifier": "svc-04c7fac0d29f77a06", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_listener2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-03fb773b9f72e0093/listener/listener-0c50ac530ea6d10f7", + "created_at": "2026-03-13 15:45:51.137 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-03fb773b9f72e0093/listener-0c50ac530ea6d10f7", + "last_updated_at": "2026-03-13 15:45:51.137 +0000 UTC", + "listener_id": "listener-0c50ac530ea6d10f7", + "name": "test-listener2", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-03fb773b9f72e0093", + "service_identifier": "svc-03fb773b9f72e0093", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_listener_rule": { + "test_rule": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06/listener/listener-09d4c687748f5183d/rule/rule-0d1442e6612b77614", + "id": "svc-04c7fac0d29f77a06/listener-09d4c687748f5183d/rule-0d1442e6612b77614", + "listener_identifier": "listener-09d4c687748f5183d", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0d1442e6612b77614", + "service_identifier": "svc-04c7fac0d29f77a06", + "tags": { + "ExistingKey": "ExistingValue" + }, + "tags_all": { + "ExistingKey": "ExistingValue" + }, + "timeouts": null + }, + "test_rule2": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-03fb773b9f72e0093/listener/listener-0c50ac530ea6d10f7/rule/rule-037641a58609b9c95", + "id": "svc-03fb773b9f72e0093/listener-0c50ac530ea6d10f7/rule-037641a58609b9c95", + "listener_identifier": "listener-0c50ac530ea6d10f7", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule2", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-037641a58609b9c95", + "service_identifier": "svc-03fb773b9f72e0093", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_service": { + "test_service": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-04c7fac0d29f77a06", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service-04c7fac0d29f77a06.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-04c7fac0d29f77a06", + "name": "test-service", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_service2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-03fb773b9f72e0093", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service2-03fb773b9f72e0093.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-03fb773b9f72e0093", + "name": "test-service2", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/lattice_rule_tagging/main.tf b/tests/terraform/lattice_rule_tagging/main.tf new file mode 100644 index 00000000000..0ec8396120b --- /dev/null +++ b/tests/terraform/lattice_rule_tagging/main.tf @@ -0,0 +1,85 @@ +resource "aws_vpclattice_service" "test_service" { + name = "test-service" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener" { + name = "test-listener" + service_identifier = aws_vpclattice_service.test_service.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule" { + name = "test-rule" + service_identifier = aws_vpclattice_service.test_service.id + listener_identifier = aws_vpclattice_listener.test_listener.listener_id + priority = 10 + tags = { + ExistingKey = "ExistingValue" + } + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} + + +resource "aws_vpclattice_service" "test_service2" { + name = "test-service2" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener2" { + name = "test-listener2" + service_identifier = aws_vpclattice_service.test_service2.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule2" { + name = "test-rule2" + service_identifier = aws_vpclattice_service.test_service2.id + listener_identifier = aws_vpclattice_listener.test_listener2.listener_id + priority = 10 + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} diff --git a/tests/terraform/lattice_rule_tagging/tf_resources.json b/tests/terraform/lattice_rule_tagging/tf_resources.json new file mode 100644 index 00000000000..dfc7b966583 --- /dev/null +++ b/tests/terraform/lattice_rule_tagging/tf_resources.json @@ -0,0 +1,194 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_vpclattice_listener": { + "test_listener": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537/listener/listener-010148a46dc5dfa6f", + "created_at": "2026-03-13 15:46:13.076 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0ecf63fb91f2b5537/listener-010148a46dc5dfa6f", + "last_updated_at": "2026-03-13 15:46:13.076 +0000 UTC", + "listener_id": "listener-010148a46dc5dfa6f", + "name": "test-listener", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537", + "service_identifier": "svc-0ecf63fb91f2b5537", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_listener2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d31c653910197eb3/listener/listener-0274c5e51745c9be9", + "created_at": "2026-03-13 15:46:13.07 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0d31c653910197eb3/listener-0274c5e51745c9be9", + "last_updated_at": "2026-03-13 15:46:13.07 +0000 UTC", + "listener_id": "listener-0274c5e51745c9be9", + "name": "test-listener2", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d31c653910197eb3", + "service_identifier": "svc-0d31c653910197eb3", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_listener_rule": { + "test_rule": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537/listener/listener-010148a46dc5dfa6f/rule/rule-07e791dc458a1967f", + "id": "svc-0ecf63fb91f2b5537/listener-010148a46dc5dfa6f/rule-07e791dc458a1967f", + "listener_identifier": "listener-010148a46dc5dfa6f", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-07e791dc458a1967f", + "service_identifier": "svc-0ecf63fb91f2b5537", + "tags": { + "ExistingKey": "ExistingValue" + }, + "tags_all": { + "ExistingKey": "ExistingValue" + }, + "timeouts": null + }, + "test_rule2": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d31c653910197eb3/listener/listener-0274c5e51745c9be9/rule/rule-0aea192139c0555c6", + "id": "svc-0d31c653910197eb3/listener-0274c5e51745c9be9/rule-0aea192139c0555c6", + "listener_identifier": "listener-0274c5e51745c9be9", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule2", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0aea192139c0555c6", + "service_identifier": "svc-0d31c653910197eb3", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_service": { + "test_service": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0ecf63fb91f2b5537", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service-0ecf63fb91f2b5537.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0ecf63fb91f2b5537", + "name": "test-service", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_service2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0d31c653910197eb3", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service2-0d31c653910197eb3.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0d31c653910197eb3", + "name": "test-service2", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/sagemaker_studio/main.tf b/tests/terraform/sagemaker_studio/main.tf new file mode 100644 index 00000000000..d589d66414c --- /dev/null +++ b/tests/terraform/sagemaker_studio/main.tf @@ -0,0 +1,152 @@ +provider "aws" {} + +resource "random_pet" "studio" { + length = 2 + separator = "-" +} + +data "aws_vpc" "default" { + default = true +} + +data "aws_subnets" "default" { + filter { + name = "vpc-id" + values = [data.aws_vpc.default.id] + } +} + +data "aws_iam_policy_document" "assume_role" { + statement { + actions = ["sts:AssumeRole"] + principals { + type = "Service" + identifiers = ["sagemaker.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "execution" { + name = "c7n-sagemaker-studio-${random_pet.studio.id}" + assume_role_policy = data.aws_iam_policy_document.assume_role.json +} + +resource "aws_sagemaker_domain" "main" { + domain_name = "c7n-studio-${random_pet.studio.id}" + auth_mode = "IAM" + vpc_id = data.aws_vpc.default.id + subnet_ids = [data.aws_subnets.default.ids[0]] + + default_user_settings { + execution_role = aws_iam_role.execution.arn + } + + default_space_settings { + execution_role = aws_iam_role.execution.arn + } + + retention_policy { + home_efs_file_system = "Delete" + } +} + +resource "aws_sagemaker_user_profile" "main" { + domain_id = aws_sagemaker_domain.main.id + user_profile_name = "c7n-profile-${random_pet.studio.id}" + tags = { "favorite-color" = "c7n" } + + user_settings { + execution_role = aws_iam_role.execution.arn + } +} + +resource "aws_sagemaker_user_profile" "untagged" { + domain_id = aws_sagemaker_domain.main.id + user_profile_name = "c7n-profile-untagged-${random_pet.studio.id}" + + user_settings { + execution_role = aws_iam_role.execution.arn + } +} + +resource "aws_sagemaker_space" "main" { + domain_id = aws_sagemaker_domain.main.id + space_name = "c7nspace${replace(random_pet.studio.id, "-", "")}" + tags = { "favorite-color" = "c7n" } +} + +resource "aws_sagemaker_space" "untagged" { + domain_id = aws_sagemaker_domain.main.id + space_name = "c7nspaceuntagged${replace(random_pet.studio.id, "-", "")}" +} + +resource "aws_sagemaker_app" "main" { + domain_id = aws_sagemaker_domain.main.id + user_profile_name = aws_sagemaker_user_profile.main.user_profile_name + app_name = "c7n-app-${random_pet.studio.id}" + app_type = "JupyterServer" + tags = { "favorite-color" = "c7n" } +} + +resource "aws_sagemaker_app" "untagged" { + domain_id = aws_sagemaker_domain.main.id + user_profile_name = aws_sagemaker_user_profile.untagged.user_profile_name + app_name = "c7n-app-untagged-${random_pet.studio.id}" + app_type = "JupyterServer" +} + +output "domain_id" { + value = aws_sagemaker_domain.main.id +} + +output "domain_arn" { + value = aws_sagemaker_domain.main.arn +} + +output "user_profile_name" { + value = aws_sagemaker_user_profile.main.user_profile_name +} + +output "user_profile_arn" { + value = aws_sagemaker_user_profile.main.arn +} + +output "user_profile_untagged_name" { + value = aws_sagemaker_user_profile.untagged.user_profile_name +} + +output "user_profile_untagged_arn" { + value = aws_sagemaker_user_profile.untagged.arn +} + +output "space_name" { + value = aws_sagemaker_space.main.space_name +} + +output "space_arn" { + value = aws_sagemaker_space.main.arn +} + +output "space_untagged_name" { + value = aws_sagemaker_space.untagged.space_name +} + +output "space_untagged_arn" { + value = aws_sagemaker_space.untagged.arn +} + +output "app_name" { + value = aws_sagemaker_app.main.app_name +} + +output "app_arn" { + value = aws_sagemaker_app.main.arn +} + +output "app_untagged_name" { + value = aws_sagemaker_app.untagged.app_name +} + +output "app_untagged_arn" { + value = aws_sagemaker_app.untagged.arn +} diff --git a/tests/terraform/sagemaker_studio/tf_resources.json b/tests/terraform/sagemaker_studio/tf_resources.json new file mode 100644 index 00000000000..37a31c206c4 --- /dev/null +++ b/tests/terraform/sagemaker_studio/tf_resources.json @@ -0,0 +1,408 @@ +{ + "pytest-terraform": 1, + "outputs": { + "app_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-comic-chicken/JupyterServer/c7n-app-comic-chicken", + "type": "string" + }, + "app_name": { + "value": "c7n-app-comic-chicken", + "type": "string" + }, + "app_untagged_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken/JupyterServer/c7n-app-untagged-comic-chicken", + "type": "string" + }, + "app_untagged_name": { + "value": "c7n-app-untagged-comic-chicken", + "type": "string" + }, + "domain_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:domain/d-szjlsjfyqmaq", + "type": "string" + }, + "domain_id": { + "value": "d-szjlsjfyqmaq", + "type": "string" + }, + "space_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspacecomicchicken", + "type": "string" + }, + "space_name": { + "value": "c7nspacecomicchicken", + "type": "string" + }, + "space_untagged_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspaceuntaggedcomicchicken", + "type": "string" + }, + "space_untagged_name": { + "value": "c7nspaceuntaggedcomicchicken", + "type": "string" + }, + "user_profile_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-comic-chicken", + "type": "string" + }, + "user_profile_name": { + "value": "c7n-profile-comic-chicken", + "type": "string" + }, + "user_profile_untagged_arn": { + "value": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken", + "type": "string" + }, + "user_profile_untagged_name": { + "value": "c7n-profile-untagged-comic-chicken", + "type": "string" + } + }, + "resources": { + "aws_iam_policy_document": { + "assume_role": { + "id": "1147345228", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"sagemaker.amazonaws.com\"\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"sagemaker.amazonaws.com\"}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "sagemaker.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + } + }, + "aws_subnets": { + "default": { + "filter": [ + { + "name": "vpc-id", + "values": [ + "vpc-06149c26f4c960573" + ] + } + ], + "id": "us-east-1", + "ids": [ + "subnet-0a6f6f3abb8e90b2f", + "subnet-006cd2b8ad66e5a41", + "subnet-067e017db7e367654", + "subnet-0716a2a72d6945140", + "subnet-0ace79265977756b4", + "subnet-0ee2c19e2088b1244" + ], + "region": "us-east-1", + "tags": null, + "timeouts": null + } + }, + "aws_vpc": { + "default": { + "arn": "arn:aws:ec2:us-east-1:644160558196:vpc/vpc-06149c26f4c960573", + "cidr_block": "172.31.0.0/16", + "cidr_block_associations": [ + { + "association_id": "vpc-cidr-assoc-0301c7ade0bfe0ded", + "cidr_block": "172.31.0.0/16", + "state": "associated" + } + ], + "default": true, + "dhcp_options_id": "dopt-0caef10e2e26f8bde", + "enable_dns_hostnames": true, + "enable_dns_support": true, + "enable_network_address_usage_metrics": false, + "filter": null, + "id": "vpc-06149c26f4c960573", + "instance_tenancy": "default", + "ipv6_association_id": "", + "ipv6_cidr_block": "", + "main_route_table_id": "rtb-0dda7323bf338d504", + "owner_id": "644160558196", + "region": "us-east-1", + "state": null, + "tags": {}, + "timeouts": null + } + }, + "aws_iam_role": { + "execution": { + "arn": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sagemaker.amazonaws.com\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2026-07-15T18:18:31Z", + "description": "", + "force_detach_policies": false, + "id": "c7n-sagemaker-studio-comic-chicken", + "inline_policy": [], + "managed_policy_arns": [], + "max_session_duration": 3600, + "name": "c7n-sagemaker-studio-comic-chicken", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": null, + "tags_all": {}, + "unique_id": "AROAV7EQQKWXRQ4C4RJMP" + } + }, + "aws_sagemaker_app": { + "main": { + "app_name": "c7n-app-comic-chicken", + "app_type": "JupyterServer", + "arn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-comic-chicken/JupyterServer/c7n-app-comic-chicken", + "domain_id": "d-szjlsjfyqmaq", + "id": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-comic-chicken/JupyterServer/c7n-app-comic-chicken", + "region": "us-east-1", + "resource_spec": [ + { + "instance_type": "system", + "lifecycle_config_arn": "", + "sagemaker_image_arn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "sagemaker_image_version_alias": "", + "sagemaker_image_version_arn": "" + } + ], + "space_name": "", + "tags": { + "favorite-color": "c7n" + }, + "tags_all": { + "favorite-color": "c7n" + }, + "user_profile_name": "c7n-profile-comic-chicken" + }, + "untagged": { + "app_name": "c7n-app-untagged-comic-chicken", + "app_type": "JupyterServer", + "arn": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken/JupyterServer/c7n-app-untagged-comic-chicken", + "domain_id": "d-szjlsjfyqmaq", + "id": "arn:aws:sagemaker:us-east-1:644160558196:app/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken/JupyterServer/c7n-app-untagged-comic-chicken", + "region": "us-east-1", + "resource_spec": [ + { + "instance_type": "system", + "lifecycle_config_arn": "", + "sagemaker_image_arn": "arn:aws:ecr:us-east-1:644160558196:repository/looseleaf-jupyter-server-3", + "sagemaker_image_version_alias": "", + "sagemaker_image_version_arn": "" + } + ], + "space_name": "", + "tags": null, + "tags_all": {}, + "user_profile_name": "c7n-profile-untagged-comic-chicken" + } + }, + "aws_sagemaker_domain": { + "main": { + "app_network_access_type": "PublicInternetOnly", + "app_security_group_management": "", + "arn": "arn:aws:sagemaker:us-east-1:644160558196:domain/d-szjlsjfyqmaq", + "auth_mode": "IAM", + "default_space_settings": [ + { + "custom_file_system_config": [], + "custom_posix_user_config": [], + "execution_role": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "jupyter_lab_app_settings": [], + "jupyter_server_app_settings": [], + "kernel_gateway_app_settings": [], + "security_groups": null, + "space_storage_settings": [] + } + ], + "default_user_settings": [ + { + "auto_mount_home_efs": "Enabled", + "canvas_app_settings": [], + "code_editor_app_settings": [], + "custom_file_system_config": [], + "custom_posix_user_config": [], + "default_landing_uri": "studio::", + "execution_role": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "jupyter_lab_app_settings": [], + "jupyter_server_app_settings": [], + "kernel_gateway_app_settings": [], + "r_session_app_settings": [], + "r_studio_server_pro_app_settings": [], + "security_groups": null, + "sharing_settings": [], + "space_storage_settings": [], + "studio_web_portal": "ENABLED", + "studio_web_portal_settings": [ + { + "hidden_app_types": null, + "hidden_instance_types": null, + "hidden_ml_tools": null + } + ], + "tensor_board_app_settings": [] + } + ], + "domain_name": "c7n-studio-comic-chicken", + "domain_settings": [], + "home_efs_file_system_id": "fs-099437aea3c1b981b", + "id": "d-szjlsjfyqmaq", + "kms_key_id": "", + "region": "us-east-1", + "retention_policy": [ + { + "home_efs_file_system": "Delete" + } + ], + "security_group_id_for_domain_boundary": "", + "single_sign_on_application_arn": "", + "single_sign_on_managed_application_instance_id": "", + "subnet_ids": [ + "subnet-0a6f6f3abb8e90b2f" + ], + "tag_propagation": "DISABLED", + "tags": null, + "tags_all": {}, + "url": "https://d-szjlsjfyqmaq.studio.us-east-1.sagemaker.aws", + "vpc_id": "vpc-06149c26f4c960573" + } + }, + "aws_sagemaker_space": { + "main": { + "arn": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspacecomicchicken", + "domain_id": "d-szjlsjfyqmaq", + "home_efs_file_system_uid": "200015", + "id": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspacecomicchicken", + "ownership_settings": [], + "region": "us-east-1", + "space_display_name": "", + "space_name": "c7nspacecomicchicken", + "space_settings": [], + "space_sharing_settings": [], + "tags": { + "favorite-color": "c7n" + }, + "tags_all": { + "favorite-color": "c7n" + }, + "url": "https://fmbqtou3xkfhnso.studio.us-east-1.sagemaker.aws" + }, + "untagged": { + "arn": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspaceuntaggedcomicchicken", + "domain_id": "d-szjlsjfyqmaq", + "home_efs_file_system_uid": "200005", + "id": "arn:aws:sagemaker:us-east-1:644160558196:space/d-szjlsjfyqmaq/c7nspaceuntaggedcomicchicken", + "ownership_settings": [], + "region": "us-east-1", + "space_display_name": "", + "space_name": "c7nspaceuntaggedcomicchicken", + "space_settings": [], + "space_sharing_settings": [], + "tags": null, + "tags_all": {}, + "url": "https://yri67bja2mhi76a.studio.us-east-1.sagemaker.aws" + } + }, + "aws_sagemaker_user_profile": { + "main": { + "arn": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-comic-chicken", + "domain_id": "d-szjlsjfyqmaq", + "home_efs_file_system_uid": "200020", + "id": "d-szjlsjfyqmaq/c7n-profile-comic-chicken", + "region": "us-east-1", + "single_sign_on_user_identifier": "", + "single_sign_on_user_value": "", + "tags": { + "favorite-color": "c7n" + }, + "tags_all": { + "favorite-color": "c7n" + }, + "user_profile_name": "c7n-profile-comic-chicken", + "user_settings": [ + { + "auto_mount_home_efs": "DefaultAsDomain", + "canvas_app_settings": [], + "code_editor_app_settings": [], + "custom_file_system_config": [], + "custom_posix_user_config": [], + "default_landing_uri": "", + "execution_role": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "jupyter_lab_app_settings": [], + "jupyter_server_app_settings": [], + "kernel_gateway_app_settings": [], + "r_session_app_settings": [], + "r_studio_server_pro_app_settings": [], + "security_groups": null, + "sharing_settings": [], + "space_storage_settings": [], + "studio_web_portal": "", + "studio_web_portal_settings": [], + "tensor_board_app_settings": [] + } + ] + }, + "untagged": { + "arn": "arn:aws:sagemaker:us-east-1:644160558196:user-profile/d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken", + "domain_id": "d-szjlsjfyqmaq", + "home_efs_file_system_uid": "200010", + "id": "d-szjlsjfyqmaq/c7n-profile-untagged-comic-chicken", + "region": "us-east-1", + "single_sign_on_user_identifier": "", + "single_sign_on_user_value": "", + "tags": null, + "tags_all": {}, + "user_profile_name": "c7n-profile-untagged-comic-chicken", + "user_settings": [ + { + "auto_mount_home_efs": "DefaultAsDomain", + "canvas_app_settings": [], + "code_editor_app_settings": [], + "custom_file_system_config": [], + "custom_posix_user_config": [], + "default_landing_uri": "", + "execution_role": "arn:aws:iam::644160558196:role/c7n-sagemaker-studio-comic-chicken", + "jupyter_lab_app_settings": [], + "jupyter_server_app_settings": [], + "kernel_gateway_app_settings": [], + "r_session_app_settings": [], + "r_studio_server_pro_app_settings": [], + "security_groups": null, + "sharing_settings": [], + "space_storage_settings": [], + "studio_web_portal": "", + "studio_web_portal_settings": [], + "tensor_board_app_settings": [] + } + ] + } + }, + "random_pet": { + "studio": { + "id": "comic-chicken", + "keepers": null, + "length": 2, + "prefix": null, + "separator": "-" + } + } + } +} \ No newline at end of file diff --git a/tests/terraform/vpc_lattice_rule/main.tf b/tests/terraform/vpc_lattice_rule/main.tf new file mode 100644 index 00000000000..0ec8396120b --- /dev/null +++ b/tests/terraform/vpc_lattice_rule/main.tf @@ -0,0 +1,85 @@ +resource "aws_vpclattice_service" "test_service" { + name = "test-service" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener" { + name = "test-listener" + service_identifier = aws_vpclattice_service.test_service.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule" { + name = "test-rule" + service_identifier = aws_vpclattice_service.test_service.id + listener_identifier = aws_vpclattice_listener.test_listener.listener_id + priority = 10 + tags = { + ExistingKey = "ExistingValue" + } + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} + + +resource "aws_vpclattice_service" "test_service2" { + name = "test-service2" + auth_type = "NONE" +} + +resource "aws_vpclattice_listener" "test_listener2" { + name = "test-listener2" + service_identifier = aws_vpclattice_service.test_service2.id + protocol = "HTTP" + port = 80 + + default_action { + fixed_response { + status_code = 404 + } + } +} + +resource "aws_vpclattice_listener_rule" "test_rule2" { + name = "test-rule2" + service_identifier = aws_vpclattice_service.test_service2.id + listener_identifier = aws_vpclattice_listener.test_listener2.listener_id + priority = 10 + + action { + fixed_response { + status_code = 404 + } + } + + match { + http_match { + path_match { + match { + prefix = "/" + } + } + } + } +} diff --git a/tests/terraform/vpc_lattice_rule/tf_resources.json b/tests/terraform/vpc_lattice_rule/tf_resources.json new file mode 100644 index 00000000000..98e5a97f0b8 --- /dev/null +++ b/tests/terraform/vpc_lattice_rule/tf_resources.json @@ -0,0 +1,194 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "aws_vpclattice_listener": { + "test_listener": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-004c557de2baa42d9/listener/listener-0b95f3e74561e16d6", + "created_at": "2026-03-13 15:31:49.501 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-004c557de2baa42d9/listener-0b95f3e74561e16d6", + "last_updated_at": "2026-03-13 15:31:49.501 +0000 UTC", + "listener_id": "listener-0b95f3e74561e16d6", + "name": "test-listener", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-004c557de2baa42d9", + "service_identifier": "svc-004c557de2baa42d9", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_listener2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0adf1a51e62605429/listener/listener-0c41dfe767f89cee5", + "created_at": "2026-03-13 15:31:51.12 +0000 UTC", + "default_action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "id": "svc-0adf1a51e62605429/listener-0c41dfe767f89cee5", + "last_updated_at": "2026-03-13 15:31:51.12 +0000 UTC", + "listener_id": "listener-0c41dfe767f89cee5", + "name": "test-listener2", + "port": 80, + "protocol": "HTTP", + "region": "us-east-1", + "service_arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0adf1a51e62605429", + "service_identifier": "svc-0adf1a51e62605429", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_listener_rule": { + "test_rule": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-004c557de2baa42d9/listener/listener-0b95f3e74561e16d6/rule/rule-0d4ab7be37bf20e5e", + "id": "svc-004c557de2baa42d9/listener-0b95f3e74561e16d6/rule-0d4ab7be37bf20e5e", + "listener_identifier": "listener-0b95f3e74561e16d6", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-0d4ab7be37bf20e5e", + "service_identifier": "svc-004c557de2baa42d9", + "tags": { + "ExistingKey": "ExistingValue" + }, + "tags_all": { + "ExistingKey": "ExistingValue" + }, + "timeouts": null + }, + "test_rule2": { + "action": [ + { + "fixed_response": [ + { + "status_code": 404 + } + ], + "forward": [] + } + ], + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0adf1a51e62605429/listener/listener-0c41dfe767f89cee5/rule/rule-05f926fa961abdc3e", + "id": "svc-0adf1a51e62605429/listener-0c41dfe767f89cee5/rule-05f926fa961abdc3e", + "listener_identifier": "listener-0c41dfe767f89cee5", + "match": [ + { + "http_match": [ + { + "header_matches": [], + "method": "", + "path_match": [ + { + "case_sensitive": false, + "match": [ + { + "exact": "", + "prefix": "/" + } + ] + } + ] + } + ] + } + ], + "name": "test-rule2", + "priority": 10, + "region": "us-east-1", + "rule_id": "rule-05f926fa961abdc3e", + "service_identifier": "svc-0adf1a51e62605429", + "tags": null, + "tags_all": {}, + "timeouts": null + } + }, + "aws_vpclattice_service": { + "test_service": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-004c557de2baa42d9", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service-004c557de2baa42d9.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-004c557de2baa42d9", + "name": "test-service", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + }, + "test_service2": { + "arn": "arn:aws:vpc-lattice:us-east-1:644160558196:service/svc-0adf1a51e62605429", + "auth_type": "NONE", + "certificate_arn": "", + "custom_domain_name": "", + "dns_entry": [ + { + "domain_name": "test-service2-0adf1a51e62605429.7d67968.vpc-lattice-svcs.us-east-1.on.aws", + "hosted_zone_id": "Z0681547Z82L3THDFSCZ" + } + ], + "id": "svc-0adf1a51e62605429", + "name": "test-service2", + "region": "us-east-1", + "status": "ACTIVE", + "tags": null, + "tags_all": {}, + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tests/test_asg.py b/tests/test_asg.py index a03374051a2..76eb35a5e36 100644 --- a/tests/test_asg.py +++ b/tests/test_asg.py @@ -11,9 +11,9 @@ from .common import BaseTest from c7n.exceptions import PolicyValidationError -from c7n.resources.asg import LaunchInfo +from c7n.resources.asg import LaunchInfo, Tag as AsgTag from c7n.resources.aws import shape_validate -from c7n.utils import jmespath_search +from c7n.utils import FormatDate, jmespath_search class LaunchConfigTest(BaseTest): @@ -1178,3 +1178,173 @@ def test_asg_scaling_policy_enabled(self): resources = p.run() self.assertEqual(len(resources), 1) self.assertTrue(resources[0].get('Enabled')) + + +class AsgDynamicTagTest(BaseTest): + """Dynamic tag values on the asg-specific tag action. + + The asg tag action is not a c7n.tags.Tag subclass, so it needs its own + wiring for the resource lookup form of a tag value. + """ + + def _run(self, asgs, action): + mock_factory = mock.MagicMock() + mock_factory.region = 'us-east-1' + create_tags = mock_factory().client('autoscaling').create_or_update_tags + create_tags.return_value = {} + policy = self.load_policy( + {"name": "d", "resource": "asg", "actions": [action]}, + session_factory=mock_factory) + policy.resource_manager.actions[0].process(asgs) + return create_tags + + def test_lookup_key_hit(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1", + "Tags": [{"Key": "Team", "Value": "platform"}]}], + {"type": "tag", "tags": {"Owner": { + "type": "resource", "key": "Tags[?Key=='Team'].Value | [0]"}}}) + create_tags.assert_called_once_with( + Tags=[{"Key": "Owner", "Value": "platform", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) + + def test_lookup_key_miss_uses_default(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1"}], + {"type": "tag", "tags": {"Owner": { + "type": "resource", "key": "Nope", "default-value": "unknown"}}}) + create_tags.assert_called_once_with( + Tags=[{"Key": "Owner", "Value": "unknown", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) + + def test_conditional_default_skips_asg_with_tag_present(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-has", + "Tags": [{"Key": "Owner", "Value": "keep-me"}]}], + {"type": "tag", "tags": {"Owner": { + "type": "resource", "default-value": "unassigned"}}}) + create_tags.assert_not_called() + + def test_conditional_default_writes_per_asg(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-has", + "Tags": [{"Key": "Owner", "Value": "keep-me"}]}, + {"AutoScalingGroupName": "asg-missing"}], + {"type": "tag", "tags": {"Owner": { + "type": "resource", "default-value": "unassigned"}}}) + create_tags.assert_called_once_with( + Tags=[{"Key": "Owner", "Value": "unassigned", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-missing"}]) + + def test_lookup_in_single_value_form(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1", + "Tags": [{"Key": "Team", "Value": "platform"}]}], + {"type": "tag", "key": "Owner", "propagate": True, + "value": {"type": "resource", "key": "Tags[?Key=='Team'].Value | [0]"}}) + create_tags.assert_called_once_with( + Tags=[{"Key": "Owner", "Value": "platform", + "PropagateAtLaunch": True, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) + + def test_placeholder_interpolated_in_lookup_default(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1"}], + {"type": "tag", "tags": {"Stamp": { + "type": "resource", "key": "Nope", + "default-value": "made-in-{region}"}}}) + create_tags.assert_called_once_with( + Tags=[{"Key": "Stamp", "Value": "made-in-us-east-1", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) + + def test_dynamic_values_batch_by_payload(self): + # batch_size is 1 today, so raise it to show the dynamic path batches + # asgs that resolve to the same payload rather than going one at a time + asgs = [{"AutoScalingGroupName": "asg-1", + "Tags": [{"Key": "Env", "Value": "prod"}]}, + {"AutoScalingGroupName": "asg-2", + "Tags": [{"Key": "Env", "Value": "dev"}]}, + {"AutoScalingGroupName": "asg-3", + "Tags": [{"Key": "Env", "Value": "prod"}]}] + with mock.patch.object(AsgTag, "batch_size", 2): + create_tags = self._run( + asgs, + {"type": "tag", "tags": {"Tier": { + "type": "resource", "key": "Tags[?Key=='Env'].Value | [0]"}}}) + self.assertEqual(create_tags.call_count, 2) + by_value = {c.kwargs["Tags"][0]["Value"]: {t["ResourceId"] for t in c.kwargs["Tags"]} + for c in create_tags.call_args_list} + self.assertEqual(by_value["prod"], {"asg-1", "asg-3"}) + self.assertEqual(by_value["dev"], {"asg-2"}) + + def test_now_resolved_once_for_the_whole_run(self): + # a clock that moves on every read - the run should only read it once, + # so both asgs get stamped alike even though batch_size sends them + # in separate calls + ticks = [FormatDate(datetime(2022, 6, 27, 12, 34, 56)), + FormatDate(datetime(2022, 6, 27, 12, 34, 57))] + with mock.patch.object(FormatDate, "utcnow", side_effect=ticks) as utcnow: + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1"}, + {"AutoScalingGroupName": "asg-2"}], + {"type": "tag", "tags": {"Stamp": { + "type": "resource", "key": "Nope", + "default-value": "at-{now}"}}}) + self.assertEqual(utcnow.call_count, 1) + stamped = [c.kwargs["Tags"][0]["Value"] for c in create_tags.call_args_list] + self.assertEqual(stamped, ["at-2022-06-27 12:34:56"] * 2) + + def test_malformed_tag_value_rejected(self): + with self.assertRaises(PolicyValidationError): + self.load_policy( + {"name": "d", "resource": "asg", + "actions": [{"type": "tag", "tags": {"Owner": {"foo": "bar"}}}]}, + validate=True) + + def test_tags_mapping_does_not_add_default_marker(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1"}], + {"type": "tag", "tags": {"Owner": "platform"}}) + create_tags.assert_called_once_with( + Tags=[{"Key": "Owner", "Value": "platform", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) + + def test_bare_mark_still_writes_default_marker(self): + create_tags = self._run( + [{"AutoScalingGroupName": "asg-1"}], {"type": "mark"}) + create_tags.assert_called_once_with( + Tags=[{"Key": "maid_status", + "Value": "AutoScaleGroup does not meet policy guidelines", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) + + def test_auto_tag_user_does_not_add_default_marker(self): + mock_factory = mock.MagicMock() + mock_factory.region = 'us-east-1' + create_tags = mock_factory().client('autoscaling').create_or_update_tags + create_tags.return_value = {} + policy = self.load_policy( + {"name": "d", "resource": "asg", + "mode": {"type": "cloudtrail", "events": ["CreateAutoScalingGroup"]}, + "actions": [{"type": "auto-tag-user", "tag": "CreatorName"}]}, + session_factory=mock_factory) + action = policy.resource_manager.actions[0] + action.set_resource_tags( + {"CreatorName": "alice"}, [{"AutoScalingGroupName": "asg-1"}]) + create_tags.assert_called_once_with( + Tags=[{"Key": "CreatorName", "Value": "alice", + "PropagateAtLaunch": False, + "ResourceType": "auto-scaling-group", + "ResourceId": "asg-1"}]) diff --git a/tests/test_cleanrooms.py b/tests/test_cleanrooms.py index 02faae8c5d9..08fee51f224 100644 --- a/tests/test_cleanrooms.py +++ b/tests/test_cleanrooms.py @@ -80,6 +80,29 @@ def test_collaboration_tag_untag(self): tags = client.list_tags_for_resource(resourceArn=arn)["tags"] self.assertNotIn("Env", tags) + def test_collaboration_members_filter(self): + factory = self.replay_flight_data("test_cleanrooms_collaboration_members") + p = self.load_policy( + { + "name": "cleanrooms-collaboration-members", + "resource": "aws.cleanrooms-collaboration", + "filters": [ + {"type": "members", + "attrs": [ + {"type": "value", "key": "status", + "op": "in", "value": ["ACTIVE", "INVITED"]}, + {"type": "value", "key": "accountId", + "op": "in", "value": [self.account_id]}, + {"type": "value", "key": "abilities", "op": "intersect", + "value": ["CAN_QUERY", "CAN_RECEIVE_RESULTS"]}, + ]}, + ], + }, + session_factory=factory, + ) + resources = p.run() + self.assertEqual(len(resources), 2) + class TestCleanRoomsMembership(BaseTest): diff --git a/tests/test_cloudfront.py b/tests/test_cloudfront.py index 9ab169b3563..c87bc827fc4 100644 --- a/tests/test_cloudfront.py +++ b/tests/test_cloudfront.py @@ -1,7 +1,9 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 from .common import BaseTest, event_data +from c7n.exceptions import PolicyValidationError from c7n.resources.aws import shape_validate +from c7n.resources.waf import WAFV2, DescribeWafV2 from c7n.utils import local_session, jmespath_compile from unittest.mock import MagicMock, patch from botocore.exceptions import ClientError @@ -1157,3 +1159,43 @@ def test_wafv2_cloudfront_scope_uses_us_east_1(self): manager = WAFV2(ctx, {}) manager.get_client() mock_session.client.assert_called_once_with('wafv2', region_name='us-west-2') + + def test_wafv2_filter_uses_cloudfront_scope(self): + """The wafv2-enabled filter must list CLOUDFRONT-scoped web acls. + + A distribution with a CLOUDFRONT WebACL attached must not be reported by + `state: false`. If the filter's requested scope is dropped in favor of the + REGIONAL default, the distribution's CLOUDFRONT WebACL ARN is never found + and the distribution is incorrectly reported as unprotected. + """ + factory = self.replay_flight_data("test_distribution_wafv2_filter_scope") + p = self.load_policy( + { + "name": "wafv2-cloudfront-scope", + "resource": "distribution", + "filters": [{"type": "wafv2-enabled", "state": False}], + }, + session_factory=factory, + ) + + scopes = [] + original = DescribeWafV2.get_query_params + + def record(self, query): + params = original(self, query) + scopes.append(params.get('Scope')) + return params + + with patch.object(DescribeWafV2, 'get_query_params', record): + resources = p.run() + + self.assertEqual(scopes, ['CLOUDFRONT']) + self.assertEqual(len(resources), 0) + + def test_wafv2_filter_scope_conflict_raises(self): + """A Scope passed via resources(query=) that conflicts with the resource + manager's own scope is an error rather than being silently ignored.""" + p = self.load_policy({"name": "wafv2", "resource": "distribution"}) + mgr = WAFV2(p.ctx, {'query': [{'Scope': 'REGIONAL'}]}) + with self.assertRaises(PolicyValidationError): + mgr.source.get_query_params({'Scope': 'CLOUDFRONT'}) diff --git a/tests/test_emr.py b/tests/test_emr.py index cabc4ca7b0c..bf2e348f173 100644 --- a/tests/test_emr.py +++ b/tests/test_emr.py @@ -2,6 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 import unittest +from pytest_terraform import terraform + from c7n.exceptions import PolicyValidationError from c7n.resources import emr from c7n.resources.emr import actions, EMRQueryParser @@ -298,72 +300,99 @@ def test_emr_security_configuration_delete(self): ) -class TestEMRServerless(BaseTest): - def test_emr_serverless_tag(self): - session_factory = self.replay_flight_data("test_emr_serverless_tag") - p = self.load_policy( - { - "name": "emr-serverless-tag", - "resource": "aws.emr-serverless-app", - "filters": [{"tag:foo": "absent"}], - "actions": [{"type": "tag", "tags": {"foo": "bar"}}] - }, - session_factory=session_factory, - ) - resources = p.run() - self.assertEqual(len(resources), 1) - client = session_factory().client("emr-serverless") - tags = client.list_tags_for_resource(resourceArn=resources[0]["arn"])["tags"] - self.assertEqual(len(tags), 1) - self.assertEqual(tags, {"foo": "bar"}) - - def test_emr_serverless_remove_tag(self): - session_factory = self.replay_flight_data("test_emr_serverless_remove_tag") - p = self.load_policy( - { - 'name': "test-emr-serverless-tag", - 'resource': "aws.emr-serverless-app", - 'filters': [{'tag:foo': 'present'}], - 'actions': [{'type': 'remove-tag', 'tags': ['foo']}] - }, - session_factory=session_factory - ) - resources = p.run() - self.assertEqual(len(resources), 1) - client = session_factory().client("emr-serverless") - tags = client.list_tags_for_resource(resourceArn=resources[0]["arn"])["tags"] - self.assertEqual(len(tags), 0) - - def test_emr_serverless_delete(self): - session_factory = self.replay_flight_data('test_emr_serverless_delete') - p = self.load_policy( - { - 'name': 'test-emr-serverless-delete', - 'resource': 'aws.emr-serverless-app', - 'actions': [{'type': 'delete'}] - }, - session_factory=session_factory - ) - resources = p.run() - self.assertEqual(len(resources), 1) - client = session_factory().client('emr-serverless') - applications = client.list_applications()['applications'] - self.assertEqual(len(applications), 0) - - def test_emr_serverless_markop(self): - session_factory = self.replay_flight_data("test_emr_serverless_markop") - p = self.load_policy( - { - "name": "emr-serverless-markop", - "resource": "aws.emr-serverless-app", - "filters": [{"tag:foo": "absent"}], - "actions": [{"type": "mark-for-op", "op": "notify", "tag": "foo", "days": 2}], - }, - session_factory=session_factory, - ) - resources = p.run() - self.assertEqual(len(resources), 1) - client = session_factory().client('emr-serverless') - tags = client.list_tags_for_resource(resourceArn=resources[0]["arn"])['tags'] - self.assertEqual(len(tags), 1) - self.assertEqual(tags, {'foo': 'Resource does not meet policy: notify@2023/01/26'}) +@terraform('emr_serverless_app_tag') +def test_emr_serverless_tag(test, emr_serverless_app_tag): + session_factory = test.replay_flight_data("test_emr_serverless_tag") + p = test.load_policy( + { + "name": "emr-serverless-tag", + "resource": "aws.emr-serverless-app", + "filters": [{"tag:foo": "absent"}], + "actions": [{"type": "tag", "tags": {"foo": "bar"}}], + }, + session_factory=session_factory, + ) + resources = p.run() + assert len(resources) == 1 + client = session_factory().client("emr-serverless") + tags = client.list_tags_for_resource(resourceArn=resources[0]["arn"])["tags"] + assert tags == {"foo": "bar"} + + +@terraform('emr_serverless_app_remove_tag') +def test_emr_serverless_remove_tag(test, emr_serverless_app_remove_tag): + session_factory = test.replay_flight_data("test_emr_serverless_remove_tag") + p = test.load_policy( + { + 'name': "test-emr-serverless-tag", + 'resource': "aws.emr-serverless-app", + 'filters': [{'tag:foo': 'present'}], + 'actions': [{'type': 'remove-tag', 'tags': ['foo']}], + }, + session_factory=session_factory, + ) + resources = p.run() + assert len(resources) == 1 + client = session_factory().client("emr-serverless") + tags = client.list_tags_for_resource(resourceArn=resources[0]["arn"])["tags"] + assert tags == {} + + +@terraform('emr_serverless_app_markop') +def test_emr_serverless_markop(test, emr_serverless_app_markop): + session_factory = test.replay_flight_data("test_emr_serverless_markop") + p = test.load_policy( + { + "name": "emr-serverless-markop", + "resource": "aws.emr-serverless-app", + "filters": [{"tag:foo": "absent"}], + "actions": [{"type": "mark-for-op", "op": "notify", "tag": "foo", "days": 2}], + }, + session_factory=session_factory, + ) + resources = p.run() + assert len(resources) == 1 + client = session_factory().client('emr-serverless') + tags = client.list_tags_for_resource(resourceArn=resources[0]["arn"])['tags'] + assert len(tags) == 1 + assert tags['foo'].startswith('Resource does not meet policy: notify@') + + +@terraform('emr_serverless_app_delete', + teardown=terraform.TEARDOWN_IGNORE) +def test_emr_serverless_delete(test, emr_serverless_app_delete): + session_factory = test.replay_flight_data('test_emr_serverless_delete') + p = test.load_policy( + { + 'name': 'test-emr-serverless-delete', + 'resource': 'aws.emr-serverless-app', + 'actions': [{'type': 'delete'}], + }, + session_factory=session_factory, + ) + resources = p.run() + assert len(resources) == 1 + client = session_factory().client('emr-serverless') + applications = client.list_applications()['applications'] + assert len(applications) == 0 + + +@terraform('emr_serverless_app_autostop') +def test_emr_serverless_autostop_filter(test, emr_serverless_app_autostop): + session_factory = test.replay_flight_data('test_emr_serverless_autostop_filter') + p = test.load_policy( + { + 'name': 'emr-serverless-autostop-disabled', + 'resource': 'aws.emr-serverless-app', + 'filters': [ + {'type': 'value', + 'key': 'autoStopConfiguration.enabled', + 'value': False}, + ], + }, + session_factory=session_factory, + ) + resources = p.run() + assert len(resources) == 1 + assert resources[0]['name'] == emr_serverless_app_autostop[ + 'aws_emrserverless_application.autostop_disabled.name'] diff --git a/tests/test_iam.py b/tests/test_iam.py index 30c106e226b..bc4074c50b1 100644 --- a/tests/test_iam.py +++ b/tests/test_iam.py @@ -14,6 +14,8 @@ from pytest_terraform import terraform from dateutil import parser +import botocore.session +from botocore.stub import Stubber from c7n.exceptions import PolicyValidationError from c7n.executor import MainThreadExecutor from c7n.filters.iamaccess import CrossAccountAccessFilter, PolicyChecker @@ -38,9 +40,13 @@ IamUserInlinePolicy, IamRoleInlinePolicy, IamGroupInlinePolicy, + RoleRemoveTag, + RoleTag, SpecificIamRoleManagedPolicy, NoSpecificIamRoleManagedPolicy, PolicyQueryParser, + UserRemoveTag, + UserTag, UserServiceSpecificCredentials, ) @@ -369,6 +375,105 @@ def test_record_transform_with_keys(self): ) +class IamTagRetry(BaseTest): + + def test_iam_tag_actions_retry_concurrent_modification(self): + self.patch(time, "sleep", lambda _: None) + cases = ( + (RoleTag, "tag_role", "RoleName"), + (RoleRemoveTag, "untag_role", "RoleName"), + (UserTag, "tag_user", "UserName"), + (UserRemoveTag, "untag_user", "UserName"), + ) + + for action_class, operation_name, id_key in cases: + with self.subTest(operation=operation_name): + resource = {id_key: "resource-one"} + missing = {id_key: "resource-missing"} + if operation_name.startswith("untag_"): + tag_key, tags = "TagKeys", ["Env"] + else: + tag_key, tags = "Tags", [{"Key": "Env", "Value": "Dev"}] + client = botocore.session.get_session().create_client( + "iam", + region_name="us-east-1", + aws_access_key_id="access-key", + aws_secret_access_key="secret-key", + ) + expected = {**resource, tag_key: tags} + missing_expected = {**missing, tag_key: tags} + stubber = Stubber(client) + stubber.add_client_error( + operation_name, + service_error_code="ConcurrentModification", + service_message="simultaneous change", + http_status_code=409, + expected_params=expected, + ) + stubber.add_response(operation_name, {}, expected) + stubber.add_client_error( + operation_name, + service_error_code="NoSuchEntity", + service_message="missing", + http_status_code=404, + expected_params=missing_expected, + ) + + action = action_class({}, mock.Mock()) + with stubber, mock.patch.object( + client, operation_name, wraps=getattr(client, operation_name) + ) as operation: + action.process_resource_set(client, [resource, missing], tags) + + self.assertEqual(operation.call_count, 3) + self.assertEqual( + operation.call_args_list, + [ + mock.call(**expected), + mock.call(**expected), + mock.call(**missing_expected), + ], + ) + + def test_iam_tag_retry_uses_single_attempt_budget(self): + sleep = mock.Mock() + self.patch(time, "sleep", sleep) + client = botocore.session.get_session().create_client( + "iam", + region_name="us-east-1", + aws_access_key_id="access-key", + aws_secret_access_key="secret-key", + ) + expected = { + "RoleName": "resource-one", + "Tags": [{"Key": "Env", "Value": "Dev"}], + } + stubber = Stubber(client) + for attempt in range(8): + throttled = attempt % 2 == 0 + stubber.add_client_error( + "tag_role", + service_error_code="Throttling" if throttled else "ConcurrentModification", + service_message="retry", + http_status_code=429 if throttled else 409, + expected_params=expected, + ) + + action = RoleTag({}, mock.Mock()) + with stubber, mock.patch.object( + client, "tag_role", wraps=client.tag_role + ) as operation: + with self.assertRaises(ClientError): + action.process_resource_set( + client, + [{"RoleName": "resource-one"}], + [{"Key": "Env", "Value": "Dev"}], + ) + + self.assertEqual(operation.call_count, 8) + self.assertEqual(sleep.call_count, 7) + + class IamUserTag(BaseTest): def test_iam_user_actions(self): @@ -2860,7 +2965,7 @@ def test_principal_org_paths_allowed(self): "Action": "s3:GetObject", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [ "o-allowed/r-ab12/ou-ab12-aaaabbbb/*" ] @@ -2901,7 +3006,7 @@ def policy_for(path): "Action": "s3:GetObject", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [path] } } @@ -2936,7 +3041,7 @@ def test_principal_org_paths_org_unit_does_not_match_whole_org(self): "Action": "s3:GetObject", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": ["o-allowed/*"] } } @@ -2955,7 +3060,7 @@ def test_principal_org_paths_wildcard_pinned_by_literal_anchors(self): "Action": "s3:GetObject", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [ "o-allowed/*/ou-ab12-prod/*" ] @@ -2968,7 +3073,7 @@ def test_principal_org_paths_wildcard_pinned_by_literal_anchors(self): self.assertEqual(len(checker.check(policy)), 0) # Same shape but org segment wildcarded — must be denied - policy["Statement"][0]["Condition"]["ForAnyValuesStringLike"][ + policy["Statement"][0]["Condition"]["ForAnyValue:StringLike"][ "aws:PrincipalOrgPaths"] = ["*/r-ab12/ou-ab12-prod/*"] self.assertEqual(len(checker.check(policy)), 1) @@ -2981,7 +3086,7 @@ def test_principal_org_paths_combines_orgid_and_org_unit(self): "Action": "s3:GetObject", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [ "o-trusted/r-aa11/ou-aa11-anything/*", "o-other/r-bb22/ou-bb22-prod/*", @@ -3000,6 +3105,37 @@ def test_principal_org_paths_combines_orgid_and_org_unit(self): checker = PolicyChecker({"allowed_orgid": {"o-trusted"}}) self.assertEqual(len(checker.check(policy)), 1) + def test_principal_org_paths_uses_real_aws_set_operator(self): + """Regression: real AWS operator is ``ForAnyValue:StringLike``, not + ``ForAnyValues...``. The plural form was never matched, so the + condition was dropped and the wildcard principal looked public.""" + policy = { + "Version": "2012-10-17", + "Statement": [{ + "Effect": "Allow", + "Principal": "*", + "Action": "s3:GetObject", + "Resource": "*", + "Condition": { + "ForAnyValue:StringLike": { + "aws:PrincipalOrgPaths": [ + "o-allowed/r-ab12/ou-ab12-aaaabbbb/*" + ] + } + } + }] + } + + checker = PolicyChecker({"allowed_orgid": {"o-allowed"}}) + # operator must be normalized, not silently dropped + conditions = checker.normalize_conditions(policy["Statement"][0]) + self.assertEqual( + [c["key"] for c in conditions], ["aws:principalorgpaths"]) + self.assertEqual(len(checker.check(policy)), 0) + + checker = PolicyChecker({"allowed_orgid": {"o-other"}}) + self.assertEqual(len(checker.check(policy)), 1) + def test_org_id_with_specific_non_whitelisted_account(self): """Test that org ID doesn't save specific non-whitelisted account.""" policy = { @@ -3619,7 +3755,7 @@ def test_cross_account_filter_whitelist_org_units(self): "Action": "*", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [ "o-example/r-ab12/ou-ab12-prod/*" ] @@ -3642,7 +3778,7 @@ def test_cross_account_filter_whitelist_org_units_from(self): "Action": "*", "Resource": "*", "Condition": { - "ForAnyValuesStringLike": { + "ForAnyValue:StringLike": { "aws:PrincipalOrgPaths": [ "o-example/r-ab12/ou-ab12-prod/*" ] diff --git a/tests/test_lattice.py b/tests/test_lattice.py index 11233309fcc..2dbfbe4fe28 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -1,5 +1,6 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import pytest from pytest_terraform import terraform from .common import BaseTest @@ -247,6 +248,132 @@ def test_lattice_service_network_detailspec(test, lattice_service_network_detail assert resources[0]['Tags'][0]['Value'] == 'TestServiceNetworkValue' +@terraform('lattice_rule_query_service') +def test_lattice_rule_query_service(test, lattice_rule_query_service): + session_factory = test.replay_flight_data("test_lattice_rule_query_service") + rule_arn = lattice_rule_query_service["aws_vpclattice_listener_rule.test_rule.arn"] + service_id = lattice_rule_query_service["aws_vpclattice_service.test_service.id"] + listener_id = lattice_rule_query_service["aws_vpclattice_listener.test_listener.listener_id"] + + p = test.load_policy( + { + "name": "lattice-rule-query", + "resource": "aws.vpc-lattice-rule", + "query": [{"serviceIdentifier": service_id}], + "filters": [{"isDefault": False}], + }, + session_factory=session_factory, + ) + + resources = p.run() + assert len(resources) == 1 + assert resources[0]["arn"] == rule_arn + assert resources[0]["serviceIdentifier"] == service_id + assert resources[0]["listenerIdentifier"] == listener_id + + +@terraform('lattice_rule_filter_listener') +def test_lattice_rule_filter_listener(test, lattice_rule_filter_listener): + session_factory = test.replay_flight_data("test_lattice_rule_filter_listener") + rule_arn = lattice_rule_filter_listener["aws_vpclattice_listener_rule.test_rule.arn"] + service_id = lattice_rule_filter_listener["aws_vpclattice_service.test_service.id"] + listener_id = lattice_rule_filter_listener["aws_vpclattice_listener.test_listener.listener_id"] + + p = test.load_policy( + { + "name": "lattice-rule-query", + "resource": "aws.vpc-lattice-rule", + "filters": [{"listenerIdentifier": listener_id}, {"isDefault": False}], + }, + session_factory=session_factory, + ) + + resources = p.run() + assert len(resources) == 1 + assert resources[0]["arn"] == rule_arn + assert resources[0]["serviceIdentifier"] == service_id + assert resources[0]["listenerIdentifier"] == listener_id + + +@terraform('lattice_rule_query_listener') +def test_lattice_rule_query_listener(test, lattice_rule_query_listener): + listener_id = lattice_rule_query_listener["aws_vpclattice_listener.test_listener.listener_id"] + + p = test.load_policy( + { + "name": "lattice-rule-query", + "resource": "aws.vpc-lattice-rule", + "query": [{"listenerIdentifier": listener_id}], + "filters": [{"isDefault": False}], + }, + ) + + with pytest.raises( + ValueError, match='Do not pass listenerIdentifier without serviceIdentifier in the query' + ): + p.run() + + +@terraform('lattice_rule_query_service_listener') +def test_lattice_rule_query_service_listener(test, lattice_rule_query_service_listener): + session_factory = test.replay_flight_data("test_lattice_rule_query_service_listener") + rule_arn = lattice_rule_query_service_listener["aws_vpclattice_listener_rule.test_rule.arn"] + service_id = lattice_rule_query_service_listener["aws_vpclattice_service.test_service.id"] + listener_id = lattice_rule_query_service_listener[ + "aws_vpclattice_listener.test_listener.listener_id"] + + p = test.load_policy( + { + "name": "lattice-rule-query", + "resource": "aws.vpc-lattice-rule", + "query": [ + {"serviceIdentifier": service_id}, + {"listenerIdentifier": listener_id}, + {"foo": "bar"}, # Test warning for ignored query parameter + ], + "filters": [{"isDefault": False}], + }, + session_factory=session_factory, + ) + + log_output = test.capture_logging('custodian.lattice') + resources = p.run() + assert len(resources) == 1 + assert resources[0]["arn"] == rule_arn + assert resources[0]["serviceIdentifier"] == service_id + assert resources[0]["listenerIdentifier"] == listener_id + assert log_output.getvalue().strip() == \ + '"foo" is not a supported query parameter for this resource.' + + +@terraform('lattice_rule_tagging') +def test_lattice_rule_tagging(test, lattice_rule_tagging): + session_factory = test.replay_flight_data("test_lattice_rule_tagging") + rule_arn = lattice_rule_tagging["aws_vpclattice_listener_rule.test_rule.arn"] + service_id = lattice_rule_tagging["aws_vpclattice_service.test_service.id"] + listener_id = lattice_rule_tagging["aws_vpclattice_listener.test_listener.listener_id"] + + p = test.load_policy( + { + "name": "lattice-rule-query", + "resource": "aws.vpc-lattice-rule", + "query": [{"serviceIdentifier": service_id}, {"listenerIdentifier": listener_id}], + "filters": [{"isDefault": False}], + "actions": [{"type": "tag", "key": "NewKey", "value": "NewValue"}] + }, + session_factory=session_factory, + ) + + resources = p.run() + assert len(resources) == 1 + assert resources[0]["arn"] == rule_arn + assert resources[0]['Tags'] == [{'Key': 'ExistingKey', 'Value': 'ExistingValue'}] + + client = session_factory().client("vpc-lattice") + tags = client.list_tags_for_resource(resourceArn=rule_arn)["tags"] + assert tags == {'ExistingKey': 'ExistingValue', 'NewKey': 'NewValue'} + + @terraform('lattice_service_network_association') def test_lattice_service_network_association_list(test, lattice_service_network_association): factory = test.replay_flight_data("test_lattice_service_network_association_list") diff --git a/tests/test_lookup.py b/tests/test_lookup.py index 6033633b989..c5649d09d15 100644 --- a/tests/test_lookup.py +++ b/tests/test_lookup.py @@ -2,6 +2,8 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import jsonschema + from .common import BaseTest from c7n.lookup import Lookup @@ -18,12 +20,12 @@ def test_lookup_type(self): self.assertEqual(number_schema, lookup_default_number['oneOf'][1]) self.assertEqual(number_schema, - lookup_default_number['oneOf'][0]['oneOf'][0] + lookup_default_number['oneOf'][0] ['properties']['default-value']) self.assertEqual(string_schema, lookup_default_string['oneOf'][1]) self.assertEqual(string_schema, - lookup_default_string['oneOf'][0]['oneOf'][0] + lookup_default_string['oneOf'][0] ['properties']['default-value']) def test_extract_no_lookup(self): @@ -76,6 +78,15 @@ def test_get_value_from_resource_value_not_exists(self): value = Lookup.get_value_from_resource(source, resource) self.assertEqual(value, 'value_2') + def test_extract_lookup_without_key_returns_default(self): + source = {'type': Lookup.RESOURCE_SOURCE, 'default-value': 'value_2'} + self.assertEqual(Lookup.extract(source, {'name': 'x'}), 'value_2') + + def test_get_value_from_resource_without_key_returns_default(self): + source = {'type': Lookup.RESOURCE_SOURCE, 'default-value': 'value_2'} + self.assertEqual( + Lookup.get_value_from_resource(source, {'name': 'x'}), 'value_2') + def test_get_value_from_resource_value_not_exists_exception(self): resource = { 'field_level_1': { @@ -89,3 +100,114 @@ def test_get_value_from_resource_value_not_exists_exception(self): with self.assertRaises(Exception): Lookup.get_value_from_resource(source, resource) + + +class LookupSchemaTest(BaseTest): + """A lookup needs a key, a fallback, or both.""" + + string_schema = {'type': 'string'} + + def validates(self, doc, schema=None): + try: + jsonschema.validate(doc, schema or Lookup.lookup_type(self.string_schema)) + return True + except jsonschema.ValidationError: + return False + + def test_key_only_accepted(self): + self.assertTrue(self.validates({'type': 'resource', 'key': 'name'})) + + def test_key_with_default_accepted(self): + self.assertTrue( + self.validates( + {'type': 'resource', 'key': 'name', 'default-value': 'x'})) + + def test_default_only_accepted(self): + self.assertTrue(self.validates({'type': 'resource', 'default-value': 'x'})) + + def test_scalar_accepted(self): + self.assertTrue(self.validates('plain')) + + def test_neither_key_nor_default_rejected(self): + self.assertFalse(self.validates({'type': 'resource'})) + + def test_unknown_property_rejected(self): + self.assertFalse(self.validates({'type': 'resource', 'ky': 'name'})) + + def test_non_lookup_dict_rejected(self): + self.assertFalse(self.validates({'foo': 'bar'})) + + def test_default_value_is_typed_by_caller(self): + self.assertFalse( + self.validates({'type': 'resource', 'default-value': 5})) + self.assertTrue( + self.validates({'type': 'resource', 'default-value': 5}, + Lookup.lookup_type({'type': 'number'}))) + + def test_default_value_may_be_typed_separately_from_the_value(self): + schema = Lookup.lookup_type( + {'type': ['string', 'number']}, default_schema={'type': 'string'}) + # the bare scalar keeps the wider type + self.assertTrue(self.validates(5, schema)) + self.assertTrue(self.validates('plain', schema)) + # the fallback is narrowed + self.assertTrue( + self.validates( + {'type': 'resource', 'key': 'k', 'default-value': 'd'}, schema)) + self.assertFalse( + self.validates( + {'type': 'resource', 'key': 'k', 'default-value': 5}, schema)) + + def test_default_schema_defaults_to_the_value_schema(self): + one_arg = Lookup.lookup_type({'type': 'number'}) + explicit = Lookup.lookup_type( + {'type': 'number'}, default_schema={'type': 'number'}) + self.assertEqual(one_arg, explicit) + + +class LookupResolveValueTest(BaseTest): + + def test_static_value_passthrough(self): + self.assertEqual(Lookup.resolve_value('plain', {}), 'plain') + + def test_key_hit(self): + resource = {'State': {'Name': 'running'}} + spec = {'type': 'resource', 'key': 'State.Name'} + self.assertEqual(Lookup.resolve_value(spec, resource), 'running') + + def test_key_miss_uses_default(self): + spec = {'type': 'resource', 'key': 'nope', 'default-value': 'dv'} + self.assertEqual(Lookup.resolve_value(spec, {}), 'dv') + + def test_key_miss_without_default_raises(self): + spec = {'type': 'resource', 'key': 'nope'} + with self.assertRaises(Exception) as cm: + Lookup.resolve_value(spec, {}) + self.assertIn('nope', str(cm.exception)) + + def test_conditional_default_writes_when_name_absent(self): + spec = {'type': 'resource', 'default-value': 'dv'} + self.assertEqual( + Lookup.resolve_value(spec, {}, 'Owner', set()), 'dv') + + def test_conditional_default_skips_when_name_present(self): + spec = {'type': 'resource', 'default-value': 'dv'} + self.assertIs( + Lookup.resolve_value(spec, {}, 'Owner', {'Owner'}), Lookup.SKIP) + + def test_skip_sentinel_is_distinct_from_none_and_empty_string(self): + self.assertIsNot(Lookup.SKIP, None) + self.assertNotEqual(Lookup.SKIP, '') + + +class LookupHasLookupsTest(BaseTest): + + def test_all_static(self): + self.assertFalse(Lookup.has_lookups({'A': 'x', 'B': 'y'})) + + def test_empty(self): + self.assertFalse(Lookup.has_lookups({})) + + def test_one_dynamic(self): + self.assertTrue( + Lookup.has_lookups({'A': 'x', 'B': {'type': 'resource', 'key': 'k'}})) diff --git a/tests/test_output.py b/tests/test_output.py index 05e5aeaf70b..1d2a547cb04 100644 --- a/tests/test_output.py +++ b/tests/test_output.py @@ -197,6 +197,50 @@ def test_sans_prefix(self): extra_args={"ACL": "bucket-owner-full-control", "ServerSideEncryption": "AES256"}, ) + def test_sse_args_default_aes256(self): + output = self.get_s3_output() + self.assertEqual( + output.get_sse_args(), + {"ServerSideEncryption": "AES256"}) + + def test_sse_args_kms_managed_key(self): + output = self.get_s3_output( + output_url="s3://cloud-custodian/policies?sse=aws:kms") + self.assertEqual( + output.get_sse_args(), + {"ServerSideEncryption": "aws:kms"}) + + def test_sse_args_kms_customer_key(self): + output = self.get_s3_output( + output_url="s3://cloud-custodian/policies?kms-key=alias/custodian-logs") + self.assertEqual( + output.get_sse_args(), + {"ServerSideEncryption": "aws:kms", + "SSEKMSKeyId": "alias/custodian-logs"}) + + def test_upload_sse_kms(self): + with mock_datetime_now(date_parse('2018/09/01 13:00'), datetime): + output = self.get_s3_output( + output_url="s3://cloud-custodian/policies?kms-key=alias/custodian-logs") + + with open(os.path.join(output.root_dir, "foo.txt"), "w") as fh: + fh.write("abc") + + output._transfer = mock.MagicMock() + output._transfer.upload_file = m = mock.MagicMock() + + output.upload() + + m.assert_called_with( + fh.name, + "cloud-custodian", + "%s/foo.txt" % output.key_prefix.lstrip('/'), + extra_args={ + "ACL": "bucket-owner-full-control", + "ServerSideEncryption": "aws:kms", + "SSEKMSKeyId": "alias/custodian-logs"}, + ) + @pytest.mark.parametrize( 'bucket, endpoint, expected_region', diff --git a/tests/test_policy.py b/tests/test_policy.py index 916d736a5b6..fda75b3ed21 100644 --- a/tests/test_policy.py +++ b/tests/test_policy.py @@ -270,6 +270,8 @@ def test_securityhub_resource_support(self): whitelist = set(('AwsS3Object', 'Container')) todo = set(( + # q2 2026 + 'AzureResource', # q2 2025 'CodeRepository', # q4 2023, diff --git a/tests/test_sagemaker.py b/tests/test_sagemaker.py index fe45ea0457b..f8191fd19a4 100644 --- a/tests/test_sagemaker.py +++ b/tests/test_sagemaker.py @@ -1,5 +1,8 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import pytest +from pytest_terraform import terraform + from .common import BaseTest from c7n.resources.sagemaker import SagemakerJobQueryParser, CompilationJobQueryParser @@ -1535,3 +1538,70 @@ def test_invalid_query(self): self.assertRaises( PolicyValidationError, SagemakerJobQueryParser.parse, [ {'StatusEquals': ['INPROGRESS', 'COMPLETED']}]) + + +@pytest.mark.audited +@terraform('sagemaker_studio', scope='module') +def test_sagemaker_user_profile(test, sagemaker_studio): + # tests the sagemaker-user-profile-untagged example policy: verify the + # tagged profile is excluded and the untagged profile is included. + factory = test.replay_flight_data('test_sagemaker_user_profile') + p = test.load_policy( + { + 'name': 'sagemaker-user-profile-untagged', + 'resource': 'sagemaker-user-profile', + 'filters': [{'tag:favorite-color': 'absent'}], + }, + session_factory=factory, + ) + [resource] = p.run() + assert resource['UserProfileName'] == sagemaker_studio[ + 'aws_sagemaker_user_profile.untagged.user_profile_name'] + + +@pytest.mark.audited +@terraform('sagemaker_studio', scope='module') +def test_sagemaker_space(test, sagemaker_studio): + # tests the sagemaker-space-untagged example policy: verify the tagged + # space is excluded and the untagged space is included. + factory = test.replay_flight_data('test_sagemaker_space') + p = test.load_policy( + { + 'name': 'sagemaker-space-untagged', + 'resource': 'sagemaker-space', + 'filters': [{'tag:favorite-color': 'absent'}], + }, + session_factory=factory, + ) + [resource] = p.run() + assert resource['SpaceName'] == sagemaker_studio[ + 'aws_sagemaker_space.untagged.space_name'] + + +@pytest.mark.audited +@terraform('sagemaker_studio', scope='module') +def test_sagemaker_app(test, sagemaker_studio): + # tests the sagemaker-app-untagged example policy: verify the tagged app + # is excluded and the untagged app is included. + # + # SageMaker retains app metadata (and keeps returning it from ListApps + # with Status Deleted/Deleting) for up to 24 hours after an app is shut + # down, so apps from earlier test recordings against now-destroyed + # domains can otherwise still show up here too. See the CreationTime + # note on: + # https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DescribeApp.html + factory = test.replay_flight_data('test_sagemaker_app') + p = test.load_policy( + { + 'name': 'sagemaker-app-untagged', + 'resource': 'sagemaker-app', + 'filters': [ + {'type': 'value', 'key': 'Status', 'op': 'not-in', + 'value': ['Deleted', 'Deleting']}, + {'tag:favorite-color': 'absent'}, + ], + }, + session_factory=factory, + ) + [resource] = p.run() + assert resource['AppName'] == sagemaker_studio['aws_sagemaker_app.untagged.app_name'] diff --git a/tests/test_sns.py b/tests/test_sns.py index 40c6e88f9b1..4ac08e5e848 100644 --- a/tests/test_sns.py +++ b/tests/test_sns.py @@ -975,6 +975,27 @@ def test_sns_metrics(self): resources = p.run() self.assertEqual(len(resources), 1) + def test_sns_cross_account_for_any_value(self): + session_factory = self.replay_flight_data("test_sns_cross_account_for_any_value") + + p = self.load_policy( + { + "name": "sns-for-any-value-matched", + "resource": "sns", + "filters": [ + { + "type": "cross-account", + "whitelist_org_units": [ + "o-abcd123456/r-xyz789/ou-xyz789-qrstuvwx" + ] + }, + ], + }, + session_factory=session_factory, + ) + resources = p.run() + self.assertEqual(len(resources), 0) + def test_sns_cross_account_return_allowed(self): session_factory = self.replay_flight_data("test_sns_cross_account_return_allowed") diff --git a/tests/test_tags.py b/tests/test_tags.py index 5aa746c3b28..d303838f880 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -4,13 +4,15 @@ module to test some universal tagging infrastructure not directly exposed. """ import time +import jsonschema +from datetime import datetime from freezegun import freeze_time -from unittest.mock import MagicMock, call +from unittest.mock import MagicMock, call, patch from c7n import tags as tagmod from c7n.tags import universal_retry, coalesce_copy_user_tags from c7n.exceptions import PolicyExecutionError, PolicyValidationError -from c7n.utils import yaml_load +from c7n.utils import FormatDate, yaml_load from .common import BaseTest @@ -606,6 +608,40 @@ def test_copy_related_tag_validate_aws_prefix_fake_resource(self): self.assertRaises(PolicyValidationError, self.load_policy, policy) +class TagValueSchemaTest(BaseTest): + """Tag values are strings, but unquoted YAML scalars have always been + accepted and coerced. The fallback is a newer field and stays strict. + """ + + def validates(self, value): + try: + jsonschema.validate( + {'X': value}, + {'type': 'object', + 'additionalProperties': tagmod.tag_value_schema()}) + return True + except jsonschema.ValidationError: + return False + + def test_scalar_accepts_number_and_boolean(self): + self.assertTrue(self.validates('plain')) + self.assertTrue(self.validates(12345)) + self.assertTrue(self.validates(True)) + + def test_default_value_must_be_a_string(self): + self.assertTrue( + self.validates({'type': 'resource', 'key': 'K', 'default-value': 'd'})) + self.assertFalse( + self.validates({'type': 'resource', 'key': 'K', 'default-value': 5})) + self.assertFalse( + self.validates({'type': 'resource', 'default-value': True})) + + def test_non_scalar_values_rejected(self): + self.assertFalse(self.validates(['a'])) + self.assertFalse(self.validates(None)) + self.assertFalse(self.validates({'foo': 'bar'})) + + class ResolveTagValueTest(BaseTest): def test_static_passthrough(self): self.assertEqual( @@ -715,6 +751,22 @@ def test_placeholder_interpolated_in_default_value(self): Tags=[{"Key": "Stamp", "Value": "created-2022-06-27 12:34:56-in-us-east-1"}], DryRun=False) + def test_now_resolved_once_for_the_whole_run(self): + # a clock that moves on every read - the run should only read it once, + # so every resource lands in one group with one timestamp + ticks = [FormatDate(datetime(2022, 6, 27, 12, 34, 56)), + FormatDate(datetime(2022, 6, 27, 12, 34, 57))] + with patch.object(FormatDate, "utcnow", side_effect=ticks) as utcnow: + create_tags = self._run( + [{"InstanceId": "i-1"}, {"InstanceId": "i-2"}], + {"Stamp": {"type": "resource", "key": "Nope", + "default-value": "at-{now}"}}) + self.assertEqual(utcnow.call_count, 1) + create_tags.assert_called_once_with( + Resources=["i-1", "i-2"], + Tags=[{"Key": "Stamp", "Value": "at-2022-06-27 12:34:56"}], + DryRun=False) + class DynamicUniversalTagTest(BaseTest): def _run(self, resources, tags, resource='rds'): diff --git a/tools/c7n_awscc/pyproject.toml b/tools/c7n_awscc/pyproject.toml index 66d0a7008e5..17410b47693 100644 --- a/tools/c7n_awscc/pyproject.toml +++ b/tools/c7n_awscc/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "jsonpatch<2.0,>=1.32", ] name = "c7n_awscc" -version = "0.1.37a5+a83dda5c9" +version = "0.1.38a1+e4c099e03" readme = "readme.md" description = "Cloud Custodian - AWS Cloud Control Provider" classifiers = [ diff --git a/tools/c7n_azure/c7n_azure/actions/tagging.py b/tools/c7n_azure/c7n_azure/actions/tagging.py index 05370fde165..32397896760 100644 --- a/tools/c7n_azure/c7n_azure/actions/tagging.py +++ b/tools/c7n_azure/c7n_azure/actions/tagging.py @@ -40,18 +40,33 @@ class Tag(AzureBaseAction): tag: Environment value: Test - - name: azure-tag-from-resource-attr + :example: + + Tag values may also be resolved per resource. A value of the form + ``{type: resource, key: }`` is looked up against the resource, + falling back to ``default-value`` when the path yields nothing. Omitting + ``key`` gives a conditional default: the tag is written only when it is + not already present, leaving existing values untouched. + + .. code-block:: yaml + + policies: + - name: azure-vm-set-default-tags resource: azure.vm - description: | - Tag all existing virtual machines with values taken from the resource + filters: + - or: + - "tag:Env": empty + - "tag:Owner": empty actions: - type: tag tags: - Environment: Test - ResourceName: - type: resource - key: name - default-value: name_not_found + Env: + type: resource + key: tags.Environment # seed from an existing tag if present + default-value: unknown # otherwise fall back + Owner: + type: resource + default-value: platform@example.com # only set if Owner absent """ schema = utils.type_schema( @@ -61,7 +76,9 @@ class Tag(AzureBaseAction): 'tag': Lookup.lookup_type({'type': 'string'}), 'tags': { 'type': 'object', - 'additionalProperties': Lookup.lookup_type({'type': 'string'}) + 'additionalProperties': Lookup.lookup_type( + {'type': ['string', 'number', 'boolean']}, + default_schema={'type': 'string'}), } } ) @@ -88,10 +105,18 @@ def _process_resource(self, resource): def _get_tags(self, resource): tags = self.data.get('tags') - if tags: - return {k: Lookup.extract(v, resource) for k, v in tags.items()} - return {Lookup.extract( - self.data.get('tag'), resource): Lookup.extract(self.data.get('value'), resource)} + if not tags: + return {Lookup.extract(self.data.get('tag'), resource): + Lookup.extract(self.data.get('value'), resource)} + + current = set(resource.get('tags') or ()) + resolved = {} + for name, spec in tags.items(): + value = Lookup.resolve_value(spec, resource, name, current) + if value is Lookup.SKIP: + continue + resolved[name] = value + return resolved class RemoveTag(AzureBaseAction): diff --git a/tools/c7n_azure/c7n_azure/constants.py b/tools/c7n_azure/c7n_azure/constants.py index 90e261ed536..90773fa8019 100644 --- a/tools/c7n_azure/c7n_azure/constants.py +++ b/tools/c7n_azure/c7n_azure/constants.py @@ -4,8 +4,8 @@ """ Azure Functions """ -FUNCTION_DOCKER_VERSION = 'python|3.8' -FUNCTION_EXT_VERSION = '~3' +FUNCTION_DOCKER_VERSION = 'python|3.12' +FUNCTION_EXT_VERSION = '~4' FUNCTION_EVENT_TRIGGER_MODE = 'azure-event-grid' FUNCTION_TIME_TRIGGER_MODE = 'azure-periodic' FUNCTION_KEY_URL = 'hostruntime/admin/host/systemkeys/_master?api-version=2018-02-01' @@ -135,7 +135,7 @@ FUNCTION_EXTENSION_BUNDLE_CONFIG = { "id": "Microsoft.Azure.Functions.ExtensionBundle", - "version": "[1.*, 2.0.0)" + "version": "[4.*, 5.0.0)" } """ diff --git a/tools/c7n_azure/c7n_azure/function_package.py b/tools/c7n_azure/c7n_azure/function_package.py index bbd64fede8a..20a117d9721 100644 --- a/tools/c7n_azure/c7n_azure/function_package.py +++ b/tools/c7n_azure/c7n_azure/function_package.py @@ -154,9 +154,9 @@ def build(self, policy, modules, requirements, queue_name=None, identity=None): # add config and policy self._add_functions_required_files(policy, requirements, queue_name, identity) - def wait_for_status(self, deployment_creds, retries=10, delay=15): + def wait_for_status(self, scm_uri, token, retries=10, delay=15): for r in range(retries): - if self.status(deployment_creds): + if self.status(scm_uri, token): return True else: self.log.info('(%s/%s) Will retry Function App status check in %s seconds...' @@ -164,10 +164,11 @@ def wait_for_status(self, deployment_creds, retries=10, delay=15): time.sleep(delay) return False - def status(self, deployment_creds): - status_url = '%s/api/deployments' % deployment_creds.scm_uri + def status(self, scm_uri, token): + status_url = '%s/api/deployments' % scm_uri + headers = {'Authorization': 'Bearer %s' % token} - r = requests.get(status_url, verify=self.enable_ssl_cert, timeout=60) + r = requests.get(status_url, headers=headers, verify=self.enable_ssl_cert, timeout=60) if r.status_code != 200: self.log.error("Application service returned an error.\n%s\n%s" % (r.status_code, r.text)) @@ -175,13 +176,16 @@ def status(self, deployment_creds): return True - def publish(self, deployment_creds): + def publish(self, scm_uri, token): self.close() # update perms of the package os.chmod(self.pkg.path, 0o0644) - zip_api_url = '%s/api/zipdeploy?isAsync=true&synctriggers=true' % deployment_creds.scm_uri - headers = {'content-type': 'application/octet-stream'} + zip_api_url = '%s/api/zipdeploy?isAsync=true&synctriggers=true' % scm_uri + headers = { + 'content-type': 'application/octet-stream', + 'Authorization': 'Bearer %s' % token, + } self.log.info("Publishing Function package from %s" % self.pkg.path) zip_file = self.pkg.get_bytes() diff --git a/tools/c7n_azure/c7n_azure/functionapp_utils.py b/tools/c7n_azure/c7n_azure/functionapp_utils.py index 9eeae13f5eb..ac68844f717 100644 --- a/tools/c7n_azure/c7n_azure/functionapp_utils.py +++ b/tools/c7n_azure/c7n_azure/functionapp_utils.py @@ -98,16 +98,20 @@ def get_function_name(policy_name, suffix): @classmethod def publish_functions_package(cls, function_params, package): session = local_session(Session) - web_client = session.client('azure.mgmt.web.WebSiteManagementClient') cls.log.info('Publishing Function application') - publish_creds = web_client.web_apps.begin_list_publishing_credentials( - function_params.function_app['resource_group_name'], - function_params.function_app['name']).result() + app_name = function_params.function_app['name'] - if package.wait_for_status(publish_creds): - package.publish(publish_creds) + # Use an Entra ID bearer token instead of SCM Basic Auth publishing credentials, so + # deployment works in tenants where Basic Auth is disabled by policy. Requires the + # deploying identity to hold Website Contributor (or equivalent) on the Function App. + scm_uri = 'https://{}.scm.azurewebsites.net'.format(app_name) + token_scope = session.cloud_endpoints.endpoints.resource_manager.rstrip('/') + '/.default' + token = session.get_credentials().get_token(token_scope).token + + if package.wait_for_status(scm_uri, token): + package.publish(scm_uri, token) cls.log.info('Finished publishing Function application') else: cls.log.error("Aborted deployment, ensure Application Service is healthy.") diff --git a/tools/c7n_azure/c7n_azure/policy.py b/tools/c7n_azure/c7n_azure/policy.py index 8a1d9fcb956..2624a04d654 100644 --- a/tools/c7n_azure/c7n_azure/policy.py +++ b/tools/c7n_azure/c7n_azure/policy.py @@ -481,7 +481,8 @@ def _create_storage_queue(self, queue_name, session): def _create_event_subscription(self, storage_account, queue_name, session): self.log.info('Creating event grid subscription') destination = StorageQueueEventSubscriptionDestination(resource_id=storage_account.id, - queue_name=queue_name) + queue_name=queue_name, + endpoint_type='StorageQueue') # filter specific events advance_filter = StringInAdvancedFilter(key='Data.OperationName', diff --git a/tools/c7n_azure/c7n_azure/resources/arm.py b/tools/c7n_azure/c7n_azure/resources/arm.py index 06cdb958726..3c38c5c90e6 100644 --- a/tools/c7n_azure/c7n_azure/resources/arm.py +++ b/tools/c7n_azure/c7n_azure/resources/arm.py @@ -21,6 +21,7 @@ # ARM resources which do not currently support tagging # for database it is a C7N known issue (#4543) arm_tags_unsupported = ['microsoft.network/dnszones/', + 'microsoft.network/privatednszones/', 'microsoft.sql/servers/databases', 'microsoft.storage/storageaccounts/blobservices/containers', 'microsoft.cognitiveservices/accounts/deployments', diff --git a/tools/c7n_azure/c7n_azure/resources/budget.py b/tools/c7n_azure/c7n_azure/resources/budget.py new file mode 100644 index 00000000000..9af7f7f7c0e --- /dev/null +++ b/tools/c7n_azure/c7n_azure/resources/budget.py @@ -0,0 +1,75 @@ +from c7n_azure.provider import resources +from c7n_azure.resources.arm import ArmResourceManager + + +@resources.register('budget') +class Budget(ArmResourceManager): + """Budget Resource + + Cost budgets are augmented with a computed ``c7n:percent-used`` field, which is the + percentage of ``properties.currentSpend.amount`` relative to ``properties.amount``. + + :example: + + Find budgets with amount > $1000: + + .. code-block:: yaml + + policies: + - name: azure-budget-list + resource: azure.budget + filters: + - properties.category: Cost + - type: value + key: properties.amount + op: greater-than + value: 1000 + + Find cost budgets that have used at least 80% of their configured amount: + + .. code-block:: yaml + + policies: + - name: azure-budget-high-utilization + resource: azure.budget + filters: + - properties.category: Cost + - type: value + key: c7n:percent-used + op: greater-than + value: 80 + """ + + class resource_type(ArmResourceManager.resource_type): + service = 'azure.mgmt.consumption' + client = 'ConsumptionManagementClient' + enum_spec = ('budgets', 'list', None) + default_report_fields = ( + 'id', + 'name', + 'properties.category', + ) + resource_type = 'Microsoft.Consumption/budgets' + + @classmethod + def extra_args(cls, resource_manager): + scope = '/subscriptions/' + resource_manager.get_session().get_subscription_id() + return {'scope': scope} + + @staticmethod + def percent_used(resource): + """Returns what percentage of the budget has already been spent. If the budget is not a Cost + budget, returns None.""" + props = resource['properties'] + if props['category'] == 'Cost': + return props['currentSpend']['amount'] / props['amount'] * 100 + + def augment(self, resources): + resources = super().augment(resources) + + for resource in resources: + percent_used = self.percent_used(resource) + if percent_used is not None: + resource['c7n:percent-used'] = percent_used + + return resources diff --git a/tools/c7n_azure/c7n_azure/resources/machine_learning_job.py b/tools/c7n_azure/c7n_azure/resources/machine_learning_job.py index 0f20ce9bd5d..fcaedf7855b 100644 --- a/tools/c7n_azure/c7n_azure/resources/machine_learning_job.py +++ b/tools/c7n_azure/c7n_azure/resources/machine_learning_job.py @@ -1,8 +1,11 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +from c7n.utils import type_schema +from c7n_azure.actions.base import AzureBaseAction from c7n_azure.provider import resources from c7n_azure.resources.arm import ChildArmResourceManager +from c7n_azure.utils import ResourceIdParser @resources.register('machine-learning-job') @@ -52,3 +55,26 @@ def extra_args(cls, parent_resource): 'resource_group_name': parent_resource['resourceGroup'], 'workspace_name': parent_resource['name'], } + + +@MachineLearningJob.action_registry.register('archive') +class MachineLearningJobArchiveAction(AzureBaseAction): + """Archive Azure Machine Learning jobs.""" + + schema = type_schema('archive') + + def _prepare_processing(self): + self.client = self.manager.get_client() + + def _process_resource(self, resource): + if resource['properties'].get('isArchived'): + return 'already archived' + + resource['properties']['isArchived'] = True + self.client.jobs.create_or_update( + resource_group_name=ResourceIdParser.get_resource_group(resource['id']), + workspace_name=ResourceIdParser.get_resource_name(resource['c7n:parent-id']), + id=resource['name'], + body=resource, + ) + return 'archived' diff --git a/tools/c7n_azure/c7n_azure/resources/machine_learning_model_version.py b/tools/c7n_azure/c7n_azure/resources/machine_learning_model_version.py new file mode 100644 index 00000000000..f786ba95db4 --- /dev/null +++ b/tools/c7n_azure/c7n_azure/resources/machine_learning_model_version.py @@ -0,0 +1,58 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from c7n_azure.provider import resources +from c7n_azure.resources.arm import ChildArmResourceManager +from c7n_azure.utils import ResourceIdParser + + +@resources.register('machine-learning-model-version') +class MachineLearningModelVersion(ChildArmResourceManager): + """Machine Learning Model Version Resource + + Enumerates every model version registered in each Machine Learning + workspace, allowing policies to find stale or unused model artifacts. + + :example: + + Find model versions that are not archived. + + .. code-block:: yaml + + policies: + - name: ml-model-versions-active + resource: azure.machine-learning-model-version + filters: + - type: value + key: properties.isArchived + value: false + """ + + class resource_type(ChildArmResourceManager.resource_type): + doc_groups = ['ML'] + + service = 'azure.mgmt.machinelearningservices' + client = 'MachineLearningServicesMgmtClient' + enum_spec = ('model_versions', 'list', None) + parent_manager_name = 'machine-learning-workspace' + resource_type = 'Microsoft.MachineLearningServices/workspaces/models/versions' + default_report_fields = ( + 'name', + 'resourceGroup', + '"c7n:parent-id"' + ) + + def enumerate_resources(self, parent_resource, type_info, vault_url=None, **params): + client = self.get_client() + resource_group = ResourceIdParser.get_resource_group(parent_resource['id']) + workspace_name = parent_resource['name'] + + versions = [] + for container in client.model_containers.list( + resource_group_name=resource_group, workspace_name=workspace_name): + for version in client.model_versions.list( + resource_group_name=resource_group, + workspace_name=workspace_name, + name=container.name): + versions.append(version.serialize(True)) + return versions diff --git a/tools/c7n_azure/c7n_azure/resources/private_dns_zone.py b/tools/c7n_azure/c7n_azure/resources/private_dns_zone.py new file mode 100644 index 00000000000..9c94c12b0af --- /dev/null +++ b/tools/c7n_azure/c7n_azure/resources/private_dns_zone.py @@ -0,0 +1,37 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from c7n_azure.provider import resources +from c7n_azure.resources.arm import ArmResourceManager + + +@resources.register('private-dns-zone') +class PrivateDnsZone(ArmResourceManager): + """Private DNS Zone Resource + + :example: + + Finds all Private DNS Zones in the subscription + + .. code-block:: yaml + + policies: + - name: find-all-private-dns-zones + resource: azure.private-dns-zone + + """ + + class resource_type(ArmResourceManager.resource_type): + doc_groups = ['Networking'] + + service = 'azure.mgmt.privatedns' + client = 'PrivateDnsManagementClient' + enum_spec = ('private_zones', 'list', {}) + resource_type = 'Microsoft.Network/privateDnsZones' + default_report_fields = ( + 'name', + 'location', + 'resourceGroup', + 'properties.numberOfRecordSets', + 'properties.numberOfVirtualNetworkLinks' + ) diff --git a/tools/c7n_azure/c7n_azure/resources/private_record_set.py b/tools/c7n_azure/c7n_azure/resources/private_record_set.py new file mode 100644 index 00000000000..59438f0ff5b --- /dev/null +++ b/tools/c7n_azure/c7n_azure/resources/private_record_set.py @@ -0,0 +1,48 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from c7n_azure.provider import resources +from c7n_azure.resources.arm import ChildArmResourceManager + + +@resources.register('private-record-set') +class PrivateRecordSet(ChildArmResourceManager): + """Private DNS Record Set Resource + + :example: + + Finds all Record Sets for all Private DNS Zones in the subscription + + .. code-block:: yaml + + policies: + - name: find-all-private-record-sets + resource: azure.private-record-set + + """ + + class resource_type(ChildArmResourceManager.resource_type): + doc_groups = ['Networking'] + + service = 'azure.mgmt.privatedns' + client = 'PrivateDnsManagementClient' + enum_spec = ('record_sets', 'list', None) + parent_manager_name = 'private-dns-zone' + default_report_fields = ( + 'name', + 'type', + 'resourceGroup', + '"c7n:parent-id"' + ) + + # NOTE: Record Sets each have their own resource_type value. Private + # zones support fewer record types than public zones. + resource_type = 'Microsoft.Network/privateDnsZones/' \ + '{A|AAAA|CNAME|MX|PTR|SOA|SRV|TXT}' + + @classmethod + def extra_args(cls, private_dns_zone): + return { + 'resource_group_name': private_dns_zone['resourceGroup'], + 'private_zone_name': private_dns_zone['name'] + } diff --git a/tools/c7n_azure/c7n_azure/resources/resource_map.py b/tools/c7n_azure/c7n_azure/resources/resource_map.py index b6882da14c5..bed7605b624 100644 --- a/tools/c7n_azure/c7n_azure/resources/resource_map.py +++ b/tools/c7n_azure/c7n_azure/resources/resource_map.py @@ -21,6 +21,7 @@ "azure.backup-vault": "c7n_azure.resources.backup_vault.BackupVault", "azure.bastion-host": "c7n_azure.resources.bastion_host.AzureBastionHost", "azure.batch": "c7n_azure.resources.batch.Batch", + "azure.budget": "c7n_azure.resources.budget.Budget", "azure.cdn-custom-domain": "c7n_azure.resources.cdn_custom_domain.CdnCustomDomain", "azure.cdn-endpoint": "c7n_azure.resources.cdn_endpoint.CdnEndpoint", "azure.cdnprofile": "c7n_azure.resources.cdn.CdnProfile", @@ -69,6 +70,7 @@ "azure.machine-learning-workspace": "c7n_azure.resources.machine_learning.MachineLearningWorkspace", # noqa "azure.machine-learning-data-container": "c7n_azure.resources.machine_learning.MachineLearningDataContainer", # noqa "azure.machine-learning-job": "c7n_azure.resources.machine_learning_job.MachineLearningJob", + "azure.machine-learning-model-version": "c7n_azure.resources.machine_learning_model_version.MachineLearningModelVersion", # noqa "azure.machine-learning-online-endpoint": "c7n_azure.resources.machine_learning_online_endpoint.MachineLearningOnlineEndpoint", # noqa "azure.mariadb": "c7n_azure.resources.mariadb.MariaDB", "azure.monitor-log-profile": "c7n_azure.resources.monitor_logprofile.MonitorLogprofile", @@ -82,6 +84,8 @@ "azure.policyassignments": "c7n_azure.resources.policy_assignments.PolicyAssignments", "azure.postgresql-database": "c7n_azure.resources.postgresql_database.PostgresqlDatabase", "azure.postgresql-server": "c7n_azure.resources.postgresql_server.PostgresqlServer", + "azure.private-dns-zone": "c7n_azure.resources.private_dns_zone.PrivateDnsZone", + "azure.private-record-set": "c7n_azure.resources.private_record_set.PrivateRecordSet", "azure.publicip": "c7n_azure.resources.public_ip.PublicIPAddress", "azure.recordset": "c7n_azure.resources.record_set.RecordSet", "azure.recovery-services": "c7n_azure.resources.recovery_services.RecoveryServices", diff --git a/tools/c7n_azure/pyproject.toml b/tools/c7n_azure/pyproject.toml index 4f0df08b402..c8f94ca1525 100644 --- a/tools/c7n_azure/pyproject.toml +++ b/tools/c7n_azure/pyproject.toml @@ -29,6 +29,7 @@ dependencies = [ "azure-mgmt-cdn<13.0.0,>=12.0.0", "azure-mgmt-cognitiveservices<14.0.0,>=13.7.0", "azure-mgmt-compute<35.0.0,>=34.1.0", + "azure-mgmt-consumption<11.0.0,>=10.0.0", "azure-mgmt-containerinstance<8.0.0,>=7.0.0", "azure-mgmt-containerregistry<15.0.0,>=14.0.0", "azure-mgmt-containerservice<16.0.0,>=15.0.0", @@ -55,6 +56,7 @@ dependencies = [ "azure-mgmt-msi<2.0.0,>=1.0.0", "azure-mgmt-network<29.0.0,>=28.0.0", "azure-mgmt-policyinsights<2.0.0,>=1.0.0", + "azure-mgmt-privatedns<3.0.0,>=2.0.0", "azure-mgmt-rdbms==10.2.0b17", "azure-mgmt-recoveryservices<4.0.0,>=3.1.0", "azure-mgmt-recoveryservicesbackup<8.0.0,>=7.0.0", @@ -87,7 +89,7 @@ dependencies = [ "requests<3.0.0,>=2.22.0", ] name = "c7n_azure" -version = "0.7.51a5+a83dda5c9" +version = "0.7.52a1+e4c099e03" description = "Cloud Custodian - Azure Support" readme = "readme.md" classifiers = [ diff --git a/tools/c7n_azure/tests_azure/azure_common.py b/tools/c7n_azure/tests_azure/azure_common.py index 46f92ae62b5..221a8e429d6 100644 --- a/tools/c7n_azure/tests_azure/azure_common.py +++ b/tools/c7n_azure/tests_azure/azure_common.py @@ -131,6 +131,7 @@ class AzureVCRBaseTest(VCRTestCase): 'x-ms-keyvault-network-info', 'x-ms-keyvault-region', 'x-ms-ratelimit-remaining-subscription-reads', + 'x-ms-operation-identifier', 'x-ms-request-id', 'x-ms-routing-request-id', 'x-ms-gateway-service-instanceid', @@ -301,7 +302,7 @@ def _response_substitutions(response): @staticmethod def _replace_subscription_id(s): - prefixes = ['(/|%2F)?subscriptions(/|%2F)', + prefixes = [r'(\\?/|%2F)?subscriptions(\\?/|%2F)', '"subscription":\\s*"'] regex = r"(?P(%s))" \ r"[\da-zA-Z]{8}-([\da-zA-Z]{4}-){3}[\da-zA-Z]{12}" \ diff --git a/tools/c7n_azure/tests_azure/cassettes/BudgetTest.common.json b/tools/c7n_azure/tests_azure/cassettes/BudgetTest.common.json new file mode 100644 index 00000000000..c788788bb3d --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/BudgetTest.common.json @@ -0,0 +1,120 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.Consumption/budgets?api-version=2021-10-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=83fcb2fd-d967-4573-a0f5-ad465aab3ab2/southcentralus/e7907465-27d4-4252-b5ff-c71f774cd1a8" + ], + "x-msedge-ref": [ + "Ref A: AF9E8521197A4B8181C007B6DA77379F Ref B: SN4AA2022302019 Ref C: 2026-03-23T20:59:50Z" + ], + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "content-length": [ + "1211" + ], + "cache-control": [ + "no-cache" + ], + "session-id": [ + "b330a4c4-a6da-451a-8d2e-d50a8290ca73" + ], + "date": [ + "Mon, 23 Mar 2026 20:59:51 GMT" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.Consumption/budgets/budget_1001", + "name": "budget_1001", + "type": "Microsoft.Consumption/budgets", + "eTag": "\"1dcbb07e349e2d8\"", + "properties": { + "timePeriod": { + "startDate": "2026-03-01T00:00:00Z", + "endDate": "2036-02-27T00:00:00Z" + }, + "timeGrain": "Monthly", + "amount": 1001.0, + "currentSpend": { + "amount": 123.45, + "unit": "USD" + }, + "category": "Cost", + "notifications": { + "actual_gte_90": { + "enabled": false, + "operator": "EqualTo", + "threshold": 90.0, + "contactEmails": [ + "test@example.com" + ], + "contactRoles": [], + "contactGroups": [], + "thresholdType": "Actual" + } + }, + "filter": {} + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.Consumption/budgets/budget_1000", + "name": "budget_1000", + "type": "Microsoft.Consumption/budgets", + "eTag": "\"1dcbb07e34a53e9\"", + "properties": { + "timePeriod": { + "startDate": "2026-03-01T00:00:00Z", + "endDate": "2036-02-27T00:00:00Z" + }, + "timeGrain": "Monthly", + "amount": 1000.0, + "currentSpend": { + "amount": 0.0, + "unit": "USD" + }, + "category": "Cost", + "notifications": { + "actual_gte_90": { + "enabled": false, + "operator": "EqualTo", + "threshold": 90.0, + "contactEmails": [ + "test@example.com" + ], + "contactRoles": [], + "contactGroups": [], + "thresholdType": "Actual" + } + }, + "filter": {} + } + } + ] + } + } + } + } + ] +} diff --git a/tools/c7n_azure/tests_azure/cassettes/DeploymentUnitsTest.test_function_app_dedicated.json b/tools/c7n_azure/tests_azure/cassettes/DeploymentUnitsTest.test_function_app_dedicated.json index 8b24e1f5010..8db089c69bc 100644 --- a/tools/c7n_azure/tests_azure/cassettes/DeploymentUnitsTest.test_function_app_dedicated.json +++ b/tools/c7n_azure/tests_azure/cassettes/DeploymentUnitsTest.test_function_app_dedicated.json @@ -387,7 +387,7 @@ "properties": [ { "name": "LinuxFxVersion", - "value": "python|3.8" + "value": "python|3.12" }, { "name": "WindowsFxVersion", @@ -521,7 +521,7 @@ "phpVersion": "", "pythonVersion": "", "nodeVersion": "", - "linuxFxVersion": "python|3.8", + "linuxFxVersion": "python|3.12", "windowsFxVersion": null, "requestTracingEnabled": false, "remoteDebuggingEnabled": false, diff --git a/tools/c7n_azure/tests_azure/cassettes/MachineLearningJobTest.machine-learning-job-archive-skip.json b/tools/c7n_azure/tests_azure/cassettes/MachineLearningJobTest.machine-learning-job-archive-skip.json new file mode 100644 index 00000000000..2f0cb7677cb --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/MachineLearningJobTest.machine-learning-job-archive-skip.json @@ -0,0 +1,138 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ], + "x-msedge-ref": [ + "Ref A: B16EB549D7BA447BBD1CC612ED077F38 Ref B: CYS013050704035 Ref C: 2026-08-13T19:26:00Z" + ], + "x-request-time": [ + "0.062" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "request-context": [ + "appId=cid-v1:2d2e8e63-272e-4b3c-8598-4ee570a0e70d" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=e89404a5-c7db-4cdf-aed3-31daf7739325/southcentralus/889b23fb-e4cb-43c4-a0e8-82d40363ec4b" + ], + "content-length": [ + "3375" + ], + "cache-control": [ + "no-cache" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:59 GMT" + ], + "x-ms-response-type": [ + "standard" + ], + "azureml-served-by-cluster": [ + "vienna-southcentralus-01" + ] + }, + "body": { + "data": { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job", + "name": "cctest-archive-job", + "type": "Microsoft.MachineLearningServices/workspaces/jobs", + "properties": { + "description": null, + "tags": { + "_aml_system_ComputeTargetStatus": "{\"AllocationState\":\"steady\",\"PreparingNodeCount\":0,\"RunningNodeCount\":0,\"CurrentNodeCount\":0}" + }, + "properties": { + "mlflow.source.git.repoURL": "test@example.com", + "mlflow.source.git.branch": "jimfulton/feat/10949-azure-ml-job-archive", + "mlflow.source.git.commit": "c1ce0dce0b77346d223400d93f5f598eec874f2d", + "azureml.git.dirty": "False", + "_azureml.ComputeTargetType": "amlctrain", + "_azureml.ClusterName": "cctestcpuarchive", + "ProcessInfoFile": "azureml-logs/process_info.json", + "ProcessStatusFile": "azureml-logs/process_status.json", + "StartTimeUtc": "2026-08-13 19:19:44", + "EndTimeUtc": "2026-08-13 19:20:44" + }, + "displayName": "cctest_archive_job", + "status": "Completed", + "experimentName": "cctest_archive", + "services": { + "Tracking": { + "jobServiceType": "Tracking", + "port": null, + "endpoint": "azureml://southcentralus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive?", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + }, + "Studio": { + "jobServiceType": "Studio", + "port": null, + "endpoint": "https://ml.azure.com/runs/cctest-archive-job?wsid=/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourcegroups/test_machine-learning-job-archive/workspaces/cctest-mlws-archive", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + } + }, + "computeId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/computes/cctestcpuarchive", + "isArchived": true, + "identity": null, + "componentId": null, + "jobType": "Command", + "resources": { + "instanceCount": 1, + "instanceType": null, + "properties": null, + "shmSize": "2g", + "dockerArgs": null + }, + "codeId": null, + "command": "echo hello", + "environmentId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/environments/cctest-archive-env/versions/1", + "inputs": {}, + "outputs": { + "default": { + "description": null, + "uri": "azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.cctest-archive-job", + "mode": "ReadWriteMount", + "jobOutputType": "uri_folder" + } + }, + "distribution": null, + "limits": null, + "environmentVariables": {}, + "parameters": {} + }, + "systemData": { + "createdAt": "2026-08-13T19:17:35.6842089+00:00", + "createdBy": "Jim Fulton", + "createdByType": "User" + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/tools/c7n_azure/tests_azure/cassettes/MachineLearningJobTest.machine-learning-job-archive.json b/tools/c7n_azure/tests_azure/cassettes/MachineLearningJobTest.machine-learning-job-archive.json new file mode 100644 index 00000000000..d0dbcd30e6c --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/MachineLearningJobTest.machine-learning-job-archive.json @@ -0,0 +1,771 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.MachineLearningServices/workspaces?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-length": [ + "7785" + ], + "x-ms-original-request-ids": [ + "", + "" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-msedge-ref": [ + "Ref A: 3BF356F9D17F4083AA76942777C51FD4 Ref B: CYS013050701047 Ref C: 2026-08-13T19:25:53Z" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:53 GMT" + ], + "cache-control": [ + "no-cache" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/stacklet-dev-westus/providers/Microsoft.MachineLearningServices/workspaces/c7n-ml-dc-drea-5cd4", + "name": "c7n-ml-dc-drea-5cd4", + "type": "Microsoft.MachineLearningServices/workspaces", + "location": "westus", + "tags": {}, + "etag": null, + "properties": { + "friendlyName": "", + "description": "", + "storageAccount": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/stacklet-dev-westus/providers/Microsoft.Storage/storageAccounts/c7nmldc5cd4", + "keyVault": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/stacklet-dev-westus/providers/Microsoft.Keyvault/vaults/c7n-ml-dc-kv-drea-5cd4", + "applicationInsights": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/stacklet-dev-westus/providers/Microsoft.insights/components/c7n-ml-dc-ai-drea-5cd4", + "hbiWorkspace": false, + "tenantId": "00000000-0000-0000-0000-000000000003", + "imageBuildCompute": null, + "provisioningState": "Succeeded", + "managedNetwork": { + "changeableIsolationModes": [ + "AllowInternetOutbound", + "AllowOnlyApprovedOutbound" + ], + "isolationMode": "Disabled", + "enableNetworkMonitor": false, + "enableFirewallLog": false + }, + "allowRoleAssignmentOnRG": true, + "v1LegacyMode": false, + "softDeleteEnabled": false, + "creationTime": "2026-08-11T15:14:07.9964944Z", + "notebookInfo": { + "resourceId": "5122454c6ce5437c879f75c63406ecb9", + "fqdn": "ml-c7n-ml-dc-drea-5-westus-3585ef7b-4a23-465f-b0a4-fefa6e09788e.westus.notebooks.azure.net", + "isPrivateLinkEnabled": false, + "notebookPreparationError": null + }, + "storageHnsEnabled": false, + "workspaceId": "3585ef7b-4a23-465f-b0a4-fefa6e09788e", + "linkedModelInventoryArmId": null, + "privateLinkCount": 0, + "publicNetworkAccess": "Enabled", + "discoveryUrl": "https://westus.api.azureml.ms/discovery", + "mlFlowTrackingUri": "azureml://westus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/stacklet-dev-westus/providers/Microsoft.MachineLearningServices/workspaces/c7n-ml-dc-drea-5cd4", + "sdkTelemetryAppInsightsKey": "ad4db683-227d-4cf9-b788-db8d151f62e0", + "enableDataIsolation": false + }, + "identity": { + "type": "SystemAssigned", + "principalId": "788d423b-20f4-4e64-86db-04ce7ee1b5c0", + "tenantId": "00000000-0000-0000-0000-000000000003" + }, + "kind": "Default", + "sku": { + "name": "Basic", + "tier": "Basic" + }, + "systemData": { + "createdAt": "2026-08-11T15:14:07.9964944Z", + "createdBy": "test@example.com", + "createdByType": "User", + "lastModifiedAt": "2026-08-11T15:14:07.9964944Z", + "lastModifiedBy": "test@example.com", + "lastModifiedByType": "User" + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/aml-delete-test-0812095033/providers/Microsoft.MachineLearningServices/workspaces/aml-delete-0812095033", + "name": "aml-delete-0812095033", + "type": "Microsoft.MachineLearningServices/workspaces", + "location": "westus", + "tags": { + "createdByToolkit": "cli-v2-1.34.1" + }, + "etag": null, + "properties": { + "friendlyName": "aml-delete-0812095033", + "description": "aml-delete-0812095033", + "storageAccount": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/aml-delete-test-0812095033/providers/Microsoft.Storage/storageAccounts/amldeletstorage25aa71048", + "keyVault": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/aml-delete-test-0812095033/providers/Microsoft.Keyvault/vaults/amldeletkeyvault5540f7e4", + "applicationInsights": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/aml-delete-test-0812095033/providers/Microsoft.insights/components/amldeletinsights95d2b2da", + "hbiWorkspace": false, + "tenantId": "00000000-0000-0000-0000-000000000003", + "imageBuildCompute": null, + "provisioningState": "Succeeded", + "managedNetwork": { + "changeableIsolationModes": [ + "AllowInternetOutbound", + "AllowOnlyApprovedOutbound" + ], + "isolationMode": "Disabled", + "enableNetworkMonitor": false, + "enableFirewallLog": false + }, + "allowRoleAssignmentOnRG": true, + "v1LegacyMode": false, + "softDeleteEnabled": false, + "creationTime": "2026-08-12T14:03:06.5147287Z", + "notebookInfo": { + "resourceId": "67293dad521f4e8c82e6f3fe495b572e", + "fqdn": "ml-aml-delete-08120-westus-fee9f3af-061d-4d78-a2c7-7dc193975323.westus.notebooks.azure.net", + "isPrivateLinkEnabled": false, + "notebookPreparationError": null + }, + "storageHnsEnabled": false, + "workspaceId": "fee9f3af-061d-4d78-a2c7-7dc193975323", + "linkedModelInventoryArmId": null, + "privateLinkCount": 0, + "publicNetworkAccess": "Enabled", + "discoveryUrl": "https://westus.api.azureml.ms/discovery", + "mlFlowTrackingUri": "azureml://westus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/aml-delete-test-0812095033/providers/Microsoft.MachineLearningServices/workspaces/aml-delete-0812095033", + "sdkTelemetryAppInsightsKey": "ad4db683-227d-4cf9-b788-db8d151f62e0", + "enableDataIsolation": false + }, + "identity": { + "type": "SystemAssigned", + "principalId": "5088aaa7-547c-4b1a-a0f2-e5242bcfcf49", + "tenantId": "00000000-0000-0000-0000-000000000003" + }, + "kind": "Default", + "sku": { + "name": "Basic", + "tier": "Basic" + }, + "systemData": { + "createdAt": "2026-08-12T14:03:06.5147287Z", + "createdBy": "test@example.com", + "createdByType": "User", + "lastModifiedAt": "2026-08-12T14:03:06.5147287Z", + "lastModifiedBy": "test@example.com", + "lastModifiedByType": "User" + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive", + "name": "cctest-mlws-archive", + "type": "Microsoft.MachineLearningServices/workspaces", + "location": "southcentralus", + "tags": { + "createdByToolkit": "cli-v2-1.34.1" + }, + "etag": null, + "properties": { + "friendlyName": "cctest-mlws-archive", + "description": "cctest-mlws-archive", + "storageAccount": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.Storage/storageAccounts/cctestmlstorage901395176", + "keyVault": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.Keyvault/vaults/cctestmlkeyvault6c6a5fec", + "applicationInsights": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.insights/components/cctestmlinsightsbf7c6786", + "hbiWorkspace": false, + "tenantId": "00000000-0000-0000-0000-000000000003", + "imageBuildCompute": null, + "provisioningState": "Succeeded", + "managedNetwork": { + "changeableIsolationModes": [ + "AllowInternetOutbound", + "AllowOnlyApprovedOutbound" + ], + "isolationMode": "Disabled", + "enableNetworkMonitor": false, + "enableFirewallLog": false + }, + "allowRoleAssignmentOnRG": true, + "v1LegacyMode": false, + "softDeleteEnabled": false, + "creationTime": "2026-08-13T19:16:00.6798670Z", + "notebookInfo": { + "resourceId": "d105071bf88c4a7699fa376a22452ffe", + "fqdn": "ml-cctest-m-southcentralus-9cb7e579-f2cf-4f6d-97cb-47cd470d3295.southcentralus.notebooks.azure.net", + "isPrivateLinkEnabled": false, + "notebookPreparationError": null + }, + "storageHnsEnabled": false, + "workspaceId": "9cb7e579-f2cf-4f6d-97cb-47cd470d3295", + "linkedModelInventoryArmId": null, + "privateLinkCount": 0, + "publicNetworkAccess": "Enabled", + "discoveryUrl": "https://southcentralus.api.azureml.ms/discovery", + "mlFlowTrackingUri": "azureml://southcentralus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive", + "sdkTelemetryAppInsightsKey": "d83d49eb-3973-4a30-937a-eb3fc2d37c24", + "enableDataIsolation": false + }, + "identity": { + "type": "SystemAssigned", + "principalId": "2bb14fea-f483-4816-b0f1-765c6b52852e", + "tenantId": "00000000-0000-0000-0000-000000000003" + }, + "kind": "Default", + "sku": { + "name": "Basic", + "tier": "Basic" + }, + "systemData": { + "createdAt": "2026-08-13T19:16:00.679867Z", + "createdBy": "test@example.com", + "createdByType": "User", + "lastModifiedAt": "2026-08-13T19:16:00.679867Z", + "lastModifiedBy": "test@example.com", + "lastModifiedByType": "User" + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/stacklet-dev-westus/providers/Microsoft.MachineLearningServices/workspaces/c7n-ml-dc-drea-5cd4/jobs?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-length": [ + "17" + ], + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=e89404a5-c7db-4cdf-aed3-31daf7739325/westus/175e693d-1347-4012-b66b-b44e5683c2ae" + ], + "x-ms-response-type": [ + "standard" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-msedge-ref": [ + "Ref A: 3DCB58AC795147DBAC85A00E836B48DC Ref B: CYS013050702017 Ref C: 2026-08-13T19:25:54Z" + ], + "cache-control": [ + "no-cache" + ], + "x-request-time": [ + "0.078" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ], + "request-context": [ + "appId=cid-v1:2d2e8e63-272e-4b3c-8598-4ee570a0e70d" + ], + "azureml-served-by-cluster": [ + "vienna-westus-01" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:54 GMT" + ] + }, + "body": { + "data": { + "value": [] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/aml-delete-test-0812095033/providers/Microsoft.MachineLearningServices/workspaces/aml-delete-0812095033/jobs?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-length": [ + "17" + ], + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=e89404a5-c7db-4cdf-aed3-31daf7739325/westus/fe3283dd-c95f-4053-b3e7-a1d650016d93" + ], + "x-ms-response-type": [ + "standard" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-msedge-ref": [ + "Ref A: 63E8998D330F4E0D81BAE73A3A143926 Ref B: CYS013050704033 Ref C: 2026-08-13T19:25:55Z" + ], + "cache-control": [ + "no-cache" + ], + "x-request-time": [ + "0.062" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ], + "request-context": [ + "appId=cid-v1:2d2e8e63-272e-4b3c-8598-4ee570a0e70d" + ], + "azureml-served-by-cluster": [ + "vienna-westus-02" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:54 GMT" + ] + }, + "body": { + "data": { + "value": [] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-length": [ + "3713" + ], + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=e89404a5-c7db-4cdf-aed3-31daf7739325/southcentralus/0692b016-52e5-40d0-96be-41286d24ef85" + ], + "x-ms-response-type": [ + "standard" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-msedge-ref": [ + "Ref A: B3B9998C3076470FA7CA16E4518F81D4 Ref B: CYS013050703029 Ref C: 2026-08-13T19:25:55Z" + ], + "cache-control": [ + "no-cache" + ], + "x-request-time": [ + "0.196" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ], + "request-context": [ + "appId=cid-v1:2d2e8e63-272e-4b3c-8598-4ee570a0e70d" + ], + "azureml-served-by-cluster": [ + "vienna-southcentralus-01" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:55 GMT" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job", + "name": "cctest-archive-job", + "type": "Microsoft.MachineLearningServices/workspaces/jobs", + "properties": { + "description": null, + "tags": { + "_aml_system_ComputeTargetStatus": "{\"AllocationState\":\"steady\",\"PreparingNodeCount\":0,\"RunningNodeCount\":0,\"CurrentNodeCount\":0}" + }, + "properties": { + "mlflow.source.git.repoURL": "test@example.com", + "mlflow.source.git.branch": "jimfulton/feat/10949-azure-ml-job-archive", + "mlflow.source.git.commit": "c1ce0dce0b77346d223400d93f5f598eec874f2d", + "azureml.git.dirty": "False", + "_azureml.ComputeTargetType": "amlctrain", + "_azureml.ClusterName": "cctestcpuarchive", + "ProcessInfoFile": "azureml-logs/process_info.json", + "ProcessStatusFile": "azureml-logs/process_status.json", + "StartTimeUtc": "2026-08-13 19:19:44", + "EndTimeUtc": "2026-08-13 19:20:44" + }, + "displayName": "cctest_archive_job", + "status": "Completed", + "experimentName": "cctest_archive", + "services": { + "Tracking": { + "jobServiceType": "Tracking", + "port": null, + "endpoint": "azureml://southcentralus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive?", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + }, + "Studio": { + "jobServiceType": "Studio", + "port": null, + "endpoint": "https://ml.azure.com/runs/cctest-archive-job?wsid=/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourcegroups/test_machine-learning-job-archive/workspaces/cctest-mlws-archive", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + } + }, + "computeId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/computes/cctestcpuarchive", + "isArchived": false, + "identity": null, + "componentId": null, + "jobType": "Command", + "resources": { + "instanceCount": 1, + "instanceType": null, + "properties": null, + "shmSize": "2g", + "dockerArgs": null + }, + "codeId": null, + "command": "echo hello", + "environmentId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/environments/cctest-archive-env/versions/1", + "inputs": {}, + "outputs": { + "default": { + "description": null, + "uri": "azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.cctest-archive-job", + "mode": "ReadWriteMount", + "jobOutputType": "uri_folder" + } + }, + "distribution": null, + "limits": null, + "environmentVariables": {}, + "parameters": {} + }, + "systemData": { + "createdAt": "2026-08-13T19:17:35.6842089+00:00", + "createdBy": "Jim Fulton", + "createdByType": "User" + } + } + ] + } + } + } + }, + { + "request": { + "method": "PUT", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job?api-version=2023-04-01", + "body": "mock_body", + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-length": [ + "3375" + ], + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=e89404a5-c7db-4cdf-aed3-31daf7739325/southcentralus/a0b501a3-a941-4de5-9301-80fbac757ef1" + ], + "x-ms-response-type": [ + "standard" + ], + "x-ms-ratelimit-remaining-subscription-global-writes": [ + "2999" + ], + "x-ms-ratelimit-remaining-subscription-writes": [ + "199" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-msedge-ref": [ + "Ref A: 36C22FD17F434C8FBE68E2617820DB55 Ref B: CYS013050701049 Ref C: 2026-08-13T19:25:56Z" + ], + "cache-control": [ + "no-cache" + ], + "x-request-time": [ + "0.201" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "request-context": [ + "appId=cid-v1:2d2e8e63-272e-4b3c-8598-4ee570a0e70d" + ], + "azureml-served-by-cluster": [ + "vienna-southcentralus-01" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:56 GMT" + ] + }, + "body": { + "data": { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job", + "name": "cctest-archive-job", + "type": "Microsoft.MachineLearningServices/workspaces/jobs", + "properties": { + "description": null, + "tags": { + "_aml_system_ComputeTargetStatus": "{\"AllocationState\":\"steady\",\"PreparingNodeCount\":0,\"RunningNodeCount\":0,\"CurrentNodeCount\":0}" + }, + "properties": { + "mlflow.source.git.repoURL": "test@example.com", + "mlflow.source.git.branch": "jimfulton/feat/10949-azure-ml-job-archive", + "mlflow.source.git.commit": "c1ce0dce0b77346d223400d93f5f598eec874f2d", + "azureml.git.dirty": "False", + "_azureml.ComputeTargetType": "amlctrain", + "_azureml.ClusterName": "cctestcpuarchive", + "ProcessInfoFile": "azureml-logs/process_info.json", + "ProcessStatusFile": "azureml-logs/process_status.json", + "StartTimeUtc": "2026-08-13 19:19:44", + "EndTimeUtc": "2026-08-13 19:20:44" + }, + "displayName": "cctest_archive_job", + "status": "Completed", + "experimentName": "cctest_archive", + "services": { + "Tracking": { + "jobServiceType": "Tracking", + "port": null, + "endpoint": "azureml://southcentralus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive?", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + }, + "Studio": { + "jobServiceType": "Studio", + "port": null, + "endpoint": "https://ml.azure.com/runs/cctest-archive-job?wsid=/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourcegroups/test_machine-learning-job-archive/workspaces/cctest-mlws-archive", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + } + }, + "computeId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/computes/cctestcpuarchive", + "isArchived": true, + "identity": null, + "componentId": null, + "jobType": "Command", + "resources": { + "instanceCount": 1, + "instanceType": null, + "properties": null, + "shmSize": "2g", + "dockerArgs": null + }, + "codeId": null, + "command": "echo hello", + "environmentId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/environments/cctest-archive-env/versions/1", + "inputs": {}, + "outputs": { + "default": { + "description": null, + "uri": "azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.cctest-archive-job", + "mode": "ReadWriteMount", + "jobOutputType": "uri_folder" + } + }, + "distribution": null, + "limits": null, + "environmentVariables": {}, + "parameters": {} + }, + "systemData": { + "createdAt": "2026-08-13T19:17:35.6842089+00:00", + "createdBy": "Jim Fulton", + "createdByType": "User" + } + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-length": [ + "3375" + ], + "x-ms-operation-identifier": [ + "tenantId=72d876e4-6b6f-4622-8566-8200130e81d4,objectId=e89404a5-c7db-4cdf-aed3-31daf7739325/southcentralus/28b8f101-74e9-4d53-951b-8014c6e3ace8" + ], + "x-ms-response-type": [ + "standard" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-msedge-ref": [ + "Ref A: 6A14A3BEB5D741B4A41BD310081516A1 Ref B: CYS013050704045 Ref C: 2026-08-13T19:25:57Z" + ], + "cache-control": [ + "no-cache" + ], + "x-request-time": [ + "0.065" + ], + "x-cache": [ + "CONFIG_NOCACHE" + ], + "x-ms-ratelimit-remaining-subscription-global-reads": [ + "3749" + ], + "request-context": [ + "appId=cid-v1:2d2e8e63-272e-4b3c-8598-4ee570a0e70d" + ], + "azureml-served-by-cluster": [ + "vienna-southcentralus-02" + ], + "date": [ + "Thu, 13 Aug 2026 19:25:56 GMT" + ] + }, + "body": { + "data": { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/jobs/cctest-archive-job", + "name": "cctest-archive-job", + "type": "Microsoft.MachineLearningServices/workspaces/jobs", + "properties": { + "description": null, + "tags": { + "_aml_system_ComputeTargetStatus": "{\"AllocationState\":\"steady\",\"PreparingNodeCount\":0,\"RunningNodeCount\":0,\"CurrentNodeCount\":0}" + }, + "properties": { + "mlflow.source.git.repoURL": "test@example.com", + "mlflow.source.git.branch": "jimfulton/feat/10949-azure-ml-job-archive", + "mlflow.source.git.commit": "c1ce0dce0b77346d223400d93f5f598eec874f2d", + "azureml.git.dirty": "False", + "_azureml.ComputeTargetType": "amlctrain", + "_azureml.ClusterName": "cctestcpuarchive", + "ProcessInfoFile": "azureml-logs/process_info.json", + "ProcessStatusFile": "azureml-logs/process_status.json", + "StartTimeUtc": "2026-08-13 19:19:44", + "EndTimeUtc": "2026-08-13 19:20:44" + }, + "displayName": "cctest_archive_job", + "status": "Completed", + "experimentName": "cctest_archive", + "services": { + "Tracking": { + "jobServiceType": "Tracking", + "port": null, + "endpoint": "azureml://southcentralus.api.azureml.ms/mlflow/v1.0/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive?", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + }, + "Studio": { + "jobServiceType": "Studio", + "port": null, + "endpoint": "https://ml.azure.com/runs/cctest-archive-job?wsid=/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourcegroups/test_machine-learning-job-archive/workspaces/cctest-mlws-archive", + "status": null, + "errorMessage": null, + "properties": null, + "nodes": null + } + }, + "computeId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/computes/cctestcpuarchive", + "isArchived": true, + "identity": null, + "componentId": null, + "jobType": "Command", + "resources": { + "instanceCount": 1, + "instanceType": null, + "properties": null, + "shmSize": "2g", + "dockerArgs": null + }, + "codeId": null, + "command": "echo hello", + "environmentId": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_machine-learning-job-archive/providers/Microsoft.MachineLearningServices/workspaces/cctest-mlws-archive/environments/cctest-archive-env/versions/1", + "inputs": {}, + "outputs": { + "default": { + "description": null, + "uri": "azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.cctest-archive-job", + "mode": "ReadWriteMount", + "jobOutputType": "uri_folder" + } + }, + "distribution": null, + "limits": null, + "environmentVariables": {}, + "parameters": {} + }, + "systemData": { + "createdAt": "2026-08-13T19:17:35.6842089+00:00", + "createdBy": "Jim Fulton", + "createdByType": "User" + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/tools/c7n_azure/tests_azure/cassettes/MachineLearningModelVersionTest.test_machine_learning_model_version_filter_archived.json b/tools/c7n_azure/tests_azure/cassettes/MachineLearningModelVersionTest.test_machine_learning_model_version_filter_archived.json new file mode 100644 index 00000000000..c78e4fa723a --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/MachineLearningModelVersionTest.test_machine_learning_model_version_filter_archived.json @@ -0,0 +1,129 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.MachineLearningServices/workspaces?api-version=2020-08-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-type": [ + "application/json; charset=utf-8" + ], + "cache-control": [ + "no-cache" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest", + "name": "mlvvtest", + "type": "Microsoft.MachineLearningServices/workspaces", + "location": "eastus", + "tags": {}, + "properties": { + "friendlyName": "mlvvtest", + "provisioningState": "Succeeded" + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-type": [ + "application/json; charset=utf-8" + ], + "cache-control": [ + "no-cache" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model", + "name": "cctest-model", + "type": "Microsoft.MachineLearningServices/workspaces/models", + "properties": { + "description": "Cloud Custodian test model", + "latestVersion": "2" + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model/versions?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-type": [ + "application/json; charset=utf-8" + ], + "cache-control": [ + "no-cache" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model/versions/1", + "name": "1", + "type": "Microsoft.MachineLearningServices/workspaces/models/versions", + "properties": { + "modelType": "CustomModel", + "modelUri": "azureml://locations/eastus/workspaces/mlvvtest/models/cctest-model/versions/1", + "isArchived": false + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model/versions/2", + "name": "2", + "type": "Microsoft.MachineLearningServices/workspaces/models/versions", + "properties": { + "modelType": "CustomModel", + "modelUri": "azureml://locations/eastus/workspaces/mlvvtest/models/cctest-model/versions/2", + "isArchived": true + } + } + ] + } + } + } + } + ] +} diff --git a/tools/c7n_azure/tests_azure/cassettes/MachineLearningModelVersionTest.test_machine_learning_model_version_query.json b/tools/c7n_azure/tests_azure/cassettes/MachineLearningModelVersionTest.test_machine_learning_model_version_query.json new file mode 100644 index 00000000000..c78e4fa723a --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/MachineLearningModelVersionTest.test_machine_learning_model_version_query.json @@ -0,0 +1,129 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.MachineLearningServices/workspaces?api-version=2020-08-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-type": [ + "application/json; charset=utf-8" + ], + "cache-control": [ + "no-cache" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest", + "name": "mlvvtest", + "type": "Microsoft.MachineLearningServices/workspaces", + "location": "eastus", + "tags": {}, + "properties": { + "friendlyName": "mlvvtest", + "provisioningState": "Succeeded" + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-type": [ + "application/json; charset=utf-8" + ], + "cache-control": [ + "no-cache" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model", + "name": "cctest-model", + "type": "Microsoft.MachineLearningServices/workspaces/models", + "properties": { + "description": "Cloud Custodian test model", + "latestVersion": "2" + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model/versions?api-version=2023-04-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "content-type": [ + "application/json; charset=utf-8" + ], + "cache-control": [ + "no-cache" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model/versions/1", + "name": "1", + "type": "Microsoft.MachineLearningServices/workspaces/models/versions", + "properties": { + "modelType": "CustomModel", + "modelUri": "azureml://locations/eastus/workspaces/mlvvtest/models/cctest-model/versions/1", + "isArchived": false + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/VV/providers/Microsoft.MachineLearningServices/workspaces/mlvvtest/models/cctest-model/versions/2", + "name": "2", + "type": "Microsoft.MachineLearningServices/workspaces/models/versions", + "properties": { + "modelType": "CustomModel", + "modelUri": "azureml://locations/eastus/workspaces/mlvvtest/models/cctest-model/versions/2", + "isArchived": true + } + } + ] + } + } + } + } + ] +} diff --git a/tools/c7n_azure/tests_azure/cassettes/PrivateDnsZoneTest.test_find_by_name.json b/tools/c7n_azure/tests_azure/cassettes/PrivateDnsZoneTest.test_find_by_name.json new file mode 100644 index 00000000000..c1305203eef --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/PrivateDnsZoneTest.test_find_by_name.json @@ -0,0 +1,82 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.Network/privateDnsZones?api-version=2024-06-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "date": [ + "Mon, 24 Aug 2026 17:59:02 GMT" + ], + "x-ms-original-request-ids": [ + "7cc5b210-9fe5-11f1-b82d-757a5d80cdc2" + ], + "cache-control": [ + "private" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-ms-ratelimit-remaining-subscription-resource-entities-read": [ + "60000" + ], + "x-ms-ratelimit-remaining-subscription-resource-requests": [ + "1099" + ], + "content-length": [ + "1441" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com", + "name": "c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com", + "type": "Microsoft.Network/privateDnsZones", + "etag": "b71cd59b-b276-489a-a4b0-fd65eab74b58", + "location": "global", + "properties": { + "internalId": "SW1tdXRhYmxlWm9uZUlkZW50aXR5OzIyNjU1OGZhLWMyMGYtNGNkMi1hYzdhLWI3MGY1YjYwYzk5NTsw", + "maxNumberOfRecordSets": 25000, + "maxNumberOfVirtualNetworkLinks": 1000, + "maxNumberOfVirtualNetworkLinksWithRegistration": 100, + "numberOfRecordSets": 1, + "numberOfVirtualNetworkLinks": 0, + "numberOfVirtualNetworkLinksWithRegistration": 0, + "provisioningState": "Succeeded" + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com", + "name": "c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com", + "type": "Microsoft.Network/privateDnsZones", + "etag": "fdb23da0-49d1-46f3-8a4f-f17870f67d30", + "location": "global", + "properties": { + "internalId": "SW1tdXRhYmxlWm9uZUlkZW50aXR5OzlhY2M0ZDViLWY0ZmItNDlhZC1hYzA4LWJlN2RmNzY0MTg0MTsw", + "maxNumberOfRecordSets": 25000, + "maxNumberOfVirtualNetworkLinks": 1000, + "maxNumberOfVirtualNetworkLinksWithRegistration": 100, + "numberOfRecordSets": 3, + "numberOfVirtualNetworkLinks": 0, + "numberOfVirtualNetworkLinksWithRegistration": 0, + "provisioningState": "Succeeded" + } + } + ] + } + } + } + } + ] +} \ No newline at end of file diff --git a/tools/c7n_azure/tests_azure/cassettes/PrivateRecordSetTest.test_find_by_name.json b/tools/c7n_azure/tests_azure/cassettes/PrivateRecordSetTest.test_find_by_name.json new file mode 100644 index 00000000000..159c3a14572 --- /dev/null +++ b/tools/c7n_azure/tests_azure/cassettes/PrivateRecordSetTest.test_find_by_name.json @@ -0,0 +1,237 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/providers/Microsoft.Network/privateDnsZones?api-version=2024-06-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "date": [ + "Mon, 24 Aug 2026 17:59:03 GMT" + ], + "x-ms-original-request-ids": [ + "7dc71cda-9fe5-11f1-b82d-757a5d80cdc2" + ], + "cache-control": [ + "private" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-ms-ratelimit-remaining-subscription-resource-entities-read": [ + "60000" + ], + "x-ms-ratelimit-remaining-subscription-resource-requests": [ + "1099" + ], + "content-length": [ + "1441" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com", + "name": "c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com", + "type": "Microsoft.Network/privateDnsZones", + "etag": "b71cd59b-b276-489a-a4b0-fd65eab74b58", + "location": "global", + "properties": { + "internalId": "SW1tdXRhYmxlWm9uZUlkZW50aXR5OzIyNjU1OGZhLWMyMGYtNGNkMi1hYzdhLWI3MGY1YjYwYzk5NTsw", + "maxNumberOfRecordSets": 25000, + "maxNumberOfVirtualNetworkLinks": 1000, + "maxNumberOfVirtualNetworkLinksWithRegistration": 100, + "numberOfRecordSets": 1, + "numberOfVirtualNetworkLinks": 0, + "numberOfVirtualNetworkLinksWithRegistration": 0, + "provisioningState": "Succeeded" + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com", + "name": "c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com", + "type": "Microsoft.Network/privateDnsZones", + "etag": "fdb23da0-49d1-46f3-8a4f-f17870f67d30", + "location": "global", + "properties": { + "internalId": "SW1tdXRhYmxlWm9uZUlkZW50aXR5OzlhY2M0ZDViLWY0ZmItNDlhZC1hYzA4LWJlN2RmNzY0MTg0MTsw", + "maxNumberOfRecordSets": 25000, + "maxNumberOfVirtualNetworkLinks": 1000, + "maxNumberOfVirtualNetworkLinksWithRegistration": 100, + "numberOfRecordSets": 3, + "numberOfVirtualNetworkLinks": 0, + "numberOfVirtualNetworkLinksWithRegistration": 0, + "provisioningState": "Succeeded" + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com/aLL?api-version=2024-06-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "date": [ + "Mon, 24 Aug 2026 17:59:04 GMT" + ], + "cache-control": [ + "private" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-ms-ratelimit-remaining-subscription-resource-entities-read": [ + "59999" + ], + "x-ms-ratelimit-remaining-subscription-resource-requests": [ + "1099" + ], + "content-length": [ + "602" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com/SOA/@", + "name": "@", + "type": "Microsoft.Network/privateDnsZones/SOA", + "etag": "f3ad410b-6e0d-42ea-a499-31160d0a86a6", + "properties": { + "fqdn": "c7n-other.neqbrvxs5rnvm.cloudcustodiantest.com.", + "ttl": 3600, + "soaRecord": { + "email": "azureprivatedns-host.microsoft.com", + "expireTime": 2419200, + "host": "azureprivatedns.net", + "minimumTtl": 10, + "refreshTime": 3600, + "retryTime": 300, + "serialNumber": 1 + }, + "isAutoRegistered": false + } + } + ] + } + } + } + }, + { + "request": { + "method": "GET", + "uri": "https://management.azure.com/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com/aLL?api-version=2024-06-01", + "body": null, + "headers": {} + }, + "response": { + "status": { + "code": 200, + "message": "OK" + }, + "headers": { + "date": [ + "Mon, 24 Aug 2026 17:59:04 GMT" + ], + "cache-control": [ + "private" + ], + "content-type": [ + "application/json; charset=utf-8" + ], + "x-ms-ratelimit-remaining-subscription-resource-entities-read": [ + "59997" + ], + "x-ms-ratelimit-remaining-subscription-resource-requests": [ + "1099" + ], + "content-length": [ + "1542" + ] + }, + "body": { + "data": { + "value": [ + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com/SOA/@", + "name": "@", + "type": "Microsoft.Network/privateDnsZones/SOA", + "etag": "02aa2346-72a4-4fcb-9cd0-2b0a3e150289", + "properties": { + "fqdn": "c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com.", + "ttl": 3600, + "soaRecord": { + "email": "azureprivatedns-host.microsoft.com", + "expireTime": 2419200, + "host": "azureprivatedns.net", + "minimumTtl": 10, + "refreshTime": 3600, + "retryTime": 300, + "serialNumber": 1 + }, + "isAutoRegistered": false + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com/A/other", + "name": "other", + "type": "Microsoft.Network/privateDnsZones/A", + "etag": "138b383b-4cdd-47ca-ad35-5fa004f48b4e", + "properties": { + "fqdn": "other.c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com.", + "ttl": 3600, + "aRecords": [ + { + "ipv4Address": "1.2.3.6" + } + ], + "isAutoRegistered": false + } + }, + { + "id": "/subscriptions/ea42f556-5106-4743-99b0-c129bfa71a47/resourceGroups/test_private-dns/providers/Microsoft.Network/privateDnsZones/c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com/A/www", + "name": "www", + "type": "Microsoft.Network/privateDnsZones/A", + "etag": "8f22ef90-0d8f-4168-a1a7-2200170dd2b2", + "properties": { + "fqdn": "www.c7n-test.neqbrvxs5rnvm.cloudcustodiantest.com.", + "ttl": 3600, + "aRecords": [ + { + "ipv4Address": "1.2.3.4" + }, + { + "ipv4Address": "1.2.3.5" + } + ], + "isAutoRegistered": false + } + } + ] + } + } + } + } + ] +} \ No newline at end of file diff --git a/tools/c7n_azure/tests_azure/templates/budget.json b/tools/c7n_azure/tests_azure/templates/budget.json new file mode 100644 index 00000000000..6605b19a6e1 --- /dev/null +++ b/tools/c7n_azure/tests_azure/templates/budget.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "budgetStartDate": { + "type": "string", + "defaultValue": "[utcNow('yyyy-MM-01T00:00:00Z')]" + } + }, + "variables": { + "budgetEndDate": "[dateTimeAdd(parameters('budgetStartDate'), 'P10Y')]" + }, + "resources": [ + { + "type": "Microsoft.Consumption/budgets", + "apiVersion": "2023-05-01", + "name": "budget_1000", + "properties": { + "category": "Cost", + "amount": 1000, + "timeGrain": "Monthly", + "timePeriod": { + "startDate": "[parameters('budgetStartDate')]", + "endDate": "[variables('budgetEndDate')]" + }, + "notifications": { + "actual_gte_90": { + "enabled": false, + "operator": "EqualTo", + "threshold": 90, + "contactEmails": [ + "test@example.com" + ], + "thresholdType": "Actual" + } + } + } + }, + { + "type": "Microsoft.Consumption/budgets", + "apiVersion": "2023-05-01", + "name": "budget_1001", + "properties": { + "category": "Cost", + "amount": 1001, + "timeGrain": "Monthly", + "timePeriod": { + "startDate": "[parameters('budgetStartDate')]", + "endDate": "[variables('budgetEndDate')]" + }, + "notifications": { + "actual_gte_90": { + "enabled": false, + "operator": "EqualTo", + "threshold": 90, + "contactEmails": [ + "test@example.com" + ], + "thresholdType": "Actual" + } + } + } + } + ] +} diff --git a/tools/c7n_azure/tests_azure/templates/cleanup.sh b/tools/c7n_azure/tests_azure/templates/cleanup.sh index a1ab6b27b77..7c0243325a6 100755 --- a/tools/c7n_azure/tests_azure/templates/cleanup.sh +++ b/tools/c7n_azure/tests_azure/templates/cleanup.sh @@ -35,6 +35,12 @@ delete_resource() { token=$(az account get-access-token --query accessToken --output tsv) url=https://management.azure.com/subscriptions/${AZURE_SUBSCRIPTION_ID}/providers/Microsoft.CostManagement/exports/cccostexport?api-version=2019-01-01 curl -X DELETE -H "Authorization: Bearer ${token}" ${url} + elif [[ "$fileName" == "budget.json" ]]; then + token=$(az account get-access-token --query accessToken --output tsv) + budget_base_url=https://management.azure.com/subscriptions/${AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Consumption/budgets + curl -X DELETE -H "Authorization: Bearer ${token}" "${budget_base_url}/budget_1000?api-version=2023-05-01" + curl -X DELETE -H "Authorization: Bearer ${token}" "${budget_base_url}/budget_1001?api-version=2023-05-01" + az deployment sub delete --name cctest-budget --output None elif [[ "$fileName" == "cognitive-service-deployment.json" ]]; then account_name="${AZURE_OPENAI_ACCOUNT_NAME}" if [[ -z "${account_name}" ]]; then diff --git a/tools/c7n_azure/tests_azure/templates/machine-learning-job-archive.json b/tools/c7n_azure/tests_azure/templates/machine-learning-job-archive.json new file mode 100644 index 00000000000..9b82362c6cd --- /dev/null +++ b/tools/c7n_azure/tests_azure/templates/machine-learning-job-archive.json @@ -0,0 +1,139 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "uniqueId": { + "type": "string" + } + }, + "variables": { + "storageAccountName": "[concat('cctestmlws', parameters('uniqueId'))]", + "keyVaultName": "[concat('cctestmlws', parameters('uniqueId'))]", + "appInsightsName": "[concat('cctestmlws', parameters('uniqueId'))]", + "workspaceName": "cctest-mlws-archive", + "computeName": "cctestcpuarchive", + "environmentName": "cctest-archive-env", + "jobName": "cctest-archive-job" + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-01-01", + "name": "[variables('storageAccountName')]", + "location": "[resourceGroup().location]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2", + "properties": { + "minimumTlsVersion": "TLS1_2", + "allowBlobPublicAccess": false + } + }, + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "name": "[variables('keyVaultName')]", + "location": "[resourceGroup().location]", + "properties": { + "tenantId": "[subscription().tenantId]", + "sku": { + "family": "A", + "name": "standard" + }, + "accessPolicies": [] + } + }, + { + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[variables('appInsightsName')]", + "location": "[resourceGroup().location]", + "kind": "web", + "properties": { + "Application_Type": "web" + } + }, + { + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2023-04-01", + "name": "[variables('workspaceName')]", + "location": "[resourceGroup().location]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "friendlyName": "[variables('workspaceName')]", + "storageAccount": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]", + "keyVault": "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]", + "applicationInsights": "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]", + "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]", + "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces/computes", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', variables('workspaceName'), variables('computeName'))]", + "location": "[resourceGroup().location]", + "properties": { + "computeLocation": "[resourceGroup().location]", + "computeType": "AmlCompute", + "disableLocalAuth": true, + "properties": { + "enableNodePublicIp": true, + "osType": "Linux", + "remoteLoginPortPublicAccess": "Enabled", + "scaleSettings": { + "maxNodeCount": 1, + "minNodeCount": 0, + "nodeIdleTimeBeforeScaleDown": "PT2M" + }, + "vmPriority": "Dedicated", + "vmSize": "Standard_DS3_v2" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', variables('workspaceName'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces/environments/versions", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/1', variables('workspaceName'), variables('environmentName'))]", + "properties": { + "environmentType": "UserCreated", + "image": "mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04", + "isArchived": false, + "osType": "Linux", + "properties": { + "azureml.labels": "latest" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', variables('workspaceName'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces/jobs", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', variables('workspaceName'), variables('jobName'))]", + "properties": { + "command": "echo hello", + "computeId": "[resourceId('Microsoft.MachineLearningServices/workspaces/computes', variables('workspaceName'), variables('computeName'))]", + "displayName": "cctest_archive_job", + "environmentId": "[resourceId('Microsoft.MachineLearningServices/workspaces/environments/versions', variables('workspaceName'), variables('environmentName'), '1')]", + "experimentName": "cctest_archive", + "isArchived": false, + "jobType": "Command" + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces/computes', variables('workspaceName'), variables('computeName'))]", + "[resourceId('Microsoft.MachineLearningServices/workspaces/environments/versions', variables('workspaceName'), variables('environmentName'), '1')]" + ] + } + ] +} diff --git a/tools/c7n_azure/tests_azure/templates/machine-learning-model-version.json b/tools/c7n_azure/tests_azure/templates/machine-learning-model-version.json new file mode 100644 index 00000000000..0d5cb542ea3 --- /dev/null +++ b/tools/c7n_azure/tests_azure/templates/machine-learning-model-version.json @@ -0,0 +1,99 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "uniqueId": { + "type": "string" + }, + "workspaceName": { + "type": "string", + "defaultValue": "cctestmlworkspace" + }, + "modelName": { + "type": "string", + "defaultValue": "cctest-model" + }, + "modelVersion": { + "type": "string", + "defaultValue": "1" + }, + "archivedModelVersion": { + "type": "string", + "defaultValue": "2" + } + }, + "variables": { + "workspaceName": "[concat(parameters('workspaceName'), parameters('uniqueId'))]", + "storageAccountName": "[concat('cctestml', parameters('uniqueId'))]", + "keyVaultName": "[concat('cctestmlkv', parameters('uniqueId'))]" + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-09-01", + "name": "[variables('storageAccountName')]", + "location": "eastus", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2" + }, + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2021-10-01", + "name": "[variables('keyVaultName')]", + "location": "eastus", + "properties": { + "tenantId": "[subscription().tenantId]", + "sku": { + "family": "A", + "name": "standard" + }, + "accessPolicies": [] + } + }, + { + "type": "Microsoft.MachineLearningServices/workspaces", + "apiVersion": "2023-04-01", + "name": "[variables('workspaceName')]", + "location": "eastus", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "storageAccount": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]", + "keyVault": "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]", + "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces/models/versions", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/{2}', variables('workspaceName'), parameters('modelName'), parameters('modelVersion'))]", + "properties": { + "modelUri": "azureml://subscriptions/{sub}/resourceGroups/{rg}/workspaces/{ws}/datastores/workspaceblobstore/paths/model.pkl", + "modelType": "CustomModel", + "isArchived": false + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', variables('workspaceName'))]" + ] + }, + { + "type": "Microsoft.MachineLearningServices/workspaces/models/versions", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}/{2}', variables('workspaceName'), parameters('modelName'), parameters('archivedModelVersion'))]", + "properties": { + "modelUri": "azureml://subscriptions/{sub}/resourceGroups/{rg}/workspaces/{ws}/datastores/workspaceblobstore/paths/model.pkl", + "modelType": "CustomModel", + "isArchived": true + }, + "dependsOn": [ + "[resourceId('Microsoft.MachineLearningServices/workspaces', variables('workspaceName'))]" + ] + } + ] +} diff --git a/tools/c7n_azure/tests_azure/templates/private-dns.json b/tools/c7n_azure/tests_azure/templates/private-dns.json new file mode 100644 index 00000000000..a4eefe0d45c --- /dev/null +++ b/tools/c7n_azure/tests_azure/templates/private-dns.json @@ -0,0 +1,73 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "privateDnsZoneName": { + "type": "string", + "defaultValue": "[concat('c7n-test.', uniqueString(resourceGroup().id), '.cloudcustodiantest.com')]" + }, + "otherPrivateDnsZoneName": { + "type": "string", + "defaultValue": "[concat('c7n-other.', uniqueString(resourceGroup().id), '.cloudcustodiantest.com')]" + }, + "wwwRecordName": { + "type": "string", + "defaultValue": "www" + }, + "otherRecordName": { + "type": "string", + "defaultValue": "other" + } + }, + "resources": [ + { + "type": "Microsoft.Network/privateDnsZones", + "name": "[parameters('privateDnsZoneName')]", + "apiVersion": "2018-09-01", + "location": "global", + "properties": {} + }, + { + "type": "Microsoft.Network/privateDnsZones", + "name": "[parameters('otherPrivateDnsZoneName')]", + "apiVersion": "2018-09-01", + "location": "global", + "properties": {} + }, + { + "type": "Microsoft.Network/privateDnsZones/A", + "name": "[concat(parameters('privateDnsZoneName'), '/', parameters('wwwRecordName'))]", + "apiVersion": "2018-09-01", + "dependsOn": [ + "[parameters('privateDnsZoneName')]" + ], + "properties": { + "ttl": 3600, + "aRecords": [ + { + "ipv4Address": "1.2.3.4" + }, + { + "ipv4Address": "1.2.3.5" + } + ] + } + }, + { + "type": "Microsoft.Network/privateDnsZones/A", + "name": "[concat(parameters('privateDnsZoneName'), '/', parameters('otherRecordName'))]", + "apiVersion": "2018-09-01", + "dependsOn": [ + "[parameters('privateDnsZoneName')]" + ], + "properties": { + "ttl": 3600, + "aRecords": [ + { + "ipv4Address": "1.2.3.6" + } + ] + } + } + ] +} diff --git a/tools/c7n_azure/tests_azure/templates/provision.sh b/tools/c7n_azure/tests_azure/templates/provision.sh index 129addf1c54..2c06ae39df3 100755 --- a/tools/c7n_azure/tests_azure/templates/provision.sh +++ b/tools/c7n_azure/tests_azure/templates/provision.sh @@ -294,6 +294,10 @@ deploy_resource() { rm -f cost-management.body + elif [[ "$fileName" == "budget.json" ]]; then + + az deployment sub create --location $resourceLocation --name cctest-budget \ + --template-file $file --output None elif [[ "$fileName" == "ai-foundry-application.json" ]]; then unique_suffix="$(date +%s%N | tail -c 13)" diff --git a/tools/c7n_azure/tests_azure/test_actions_tag.py b/tools/c7n_azure/tests_azure/test_actions_tag.py index 8ddbd51de49..d38893ed42d 100644 --- a/tools/c7n_azure/tests_azure/test_actions_tag.py +++ b/tools/c7n_azure/tests_azure/test_actions_tag.py @@ -195,58 +195,162 @@ def test_add_or_update_tags(self, update_resource_tags): self.assertEqual(tags, expected_tags) + +class ActionsTagMappingLookupTest(BaseTest): + """Resource lookups used as values inside the ``tags`` mapping.""" + + existing_tags = {'pre-existing-1': 'unmodified', 'pre-existing-2': 'unmodified'} + + def _get_action(self, data): + # build through a real policy so the action is registry-registered and + # the mapping is run through schema validation on the way in + policy = self.load_policy( + tools.get_policy([dict(data, type='tag')]), validate=True) + return policy.resource_manager.actions[0] + @patch('c7n_azure.tags.TagHelper.update_resource_tags') - def test_add_or_update_tags_from_resource(self, update_resource_tags): - """Verifies values in the tags dictionary are resolved from the resource - rather than passed through as the raw lookup directive - """ + def test_mapping_lookup_by_key_resolves(self, update_resource_tags): + action = self._get_action({ + 'tags': {'from_name': {'type': 'resource', 'key': 'name'}}}) + resource = tools.get_resource(self.existing_tags) - action = self._get_action( - { - 'tags': { - 'tag1': 'value1', - 'tag2': { - 'type': 'resource', - 'key': 'name' - } - } - }) + action.process([resource]) + + expected_tags = self.existing_tags.copy() + expected_tags.update({'from_name': resource['name']}) + self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags) + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_mapping_lookup_miss_uses_default_value(self, update_resource_tags): + action = self._get_action({ + 'tags': {'env': {'type': 'resource', + 'key': 'doesnotexist', + 'default-value': 'production'}}}) resource = tools.get_resource(self.existing_tags) action.process([resource]) - tags = tools.get_tags_parameter(update_resource_tags) + expected_tags = self.existing_tags.copy() + expected_tags.update({'env': 'production'}) + self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags) + + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_mapping_lookup_preserves_existing_tag_value(self, update_resource_tags): + """key pointing at an existing tag keeps that tag's current value. + + A second, changing tag forces the write so the preserved value is + visible in the payload. + """ + action = self._get_action({ + 'tags': {'pre-existing-1': {'type': 'resource', + 'key': 'tags."pre-existing-1"', + 'default-value': 'fallback'}, + 'new': 'added'}}) + resource = tools.get_resource(self.existing_tags) + + action.process([resource]) expected_tags = self.existing_tags.copy() - expected_tags.update({'tag1': 'value1', 'tag2': resource['name']}) + expected_tags.update({'new': 'added'}) + self.assertEqual( + tools.get_tags_parameter(update_resource_tags), expected_tags) - self.assertEqual(tags, expected_tags) + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_no_write_when_lookup_resolves_to_current_value(self, update_resource_tags): + """Resolving a tag to the value it already has is a no-op.""" + action = self._get_action({ + 'tags': {'pre-existing-1': {'type': 'resource', + 'key': 'tags."pre-existing-1"', + 'default-value': 'fallback'}}}) + resource = tools.get_resource(self.existing_tags) + + action.process([resource]) + + update_resource_tags.assert_not_called() @patch('c7n_azure.tags.TagHelper.update_resource_tags') - def test_add_or_update_tags_from_resource_default(self, update_resource_tags): - """Verifies values in the tags dictionary fall back to default-value - when the looked up key does not exist on the resource - """ + def test_mapping_mixes_static_and_lookup_values(self, update_resource_tags): + action = self._get_action({ + 'tags': {'static': 'plain', + 'dynamic': {'type': 'resource', 'key': 'name'}}}) + resource = tools.get_resource(self.existing_tags) - action = self._get_action( - { - 'tags': { - 'tag1': { - 'type': 'resource', - 'key': 'doesnotexist', - 'default-value': 'default_value' - } - } - }) + action.process([resource]) + + expected_tags = self.existing_tags.copy() + expected_tags.update({'static': 'plain', 'dynamic': resource['name']}) + self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags) + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_conditional_default_writes_when_tag_absent(self, update_resource_tags): + action = self._get_action({ + 'tags': {'owner': {'type': 'resource', 'default-value': 'platform'}}}) resource = tools.get_resource(self.existing_tags) action.process([resource]) - tags = tools.get_tags_parameter(update_resource_tags) + expected_tags = self.existing_tags.copy() + expected_tags.update({'owner': 'platform'}) + self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags) + + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_conditional_default_skipped_when_tag_present(self, update_resource_tags): + action = self._get_action({ + 'tags': {'pre-existing-1': {'type': 'resource', + 'default-value': 'should-not-be-written'}}}) + resource = tools.get_resource(self.existing_tags) + + action.process([resource]) + + # nothing left to write, so no update call is made at all + update_resource_tags.assert_not_called() + + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_conditional_default_partial_skip(self, update_resource_tags): + action = self._get_action({ + 'tags': {'pre-existing-1': {'type': 'resource', 'default-value': 'skipped'}, + 'owner': {'type': 'resource', 'default-value': 'platform'}}}) + resource = tools.get_resource(self.existing_tags) + + action.process([resource]) expected_tags = self.existing_tags.copy() - expected_tags.update({'tag1': 'default_value'}) + expected_tags.update({'owner': 'platform'}) + self.assertEqual(tools.get_tags_parameter(update_resource_tags), expected_tags) - self.assertEqual(tags, expected_tags) + @patch('c7n_azure.tags.TagHelper.update_resource_tags') + def test_lookup_resolved_per_resource(self, update_resource_tags): + """Two resources with different values each get their own tag value.""" + action = self._get_action({ + 'tags': {'from_name': {'type': 'resource', 'key': 'name'}}}) + first = tools.get_resource({}) + second = tools.get_resource({}) + second['name'] = 'other-vm' + + action.process([first, second]) + + written = [c[0][2]['from_name'] for c in update_resource_tags.call_args_list] + self.assertEqual(written, ['cctestvm', 'other-vm']) + + def test_schema_accepts_lookup_forms_in_mapping(self): + self.assertTrue(self.load_policy( + tools.get_policy([ + {'type': 'tag', + 'tags': { + 'by_key': {'type': 'resource', 'key': 'name'}, + 'by_key_default': {'type': 'resource', + 'key': 'name', + 'default-value': 'dv'}, + 'conditional': {'type': 'resource', 'default-value': 'dv'}, + 'static': 'plain'}} + ]), validate=True)) + + def test_schema_rejects_malformed_mapping_values(self): + for bad in ({'type': 'resource'}, + {'type': 'resource', 'ky': 'name'}, + {'foo': 'bar'}, + ['a']): + with self.assertRaises(Exception): + self.load_policy( + tools.get_policy([{'type': 'tag', 'tags': {'X': bad}}]), + validate=True) diff --git a/tools/c7n_azure/tests_azure/test_function_package.py b/tools/c7n_azure/tests_azure/test_function_package.py index 47a4128f367..097efa69751 100644 --- a/tools/c7n_azure/tests_azure/test_function_package.py +++ b/tools/c7n_azure/tests_azure/test_function_package.py @@ -5,7 +5,6 @@ import time import zipfile -from azure.mgmt.web.models import User from c7n_azure.constants import ENV_CUSTODIAN_DISABLE_SSL_CERT_VERIFICATION, \ FUNCTION_TIME_TRIGGER_MODE, FUNCTION_EVENT_TRIGGER_MODE from c7n_azure.function_package import FunctionPackage, AzurePythonPackageArchive @@ -173,19 +172,65 @@ def test_publish(self, post_mock): post_mock.return_value = status_mock packer = FunctionPackage('test') packer.pkg = AzurePythonPackageArchive() - creds = User(publishing_user_name='user', - publishing_password='password', - scm_uri='https://uri') - packer.publish(creds) + packer.publish('https://testapp.scm.azurewebsites.net', 'test-bearer-token') post_mock.assert_called_once() status_mock.raise_for_status.assert_called_once() self.assertEqual(post_mock.call_args[0][0], - 'https://uri/api/zipdeploy?isAsync=true&synctriggers=true') + 'https://testapp.scm.azurewebsites.net' + '/api/zipdeploy?isAsync=true&synctriggers=true') self.assertEqual(post_mock.call_args[1]['headers']['content-type'], 'application/octet-stream') + self.assertEqual(post_mock.call_args[1]['headers']['Authorization'], + 'Bearer test-bearer-token') + + @patch('requests.get') + def test_status(self, get_mock): + get_mock.return_value = MagicMock(status_code=200) + packer = FunctionPackage('test') + + result = packer.status('https://testapp.scm.azurewebsites.net', 'test-bearer-token') + + self.assertTrue(result) + get_mock.assert_called_once() + self.assertEqual(get_mock.call_args[0][0], + 'https://testapp.scm.azurewebsites.net/api/deployments') + self.assertEqual(get_mock.call_args[1]['headers']['Authorization'], + 'Bearer test-bearer-token') + + @patch('requests.get') + def test_status_unhealthy(self, get_mock): + get_mock.return_value = MagicMock(status_code=503) + packer = FunctionPackage('test') + + result = packer.status('https://testapp.scm.azurewebsites.net', 'test-bearer-token') + + self.assertFalse(result) + + @patch('time.sleep') + @patch('requests.get') + def test_wait_for_status_success(self, get_mock, _sleep): + get_mock.return_value = MagicMock(status_code=200) + packer = FunctionPackage('test') + + result = packer.wait_for_status('https://testapp.scm.azurewebsites.net', 'test-token') + + self.assertTrue(result) + get_mock.assert_called_once() + + @patch('time.sleep') + @patch('requests.get') + def test_wait_for_status_exhausted(self, get_mock, _sleep): + get_mock.return_value = MagicMock(status_code=503) + packer = FunctionPackage('test') + + result = packer.wait_for_status( + 'https://testapp.scm.azurewebsites.net', 'test-token', retries=3, delay=0) + + self.assertFalse(result) + self.assertEqual(get_mock.call_count, 3) def test_env_var_disables_cert_validation(self): p = self.load_policy({ diff --git a/tools/c7n_azure/tests_azure/tests_resources/terraform/budget/main.tf b/tools/c7n_azure/tests_azure/tests_resources/terraform/budget/main.tf new file mode 100644 index 00000000000..fc9dec94db8 --- /dev/null +++ b/tools/c7n_azure/tests_azure/tests_resources/terraform/budget/main.tf @@ -0,0 +1,52 @@ +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "current" {} + +resource "azurerm_consumption_budget_subscription" "budget_1000" { + name = "budget_1000" + subscription_id = data.azurerm_subscription.current.id + + amount = 1000 + time_grain = "Monthly" + + time_period { + start_date = local.first_of_month + } + + notification { + enabled = false + threshold = 90.0 + operator = "EqualTo" + contact_emails = ["test@example.com"] + } +} + +resource "azurerm_consumption_budget_subscription" "budget_1001" { + name = "budget_1001" + subscription_id = data.azurerm_subscription.current.id + + amount = 1001 + time_grain = "Monthly" + + time_period { + start_date = local.first_of_month + } + + notification { + enabled = false + threshold = 90.0 + operator = "EqualTo" + contact_emails = ["test@example.com"] + } +} + +locals { + today = timestamp() + current_year = formatdate("YYYY", local.today) + current_month = formatdate("MM", local.today) + first_of_month = "${local.current_year}-${local.current_month}-01T00:00:00Z" +} + + diff --git a/tools/c7n_azure/tests_azure/tests_resources/terraform/budget/tf_resources.json b/tools/c7n_azure/tests_azure/tests_resources/terraform/budget/tf_resources.json new file mode 100644 index 00000000000..62bcb5d2c27 --- /dev/null +++ b/tools/c7n_azure/tests_azure/tests_resources/terraform/budget/tf_resources.json @@ -0,0 +1,80 @@ +{ + "pytest-terraform": 1, + "outputs": {}, + "resources": { + "azurerm_subscription": { + "current": { + "display_name": "Stacklet Dev 2", + "id": "/subscriptions/00000000-0000-0000-0000-000000000000", + "location_placement_id": "Public_2014-09-01", + "quota_id": "PayAsYouGo_2014-09-01", + "spending_limit": "Off", + "state": "Enabled", + "subscription_id": "00000000-0000-0000-0000-000000000000", + "tags": {}, + "tenant_id": "00000000-0000-0000-0000-000000000000", + "timeouts": null + } + }, + "azurerm_consumption_budget_subscription": { + "budget_1000": { + "amount": 1000, + "etag": "\"1dc80c867735072\"", + "filter": [], + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Consumption/budgets/budget_1000", + "name": "budget_1000", + "notification": [ + { + "contact_emails": [ + "test@example.com" + ], + "contact_groups": [], + "contact_roles": [], + "enabled": false, + "operator": "EqualTo", + "threshold": 90, + "threshold_type": "Actual" + } + ], + "subscription_id": "/subscriptions/00000000-0000-0000-0000-000000000000", + "time_grain": "Monthly", + "time_period": [ + { + "end_date": "2036-01-01T00:00:00Z", + "start_date": "2026-01-01T00:00:00Z" + } + ], + "timeouts": null + }, + "budget_1001": { + "amount": 1001, + "etag": "\"1dc80c8679dd2f7\"", + "filter": [], + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Consumption/budgets/budget_1001", + "name": "budget_1001", + "notification": [ + { + "contact_emails": [ + "test@example.com" + ], + "contact_groups": [], + "contact_roles": [], + "enabled": false, + "operator": "EqualTo", + "threshold": 90, + "threshold_type": "Actual" + } + ], + "subscription_id": "/subscriptions/00000000-0000-0000-0000-000000000000", + "time_grain": "Monthly", + "time_period": [ + { + "end_date": "2036-01-01T00:00:00Z", + "start_date": "2026-01-01T00:00:00Z" + } + ], + "timeouts": null + } + } + } +} \ No newline at end of file diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_budget.py b/tools/c7n_azure/tests_azure/tests_resources/test_budget.py new file mode 100644 index 00000000000..1644e05d43c --- /dev/null +++ b/tools/c7n_azure/tests_azure/tests_resources/test_budget.py @@ -0,0 +1,44 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 +from ..azure_common import BaseTest, arm_template, cassette_name + + +class BudgetTest(BaseTest): + + def test_budget_schema_validate(self): + with self.sign_out_patch(): + p = self.load_policy({ + 'name': 'test-azure-budget', + 'resource': 'azure.budget', + 'filters': [ + { + 'type': 'value', + 'key': 'properties.amount', + 'op': 'greater-than', + 'value': 1000, + } + ] + }, validate=True) + self.assertTrue(p) + + @arm_template('budget.json') + @cassette_name('common') + def test_find_by_amount(self): + p = self.load_policy({ + 'name': 'test-azure-budget', + 'resource': 'azure.budget', + 'filters': [ + { + 'type': 'value', + 'key': 'properties.amount', + 'op': 'greater-than', + 'value': 1000, + } + ] + }) + resources = p.run() + self.assertEqual(len(resources), 1) + self.assertEqual(resources[0]['name'], 'budget_1001') + # Instead of actually generating cost, it's easiest to update currentSpend in the cassette + # directly. (123.56 / 1001 ~= 12.333) + self.assertEqual(round(resources[0]['c7n:percent-used'], 3), 12.333) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_job.py b/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_job.py index 62f03600b6c..8786bdcc3a8 100644 --- a/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_job.py +++ b/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_job.py @@ -1,8 +1,15 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +from c7n.utils import local_session +from c7n_azure.query import _serialize +from c7n_azure.resources.machine_learning_job import ( + MachineLearningJob, + MachineLearningJobArchiveAction, +) +from c7n_azure.session import Session +from c7n_azure.utils import ResourceIdParser from ..azure_common import BaseTest, arm_template, cassette_name -from c7n_azure.resources.machine_learning_job import MachineLearningJob class MachineLearningJobTest(BaseTest): @@ -14,6 +21,13 @@ def test_machine_learning_job_schema_validate(self): }, validate=True) self.assertTrue(p) + p = self.load_policy({ + 'name': 'archive-machine-learning-jobs', + 'resource': 'azure.machine-learning-job', + 'actions': [{'type': 'archive'}], + }, validate=True) + self.assertTrue(p) + for action in ('tag', 'untag', 'auto-tag-user', 'auto-tag-date', 'tag-trim', 'mark-for-op'): self.assertNotIn(action, MachineLearningJob.action_registry) @@ -52,3 +66,65 @@ def test_machine_learning_job_filter_sweep_parallelism(self): resources = p.run() self.assertEqual(1, len(resources)) self.assertEqual('cctest-sweep-job', resources[0]['name']) + + @arm_template('machine-learning-job-archive.json') + @cassette_name('machine-learning-job-archive') + def test_machine_learning_job_archive(self): + p = self.load_policy({ + 'name': 'archive-machine-learning-job', + 'resource': 'azure.machine-learning-job', + 'filters': [{ + 'type': 'value', + 'key': 'resourceGroup', + 'value': 'test_machine-learning-job-archive', + }, { + 'type': 'value', + 'key': 'name', + 'value': 'cctest-archive-job', + }, { + 'type': 'value', + 'key': 'properties.status', + 'value': 'Completed', + }, { + 'type': 'value', + 'key': 'properties.isArchived', + 'op': 'ne', + 'value': True, + }], + 'actions': [{'type': 'archive'}], + }, validate=True, session_factory=Session) + + resources = p.run() + self.assertEqual(1, len(resources)) + + client = local_session(Session).client( + 'azure.mgmt.machinelearningservices.MachineLearningServicesMgmtClient') + job = client.jobs.get( + ResourceIdParser.get_resource_group(resources[0]['id']), + ResourceIdParser.get_resource_name(resources[0]['c7n:parent-id']), + resources[0]['name'], + ) + self.assertTrue(job.properties.is_archived) + + @arm_template('machine-learning-job-archive.json') + @cassette_name('machine-learning-job-archive-skip') + def test_machine_learning_job_archive_skips_archived_job(self): + p = self.load_policy({ + 'name': 'archive-machine-learning-job', + 'resource': 'azure.machine-learning-job', + 'actions': [{'type': 'archive'}], + }, validate=True, session_factory=Session) + client = local_session(Session).client( + 'azure.mgmt.machinelearningservices.MachineLearningServicesMgmtClient') + job = client.jobs.get( + 'test_machine-learning-job-archive', + 'cctest-mlws-archive', + 'cctest-archive-job', + ) + resource = _serialize(job) + + self.assertTrue(resource['properties']['isArchived']) + action = MachineLearningJobArchiveAction({'type': 'archive'}, p.resource_manager) + action._prepare_processing() + + self.assertEqual('already archived', action._process_resource(resource)) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_model_version.py b/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_model_version.py new file mode 100644 index 00000000000..2618b9f4f76 --- /dev/null +++ b/tools/c7n_azure/tests_azure/tests_resources/test_machine_learning_model_version.py @@ -0,0 +1,41 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from ..azure_common import BaseTest, arm_template + + +class MachineLearningModelVersionTest(BaseTest): + + def test_machine_learning_model_version_schema_validate(self): + with self.sign_out_patch(): + p = self.load_policy({ + 'name': 'find-all-machine-learning-model-versions', + 'resource': 'azure.machine-learning-model-version' + }, validate=True) + self.assertTrue(p) + + @arm_template('machine-learning-model-version.json') + def test_machine_learning_model_version_query(self): + p = self.load_policy({ + 'name': 'find-all-machine-learning-model-versions', + 'resource': 'azure.machine-learning-model-version', + }) + resources = p.run() + self.assertEqual(2, len(resources)) + self.assertTrue(all('/models/cctest-model/versions/' in r['id'] for r in resources)) + self.assertTrue(all('c7n:parent-id' in r for r in resources)) + + @arm_template('machine-learning-model-version.json') + def test_machine_learning_model_version_filter_archived(self): + p = self.load_policy({ + 'name': 'find-archived-model-versions', + 'resource': 'azure.machine-learning-model-version', + 'filters': [{ + 'type': 'value', + 'key': 'properties.isArchived', + 'value': True + }], + }) + resources = p.run() + self.assertEqual(1, len(resources)) + self.assertEqual('2', resources[0]['name']) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_private_dns_zone.py b/tools/c7n_azure/tests_azure/tests_resources/test_private_dns_zone.py new file mode 100644 index 00000000000..df5aad28acc --- /dev/null +++ b/tools/c7n_azure/tests_azure/tests_resources/test_private_dns_zone.py @@ -0,0 +1,34 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from ..azure_common import BaseTest, arm_template + + +class PrivateDnsZoneTest(BaseTest): + + def test_private_dns_zone_schema_validate(self): + with self.sign_out_patch(): + p = self.load_policy({ + 'name': 'azure-private-dns-zone-policy', + 'resource': 'azure.private-dns-zone' + }, validate=True) + self.assertTrue(p) + + @arm_template('private-dns.json') + def test_find_by_name(self): + p = self.load_policy({ + 'name': 'test-find-by-name', + 'resource': 'azure.private-dns-zone', + 'filters': [ + { + 'type': 'value', + 'key': 'name', + 'op': 'regex', + 'value': '^c7n-test\\..*\\.cloudcustodiantest\\.com$' + } + ] + }) + + resources = p.run() + self.assertEqual(len(resources), 1) + self.assertTrue(resources[0]['name'].startswith('c7n-test.')) diff --git a/tools/c7n_azure/tests_azure/tests_resources/test_private_record_set.py b/tools/c7n_azure/tests_azure/tests_resources/test_private_record_set.py new file mode 100644 index 00000000000..87188e9b6b8 --- /dev/null +++ b/tools/c7n_azure/tests_azure/tests_resources/test_private_record_set.py @@ -0,0 +1,61 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from ..azure_common import BaseTest, arm_template, cassette_name +from c7n_azure.query import ChildTypeInfo +from c7n_azure.resources.private_record_set import PrivateRecordSet +from c7n_azure.utils import ResourceIdParser + + +class PrivateRecordSetTest(BaseTest): + + def test_private_record_set_schema_validate(self): + with self.sign_out_patch(): + p = self.load_policy({ + 'name': 'azure-private-record-set-policy', + 'resource': 'azure.private-record-set' + }, validate=True) + self.assertTrue(p) + + # Record sets carry metadata rather than tags, so the ARM tagging + # actions must not be registered. + for action in ('tag', 'untag', 'auto-tag-user', 'auto-tag-date', + 'tag-trim', 'mark-for-op'): + self.assertNotIn(action, PrivateRecordSet.action_registry) + self.assertNotIn('marked-for-op', PrivateRecordSet.filter_registry) + + @arm_template('private-dns.json') + def test_find_by_name(self): + p = self.load_policy({ + 'name': 'test-find-by-name', + 'resource': 'azure.private-record-set', + 'filters': [ + { + 'type': 'value', + 'key': 'name', + 'op': 'eq', + 'value': 'www' + } + ] + }) + + resources = p.run() + self.assertEqual(len(resources), 1) + self.assertEqual(resources[0]['name'], 'www') + self.assertEqual(resources[0]['type'], 'Microsoft.Network/privateDnsZones/A') + self.assertTrue( + ResourceIdParser.get_resource_name( + resources[0][ChildTypeInfo.parent_key]).startswith('c7n-test.')) + + @arm_template('private-dns.json') + @cassette_name('test_find_by_name') + def test_enumerates_every_zone(self): + p = self.load_policy({ + 'name': 'test-enumerates-every-zone', + 'resource': 'azure.private-record-set' + }) + + resources = p.run() + zones = {ResourceIdParser.get_resource_name(r[ChildTypeInfo.parent_key]) + for r in resources} + self.assertEqual(len(zones), 2) diff --git a/tools/c7n_gcp/c7n_gcp/actions/labels.py b/tools/c7n_gcp/c7n_gcp/actions/labels.py index 28797476661..0e1fd8c7b82 100644 --- a/tools/c7n_gcp/c7n_gcp/actions/labels.py +++ b/tools/c7n_gcp/c7n_gcp/actions/labels.py @@ -48,6 +48,14 @@ def _merge_labels(self, current_labels, new_labels, remove_labels): def get_operation_name(self, model, resource): return model.labels_op + def get_client(self, session, model): + # Some resources (e.g. gcp.disk) need a different client depending + # on the resource being labeled, since it dispatches to one of + # several apis. + if get_client := getattr(model, 'get_client', None): + return get_client(session) + return super().get_client(session, model) + def get_resource_params(self, model, resource): current_labels = self._get_current_labels(resource) new_labels = self.get_labels_to_add(resource) @@ -115,6 +123,18 @@ class SetLabelsAction(BaseLabelAction): key: name default-value: name_not_found + - name: gcp-add-default-label + resource: gcp.instance + description: | + Omitting key gives a conditional default - the label is set only + when it is absent, leaving an existing value untouched + actions: + - type: set-labels + labels: + owner: + type: resource + default-value: platform + - name: gcp-remove-label resource: gcp.instance description: | @@ -135,7 +155,14 @@ def validate(self): raise FilterValidationError("Must specify one of labels or remove") def get_labels_to_add(self, resource): - return {k: Lookup.extract(v, resource) for k, v in self.data.get('labels', {}).items()} + current = set(self._get_current_labels(resource)) + labels = {} + for name, spec in self.data.get('labels', {}).items(): + value = Lookup.resolve_value(spec, resource, name, current) + if value is Lookup.SKIP: + continue + labels[name] = value + return labels def get_labels_to_delete(self, resource): return self.data.get('remove') diff --git a/tools/c7n_gcp/c7n_gcp/query.py b/tools/c7n_gcp/c7n_gcp/query.py index 32819d419b8..25626085284 100644 --- a/tools/c7n_gcp/c7n_gcp/query.py +++ b/tools/c7n_gcp/c7n_gcp/query.py @@ -4,6 +4,7 @@ import json import itertools import logging +import os import re import jmespath @@ -336,15 +337,36 @@ def _extract_fields(source, mappings): return result +def config_regions(config): + """Resolve cli/programmatic region selection to explicit region names. + + - config.regions is the cli's raw, repeatable '-r/--region' list. + + 'all' anywhere in it means every region, overriding any other + entries in the list. For backward compatibility, however, if + 'all' is present and config.region is set, then config.region is + used. + + - config.region is a single-region value set by some callers + (tests, embedders). Normally an empty string in production. + Lore suggests it could be set to + `os.environ.get('AWS_DEFAULT_REGION', 'us-east-1')`, but that + seems unlikely for GCP. + + Returns () when nothing explicit was given, meaning "no filter". + """ + if config.regions and 'all' not in config.regions: + return tuple(config.regions) + elif config.region and config.region != os.environ.get('AWS_DEFAULT_REGION', 'us-east-1'): + return (config.region,) + return () + + class RegionalResourceManager(ChildResourceManager): def get_parent_resource_query(self): - query = None - if self.config.regions and 'all' not in self.config.regions: - query = [{'name': r} for r in self.config.regions] - elif self.config.region: - query = [{'name': self.config.region}] - return query + regions = config_regions(self.config) + return [{'name': r} for r in regions] if regions else None class TypeMeta(type): diff --git a/tools/c7n_gcp/c7n_gcp/region.py b/tools/c7n_gcp/c7n_gcp/region.py index 11aa260eb74..ed0ac0a15e0 100644 --- a/tools/c7n_gcp/c7n_gcp/region.py +++ b/tools/c7n_gcp/c7n_gcp/region.py @@ -4,7 +4,7 @@ from pathlib import Path from .provider import resources -from .query import TypeInfo +from .query import config_regions, TypeInfo REGION_DATA_PATH = Path(__file__).parent / "regions.json" @@ -49,12 +49,8 @@ def set_regions(cls, regions): def resources(self, resource_ids=()): if resource_ids: return [{'name': r} for r in self.regions if r in resource_ids] - elif self.config.regions or self.config.region != 'us-east-1': - regions = list(self.config.regions) - regions.append(self.config.region) - regions = list(filter(None, regions)) - if 'us-east-1' in regions: - regions.remove('us-east-1') + regions = config_regions(self.config) + if regions: return [{'name': r} for r in self.regions if r in regions] elif 'query' in self.data: qregions = {q['name'] for q in self.data['query']} diff --git a/tools/c7n_gcp/c7n_gcp/resources/cloudrun.py b/tools/c7n_gcp/c7n_gcp/resources/cloudrun.py index 54f479b60d0..7941f7b746e 100644 --- a/tools/c7n_gcp/c7n_gcp/resources/cloudrun.py +++ b/tools/c7n_gcp/c7n_gcp/resources/cloudrun.py @@ -1,13 +1,64 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 -import copy - from c7n_gcp.provider import resources from c7n_gcp.query import QueryResourceManager, TypeInfo from c7n_gcp.filters import IamPolicyFilter from c7n_gcp.filters.iampolicy import IamPolicyValueFilter +from c7n.exceptions import PolicyExecutionError from c7n.utils import local_session, jmespath_search +# The only fields the Knative schema defines at the root of a Service or a Job. +KNATIVE_FIELDS = ('apiVersion', 'kind', 'metadata', 'spec', 'status') + +# Prefixes of the annotations c7n keeps on a resource. Only the colon form is +# written to a nested object; the dotted `c7n.metrics` is set at the root alone. +# Nesting matches on the colon form only, because kubernetes annotation keys - +# user controlled, and carried in `metadata.annotations` - may contain a dot but +# never a colon, and this is a whole object replace: a key dropped from the body +# is a key deleted from the service. +C7N_ANNOTATION = 'c7n:' +C7N_ROOT_ANNOTATIONS = (C7N_ANNOTATION, 'c7n.') + + +def _without_annotations(value): + "Copy a value, dropping any c7n annotation held anywhere beneath it." + if isinstance(value, dict): + return {k: _without_annotations(v) for k, v in value.items() + if not k.startswith(C7N_ANNOTATION)} + if isinstance(value, list): + return [_without_annotations(v) for v in value] + # everything else in a decoded api response is an immutable scalar + return value + + +def knative_body(resource): + """Copy a resource into a replace request body, dropping non schema fields. + + Cloud Run replaces the whole object, so the body is the resource itself + rather than a fragment, and the api rejects the request with a 400 on any + field it can't place. A resource carries two kinds it can't: the top level + `labels` key that augment() flattens out of the metadata, and the + annotations the policy's filters leave behind - at the root, and nested + within `spec` when a list-item filter matched on something there. + + A root field that is neither raises rather than being dropped. Under a + whole object replace a field left out of the body is deleted from the + service, so a field this doesn't recognize is one it cannot safely send + or safely omit. + """ + unrecognized = { + k for k in resource + if k not in KNATIVE_FIELDS and k != 'labels' + and not k.startswith(C7N_ROOT_ANNOTATIONS) + } + if unrecognized: + raise PolicyExecutionError( + '%s %s has fields absent from the cloud run schema: %s' % ( + resource.get('kind', 'resource'), + resource.get('metadata', {}).get('name'), + ', '.join(sorted(unrecognized)))) + return {k: _without_annotations(v) for k, v in resource.items() if k in KNATIVE_FIELDS} + @resources.register("cloud-run-service") class CloudRunService(QueryResourceManager): @@ -35,7 +86,7 @@ def get_label_params(resource, all_labels): location = metadata['labels']['cloud.googleapis.com/location'] namespace = metadata['namespace'] svc_name = metadata['name'] - body = copy.deepcopy(resource) + body = knative_body(resource) body['metadata']['labels'] = all_labels return { 'name': 'projects/{}/locations/{}/services/{}'.format( @@ -98,7 +149,7 @@ def get_label_params(resource, all_labels): metadata = resource['metadata'] namespace = metadata['namespace'] job_name = metadata['name'] - body = copy.deepcopy(resource) + body = knative_body(resource) body['metadata']['labels'] = all_labels return { 'name': 'namespaces/{}/jobs/{}'.format(namespace, job_name), diff --git a/tools/c7n_gcp/c7n_gcp/resources/compute.py b/tools/c7n_gcp/c7n_gcp/resources/compute.py index 4405ca74d48..4737f3c2cf6 100644 --- a/tools/c7n_gcp/c7n_gcp/resources/compute.py +++ b/tools/c7n_gcp/c7n_gcp/resources/compute.py @@ -450,6 +450,42 @@ def get_resource_params(self, m, r): return {'project': project, 'image': image_id} +# Disks are either zonal (compute.disks) or regional (compute.regionDisks). +# Both apis take the same params, keyed by 'zone' or 'region' respectively. +DISK_PATH_RE = re.compile(r'(?:.*/)?projects/(.*?)/(zones|regions)/(.*?)/disks/(.*)') + + +def parse_disk_path(path): + """Parse a disk's selfLink or audit log resourceName. + + Returns (project, {'zone': z} | {'region': r}, disk_name). + """ + project, scope, location, name = DISK_PATH_RE.match(path).groups() + loc_key = 'zone' if scope == 'zones' else 'region' + return project, {loc_key: location}, name + + +class ZonalOrRegionalClient: + """Dispatches disk api calls to the zonal or regional client. + + Selection is based on whether `params` has a 'zone' or 'region' key. + """ + + def __init__(self, zonal, regional): + self.zonal = zonal + self.regional = regional + + def execute_command(self, op, params): + client = self.regional if 'region' in params else self.zonal + return client.execute_command(op, params) + + +class DiskScopeMixin: + + def get_client(self, session, model): + return model.get_client(session) + + @resources.register('disk') class Disk(QueryResourceManager): @@ -468,22 +504,36 @@ class resource_type(TypeInfo): @staticmethod def get(client, resource_info): + # resourceName is the only part of a disk audit event that + # identifies the disk across both scopes: zonal events carry a + # numeric disk_id and a zone, regional events carry neither. + project, loc, name = parse_disk_path(resource_info['resourceName']) return client.execute_command( - 'get', {'project': resource_info['project_id'], - 'zone': resource_info['zone'], - 'disk': resource_info['disk_id']}) + 'get', {'project': project, 'disk': name, **loc}) @staticmethod def get_label_params(resource, all_labels): - path_param_re = re.compile('.*?/projects/(.*?)/zones/(.*?)/disks/(.*)') - project, zone, instance = path_param_re.match( - resource['selfLink']).groups() - return {'project': project, 'zone': zone, 'resource': instance, + project, loc, resc_id = parse_disk_path(resource['selfLink']) + return {'project': project, 'resource': resc_id, **loc, 'body': { 'labels': all_labels, 'labelFingerprint': resource['labelFingerprint'] }} + @staticmethod + def get_client(session): + return ZonalOrRegionalClient( + session.client('compute', 'v1', 'disks'), + session.client('compute', 'v1', 'regionDisks')) + + def get_resource(self, resource_info): + # The base implementation's get_client() builds a zonal-only + # client, which can't reach regional disks (used by event-driven + # policies, e.g. gcp-audit mode). + session = local_session(self.session_factory) + client = self.resource_type.get_client(session) + return self.resource_type.get(client, resource_info) + @Disk.filter_registry.register('snapshots') class DiskSnapshotsFilter(ListItemFilter): @@ -533,7 +583,7 @@ def get_item_values(self, resource): @Disk.action_registry.register('snapshot') -class DiskSnapshot(MethodAction): +class DiskSnapshot(DiskScopeMixin, MethodAction): """ `Snapshots `_ disk. @@ -563,19 +613,17 @@ class DiskSnapshot(MethodAction): """ schema = type_schema('snapshot', name_format={'type': 'string'}) method_spec = {'op': 'createSnapshot'} - path_param_re = re.compile( - '.*?/projects/(.*?)/zones/(.*?)/disks/(.*)') attr_filter = ('status', ('RUNNING', 'READY')) def get_resource_params(self, model, resource): - project, zone, resourceId = self.path_param_re.match(resource['selfLink']).groups() + project, loc, resourceId = parse_disk_path(resource['selfLink']) name_format = self.data.get('name_format', '{disk[name]}') name = name_format.format(disk=resource, now=datetime.now()) return { 'project': project, - 'zone': zone, 'disk': resourceId, + **loc, 'body': { 'name': name, 'labels': resource.get('labels', {}), @@ -584,20 +632,18 @@ def get_resource_params(self, model, resource): @Disk.action_registry.register('delete') -class DiskDelete(MethodAction): +class DiskDelete(DiskScopeMixin, MethodAction): schema = type_schema('delete') method_spec = {'op': 'delete'} - path_param_re = re.compile( - '.*?/projects/(.*?)/zones/(.*?)/disks/(.*)') attr_filter = ('status', ('RUNNING', 'READY')) def get_resource_params(self, m, r): - project, zone, resourceId = self.path_param_re.match(r['selfLink']).groups() + project, loc, resourceId = parse_disk_path(r['selfLink']) return { 'project': project, - 'zone': zone, 'disk': resourceId, + **loc, } diff --git a/tools/c7n_gcp/c7n_gcp/resources/notebook.py b/tools/c7n_gcp/c7n_gcp/resources/notebook.py index 06e386dbff3..c896e98da32 100644 --- a/tools/c7n_gcp/c7n_gcp/resources/notebook.py +++ b/tools/c7n_gcp/c7n_gcp/resources/notebook.py @@ -1,5 +1,7 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +from c7n.utils import type_schema +from c7n_gcp.actions import MethodAction from c7n_gcp.provider import resources from c7n_gcp.query import QueryResourceManager, TypeInfo @@ -77,6 +79,53 @@ class resource_type(TypeInfo): urn_component = "instances" asset_type = "notebooks.googleapis.com/Instance" + @staticmethod + def get(client, resource_info): + return client.execute_query( + 'get', {'name': resource_info['resourceName']}) + @classmethod def _get_location(cls, resource): return resource['name'].split('/')[3] + + +@NotebookInstanceV2.action_registry.register('update-metadata') +class UpdateMetadata(MethodAction): + """Merge keys into a notebook-v2 instance's gceSetup.metadata. + + gceSetup.metadata is a map field, so a patch to it replaces the whole + map -- this action merges the given keys into the instance's current + metadata rather than replacing it outright. + + :example: + + .. yaml: + + policies: + - name: notebook-v2-enforce-idle-timeout + resource: gcp.notebook-v2 + filters: + - type: value + key: gceSetup.metadata."idle-timeout-seconds" + value: absent + actions: + - type: update-metadata + metadata: + idle-timeout-seconds: "3600" + """ + schema = type_schema( + 'update-metadata', + required=('metadata',), + metadata={'type': 'object', 'additionalProperties': {'type': 'string'}}, + ) + method_spec = {'op': 'patch'} + method_perm = 'update' + + def get_resource_params(self, model, resource): + metadata = dict(resource.get('gceSetup', {}).get('metadata') or {}) + metadata.update(self.data['metadata']) + return { + 'name': resource['name'], + 'updateMask': 'gceSetup.metadata', + 'body': {'gceSetup': {'metadata': metadata}}, + } diff --git a/tools/c7n_gcp/c7n_gcp/resources/resource_map.py b/tools/c7n_gcp/c7n_gcp/resources/resource_map.py index 919d31e1237..4c8f6335313 100644 --- a/tools/c7n_gcp/c7n_gcp/resources/resource_map.py +++ b/tools/c7n_gcp/c7n_gcp/resources/resource_map.py @@ -128,6 +128,7 @@ "gcp.vertex-ai-custom-job": "c7n_gcp.resources.vertexai.VertexAICustomJob", "gcp.vertex-ai-dataset": "c7n_gcp.resources.vertexai.VertexAIDataset", "gcp.vertex-ai-endpoint": "c7n_gcp.resources.vertexai.VertexAIEndpoint", + "gcp.vertex-ai-evaluation-run": "c7n_gcp.resources.vertexai.VertexAIEvaluationRun", "gcp.vertex-ai-hyperparameter-tuning-job": ( "c7n_gcp.resources.vertexai.VertexAIHyperparameterTuningJob"), "gcp.vertex-ai-location": "c7n_gcp.resources.vertexai.VertexAILocation", diff --git a/tools/c7n_gcp/c7n_gcp/resources/vertexai.py b/tools/c7n_gcp/c7n_gcp/resources/vertexai.py index 5055717c180..998b0108ae3 100644 --- a/tools/c7n_gcp/c7n_gcp/resources/vertexai.py +++ b/tools/c7n_gcp/c7n_gcp/resources/vertexai.py @@ -14,7 +14,8 @@ from c7n_gcp.actions import MethodAction from c7n_gcp.filters.metrics import GCPMetricsFilter from c7n_gcp.provider import resources -from c7n_gcp.query import QueryResourceManager, TypeInfo, ChildResourceManager, ChildTypeInfo +from c7n_gcp.query import ( + config_regions, QueryResourceManager, TypeInfo, ChildResourceManager, ChildTypeInfo) REGION_DATA_PATH = Path(__file__).parent.parent / 'regions.json' @@ -235,9 +236,8 @@ def resources(self, resource_ids=None): Locations can be specified via: 1. Policy query: {'query': [{'location': 'us-central1'}, {'location': 'us-east1'}]} - 2. Config regions: --regions us-central1,us-east1 - 3. Config region: --region us-central1 - 4. Default: All Vertex AI supported regions from vertexai_regions.json + 2. Configured regions + 3. Default: All Vertex AI supported regions from vertexai_regions.json """ # If query specified in policy, use those locations @@ -245,13 +245,10 @@ def resources(self, resource_ids=None): query_locations = {q['location'] for q in self.data['query'] if 'location' in q} return [{'name': loc} for loc in self.regions if loc in query_locations] - # If config regions specified, use those - if self.config and self.config.regions and 'all' not in self.config.regions: - return [{'name': r} for r in self.regions if r in self.config.regions] - - # If single config region specified, use that - if self.config and self.config.region and self.config.region != 'us-east-1': - return [{'name': self.config.region}] if self.config.region in self.regions else [] + # If cli/config regions specified, use those + regions = config_regions(self.config) if self.config else () + if regions: + return [{'name': r} for r in self.regions if r in regions] # Default: return all Vertex AI supported regions return [{'name': loc} for loc in self.regions] @@ -787,6 +784,61 @@ class resource_type(VertexAITypeInfo): urn_component = 'model' +@resources.register('vertex-ai-evaluation-run') +class VertexAIEvaluationRun(VertexAIQueryManager): + """GCP Vertex AI Evaluation Run Resource + + Vertex AI Evaluation Runs assess model or dataset quality against an + evaluation set, producing a terminal state and completion time that + can drive a retention-review policy on completed runs. + + :example: + + List all Vertex AI Evaluation Runs across all locations: + + .. code-block:: yaml + + policies: + - name: vertexai-evaluation-runs-inventory + resource: gcp.vertex-ai-evaluation-run + + :example: + + Find terminal evaluation runs older than 30 days: + + .. code-block:: yaml + + policies: + - name: vertex-ai-completed-evaluation-runs-past-retention + resource: gcp.vertex-ai-evaluation-run + filters: + - or: + - type: value + key: state + value: SUCCEEDED + - type: value + key: state + value: FAILED + - type: value + key: state + value: CANCELLED + - type: value + key: completionTime + value_type: age + op: greater-than + value: 30 + """ + + class resource_type(VertexAITypeInfo): + component = 'projects.locations.evaluationRuns' + enum_spec = ('list', 'evaluationRuns[]', None) + default_report_fields = [ + 'name', 'displayName', 'state', 'createTime', 'completionTime' + ] + permissions = ('aiplatform.evaluationRuns.list',) + urn_component = 'evaluation-run' + + @resources.register('vertex-ai-batch-prediction-job') class VertexAIBatchPredictionJob(VertexAIQueryManager): """GCP Vertex AI Batch Prediction Job Resource diff --git a/tools/c7n_gcp/pyproject.toml b/tools/c7n_gcp/pyproject.toml index 2886dc30f38..82bea832862 100644 --- a/tools/c7n_gcp/pyproject.toml +++ b/tools/c7n_gcp/pyproject.toml @@ -15,7 +15,7 @@ dependencies = [ "retrying<2.0.0,>=1.3.3", ] name = "c7n_gcp" -version = "0.4.51a5+a83dda5c9" +version = "0.4.52a1+e4c099e03" description = "Cloud Custodian - Google Cloud Provider" readme = "readme.md" classifiers = [ diff --git a/tools/c7n_gcp/tests/data/events/disk-regional-create-first.json b/tools/c7n_gcp/tests/data/events/disk-regional-create-first.json new file mode 100644 index 00000000000..d891ac0a8f1 --- /dev/null +++ b/tools/c7n_gcp/tests/data/events/disk-regional-create-first.json @@ -0,0 +1,110 @@ +{ + "insertId": "-o3w95dd34ku", + "labels": { + "compute.googleapis.com/root_trigger_id": "341f2f26-73f0-49f4-b966-dbd6e87bfe9d" + }, + "logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "first": true, + "id": "operation-1787255378983-6597fd1fcb972-0bca07bc-e5416c85", + "producer": "compute.googleapis.com" + }, + "protoPayload": { + "@type": "type.googleapis.com/google.cloud.audit.AuditLog", + "apiVersionIdentifier": "v1", + "authenticationInfo": { + "oauthInfo": { + "oauthClientId": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com" + }, + "principalEmail": "user@example.com", + "principalSubject": "user:user@example.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.disks.create", + "permissionType": "ADMIN_WRITE", + "resource": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "resourceAttributes": { + "name": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "service": "compute", + "type": "compute.disks" + } + }, + { + "granted": true, + "permission": "compute.disks.setLabels", + "permissionType": "ADMIN_WRITE", + "resource": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "resourceAttributes": { + "name": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "service": "compute", + "type": "compute.disks" + } + } + ], + "methodName": "v1.compute.regionDisks.insert", + "request": { + "@type": "type.googleapis.com/compute.regionDisks.insert", + "labels": [ + { + "key": "goog-terraform-provisioned", + "value": "true" + } + ], + "name": "c7n-audit-regional-default-f5b3", + "replicaZones": [ + "projects/cloud-custodian/global/zones/us-central1-a", + "projects/cloud-custodian/global/zones/us-central1-b" + ], + "sizeGb": "10", + "type": "projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd" + }, + "requestMetadata": { + "callerIp": "198.51.100.1", + "callerSuppliedUserAgent": "Terraform/1.13.0 (+https://www.terraform.io) Terraform-Plugin-SDK/2.40.1 terraform-provider-google/dev7,gzip(gfe)", + "destinationAttributes": {}, + "requestAttributes": { + "auth": {}, + "time": "2026-08-20T19:49:39.365797Z" + } + }, + "resourceLocation": { + "currentLocations": [ + "us-central1" + ] + }, + "resourceName": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "response": { + "@type": "type.googleapis.com/operation", + "id": "7436650565111309500", + "insertTime": "2026-08-20T12:49:39.193-07:00", + "name": "operation-1787255378983-6597fd1fcb972-0bca07bc-e5416c85", + "operationType": "insert", + "progress": "0", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/operation-1787255378983-6597fd1fcb972-0bca07bc-e5416c85", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/7436650565111309500", + "startTime": "2026-08-20T12:49:39.197-07:00", + "status": "RUNNING", + "targetId": "685703828320478397", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "user": "user@example.com" + }, + "serviceName": "compute.googleapis.com", + "status": {} + }, + "receiveTimestamp": "2026-08-20T19:49:39.733197453Z", + "resource": { + "labels": { + "location": "us-central1", + "method": "compute.regionDisks.insert", + "project_id": "cloud-custodian", + "service": "compute.googleapis.com", + "version": "v1" + }, + "type": "api" + }, + "severity": "NOTICE", + "timestamp": "2026-08-20T19:49:38.935927Z" +} diff --git a/tools/c7n_gcp/tests/data/events/disk-regional-create-last.json b/tools/c7n_gcp/tests/data/events/disk-regional-create-last.json new file mode 100644 index 00000000000..d1c2e4c1999 --- /dev/null +++ b/tools/c7n_gcp/tests/data/events/disk-regional-create-last.json @@ -0,0 +1,49 @@ +{ + "insertId": "-hgppkic7c8", + "labels": { + "compute.googleapis.com/root_trigger_id": "341f2f26-73f0-49f4-b966-dbd6e87bfe9d" + }, + "logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "id": "operation-1787255378983-6597fd1fcb972-0bca07bc-e5416c85", + "last": true, + "producer": "compute.googleapis.com" + }, + "protoPayload": { + "@type": "type.googleapis.com/google.cloud.audit.AuditLog", + "apiVersionIdentifier": "v1", + "authenticationInfo": { + "oauthInfo": { + "oauthClientId": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com" + }, + "principalEmail": "user@example.com", + "principalSubject": "user:user@example.com" + }, + "methodName": "v1.compute.regionDisks.insert", + "request": { + "@type": "type.googleapis.com/compute.regionDisks.insert" + }, + "requestMetadata": { + "callerIp": "198.51.100.1", + "callerSuppliedUserAgent": "Terraform/1.13.0 (+https://www.terraform.io) Terraform-Plugin-SDK/2.40.1 terraform-provider-google/dev7,gzip(gfe)", + "destinationAttributes": {}, + "requestAttributes": {} + }, + "resourceName": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "serviceName": "compute.googleapis.com", + "status": {} + }, + "receiveTimestamp": "2026-08-20T19:49:40.612067442Z", + "resource": { + "labels": { + "location": "us-central1", + "method": "compute.regionDisks.insert", + "project_id": "cloud-custodian", + "service": "compute.googleapis.com", + "version": "v1" + }, + "type": "api" + }, + "severity": "NOTICE", + "timestamp": "2026-08-20T19:49:40.536859Z" +} diff --git a/tools/c7n_gcp/tests/data/events/disk-regional-update-first-last.json b/tools/c7n_gcp/tests/data/events/disk-regional-update-first-last.json new file mode 100644 index 00000000000..c1a16e9537d --- /dev/null +++ b/tools/c7n_gcp/tests/data/events/disk-regional-update-first-last.json @@ -0,0 +1,95 @@ +{ + "insertId": "65l82id1396", + "labels": { + "compute.googleapis.com/root_trigger_id": "bda69b1a-c092-4cae-979c-36099a893778" + }, + "logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "first": true, + "id": "operation-1787255391739-6597fd2bf5e56-f5d197f8-2ae782c0", + "last": true, + "producer": "compute.googleapis.com" + }, + "protoPayload": { + "@type": "type.googleapis.com/google.cloud.audit.AuditLog", + "apiVersionIdentifier": "v1", + "authenticationInfo": { + "oauthInfo": { + "oauthClientId": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com" + }, + "principalEmail": "user@example.com", + "principalSubject": "user:user@example.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.disks.setLabels", + "permissionType": "ADMIN_WRITE", + "resource": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "resourceAttributes": { + "name": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "service": "compute", + "type": "compute.disks" + } + } + ], + "methodName": "v1.compute.regionDisks.setLabels", + "request": { + "@type": "type.googleapis.com/compute.regionDisks.setLabels", + "labelFingerprint": "\ufffd\ufffd\ufffdK\ufffd6,\ufffd", + "labels": [ + { + "key": "c7n-audit", + "value": "recorded" + } + ] + }, + "requestMetadata": { + "callerIp": "198.51.100.1", + "callerSuppliedUserAgent": "Python-httplib2/0.32.0 (gzip), custodian-gcp/0.1 (gzip),gzip(gfe)", + "destinationAttributes": {}, + "requestAttributes": { + "auth": {}, + "time": "2026-08-20T19:49:51.887189Z" + } + }, + "resourceLocation": { + "currentLocations": [ + "us-central1" + ] + }, + "resourceName": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "response": { + "@type": "type.googleapis.com/operation", + "endTime": "2026-08-20T12:49:51.807-07:00", + "id": "34962613065147568", + "insertTime": "2026-08-20T12:49:51.792-07:00", + "name": "operation-1787255391739-6597fd2bf5e56-f5d197f8-2ae782c0", + "operationType": "setLabels", + "progress": "100", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/operation-1787255391739-6597fd2bf5e56-f5d197f8-2ae782c0", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/34962613065147568", + "startTime": "2026-08-20T12:49:51.807-07:00", + "status": "DONE", + "targetId": "685703828320478397", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "user": "user@example.com" + }, + "serviceName": "compute.googleapis.com", + "status": {} + }, + "receiveTimestamp": "2026-08-20T19:49:52.548304769Z", + "resource": { + "labels": { + "location": "us-central1", + "method": "compute.regionDisks.setLabels", + "project_id": "cloud-custodian", + "service": "compute.googleapis.com", + "version": "v1" + }, + "type": "api" + }, + "severity": "NOTICE", + "timestamp": "2026-08-20T19:49:51.713617Z" +} diff --git a/tools/c7n_gcp/tests/data/events/disk-zonal-create-first.json b/tools/c7n_gcp/tests/data/events/disk-zonal-create-first.json new file mode 100644 index 00000000000..4293832f144 --- /dev/null +++ b/tools/c7n_gcp/tests/data/events/disk-zonal-create-first.json @@ -0,0 +1,104 @@ +{ + "insertId": "r8vz4af1rld5w", + "labels": { + "compute.googleapis.com/root_trigger_id": "83bb1aa1-1317-4779-8737-82dd1eed5ce9" + }, + "logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "first": true, + "id": "operation-1787255378942-6597fd1fc18a3-18e93fdb-2cf54cd4", + "producer": "compute.googleapis.com" + }, + "protoPayload": { + "@type": "type.googleapis.com/google.cloud.audit.AuditLog", + "apiVersionIdentifier": "v1", + "authenticationInfo": { + "oauthInfo": { + "oauthClientId": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com" + }, + "principalEmail": "user@example.com", + "principalSubject": "user:user@example.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.disks.create", + "permissionType": "ADMIN_WRITE", + "resource": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "resourceAttributes": { + "name": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "service": "compute", + "type": "compute.disks" + } + }, + { + "granted": true, + "permission": "compute.disks.setLabels", + "permissionType": "ADMIN_WRITE", + "resource": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "resourceAttributes": { + "name": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "service": "compute", + "type": "compute.disks" + } + } + ], + "methodName": "v1.compute.disks.insert", + "request": { + "@type": "type.googleapis.com/compute.disks.insert", + "labels": [ + { + "key": "goog-terraform-provisioned", + "value": "true" + } + ], + "name": "c7n-audit-zonal-default-f5b3", + "sizeGb": "10", + "type": "projects/cloud-custodian/zones/us-central1-a/diskTypes/pd-ssd" + }, + "requestMetadata": { + "callerIp": "198.51.100.1", + "callerSuppliedUserAgent": "Terraform/1.13.0 (+https://www.terraform.io) Terraform-Plugin-SDK/2.40.1 terraform-provider-google/dev7,gzip(gfe)", + "destinationAttributes": {}, + "requestAttributes": { + "auth": {}, + "time": "2026-08-20T19:49:39.300360Z" + } + }, + "resourceLocation": { + "currentLocations": [ + "us-central1-a" + ] + }, + "resourceName": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "response": { + "@type": "type.googleapis.com/operation", + "id": "1996680382823195836", + "insertTime": "2026-08-20T12:49:39.158-07:00", + "name": "operation-1787255378942-6597fd1fc18a3-18e93fdb-2cf54cd4", + "operationType": "insert", + "progress": "0", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/operations/operation-1787255378942-6597fd1fc18a3-18e93fdb-2cf54cd4", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/operations/1996680382823195836", + "startTime": "2026-08-20T12:49:39.162-07:00", + "status": "RUNNING", + "targetId": "4992374716928550077", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "user": "user@example.com", + "zone": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a" + }, + "serviceName": "compute.googleapis.com", + "status": {} + }, + "receiveTimestamp": "2026-08-20T19:49:39.780150948Z", + "resource": { + "labels": { + "disk_id": "4992374716928550077", + "project_id": "cloud-custodian", + "zone": "us-central1-a" + }, + "type": "gce_disk" + }, + "severity": "NOTICE", + "timestamp": "2026-08-20T19:49:38.912796Z" +} diff --git a/tools/c7n_gcp/tests/data/events/disk-zonal-create-last.json b/tools/c7n_gcp/tests/data/events/disk-zonal-create-last.json new file mode 100644 index 00000000000..87180685908 --- /dev/null +++ b/tools/c7n_gcp/tests/data/events/disk-zonal-create-last.json @@ -0,0 +1,47 @@ +{ + "insertId": "w7nlbrd4srw", + "labels": { + "compute.googleapis.com/root_trigger_id": "83bb1aa1-1317-4779-8737-82dd1eed5ce9" + }, + "logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "id": "operation-1787255378942-6597fd1fc18a3-18e93fdb-2cf54cd4", + "last": true, + "producer": "compute.googleapis.com" + }, + "protoPayload": { + "@type": "type.googleapis.com/google.cloud.audit.AuditLog", + "apiVersionIdentifier": "v1", + "authenticationInfo": { + "oauthInfo": { + "oauthClientId": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com" + }, + "principalEmail": "user@example.com", + "principalSubject": "user:user@example.com" + }, + "methodName": "v1.compute.disks.insert", + "request": { + "@type": "type.googleapis.com/compute.disks.insert" + }, + "requestMetadata": { + "callerIp": "198.51.100.1", + "callerSuppliedUserAgent": "Terraform/1.13.0 (+https://www.terraform.io) Terraform-Plugin-SDK/2.40.1 terraform-provider-google/dev7,gzip(gfe)", + "destinationAttributes": {}, + "requestAttributes": {} + }, + "resourceName": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "serviceName": "compute.googleapis.com", + "status": {} + }, + "receiveTimestamp": "2026-08-20T19:49:39.967810613Z", + "resource": { + "labels": { + "disk_id": "4992374716928550077", + "project_id": "cloud-custodian", + "zone": "us-central1-a" + }, + "type": "gce_disk" + }, + "severity": "NOTICE", + "timestamp": "2026-08-20T19:49:39.790299Z" +} diff --git a/tools/c7n_gcp/tests/data/events/disk-zonal-update-first-last.json b/tools/c7n_gcp/tests/data/events/disk-zonal-update-first-last.json new file mode 100644 index 00000000000..02c2592f7b6 --- /dev/null +++ b/tools/c7n_gcp/tests/data/events/disk-zonal-update-first-last.json @@ -0,0 +1,93 @@ +{ + "insertId": "r8phjaf1pajbg", + "labels": { + "compute.googleapis.com/root_trigger_id": "536091e9-460c-432b-be3d-6c5ccbddc893" + }, + "logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "first": true, + "id": "operation-1787255391283-6597fd2b86918-c598f483-6c6e18e8", + "last": true, + "producer": "compute.googleapis.com" + }, + "protoPayload": { + "@type": "type.googleapis.com/google.cloud.audit.AuditLog", + "apiVersionIdentifier": "v1", + "authenticationInfo": { + "oauthInfo": { + "oauthClientId": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com" + }, + "principalEmail": "user@example.com", + "principalSubject": "user:user@example.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.disks.setLabels", + "permissionType": "ADMIN_WRITE", + "resource": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "resourceAttributes": { + "name": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "service": "compute", + "type": "compute.disks" + } + } + ], + "methodName": "v1.compute.disks.setLabels", + "request": { + "@type": "type.googleapis.com/compute.disks.setLabels", + "labelFingerprint": "\ufffd\ufffd\ufffdK\ufffd6,\ufffd", + "labels": [ + { + "key": "c7n-audit", + "value": "recorded" + } + ] + }, + "requestMetadata": { + "callerIp": "198.51.100.1", + "callerSuppliedUserAgent": "Python-httplib2/0.32.0 (gzip), custodian-gcp/0.1 (gzip),gzip(gfe)", + "destinationAttributes": {}, + "requestAttributes": { + "auth": {}, + "time": "2026-08-20T19:49:51.387590Z" + } + }, + "resourceLocation": { + "currentLocations": [ + "us-central1-a" + ] + }, + "resourceName": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "response": { + "@type": "type.googleapis.com/operation", + "endTime": "2026-08-20T12:49:51.356-07:00", + "id": "8069022862371644592", + "insertTime": "2026-08-20T12:49:51.349-07:00", + "name": "operation-1787255391283-6597fd2b86918-c598f483-6c6e18e8", + "operationType": "setLabels", + "progress": "100", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/operations/operation-1787255391283-6597fd2b86918-c598f483-6c6e18e8", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/operations/8069022862371644592", + "startTime": "2026-08-20T12:49:51.355-07:00", + "status": "DONE", + "targetId": "4992374716928550077", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "user": "user@example.com", + "zone": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a" + }, + "serviceName": "compute.googleapis.com", + "status": {} + }, + "receiveTimestamp": "2026-08-20T19:49:51.474012965Z", + "resource": { + "labels": { + "disk_id": "4992374716928550077", + "project_id": "cloud-custodian", + "zone": "us-central1-a" + }, + "type": "gce_disk" + }, + "severity": "NOTICE", + "timestamp": "2026-08-20T19:49:51.251408Z" +} diff --git a/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_1.json b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_1.json new file mode 100644 index 00000000000..7f3636a7720 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_1.json @@ -0,0 +1,39 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Thu, 20 Aug 2026 19:50:12 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "935", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3?alt=json" + }, + "body": { + "kind": "compute#disk", + "id": "685703828320478397", + "creationTimestamp": "2026-08-20T12:49:39.196-07:00", + "name": "c7n-audit-regional-default-f5b3", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labels": { + "c7n-audit": "recorded" + }, + "labelFingerprint": "zDEAsyrnel8=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_2.json b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_2.json new file mode 100644 index 00000000000..7f3636a7720 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_2.json @@ -0,0 +1,39 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Thu, 20 Aug 2026 19:50:12 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "935", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3?alt=json" + }, + "body": { + "kind": "compute#disk", + "id": "685703828320478397", + "creationTimestamp": "2026-08-20T12:49:39.196-07:00", + "name": "c7n-audit-regional-default-f5b3", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labels": { + "c7n-audit": "recorded" + }, + "labelFingerprint": "zDEAsyrnel8=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_3.json b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_3.json new file mode 100644 index 00000000000..629d00a547d --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-audit-regional-default-f5b3_3.json @@ -0,0 +1,39 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Thu, 20 Aug 2026 19:50:13 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "935", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3?alt=json" + }, + "body": { + "kind": "compute#disk", + "id": "685703828320478397", + "creationTimestamp": "2026-08-20T12:49:39.196-07:00", + "name": "c7n-audit-regional-default-f5b3", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labels": { + "c7n-audit": "recorded" + }, + "labelFingerprint": "zDEAsyrnel8=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_1.json b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_1.json new file mode 100644 index 00000000000..2a6abe8e090 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_1.json @@ -0,0 +1,35 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Thu, 20 Aug 2026 19:50:11 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "724", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3?alt=json" + }, + "body": { + "kind": "compute#disk", + "id": "4992374716928550077", + "creationTimestamp": "2026-08-20T12:49:39.162-07:00", + "name": "c7n-audit-zonal-default-f5b3", + "sizeGb": "10", + "zone": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/diskTypes/pd-ssd", + "labels": { + "c7n-audit": "recorded" + }, + "labelFingerprint": "zDEAsyrnel8=", + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_2.json b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_2.json new file mode 100644 index 00000000000..a65728e03ca --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_2.json @@ -0,0 +1,35 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Thu, 20 Aug 2026 19:50:12 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "724", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3?alt=json" + }, + "body": { + "kind": "compute#disk", + "id": "4992374716928550077", + "creationTimestamp": "2026-08-20T12:49:39.162-07:00", + "name": "c7n-audit-zonal-default-f5b3", + "sizeGb": "10", + "zone": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/diskTypes/pd-ssd", + "labels": { + "c7n-audit": "recorded" + }, + "labelFingerprint": "zDEAsyrnel8=", + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_3.json b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_3.json new file mode 100644 index 00000000000..a65728e03ca --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-audit/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-zones-us-central1-a-disks-c7n-audit-zonal-default-f5b3_3.json @@ -0,0 +1,35 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Thu, 20 Aug 2026 19:50:12 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "724", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3?alt=json" + }, + "body": { + "kind": "compute#disk", + "id": "4992374716928550077", + "creationTimestamp": "2026-08-20T12:49:39.162-07:00", + "name": "c7n-audit-zonal-default-f5b3", + "sizeGb": "10", + "zone": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/diskTypes/pd-ssd", + "labels": { + "c7n-audit": "recorded" + }, + "labelFingerprint": "zDEAsyrnel8=", + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-delete/delete-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-delete/delete-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins_1.json new file mode 100644 index 00000000000..1be192db8e7 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-delete/delete-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins_1.json @@ -0,0 +1,31 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:04:38 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "769", + "-content-encoding": "gzip" + }, + "body": { + "kind": "compute#operation", + "id": "2151607219069742905", + "name": "operation-1786565078111-658df18d954e4-655cd045-1f45c8c9", + "operationType": "delete", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "targetId": "8844375321006403361", + "status": "RUNNING", + "user": "jim.fulton@sixfeetup.com", + "progress": 0, + "insertTime": "2026-08-12T13:04:38.203-07:00", + "startTime": "2026-08-12T13:04:38.218-07:00", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/operation-1786565078111-658df18d954e4-655cd045-1f45c8c9", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-delete/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-delete/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json new file mode 100644 index 00000000000..da88d3a3587 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-delete/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json @@ -0,0 +1,2136 @@ +{ + "headers": { + "etag": "Yr5UOcrYhlLxBjVNRmN9Jd_09lw=/c0_WTIgJPwwTtPhfZPfDRVXFyEo=", + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:04:37 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "53505", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/disks?alt=json" + }, + "body": { + "kind": "compute#diskAggregatedList", + "id": "projects/cloud-custodian/aggregated/disks", + "items": { + "regions/us-central1": { + "disks": [ + { + "kind": "compute#disk", + "id": "8844375321006403361", + "creationTimestamp": "2026-08-12T13:04:30.472-07:00", + "name": "c7n-regional-jenkins", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labelFingerprint": "42WmSpB8rSM=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } + ] + }, + "regions/europe-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west1" + } + ] + } + }, + "regions/us-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west1" + } + ] + } + }, + "regions/asia-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east1" + } + ] + } + }, + "regions/us-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east1" + } + ] + } + }, + "regions/asia-northeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast1" + } + ] + } + }, + "regions/asia-southeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast1" + } + ] + } + }, + "regions/us-east4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east4'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east4" + } + ] + } + }, + "regions/australia-southeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/australia-southeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/australia-southeast1" + } + ] + } + }, + "regions/europe-west2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west2" + } + ] + } + }, + "regions/europe-west3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west3'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west3" + } + ] + } + }, + "regions/southamerica-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/southamerica-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/southamerica-east1" + } + ] + } + }, + "regions/asia-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-south1" + } + ] + } + }, + "regions/northamerica-northeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-northeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-northeast1" + } + ] + } + }, + "regions/europe-west4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west4'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west4" + } + ] + } + }, + "regions/europe-north1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-north1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-north1" + } + ] + } + }, + "regions/us-west2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west2'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west2" + } + ] + } + }, + "regions/asia-east2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-east2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east2" + } + ] + } + }, + "regions/europe-west6": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west6'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west6" + } + ] + } + }, + "regions/asia-northeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast2" + } + ] + } + }, + "regions/asia-northeast3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast3'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast3" + } + ] + } + }, + "regions/us-west3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west3'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west3" + } + ] + } + }, + "regions/us-west4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west4'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west4" + } + ] + } + }, + "regions/asia-southeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast2" + } + ] + } + }, + "regions/europe-central2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-central2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-central2" + } + ] + } + }, + "regions/northamerica-northeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-northeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-northeast2" + } + ] + } + }, + "regions/asia-south2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-south2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-south2" + } + ] + } + }, + "regions/australia-southeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/australia-southeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/australia-southeast2" + } + ] + } + }, + "regions/southamerica-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/southamerica-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/southamerica-west1" + } + ] + } + }, + "regions/europe-west8": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west8'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west8" + } + ] + } + }, + "regions/europe-west9": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west9'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west9" + } + ] + } + }, + "regions/us-east5": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east5'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east5" + } + ] + } + }, + "regions/europe-southwest1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-southwest1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-southwest1" + } + ] + } + }, + "regions/us-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-south1" + } + ] + } + }, + "regions/me-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/me-west1" + } + ] + } + }, + "regions/europe-west12": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west12'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west12" + } + ] + } + }, + "regions/me-central1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-central1'.", + "data": [ + { + "key": "scope", + "value": "regions/me-central1" + } + ] + } + }, + "regions/europe-west10": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west10'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west10" + } + ] + } + }, + "regions/me-central2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-central2'.", + "data": [ + { + "key": "scope", + "value": "regions/me-central2" + } + ] + } + }, + "regions/africa-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/africa-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/africa-south1" + } + ] + } + }, + "regions/northamerica-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-south1" + } + ] + } + }, + "regions/europe-north2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-north2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-north2" + } + ] + } + }, + "regions/asia-southeast3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast3'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast3" + } + ] + } + }, + "zones/us-central1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-a" + } + ] + } + }, + "zones/us-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-b" + } + ] + } + }, + "zones/us-central1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-c" + } + ] + } + }, + "zones/us-central1-f": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-f'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-f" + } + ] + } + }, + "zones/europe-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-b" + } + ] + } + }, + "zones/europe-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-c" + } + ] + } + }, + "zones/europe-west1-d": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-d'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-d" + } + ] + } + }, + "zones/us-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-a" + } + ] + } + }, + "zones/us-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-b" + } + ] + } + }, + "zones/us-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-c" + } + ] + } + }, + "zones/asia-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-a" + } + ] + } + }, + "zones/asia-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-b" + } + ] + } + }, + "zones/asia-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-c" + } + ] + } + }, + "zones/us-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-b" + } + ] + } + }, + "zones/us-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-c" + } + ] + } + }, + "zones/us-east1-d": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-d'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-d" + } + ] + } + }, + "zones/asia-northeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-a" + } + ] + } + }, + "zones/asia-northeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-b" + } + ] + } + }, + "zones/asia-northeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-c" + } + ] + } + }, + "zones/asia-southeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-a" + } + ] + } + }, + "zones/asia-southeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-b" + } + ] + } + }, + "zones/asia-southeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-c" + } + ] + } + }, + "zones/us-east4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-a" + } + ] + } + }, + "zones/us-east4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-b" + } + ] + } + }, + "zones/us-east4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-c" + } + ] + } + }, + "zones/australia-southeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-c" + } + ] + } + }, + "zones/australia-southeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-a" + } + ] + } + }, + "zones/australia-southeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-b" + } + ] + } + }, + "zones/europe-west2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-a" + } + ] + } + }, + "zones/europe-west2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-b" + } + ] + } + }, + "zones/europe-west2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-c" + } + ] + } + }, + "zones/europe-west3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-c" + } + ] + } + }, + "zones/europe-west3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-a" + } + ] + } + }, + "zones/europe-west3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-b" + } + ] + } + }, + "zones/southamerica-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-a" + } + ] + } + }, + "zones/southamerica-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-b" + } + ] + } + }, + "zones/southamerica-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-c" + } + ] + } + }, + "zones/asia-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-b" + } + ] + } + }, + "zones/asia-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-a" + } + ] + } + }, + "zones/asia-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-c" + } + ] + } + }, + "zones/northamerica-northeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-a" + } + ] + } + }, + "zones/northamerica-northeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-b" + } + ] + } + }, + "zones/northamerica-northeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-c" + } + ] + } + }, + "zones/europe-west4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-c" + } + ] + } + }, + "zones/europe-west4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-b" + } + ] + } + }, + "zones/europe-west4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-a" + } + ] + } + }, + "zones/europe-west4-ai1a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-ai1a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-ai1a" + } + ] + } + }, + "zones/europe-north1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-b" + } + ] + } + }, + "zones/europe-north1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-c" + } + ] + } + }, + "zones/europe-north1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-a" + } + ] + } + }, + "zones/us-west2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-c" + } + ] + } + }, + "zones/us-west2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-b" + } + ] + } + }, + "zones/us-west2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-a" + } + ] + } + }, + "zones/asia-east2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-c" + } + ] + } + }, + "zones/asia-east2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-b" + } + ] + } + }, + "zones/asia-east2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-a" + } + ] + } + }, + "zones/europe-west6-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-b" + } + ] + } + }, + "zones/europe-west6-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-c" + } + ] + } + }, + "zones/europe-west6-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-a" + } + ] + } + }, + "zones/asia-northeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-b" + } + ] + } + }, + "zones/asia-northeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-c" + } + ] + } + }, + "zones/asia-northeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-a" + } + ] + } + }, + "zones/asia-northeast3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-a" + } + ] + } + }, + "zones/asia-northeast3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-c" + } + ] + } + }, + "zones/asia-northeast3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-b" + } + ] + } + }, + "zones/us-west3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-a" + } + ] + } + }, + "zones/us-west3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-b" + } + ] + } + }, + "zones/us-west3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-c" + } + ] + } + }, + "zones/us-west4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-c" + } + ] + } + }, + "zones/us-west4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-a" + } + ] + } + }, + "zones/us-west4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-b" + } + ] + } + }, + "zones/asia-southeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-a" + } + ] + } + }, + "zones/asia-southeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-c" + } + ] + } + }, + "zones/asia-southeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-b" + } + ] + } + }, + "zones/europe-central2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-b" + } + ] + } + }, + "zones/europe-central2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-c" + } + ] + } + }, + "zones/europe-central2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-a" + } + ] + } + }, + "zones/northamerica-northeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-b" + } + ] + } + }, + "zones/northamerica-northeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-a" + } + ] + } + }, + "zones/northamerica-northeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-c" + } + ] + } + }, + "zones/asia-south2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-a" + } + ] + } + }, + "zones/asia-south2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-c" + } + ] + } + }, + "zones/asia-south2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-b" + } + ] + } + }, + "zones/australia-southeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-a" + } + ] + } + }, + "zones/australia-southeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-c" + } + ] + } + }, + "zones/australia-southeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-b" + } + ] + } + }, + "zones/southamerica-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-a" + } + ] + } + }, + "zones/southamerica-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-b" + } + ] + } + }, + "zones/southamerica-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-c" + } + ] + } + }, + "zones/europe-west8-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-a" + } + ] + } + }, + "zones/europe-west8-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-b" + } + ] + } + }, + "zones/europe-west8-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-c" + } + ] + } + }, + "zones/europe-west9-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-b" + } + ] + } + }, + "zones/europe-west9-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-a" + } + ] + } + }, + "zones/europe-west9-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-c" + } + ] + } + }, + "zones/us-east5-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-c" + } + ] + } + }, + "zones/us-east5-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-b" + } + ] + } + }, + "zones/us-east5-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-a" + } + ] + } + }, + "zones/europe-southwest1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-b" + } + ] + } + }, + "zones/europe-southwest1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-a" + } + ] + } + }, + "zones/europe-southwest1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-c" + } + ] + } + }, + "zones/us-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-c" + } + ] + } + }, + "zones/us-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-a" + } + ] + } + }, + "zones/us-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-b" + } + ] + } + }, + "zones/us-south1-ai1b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-ai1b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-ai1b" + } + ] + } + }, + "zones/me-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-b" + } + ] + } + }, + "zones/me-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-a" + } + ] + } + }, + "zones/me-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-c" + } + ] + } + }, + "zones/europe-west12-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-c" + } + ] + } + }, + "zones/europe-west12-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-a" + } + ] + } + }, + "zones/europe-west12-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-b" + } + ] + } + }, + "zones/me-central1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-a" + } + ] + } + }, + "zones/me-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-b" + } + ] + } + }, + "zones/me-central1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-c" + } + ] + } + }, + "zones/europe-west10-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-c" + } + ] + } + }, + "zones/europe-west10-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-a" + } + ] + } + }, + "zones/europe-west10-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-b" + } + ] + } + }, + "zones/me-central2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-c" + } + ] + } + }, + "zones/me-central2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-a" + } + ] + } + }, + "zones/me-central2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-b" + } + ] + } + }, + "zones/africa-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-b" + } + ] + } + }, + "zones/africa-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-a" + } + ] + } + }, + "zones/africa-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-c" + } + ] + } + }, + "zones/northamerica-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-b" + } + ] + } + }, + "zones/northamerica-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-a" + } + ] + } + }, + "zones/northamerica-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-c" + } + ] + } + }, + "zones/europe-north2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-c" + } + ] + } + }, + "zones/europe-north2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-a" + } + ] + } + }, + "zones/europe-north2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-b" + } + ] + } + }, + "zones/asia-southeast3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-b" + } + ] + } + }, + "zones/asia-southeast3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-c" + } + ] + } + }, + "zones/asia-southeast3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-a" + } + ] + } + } + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/disks" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-delete/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-delete/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks_1.json new file mode 100644 index 00000000000..682e048ec7e --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-delete/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks_1.json @@ -0,0 +1,23 @@ +{ + "headers": { + "etag": "S8CFtOoGhdBCggbCWg-S-jJ1C28=/PMqKmM6iFft3hgn8QAq-itZF31Q=", + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:04:48 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "201", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks?filter=name+%3D+c7n-regional-jenkins&alt=json" + }, + "body": { + "kind": "compute#diskList", + "id": "projects/cloud-custodian/regions/us-central1/disks", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-label/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-label/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json new file mode 100644 index 00000000000..06e3c6b56b9 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-label/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json @@ -0,0 +1,2136 @@ +{ + "headers": { + "etag": "6XAEYg3uB4_sqk4LxEYUrZ79TsU=/s9c0nTINKqvx_e3I0pfqmLOwz6w=", + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:03:34 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "53505", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/disks?alt=json" + }, + "body": { + "kind": "compute#diskAggregatedList", + "id": "projects/cloud-custodian/aggregated/disks", + "items": { + "regions/us-central1": { + "disks": [ + { + "kind": "compute#disk", + "id": "6800825139925708326", + "creationTimestamp": "2026-08-12T13:00:09.315-07:00", + "name": "c7n-regional-jenkins", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labelFingerprint": "42WmSpB8rSM=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } + ] + }, + "regions/europe-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west1" + } + ] + } + }, + "regions/us-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west1" + } + ] + } + }, + "regions/asia-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east1" + } + ] + } + }, + "regions/us-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east1" + } + ] + } + }, + "regions/asia-northeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast1" + } + ] + } + }, + "regions/asia-southeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast1" + } + ] + } + }, + "regions/us-east4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east4'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east4" + } + ] + } + }, + "regions/australia-southeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/australia-southeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/australia-southeast1" + } + ] + } + }, + "regions/europe-west2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west2" + } + ] + } + }, + "regions/europe-west3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west3'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west3" + } + ] + } + }, + "regions/southamerica-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/southamerica-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/southamerica-east1" + } + ] + } + }, + "regions/asia-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-south1" + } + ] + } + }, + "regions/northamerica-northeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-northeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-northeast1" + } + ] + } + }, + "regions/europe-west4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west4'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west4" + } + ] + } + }, + "regions/europe-north1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-north1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-north1" + } + ] + } + }, + "regions/us-west2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west2'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west2" + } + ] + } + }, + "regions/asia-east2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-east2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east2" + } + ] + } + }, + "regions/europe-west6": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west6'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west6" + } + ] + } + }, + "regions/asia-northeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast2" + } + ] + } + }, + "regions/asia-northeast3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast3'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast3" + } + ] + } + }, + "regions/us-west3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west3'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west3" + } + ] + } + }, + "regions/us-west4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west4'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west4" + } + ] + } + }, + "regions/asia-southeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast2" + } + ] + } + }, + "regions/europe-central2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-central2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-central2" + } + ] + } + }, + "regions/northamerica-northeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-northeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-northeast2" + } + ] + } + }, + "regions/asia-south2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-south2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-south2" + } + ] + } + }, + "regions/australia-southeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/australia-southeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/australia-southeast2" + } + ] + } + }, + "regions/southamerica-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/southamerica-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/southamerica-west1" + } + ] + } + }, + "regions/europe-west8": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west8'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west8" + } + ] + } + }, + "regions/europe-west9": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west9'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west9" + } + ] + } + }, + "regions/us-east5": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east5'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east5" + } + ] + } + }, + "regions/europe-southwest1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-southwest1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-southwest1" + } + ] + } + }, + "regions/us-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-south1" + } + ] + } + }, + "regions/me-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/me-west1" + } + ] + } + }, + "regions/europe-west12": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west12'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west12" + } + ] + } + }, + "regions/me-central1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-central1'.", + "data": [ + { + "key": "scope", + "value": "regions/me-central1" + } + ] + } + }, + "regions/europe-west10": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west10'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west10" + } + ] + } + }, + "regions/me-central2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-central2'.", + "data": [ + { + "key": "scope", + "value": "regions/me-central2" + } + ] + } + }, + "regions/africa-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/africa-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/africa-south1" + } + ] + } + }, + "regions/northamerica-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-south1" + } + ] + } + }, + "regions/europe-north2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-north2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-north2" + } + ] + } + }, + "regions/asia-southeast3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast3'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast3" + } + ] + } + }, + "zones/us-central1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-a" + } + ] + } + }, + "zones/us-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-b" + } + ] + } + }, + "zones/us-central1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-c" + } + ] + } + }, + "zones/us-central1-f": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-f'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-f" + } + ] + } + }, + "zones/europe-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-b" + } + ] + } + }, + "zones/europe-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-c" + } + ] + } + }, + "zones/europe-west1-d": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-d'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-d" + } + ] + } + }, + "zones/us-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-a" + } + ] + } + }, + "zones/us-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-b" + } + ] + } + }, + "zones/us-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-c" + } + ] + } + }, + "zones/asia-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-a" + } + ] + } + }, + "zones/asia-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-b" + } + ] + } + }, + "zones/asia-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-c" + } + ] + } + }, + "zones/us-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-b" + } + ] + } + }, + "zones/us-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-c" + } + ] + } + }, + "zones/us-east1-d": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-d'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-d" + } + ] + } + }, + "zones/asia-northeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-a" + } + ] + } + }, + "zones/asia-northeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-b" + } + ] + } + }, + "zones/asia-northeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-c" + } + ] + } + }, + "zones/asia-southeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-a" + } + ] + } + }, + "zones/asia-southeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-b" + } + ] + } + }, + "zones/asia-southeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-c" + } + ] + } + }, + "zones/us-east4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-a" + } + ] + } + }, + "zones/us-east4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-b" + } + ] + } + }, + "zones/us-east4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-c" + } + ] + } + }, + "zones/australia-southeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-c" + } + ] + } + }, + "zones/australia-southeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-a" + } + ] + } + }, + "zones/australia-southeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-b" + } + ] + } + }, + "zones/europe-west2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-a" + } + ] + } + }, + "zones/europe-west2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-b" + } + ] + } + }, + "zones/europe-west2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-c" + } + ] + } + }, + "zones/europe-west3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-c" + } + ] + } + }, + "zones/europe-west3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-a" + } + ] + } + }, + "zones/europe-west3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-b" + } + ] + } + }, + "zones/southamerica-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-a" + } + ] + } + }, + "zones/southamerica-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-b" + } + ] + } + }, + "zones/southamerica-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-c" + } + ] + } + }, + "zones/asia-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-b" + } + ] + } + }, + "zones/asia-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-a" + } + ] + } + }, + "zones/asia-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-c" + } + ] + } + }, + "zones/northamerica-northeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-a" + } + ] + } + }, + "zones/northamerica-northeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-b" + } + ] + } + }, + "zones/northamerica-northeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-c" + } + ] + } + }, + "zones/europe-west4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-c" + } + ] + } + }, + "zones/europe-west4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-b" + } + ] + } + }, + "zones/europe-west4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-a" + } + ] + } + }, + "zones/europe-west4-ai1a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-ai1a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-ai1a" + } + ] + } + }, + "zones/europe-north1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-b" + } + ] + } + }, + "zones/europe-north1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-c" + } + ] + } + }, + "zones/europe-north1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-a" + } + ] + } + }, + "zones/us-west2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-c" + } + ] + } + }, + "zones/us-west2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-b" + } + ] + } + }, + "zones/us-west2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-a" + } + ] + } + }, + "zones/asia-east2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-c" + } + ] + } + }, + "zones/asia-east2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-b" + } + ] + } + }, + "zones/asia-east2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-a" + } + ] + } + }, + "zones/europe-west6-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-b" + } + ] + } + }, + "zones/europe-west6-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-c" + } + ] + } + }, + "zones/europe-west6-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-a" + } + ] + } + }, + "zones/asia-northeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-b" + } + ] + } + }, + "zones/asia-northeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-c" + } + ] + } + }, + "zones/asia-northeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-a" + } + ] + } + }, + "zones/asia-northeast3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-a" + } + ] + } + }, + "zones/asia-northeast3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-c" + } + ] + } + }, + "zones/asia-northeast3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-b" + } + ] + } + }, + "zones/us-west3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-a" + } + ] + } + }, + "zones/us-west3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-b" + } + ] + } + }, + "zones/us-west3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-c" + } + ] + } + }, + "zones/us-west4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-c" + } + ] + } + }, + "zones/us-west4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-a" + } + ] + } + }, + "zones/us-west4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-b" + } + ] + } + }, + "zones/asia-southeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-a" + } + ] + } + }, + "zones/asia-southeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-c" + } + ] + } + }, + "zones/asia-southeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-b" + } + ] + } + }, + "zones/europe-central2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-b" + } + ] + } + }, + "zones/europe-central2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-c" + } + ] + } + }, + "zones/europe-central2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-a" + } + ] + } + }, + "zones/northamerica-northeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-b" + } + ] + } + }, + "zones/northamerica-northeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-a" + } + ] + } + }, + "zones/northamerica-northeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-c" + } + ] + } + }, + "zones/asia-south2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-a" + } + ] + } + }, + "zones/asia-south2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-c" + } + ] + } + }, + "zones/asia-south2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-b" + } + ] + } + }, + "zones/australia-southeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-a" + } + ] + } + }, + "zones/australia-southeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-c" + } + ] + } + }, + "zones/australia-southeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-b" + } + ] + } + }, + "zones/southamerica-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-a" + } + ] + } + }, + "zones/southamerica-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-b" + } + ] + } + }, + "zones/southamerica-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-c" + } + ] + } + }, + "zones/europe-west8-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-a" + } + ] + } + }, + "zones/europe-west8-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-b" + } + ] + } + }, + "zones/europe-west8-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-c" + } + ] + } + }, + "zones/europe-west9-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-b" + } + ] + } + }, + "zones/europe-west9-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-a" + } + ] + } + }, + "zones/europe-west9-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-c" + } + ] + } + }, + "zones/us-east5-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-c" + } + ] + } + }, + "zones/us-east5-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-b" + } + ] + } + }, + "zones/us-east5-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-a" + } + ] + } + }, + "zones/europe-southwest1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-b" + } + ] + } + }, + "zones/europe-southwest1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-a" + } + ] + } + }, + "zones/europe-southwest1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-c" + } + ] + } + }, + "zones/us-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-c" + } + ] + } + }, + "zones/us-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-a" + } + ] + } + }, + "zones/us-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-b" + } + ] + } + }, + "zones/us-south1-ai1b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-ai1b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-ai1b" + } + ] + } + }, + "zones/me-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-b" + } + ] + } + }, + "zones/me-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-a" + } + ] + } + }, + "zones/me-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-c" + } + ] + } + }, + "zones/europe-west12-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-c" + } + ] + } + }, + "zones/europe-west12-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-a" + } + ] + } + }, + "zones/europe-west12-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-b" + } + ] + } + }, + "zones/me-central1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-a" + } + ] + } + }, + "zones/me-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-b" + } + ] + } + }, + "zones/me-central1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-c" + } + ] + } + }, + "zones/europe-west10-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-c" + } + ] + } + }, + "zones/europe-west10-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-a" + } + ] + } + }, + "zones/europe-west10-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-b" + } + ] + } + }, + "zones/me-central2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-c" + } + ] + } + }, + "zones/me-central2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-a" + } + ] + } + }, + "zones/me-central2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-b" + } + ] + } + }, + "zones/africa-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-b" + } + ] + } + }, + "zones/africa-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-a" + } + ] + } + }, + "zones/africa-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-c" + } + ] + } + }, + "zones/northamerica-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-b" + } + ] + } + }, + "zones/northamerica-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-a" + } + ] + } + }, + "zones/northamerica-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-c" + } + ] + } + }, + "zones/europe-north2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-c" + } + ] + } + }, + "zones/europe-north2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-a" + } + ] + } + }, + "zones/europe-north2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-b" + } + ] + } + }, + "zones/asia-southeast3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-b" + } + ] + } + }, + "zones/asia-southeast3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-c" + } + ] + } + }, + "zones/asia-southeast3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-a" + } + ] + } + } + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/disks" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-label/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-label/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks_1.json new file mode 100644 index 00000000000..e1f8f9be697 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-label/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks_1.json @@ -0,0 +1,47 @@ +{ + "headers": { + "etag": "XgZHu_Epie0YwFBAbOMv2mjmAr4=/UhSUzIDbJby5LqzoJ_6AVwuGbrA=", + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:03:35 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1224", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks?filter=name+%3D+c7n-regional-jenkins&alt=json" + }, + "body": { + "kind": "compute#diskList", + "id": "projects/cloud-custodian/regions/us-central1/disks", + "items": [ + { + "kind": "compute#disk", + "id": "6800825139925708326", + "creationTimestamp": "2026-08-12T13:00:09.315-07:00", + "name": "c7n-regional-jenkins", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labels": { + "test_label": "test_value" + }, + "labelFingerprint": "CHILmtzyjdE=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } + ], + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-label/post-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins-setLabels_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-label/post-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins-setLabels_1.json new file mode 100644 index 00000000000..e5e93d9a3e6 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-label/post-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins-setLabels_1.json @@ -0,0 +1,32 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:03:35 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "817", + "-content-encoding": "gzip" + }, + "body": { + "kind": "compute#operation", + "id": "1422926374755200888", + "name": "operation-1786565015150-658df15189ef9-1d4b7499-b1d347f3", + "operationType": "setLabels", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "targetId": "6800825139925708326", + "status": "DONE", + "user": "jim.fulton@sixfeetup.com", + "progress": 100, + "insertTime": "2026-08-12T13:03:35.257-07:00", + "startTime": "2026-08-12T13:03:35.264-07:00", + "endTime": "2026-08-12T13:03:35.266-07:00", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/operation-1786565015150-658df15189ef9-1d4b7499-b1d347f3", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-snapshot/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-snapshot/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json new file mode 100644 index 00000000000..c84d4984f5e --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-snapshot/get-compute.googleapis.com-compute-v1-projects-cloud-custodian-aggregated-disks_1.json @@ -0,0 +1,2136 @@ +{ + "headers": { + "etag": "U3cawc25C9cb00RlTzTp2zhar-k=/hidQr16Aqg-wygRuclC0ZI50hIk=", + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:02:30 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "53505", + "-content-encoding": "gzip", + "content-location": "https://compute.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/disks?alt=json" + }, + "body": { + "kind": "compute#diskAggregatedList", + "id": "projects/cloud-custodian/aggregated/disks", + "items": { + "regions/us-central1": { + "disks": [ + { + "kind": "compute#disk", + "id": "6800825139925708326", + "creationTimestamp": "2026-08-12T13:00:09.315-07:00", + "name": "c7n-regional-jenkins", + "sizeGb": "10", + "status": "READY", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "type": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/diskTypes/pd-ssd", + "labelFingerprint": "42WmSpB8rSM=", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1", + "replicaZones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "physicalBlockSizeBytes": "4096", + "enableConfidentialCompute": false, + "satisfiesPzi": true + } + ] + }, + "regions/europe-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west1" + } + ] + } + }, + "regions/us-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west1" + } + ] + } + }, + "regions/asia-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east1" + } + ] + } + }, + "regions/us-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east1" + } + ] + } + }, + "regions/asia-northeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast1" + } + ] + } + }, + "regions/asia-southeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast1" + } + ] + } + }, + "regions/us-east4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east4'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east4" + } + ] + } + }, + "regions/australia-southeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/australia-southeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/australia-southeast1" + } + ] + } + }, + "regions/europe-west2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west2" + } + ] + } + }, + "regions/europe-west3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west3'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west3" + } + ] + } + }, + "regions/southamerica-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/southamerica-east1'.", + "data": [ + { + "key": "scope", + "value": "regions/southamerica-east1" + } + ] + } + }, + "regions/asia-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-south1" + } + ] + } + }, + "regions/northamerica-northeast1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-northeast1'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-northeast1" + } + ] + } + }, + "regions/europe-west4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west4'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west4" + } + ] + } + }, + "regions/europe-north1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-north1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-north1" + } + ] + } + }, + "regions/us-west2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west2'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west2" + } + ] + } + }, + "regions/asia-east2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-east2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east2" + } + ] + } + }, + "regions/europe-west6": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west6'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west6" + } + ] + } + }, + "regions/asia-northeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast2" + } + ] + } + }, + "regions/asia-northeast3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-northeast3'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-northeast3" + } + ] + } + }, + "regions/us-west3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west3'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west3" + } + ] + } + }, + "regions/us-west4": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-west4'.", + "data": [ + { + "key": "scope", + "value": "regions/us-west4" + } + ] + } + }, + "regions/asia-southeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast2" + } + ] + } + }, + "regions/europe-central2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-central2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-central2" + } + ] + } + }, + "regions/northamerica-northeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-northeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-northeast2" + } + ] + } + }, + "regions/asia-south2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-south2'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-south2" + } + ] + } + }, + "regions/australia-southeast2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/australia-southeast2'.", + "data": [ + { + "key": "scope", + "value": "regions/australia-southeast2" + } + ] + } + }, + "regions/southamerica-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/southamerica-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/southamerica-west1" + } + ] + } + }, + "regions/europe-west8": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west8'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west8" + } + ] + } + }, + "regions/europe-west9": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west9'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west9" + } + ] + } + }, + "regions/us-east5": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-east5'.", + "data": [ + { + "key": "scope", + "value": "regions/us-east5" + } + ] + } + }, + "regions/europe-southwest1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-southwest1'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-southwest1" + } + ] + } + }, + "regions/us-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/us-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/us-south1" + } + ] + } + }, + "regions/me-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-west1'.", + "data": [ + { + "key": "scope", + "value": "regions/me-west1" + } + ] + } + }, + "regions/europe-west12": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west12'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west12" + } + ] + } + }, + "regions/me-central1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-central1'.", + "data": [ + { + "key": "scope", + "value": "regions/me-central1" + } + ] + } + }, + "regions/europe-west10": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-west10'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west10" + } + ] + } + }, + "regions/me-central2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/me-central2'.", + "data": [ + { + "key": "scope", + "value": "regions/me-central2" + } + ] + } + }, + "regions/africa-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/africa-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/africa-south1" + } + ] + } + }, + "regions/northamerica-south1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/northamerica-south1'.", + "data": [ + { + "key": "scope", + "value": "regions/northamerica-south1" + } + ] + } + }, + "regions/europe-north2": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/europe-north2'.", + "data": [ + { + "key": "scope", + "value": "regions/europe-north2" + } + ] + } + }, + "regions/asia-southeast3": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'regions/asia-southeast3'.", + "data": [ + { + "key": "scope", + "value": "regions/asia-southeast3" + } + ] + } + }, + "zones/us-central1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-a" + } + ] + } + }, + "zones/us-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-b" + } + ] + } + }, + "zones/us-central1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-c" + } + ] + } + }, + "zones/us-central1-f": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-central1-f'.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-f" + } + ] + } + }, + "zones/europe-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-b" + } + ] + } + }, + "zones/europe-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-c" + } + ] + } + }, + "zones/europe-west1-d": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west1-d'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-d" + } + ] + } + }, + "zones/us-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-a" + } + ] + } + }, + "zones/us-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-b" + } + ] + } + }, + "zones/us-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west1-c" + } + ] + } + }, + "zones/asia-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-a" + } + ] + } + }, + "zones/asia-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-b" + } + ] + } + }, + "zones/asia-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-c" + } + ] + } + }, + "zones/us-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-b" + } + ] + } + }, + "zones/us-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-c" + } + ] + } + }, + "zones/us-east1-d": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east1-d'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east1-d" + } + ] + } + }, + "zones/asia-northeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-a" + } + ] + } + }, + "zones/asia-northeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-b" + } + ] + } + }, + "zones/asia-northeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast1-c" + } + ] + } + }, + "zones/asia-southeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-a" + } + ] + } + }, + "zones/asia-southeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-b" + } + ] + } + }, + "zones/asia-southeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast1-c" + } + ] + } + }, + "zones/us-east4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-a" + } + ] + } + }, + "zones/us-east4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-b" + } + ] + } + }, + "zones/us-east4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east4-c" + } + ] + } + }, + "zones/australia-southeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-c" + } + ] + } + }, + "zones/australia-southeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-a" + } + ] + } + }, + "zones/australia-southeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast1-b" + } + ] + } + }, + "zones/europe-west2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-a" + } + ] + } + }, + "zones/europe-west2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-b" + } + ] + } + }, + "zones/europe-west2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west2-c" + } + ] + } + }, + "zones/europe-west3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-c" + } + ] + } + }, + "zones/europe-west3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-a" + } + ] + } + }, + "zones/europe-west3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west3-b" + } + ] + } + }, + "zones/southamerica-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-a" + } + ] + } + }, + "zones/southamerica-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-b" + } + ] + } + }, + "zones/southamerica-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-east1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-east1-c" + } + ] + } + }, + "zones/asia-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-b" + } + ] + } + }, + "zones/asia-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-a" + } + ] + } + }, + "zones/asia-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south1-c" + } + ] + } + }, + "zones/northamerica-northeast1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-a" + } + ] + } + }, + "zones/northamerica-northeast1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-b" + } + ] + } + }, + "zones/northamerica-northeast1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast1-c" + } + ] + } + }, + "zones/europe-west4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-c" + } + ] + } + }, + "zones/europe-west4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-b" + } + ] + } + }, + "zones/europe-west4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-a" + } + ] + } + }, + "zones/europe-west4-ai1a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west4-ai1a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west4-ai1a" + } + ] + } + }, + "zones/europe-north1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-b" + } + ] + } + }, + "zones/europe-north1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-c" + } + ] + } + }, + "zones/europe-north1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north1-a" + } + ] + } + }, + "zones/us-west2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-c" + } + ] + } + }, + "zones/us-west2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-b" + } + ] + } + }, + "zones/us-west2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west2-a" + } + ] + } + }, + "zones/asia-east2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-c" + } + ] + } + }, + "zones/asia-east2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-b" + } + ] + } + }, + "zones/asia-east2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-east2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east2-a" + } + ] + } + }, + "zones/europe-west6-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-b" + } + ] + } + }, + "zones/europe-west6-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-c" + } + ] + } + }, + "zones/europe-west6-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west6-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west6-a" + } + ] + } + }, + "zones/asia-northeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-b" + } + ] + } + }, + "zones/asia-northeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-c" + } + ] + } + }, + "zones/asia-northeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast2-a" + } + ] + } + }, + "zones/asia-northeast3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-a" + } + ] + } + }, + "zones/asia-northeast3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-c" + } + ] + } + }, + "zones/asia-northeast3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-northeast3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-northeast3-b" + } + ] + } + }, + "zones/us-west3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-a" + } + ] + } + }, + "zones/us-west3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-b" + } + ] + } + }, + "zones/us-west3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west3-c" + } + ] + } + }, + "zones/us-west4-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-c" + } + ] + } + }, + "zones/us-west4-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-a" + } + ] + } + }, + "zones/us-west4-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-west4-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-west4-b" + } + ] + } + }, + "zones/asia-southeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-a" + } + ] + } + }, + "zones/asia-southeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-c" + } + ] + } + }, + "zones/asia-southeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast2-b" + } + ] + } + }, + "zones/europe-central2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-b" + } + ] + } + }, + "zones/europe-central2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-c" + } + ] + } + }, + "zones/europe-central2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-central2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-central2-a" + } + ] + } + }, + "zones/northamerica-northeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-b" + } + ] + } + }, + "zones/northamerica-northeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-a" + } + ] + } + }, + "zones/northamerica-northeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-northeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-northeast2-c" + } + ] + } + }, + "zones/asia-south2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-a" + } + ] + } + }, + "zones/asia-south2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-c" + } + ] + } + }, + "zones/asia-south2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-south2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-south2-b" + } + ] + } + }, + "zones/australia-southeast2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-a" + } + ] + } + }, + "zones/australia-southeast2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-c" + } + ] + } + }, + "zones/australia-southeast2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/australia-southeast2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/australia-southeast2-b" + } + ] + } + }, + "zones/southamerica-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-a" + } + ] + } + }, + "zones/southamerica-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-b" + } + ] + } + }, + "zones/southamerica-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/southamerica-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/southamerica-west1-c" + } + ] + } + }, + "zones/europe-west8-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-a" + } + ] + } + }, + "zones/europe-west8-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-b" + } + ] + } + }, + "zones/europe-west8-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west8-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west8-c" + } + ] + } + }, + "zones/europe-west9-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-b" + } + ] + } + }, + "zones/europe-west9-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-a" + } + ] + } + }, + "zones/europe-west9-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west9-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west9-c" + } + ] + } + }, + "zones/us-east5-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-c" + } + ] + } + }, + "zones/us-east5-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-b" + } + ] + } + }, + "zones/us-east5-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-east5-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-east5-a" + } + ] + } + }, + "zones/europe-southwest1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-b" + } + ] + } + }, + "zones/europe-southwest1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-a" + } + ] + } + }, + "zones/europe-southwest1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-southwest1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-southwest1-c" + } + ] + } + }, + "zones/us-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-c" + } + ] + } + }, + "zones/us-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-a" + } + ] + } + }, + "zones/us-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-b" + } + ] + } + }, + "zones/us-south1-ai1b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/us-south1-ai1b'.", + "data": [ + { + "key": "scope", + "value": "zones/us-south1-ai1b" + } + ] + } + }, + "zones/me-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-b" + } + ] + } + }, + "zones/me-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-a" + } + ] + } + }, + "zones/me-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-west1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-west1-c" + } + ] + } + }, + "zones/europe-west12-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-c" + } + ] + } + }, + "zones/europe-west12-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-a" + } + ] + } + }, + "zones/europe-west12-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west12-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west12-b" + } + ] + } + }, + "zones/me-central1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-a" + } + ] + } + }, + "zones/me-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-b" + } + ] + } + }, + "zones/me-central1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central1-c" + } + ] + } + }, + "zones/europe-west10-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-c" + } + ] + } + }, + "zones/europe-west10-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-a" + } + ] + } + }, + "zones/europe-west10-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-west10-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west10-b" + } + ] + } + }, + "zones/me-central2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-c" + } + ] + } + }, + "zones/me-central2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-a" + } + ] + } + }, + "zones/me-central2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/me-central2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/me-central2-b" + } + ] + } + }, + "zones/africa-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-b" + } + ] + } + }, + "zones/africa-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-a" + } + ] + } + }, + "zones/africa-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/africa-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/africa-south1-c" + } + ] + } + }, + "zones/northamerica-south1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-b'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-b" + } + ] + } + }, + "zones/northamerica-south1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-a'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-a" + } + ] + } + }, + "zones/northamerica-south1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/northamerica-south1-c'.", + "data": [ + { + "key": "scope", + "value": "zones/northamerica-south1-c" + } + ] + } + }, + "zones/europe-north2-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-c'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-c" + } + ] + } + }, + "zones/europe-north2-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-a'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-a" + } + ] + } + }, + "zones/europe-north2-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/europe-north2-b'.", + "data": [ + { + "key": "scope", + "value": "zones/europe-north2-b" + } + ] + } + }, + "zones/asia-southeast3-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-b'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-b" + } + ] + } + }, + "zones/asia-southeast3-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-c'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-c" + } + ] + } + }, + "zones/asia-southeast3-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "No results for the scope 'zones/asia-southeast3-a'.", + "data": [ + { + "key": "scope", + "value": "zones/asia-southeast3-a" + } + ] + } + } + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/aggregated/disks" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/disk-regional-snapshot/post-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins-createSnapshot_1.json b/tools/c7n_gcp/tests/data/flights/disk-regional-snapshot/post-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins-createSnapshot_1.json new file mode 100644 index 00000000000..4aa5e0ce739 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/disk-regional-snapshot/post-compute.googleapis.com-compute-v1-projects-cloud-custodian-regions-us-central1-disks-c7n-regional-jenkins-createSnapshot_1.json @@ -0,0 +1,31 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 20:02:31 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "777", + "-content-encoding": "gzip" + }, + "body": { + "kind": "compute#operation", + "id": "5416409115722346425", + "name": "operation-1786564950373-658df113c3332-2a0bc0ef-21d43838", + "operationType": "createSnapshot", + "targetLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-regional-jenkins", + "targetId": "6800825139925708326", + "status": "RUNNING", + "user": "jim.fulton@sixfeetup.com", + "progress": 0, + "insertTime": "2026-08-12T13:02:30.528-07:00", + "startTime": "2026-08-12T13:02:30.534-07:00", + "selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/operations/operation-1786564950373-658df113c3332-2a0bc0ef-21d43838", + "region": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/gcp-cloud-run-service-mark-for-op/get-v1-projects-cloud-custodian-locations---services_1.json b/tools/c7n_gcp/tests/data/flights/gcp-cloud-run-service-mark-for-op/get-v1-projects-cloud-custodian-locations---services_1.json new file mode 100644 index 00000000000..998083a29fb --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/gcp-cloud-run-service-mark-for-op/get-v1-projects-cloud-custodian-locations---services_1.json @@ -0,0 +1,57 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "status": "200" + }, + "body": { + "apiVersion": "serving.knative.dev/v1", + "kind": "ServiceList", + "items": [ + { + "apiVersion": "serving.knative.dev/v1", + "kind": "Service", + "metadata": { + "name": "hello", + "namespace": "cloud-custodian", + "selfLink": "/apis/serving.knative.dev/v1/namespaces/cloud-custodian/services/hello", + "uid": "46b28549-6c5c-4245-bc8d-9cec06d262b6", + "resourceVersion": "AAX4MAndusc", + "generation": 1, + "labels": { + "cloud.googleapis.com/location": "us-central1" + }, + "annotations": { + "run.googleapis.com/ingress": "all" + }, + "creationTimestamp": "2023-03-31T10:53:45.882066Z" + }, + "spec": { + "template": { + "metadata": { + "name": "hello-00001-tiv", + "annotations": {} + }, + "spec": { + "containerConcurrency": 80, + "timeoutSeconds": 300, + "containers": [ + { + "image": "us-docker.pkg.dev/cloudrun/container/hello", + "ports": [{"name": "http1", "containerPort": 8080}] + } + ] + } + }, + "traffic": [{"percent": 100, "latestRevision": true}] + }, + "status": { + "observedGeneration": 1, + "conditions": [ + {"type": "Ready", "status": "True"} + ], + "url": "https://hello-g3kdvpt64a-uc.a.run.app" + } + } + ] + } +} diff --git a/tools/c7n_gcp/tests/data/flights/gcp-cloud-run-service-mark-for-op/put-v1-projects-cloud-custodian-locations-us-central1-services-hello_1.json b/tools/c7n_gcp/tests/data/flights/gcp-cloud-run-service-mark-for-op/put-v1-projects-cloud-custodian-locations-us-central1-services-hello_1.json new file mode 100644 index 00000000000..b64a30335e2 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/gcp-cloud-run-service-mark-for-op/put-v1-projects-cloud-custodian-locations-us-central1-services-hello_1.json @@ -0,0 +1,52 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "status": "200" + }, + "body": { + "apiVersion": "serving.knative.dev/v1", + "kind": "Service", + "metadata": { + "name": "hello", + "namespace": "cloud-custodian", + "selfLink": "/apis/serving.knative.dev/v1/namespaces/cloud-custodian/services/hello", + "uid": "46b28549-6c5c-4245-bc8d-9cec06d262b6", + "resourceVersion": "AAX4MBndusc", + "generation": 2, + "labels": { + "cloud.googleapis.com/location": "us-central1", + "custodian_status": "resource_policy-notify-2026_08_21__0_0" + }, + "annotations": { + "run.googleapis.com/ingress": "all" + }, + "creationTimestamp": "2023-03-31T10:53:45.882066Z" + }, + "spec": { + "template": { + "metadata": { + "name": "hello-00001-tiv", + "annotations": {} + }, + "spec": { + "containerConcurrency": 80, + "timeoutSeconds": 300, + "containers": [ + { + "image": "us-docker.pkg.dev/cloudrun/container/hello", + "ports": [{"name": "http1", "containerPort": 8080}] + } + ] + } + }, + "traffic": [{"percent": 100, "latestRevision": true}] + }, + "status": { + "observedGeneration": 2, + "conditions": [ + {"type": "Ready", "status": "True"} + ], + "url": "https://hello-g3kdvpt64a-uc.a.run.app" + } + } +} diff --git a/tools/c7n_gcp/tests/data/flights/notebook_v2/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json b/tools/c7n_gcp/tests/data/flights/notebook_v2/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json new file mode 100644 index 00000000000..51ae092eb33 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/notebook_v2/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json @@ -0,0 +1,199 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 17:31:46 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "7337", + "-content-encoding": "gzip", + "content-location": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/-/instances?alt=json" + }, + "body": { + "instances": [ + { + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "gceSetup": { + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", + "serviceAccounts": [ + { + "email": "693936050605-compute@developer.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email" + ] + } + ], + "bootDisk": { + "diskSizeGb": "150", + "diskEncryption": "GMEK" + }, + "dataDisks": [ + { + "diskSizeGb": "100", + "diskEncryption": "GMEK" + } + ], + "shieldedInstanceConfig": { + "enableVtpm": true, + "enableIntegrityMonitoring": true + }, + "networkInterfaces": [ + { + "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default", + "accessConfigs": [ + { + "externalIp": "34.24.11.45" + } + ] + } + ], + "tags": [ + "deeplearning-vm", + "notebook-instance" + ], + "metadata": { + "proxy-mode": "service_account", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "notebooks-api": "PROD", + "version": "20260809-2130-rc0", + "new-proxy-agent-enabled": "true", + "serial-port-logging-enable": "true", + "enable-jupyterlab4": "true", + "disable-swap-binaries": "true", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-backend-id": "4c6d45c45d3b5c10", + "notebooks-api-version": "v2", + "instance-region": "us-east1", + "enable-guest-attributes": "TRUE", + "enable-oslogin": "TRUE", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a:reportInfoSystem", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "proxy-url": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com" + }, + "gpuDriverConfig": {}, + "reservationAffinity": { + "consumeReservationType": "RESERVATION_NONE" + }, + "minCpuPlatform": "Intel Broadwell", + "instanceId": "4532768441233380276" + }, + "proxyUri": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", + "state": "ACTIVE", + "id": "4592c76e-b080-4826-8607-f0a052691732", + "healthState": "HEALTHY", + "healthInfo": { + "last_updated": "2026-08-12T17:31:31+00:00", + "system_health": "1", + "docker_status": "1", + "jupyterlab_status": "1", + "jupyterlab_api_status": "1" + }, + "createTime": "2026-08-12T17:28:57.651511852Z", + "updateTime": "2026-08-12T17:31:34.414168879Z", + "labels": { + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", + "goog-terraform-provisioned": "true", + "notebooks-product": "workbench-instances", + "resource-name": "c7n-notebook-public-default-e84a" + }, + "satisfiesPzi": true + }, + { + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", + "gceSetup": { + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", + "serviceAccounts": [ + { + "email": "693936050605-compute@developer.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email" + ] + } + ], + "bootDisk": { + "diskSizeGb": "150", + "diskEncryption": "GMEK" + }, + "dataDisks": [ + { + "diskSizeGb": "100", + "diskEncryption": "GMEK" + } + ], + "shieldedInstanceConfig": { + "enableVtpm": true, + "enableIntegrityMonitoring": true + }, + "networkInterfaces": [ + { + "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default" + } + ], + "disablePublicIp": true, + "tags": [ + "deeplearning-vm", + "notebook-instance" + ], + "metadata": { + "new-proxy-agent-enabled": "true", + "enable-guest-attributes": "TRUE", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-backend-id": "18e7172261907cfe", + "disable-swap-binaries": "true", + "serial-port-logging-enable": "true", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a:reportInfoSystem", + "enable-oslogin": "TRUE", + "proxy-mode": "service_account", + "notebooks-api-version": "v2", + "notebooks-api": "PROD", + "proxy-url": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "version": "20260809-2130-rc0", + "enable-jupyterlab4": "true", + "instance-region": "us-east1" + }, + "gpuDriverConfig": {}, + "reservationAffinity": { + "consumeReservationType": "RESERVATION_NONE" + }, + "minCpuPlatform": "Intel Broadwell", + "instanceId": "3328585780394267572" + }, + "proxyUri": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", + "state": "ACTIVE", + "id": "aa2cf267-c071-4c10-a58e-d77e1b31c80c", + "healthState": "HEALTHY", + "healthInfo": { + "system_health": "1", + "docker_status": "1", + "jupyterlab_status": "1", + "jupyterlab_api_status": "1", + "last_updated": "2026-08-12T17:31:31+00:00" + }, + "createTime": "2026-08-12T17:28:57.622710654Z", + "updateTime": "2026-08-12T17:31:33.883494551Z", + "labels": { + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", + "goog-terraform-provisioned": "true", + "notebooks-product": "workbench-instances", + "resource-name": "c7n-notebook-private-default-e84a" + }, + "satisfiesPzi": true + } + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/notebook_v2/get-v2-projects-cloud-custodian-locations---instances_1.json b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_get/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json similarity index 60% rename from tools/c7n_gcp/tests/data/flights/notebook_v2/get-v2-projects-cloud-custodian-locations---instances_1.json rename to tools/c7n_gcp/tests/data/flights/test_notebook_v2_get/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json index 8a69fc284cf..a395fbdac6c 100644 --- a/tools/c7n_gcp/tests/data/flights/notebook_v2/get-v2-projects-cloud-custodian-locations---instances_1.json +++ b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_get/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json @@ -2,7 +2,7 @@ "headers": { "content-type": "application/json; charset=UTF-8", "vary": "Origin, X-Origin, Referer", - "date": "Mon, 06 Jul 2026 21:17:17 GMT", + "date": "Wed, 12 Aug 2026 17:31:48 GMT", "server": "ESF", "x-xss-protection": "0", "x-frame-options": "SAMEORIGIN", @@ -10,19 +10,19 @@ "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", "transfer-encoding": "chunked", "status": "200", - "content-length": "7344", + "content-length": "7337", "-content-encoding": "gzip", "content-location": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/-/instances?alt=json" }, "body": { "instances": [ { - "name": "projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-private-default-62ac", + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", "gceSetup": { - "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/machineTypes/e2-standard-4", + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", "serviceAccounts": [ { - "email": "859150599087-compute@developer.gserviceaccount.com", + "email": "693936050605-compute@developer.gserviceaccount.com", "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email" @@ -46,68 +46,74 @@ "networkInterfaces": [ { "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", - "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/subnetworks/default" + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default", + "accessConfigs": [ + { + "externalIp": "34.24.11.45" + } + ] } ], - "disablePublicIp": true, "tags": [ "deeplearning-vm", "notebook-instance" ], "metadata": { "enable-guest-attributes": "TRUE", - "version": "20260701-2130-rc0", - "proxy-registration-url": "https://us-central1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", - "proxy-backend-id": "c1cccbd5b589747", - "enable-oslogin": "TRUE", - "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-private-default-62ac:reportInfoSystem", + "notebooks-api-version": "v2", + "enable-jupyterlab4": "true", + "instance-region": "us-east1", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-url": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a:reportInfoSystem", + "disable-swap-binaries": "true", + "new-proxy-agent-enabled": "true", "proxy-mode": "service_account", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", "serial-port-logging-enable": "true", - "enable-jupyterlab4": "true", - "proxy-url": "c1cccbd5b589747-dot-us-central1.notebooks.googleusercontent.com", - "instance-region": "us-central1", - "disable-swap-binaries": "true", - "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-private-default-62ac", + "enable-oslogin": "TRUE", "notebooks-api": "PROD", - "notebooks-api-version": "v2" + "proxy-backend-id": "4c6d45c45d3b5c10", + "version": "20260809-2130-rc0" }, "gpuDriverConfig": {}, "reservationAffinity": { "consumeReservationType": "RESERVATION_NONE" }, "minCpuPlatform": "Intel Broadwell", - "instanceId": "4627125088861398104" + "instanceId": "4532768441233380276" }, - "proxyUri": "c1cccbd5b589747-dot-us-central1.notebooks.googleusercontent.com", - "creator": "caleb.syring@sixfeetup.com", + "proxyUri": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", "state": "ACTIVE", - "id": "795baaa1-dd66-4928-bbfe-f3c13817168d", + "id": "4592c76e-b080-4826-8607-f0a052691732", "healthState": "HEALTHY", "healthInfo": { - "system_health": "1", - "docker_status": "1", "jupyterlab_status": "1", "jupyterlab_api_status": "1", - "last_updated": "2026-07-06T21:17:05+00:00" + "last_updated": "2026-08-12T17:31:31+00:00", + "system_health": "1", + "docker_status": "1" }, - "createTime": "2026-07-06T21:14:29.701611482Z", - "updateTime": "2026-07-06T21:17:08.522978131Z", + "createTime": "2026-08-12T17:28:57.651511852Z", + "updateTime": "2026-08-12T17:31:34.414168879Z", "labels": { "notebooks-product": "workbench-instances", - "resource-name": "c7n-notebook-private-default-62ac", - "consumer-project-id": "stacklet-test-policies", - "consumer-project-number": "859150599087", + "resource-name": "c7n-notebook-public-default-e84a", + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", "goog-terraform-provisioned": "true" - } + }, + "satisfiesPzi": true }, { - "name": "projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-public-default-62ac", + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", "gceSetup": { - "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/machineTypes/e2-standard-4", + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", "serviceAccounts": [ { - "email": "859150599087-compute@developer.gserviceaccount.com", + "email": "693936050605-compute@developer.gserviceaccount.com", "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email" @@ -131,64 +137,62 @@ "networkInterfaces": [ { "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", - "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/subnetworks/default", - "accessConfigs": [ - { - "externalIp": "34.44.21.60" - } - ] + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default" } ], + "disablePublicIp": true, "tags": [ "deeplearning-vm", "notebook-instance" ], "metadata": { - "proxy-mode": "service_account", + "serial-port-logging-enable": "true", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", "notebooks-api-version": "v2", - "proxy-backend-id": "42ebbe1e0dc75006", - "enable-oslogin": "TRUE", - "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-public-default-62ac", - "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-public-default-62ac:reportInfoSystem", - "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "instance-region": "us-east1", "notebooks-api": "PROD", + "proxy-backend-id": "18e7172261907cfe", "disable-swap-binaries": "true", - "enable-jupyterlab4": "true", - "proxy-registration-url": "https://us-central1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "new-proxy-agent-enabled": "true", "enable-guest-attributes": "TRUE", - "proxy-url": "42ebbe1e0dc75006-dot-us-central1.notebooks.googleusercontent.com", - "version": "20260701-2130-rc0", - "instance-region": "us-central1", - "serial-port-logging-enable": "true" + "enable-jupyterlab4": "true", + "enable-oslogin": "TRUE", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a:reportInfoSystem", + "proxy-url": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "version": "20260809-2130-rc0", + "proxy-mode": "service_account", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14" }, "gpuDriverConfig": {}, "reservationAffinity": { "consumeReservationType": "RESERVATION_NONE" }, "minCpuPlatform": "Intel Broadwell", - "instanceId": "6403941033308169304" + "instanceId": "3328585780394267572" }, - "proxyUri": "42ebbe1e0dc75006-dot-us-central1.notebooks.googleusercontent.com", - "creator": "caleb.syring@sixfeetup.com", + "proxyUri": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", "state": "ACTIVE", - "id": "b741f681-7032-45a3-ba13-5d4623f7987d", + "id": "aa2cf267-c071-4c10-a58e-d77e1b31c80c", "healthState": "HEALTHY", "healthInfo": { "system_health": "1", "docker_status": "1", "jupyterlab_status": "1", "jupyterlab_api_status": "1", - "last_updated": "2026-07-06T21:17:04+00:00" + "last_updated": "2026-08-12T17:31:31+00:00" }, - "createTime": "2026-07-06T21:14:29.722087079Z", - "updateTime": "2026-07-06T21:17:07.483043670Z", + "createTime": "2026-08-12T17:28:57.622710654Z", + "updateTime": "2026-08-12T17:31:33.883494551Z", "labels": { - "consumer-project-id": "stacklet-test-policies", - "consumer-project-number": "859150599087", + "consumer-project-number": "693936050605", "goog-terraform-provisioned": "true", "notebooks-product": "workbench-instances", - "resource-name": "c7n-notebook-public-default-62ac" - } + "resource-name": "c7n-notebook-private-default-e84a", + "consumer-project-id": "stkl-jim-fulton" + }, + "satisfiesPzi": true } ] } diff --git a/tools/c7n_gcp/tests/data/flights/test_notebook_v2_get/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_get/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json new file mode 100644 index 00000000000..25fae5cd53d --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_get/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json @@ -0,0 +1,114 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 17:31:48 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "3513", + "-content-encoding": "gzip", + "content-location": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a?alt=json" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "gceSetup": { + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", + "serviceAccounts": [ + { + "email": "693936050605-compute@developer.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email" + ] + } + ], + "vmImage": { + "project": "cloud-notebooks-managed", + "family": "workbench-instances-2603" + }, + "bootDisk": { + "diskSizeGb": "150", + "diskType": "PD_STANDARD", + "diskEncryption": "GMEK" + }, + "dataDisks": [ + { + "diskSizeGb": "100", + "diskType": "PD_STANDARD", + "diskEncryption": "GMEK" + } + ], + "shieldedInstanceConfig": { + "enableVtpm": true, + "enableIntegrityMonitoring": true + }, + "networkInterfaces": [ + { + "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default", + "accessConfigs": [ + { + "externalIp": "34.24.11.45" + } + ] + } + ], + "tags": [ + "deeplearning-vm", + "notebook-instance" + ], + "metadata": { + "proxy-url": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "serial-port-logging-enable": "true", + "version": "20260809-2130-rc0", + "enable-oslogin": "TRUE", + "disable-swap-binaries": "true", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "notebooks-api-version": "v2", + "enable-jupyterlab4": "true", + "proxy-mode": "service_account", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-backend-id": "4c6d45c45d3b5c10", + "notebooks-api": "PROD", + "new-proxy-agent-enabled": "true", + "enable-guest-attributes": "TRUE", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a:reportInfoSystem", + "instance-region": "us-east1" + }, + "gpuDriverConfig": {}, + "reservationAffinity": { + "consumeReservationType": "RESERVATION_NONE" + }, + "minCpuPlatform": "Intel Broadwell", + "instanceId": "4532768441233380276" + }, + "proxyUri": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", + "state": "ACTIVE", + "id": "4592c76e-b080-4826-8607-f0a052691732", + "healthState": "HEALTHY", + "healthInfo": { + "system_health": "1", + "docker_status": "1", + "jupyterlab_status": "1", + "jupyterlab_api_status": "1", + "last_updated": "2026-08-12T17:31:31+00:00" + }, + "createTime": "2026-08-12T17:28:57.651511852Z", + "updateTime": "2026-08-12T17:31:34.414168879Z", + "labels": { + "consumer-project-number": "693936050605", + "goog-terraform-provisioned": "true", + "notebooks-product": "workbench-instances", + "resource-name": "c7n-notebook-public-default-e84a", + "consumer-project-id": "stkl-jim-fulton" + }, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json new file mode 100644 index 00000000000..7ee3b9b4b15 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations---instances_1.json @@ -0,0 +1,199 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 17:32:19 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "7337", + "-content-encoding": "gzip", + "content-location": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/-/instances?alt=json" + }, + "body": { + "instances": [ + { + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "gceSetup": { + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", + "serviceAccounts": [ + { + "email": "693936050605-compute@developer.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email" + ] + } + ], + "bootDisk": { + "diskSizeGb": "150", + "diskEncryption": "GMEK" + }, + "dataDisks": [ + { + "diskSizeGb": "100", + "diskEncryption": "GMEK" + } + ], + "shieldedInstanceConfig": { + "enableVtpm": true, + "enableIntegrityMonitoring": true + }, + "networkInterfaces": [ + { + "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default", + "accessConfigs": [ + { + "externalIp": "34.24.11.45" + } + ] + } + ], + "tags": [ + "deeplearning-vm", + "notebook-instance" + ], + "metadata": { + "disable-swap-binaries": "true", + "notebooks-api": "PROD", + "version": "20260809-2130-rc0", + "proxy-mode": "service_account", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-backend-id": "4c6d45c45d3b5c10", + "proxy-url": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "enable-jupyterlab4": "true", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "serial-port-logging-enable": "true", + "enable-oslogin": "TRUE", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a:reportInfoSystem", + "new-proxy-agent-enabled": "true", + "enable-guest-attributes": "TRUE", + "notebooks-api-version": "v2", + "instance-region": "us-east1" + }, + "gpuDriverConfig": {}, + "reservationAffinity": { + "consumeReservationType": "RESERVATION_NONE" + }, + "minCpuPlatform": "Intel Broadwell", + "instanceId": "4532768441233380276" + }, + "proxyUri": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", + "state": "ACTIVE", + "id": "4592c76e-b080-4826-8607-f0a052691732", + "healthState": "HEALTHY", + "healthInfo": { + "jupyterlab_status": "1", + "jupyterlab_api_status": "1", + "last_updated": "2026-08-12T17:32:04+00:00", + "system_health": "1", + "docker_status": "1" + }, + "createTime": "2026-08-12T17:28:57.651511852Z", + "updateTime": "2026-08-12T17:32:04.862408802Z", + "labels": { + "notebooks-product": "workbench-instances", + "resource-name": "c7n-notebook-public-default-e84a", + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", + "goog-terraform-provisioned": "true" + }, + "satisfiesPzi": true + }, + { + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", + "gceSetup": { + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", + "serviceAccounts": [ + { + "email": "693936050605-compute@developer.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email" + ] + } + ], + "bootDisk": { + "diskSizeGb": "150", + "diskEncryption": "GMEK" + }, + "dataDisks": [ + { + "diskSizeGb": "100", + "diskEncryption": "GMEK" + } + ], + "shieldedInstanceConfig": { + "enableVtpm": true, + "enableIntegrityMonitoring": true + }, + "networkInterfaces": [ + { + "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default" + } + ], + "disablePublicIp": true, + "tags": [ + "deeplearning-vm", + "notebook-instance" + ], + "metadata": { + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "version": "20260809-2130-rc0", + "disable-swap-binaries": "true", + "enable-oslogin": "TRUE", + "instance-region": "us-east1", + "proxy-backend-id": "18e7172261907cfe", + "proxy-url": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a:reportInfoSystem", + "notebooks-api": "PROD", + "enable-jupyterlab4": "true", + "new-proxy-agent-enabled": "true", + "enable-guest-attributes": "TRUE", + "serial-port-logging-enable": "true", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", + "proxy-mode": "service_account", + "notebooks-api-version": "v2" + }, + "gpuDriverConfig": {}, + "reservationAffinity": { + "consumeReservationType": "RESERVATION_NONE" + }, + "minCpuPlatform": "Intel Broadwell", + "instanceId": "3328585780394267572" + }, + "proxyUri": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", + "state": "ACTIVE", + "id": "aa2cf267-c071-4c10-a58e-d77e1b31c80c", + "healthState": "HEALTHY", + "healthInfo": { + "jupyterlab_status": "1", + "jupyterlab_api_status": "1", + "last_updated": "2026-08-12T17:32:03+00:00", + "system_health": "1", + "docker_status": "1" + }, + "createTime": "2026-08-12T17:28:57.622710654Z", + "updateTime": "2026-08-12T17:32:04.464427238Z", + "labels": { + "resource-name": "c7n-notebook-private-default-e84a", + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", + "goog-terraform-provisioned": "true", + "notebooks-product": "workbench-instances" + }, + "satisfiesPzi": true + } + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json new file mode 100644 index 00000000000..280458343b1 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/get-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json @@ -0,0 +1,115 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 17:32:51 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "3551", + "-content-encoding": "gzip", + "content-location": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a?alt=json" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "gceSetup": { + "machineType": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-east1-b/machineTypes/e2-standard-4", + "serviceAccounts": [ + { + "email": "693936050605-compute@developer.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email" + ] + } + ], + "vmImage": { + "project": "cloud-notebooks-managed", + "family": "workbench-instances-2603" + }, + "bootDisk": { + "diskSizeGb": "150", + "diskType": "PD_STANDARD", + "diskEncryption": "GMEK" + }, + "dataDisks": [ + { + "diskSizeGb": "100", + "diskType": "PD_STANDARD", + "diskEncryption": "GMEK" + } + ], + "shieldedInstanceConfig": { + "enableVtpm": true, + "enableIntegrityMonitoring": true + }, + "networkInterfaces": [ + { + "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default", + "accessConfigs": [ + { + "externalIp": "34.24.11.45" + } + ] + } + ], + "tags": [ + "deeplearning-vm", + "notebook-instance" + ], + "metadata": { + "disable-swap-binaries": "true", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "notebooks-api": "PROD", + "idle-timeout-seconds": "3600", + "notebooks-api-version": "v2", + "instance-region": "us-east1", + "proxy-url": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "version": "20260809-2130-rc0", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a:reportInfoSystem", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "enable-jupyterlab4": "true", + "proxy-mode": "service_account", + "proxy-backend-id": "4c6d45c45d3b5c10", + "enable-guest-attributes": "TRUE", + "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", + "enable-oslogin": "TRUE", + "serial-port-logging-enable": "true", + "new-proxy-agent-enabled": "true" + }, + "gpuDriverConfig": {}, + "reservationAffinity": { + "consumeReservationType": "RESERVATION_NONE" + }, + "minCpuPlatform": "Intel Broadwell", + "instanceId": "4532768441233380276" + }, + "proxyUri": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "creator": "jim.fulton@sixfeetup.com", + "state": "ACTIVE", + "id": "4592c76e-b080-4826-8607-f0a052691732", + "healthState": "HEALTHY", + "healthInfo": { + "docker_status": "1", + "jupyterlab_status": "1", + "jupyterlab_api_status": "1", + "last_updated": "2026-08-12T17:32:34+00:00", + "system_health": "1" + }, + "createTime": "2026-08-12T17:28:57.651511852Z", + "updateTime": "2026-08-12T17:32:35.449944508Z", + "labels": { + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", + "goog-terraform-provisioned": "true", + "notebooks-product": "workbench-instances", + "resource-name": "c7n-notebook-public-default-e84a" + }, + "satisfiesPzi": true + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/patch-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/patch-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json new file mode 100644 index 00000000000..a23863922c6 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/test_notebook_v2_update_metadata/patch-notebooks.googleapis.com-v2-projects-cloud-custodian-locations-us-east1-b-instances-c7n-notebook-public-default-e84a_1.json @@ -0,0 +1,29 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Wed, 12 Aug 2026 17:32:20 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "520", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1-b/operations/operation-1786555940298-658dcf8315d97-909c4784-76d85518", + "metadata": { + "@type": "type.googleapis.com/google.cloud.notebooks.v2.OperationMetadata", + "createTime": "2026-08-12T17:32:20.472518464Z", + "target": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", + "verb": "update", + "requestedCancellation": false, + "apiVersion": "v2", + "endpoint": "UpdateInstance" + }, + "done": false + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-5527392287388073984_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-5527392287388073984_1.json new file mode 100644 index 00000000000..9fd01eb88f1 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-5527392287388073984_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:06 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/4639314379106418688", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:06.894022Z", + "updateTime": "2026-08-14T17:31:06.894022Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-6642033195162271744_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-6642033195162271744_1.json new file mode 100644 index 00000000000..032d1bc972b --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-6642033195162271744_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:06 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/3252205693876305920", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:06.231315Z", + "updateTime": "2026-08-14T17:31:06.231315Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-1375049241696665600_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-1375049241696665600_1.json new file mode 100644 index 00000000000..c430ad86bf6 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-1375049241696665600_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:05 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "424", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/457159175139491840", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:05.907250Z", + "updateTime": "2026-08-14T17:31:05.907250Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7512329633895809024_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7512329633895809024_1.json new file mode 100644 index 00000000000..d16c2de014f --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7512329633895809024_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:06 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/2209059430186614784", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:06.575250Z", + "updateTime": "2026-08-14T17:31:06.575250Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-1733588988398141440_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-1733588988398141440_1.json new file mode 100644 index 00000000000..69f21c8b022 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-1733588988398141440_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:05 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/7876276611278962688", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:05.764489Z", + "updateTime": "2026-08-14T17:31:05.764489Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-2203089249551515648_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-2203089249551515648_1.json new file mode 100644 index 00000000000..5fb7e245fae --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-2203089249551515648_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:06 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/6928831839670894592", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:06.084311Z", + "updateTime": "2026-08-14T17:31:06.084311Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-7844410732786483200_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-7844410732786483200_1.json new file mode 100644 index 00000000000..6d20b569c49 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-7844410732786483200_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:06 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/6958105237248802816", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:06.377339Z", + "updateTime": "2026-08-14T17:31:06.377339Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-849194611573260288_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-849194611573260288_1.json new file mode 100644 index 00000000000..7d3e7a0a42e --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-849194611573260288_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:06 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "423", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/99017451647270912", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:31:06.746906Z", + "updateTime": "2026-08-14T17:31:06.746906Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-1375049241696665600_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-1375049241696665600_1.json new file mode 100644 index 00000000000..cfa6c55a2a8 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-1375049241696665600_1.json @@ -0,0 +1,48 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:04 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1004", + "-content-encoding": "gzip", + "content-location": "https://us-central1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-central1/evaluationRuns/1375049241696665600?alt=json" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/1375049241696665600", + "displayName": "c7n-test-eval-run-failed", + "metadata": { + "pipeline_id": "1606706559881052160" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/2203089249551515648" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "FAILED", + "error": { + "code": 9, + "message": "No metric scores to aggregate. Please check the result evaluation items for errors." + }, + "evaluationResults": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/1733588988398141440" + }, + "createTime": "2026-08-14T17:30:59.615666Z", + "completionTime": "2026-08-14T17:31:00.781015Z", + "evaluationSetSnapshot": "projects/cloud-custodian/locations/us-central1/evaluationSets/1733588988398141440" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7512329633895809024_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7512329633895809024_1.json new file mode 100644 index 00000000000..1ee37898f34 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7512329633895809024_1.json @@ -0,0 +1,58 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:58 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1446", + "-content-encoding": "gzip", + "content-location": "https://us-central1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-central1/evaluationRuns/7512329633895809024?alt=json" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/7512329633895809024", + "displayName": "c7n-test-eval-run-succeeded", + "metadata": { + "pipeline_id": "8253914056763637760" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/849194611573260288" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "SUCCEEDED", + "evaluationResults": { + "summaryMetrics": { + "metrics": { + "model-under-test/exact_match/VARIANCE": 0, + "model-under-test/exact_match/PERCENTILE_P99": 1, + "model-under-test/exact_match/AVERAGE": 1, + "model-under-test/exact_match/STANDARD_DEVIATION": 0, + "model-under-test/exact_match/PERCENTILE_P95": 1, + "model-under-test/exact_match/MINIMUM": 1, + "model-under-test/exact_match/MAXIMUM": 1, + "model-under-test/exact_match/MEDIAN": 1, + "model-under-test/exact_match/PERCENTILE_P90": 1 + }, + "totalItems": 1 + }, + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/7844410732786483200" + }, + "createTime": "2026-08-14T17:30:53.076299Z", + "completionTime": "2026-08-14T17:30:54.154065Z", + "evaluationSetSnapshot": "projects/cloud-custodian/locations/us-central1/evaluationSets/7844410732786483200" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json new file mode 100644 index 00000000000..c1579924180 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json @@ -0,0 +1,89 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:31:05 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "2433", + "-content-encoding": "gzip", + "content-location": "https://us-central1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-central1/evaluationRuns?alt=json" + }, + "body": { + "evaluationRuns": [ + { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/1375049241696665600", + "displayName": "c7n-test-eval-run-failed", + "metadata": { + "pipeline_id": "1606706559881052160" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/2203089249551515648" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "FAILED", + "error": { + "code": 9, + "message": "No metric scores to aggregate. Please check the result evaluation items for errors." + }, + "evaluationResults": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/1733588988398141440" + }, + "createTime": "2026-08-14T17:30:59.615666Z" + }, + { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/7512329633895809024", + "displayName": "c7n-test-eval-run-succeeded", + "metadata": { + "pipeline_id": "8253914056763637760" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/849194611573260288" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "SUCCEEDED", + "evaluationResults": { + "summaryMetrics": { + "metrics": { + "model-under-test/exact_match/VARIANCE": 0, + "model-under-test/exact_match/PERCENTILE_P99": 1, + "model-under-test/exact_match/AVERAGE": 1, + "model-under-test/exact_match/STANDARD_DEVIATION": 0, + "model-under-test/exact_match/PERCENTILE_P95": 1, + "model-under-test/exact_match/MINIMUM": 1, + "model-under-test/exact_match/MAXIMUM": 1, + "model-under-test/exact_match/MEDIAN": 1, + "model-under-test/exact_match/PERCENTILE_P90": 1 + }, + "totalItems": 1 + }, + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/7844410732786483200" + }, + "createTime": "2026-08-14T17:30:53.076299Z" + } + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_1.json new file mode 100644 index 00000000000..184d6eed8c9 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_1.json @@ -0,0 +1,35 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:52 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "426", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationItems/5527392287388073984", + "displayName": "c7n-test-eval-run-succeeded-item", + "evaluationItemType": "REQUEST", + "evaluationRequest": { + "prompt": { + "text": "What is 2+2?" + }, + "goldenResponse": { + "text": "4" + }, + "candidateResponses": [ + { + "candidate": "model-under-test", + "text": "4" + } + ] + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_2.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_2.json new file mode 100644 index 00000000000..9e8db777c90 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_2.json @@ -0,0 +1,29 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:58 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "311", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationItems/6642033195162271744", + "displayName": "c7n-test-eval-run-failed-item", + "evaluationItemType": "REQUEST", + "evaluationRequest": { + "prompt": { + "text": "What is 2+2?" + }, + "goldenResponse": { + "text": "4" + } + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json new file mode 100644 index 00000000000..d83dfe4ab80 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json @@ -0,0 +1,38 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:53 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "578", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/7512329633895809024", + "displayName": "c7n-test-eval-run-succeeded", + "metadata": { + "pipeline_id": "8253914056763637760" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/849194611573260288" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "PENDING", + "completionTime": "1970-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_2.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_2.json new file mode 100644 index 00000000000..70a05192dfb --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_2.json @@ -0,0 +1,38 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:59 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "576", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/1375049241696665600", + "displayName": "c7n-test-eval-run-failed", + "metadata": { + "pipeline_id": "1606706559881052160" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/2203089249551515648" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "PENDING", + "completionTime": "1970-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_1.json new file mode 100644 index 00000000000..9de94d8826a --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_1.json @@ -0,0 +1,23 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:52 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "260", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationSets/849194611573260288", + "displayName": "c7n-test-eval-run-succeeded-set", + "evaluationItems": [ + "projects/cloud-custodian/locations/us-central1/evaluationItems/5527392287388073984" + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_2.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_2.json new file mode 100644 index 00000000000..ff8063e6953 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-filtering/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_2.json @@ -0,0 +1,23 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:59 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "258", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationSets/2203089249551515648", + "displayName": "c7n-test-eval-run-failed-set", + "evaluationItems": [ + "projects/cloud-custodian/locations/us-central1/evaluationItems/6642033195162271744" + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-4635679561168715776_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-4635679561168715776_1.json new file mode 100644 index 00000000000..c67c7dc68b6 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems-4635679561168715776_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:45 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/3938441687096885248", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:45.220982Z", + "updateTime": "2026-08-14T17:30:45.220982Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7139656764730900480_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7139656764730900480_1.json new file mode 100644 index 00000000000..551b5629520 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7139656764730900480_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:44 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/6306666588024078336", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:44.860467Z", + "updateTime": "2026-08-14T17:30:44.860467Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-6420851038072340480_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-6420851038072340480_1.json new file mode 100644 index 00000000000..95a5ab2b5af --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-6420851038072340480_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:45 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/5546226754068152320", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:45.050113Z", + "updateTime": "2026-08-14T17:30:45.050113Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-978954575836872704_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-978954575836872704_1.json new file mode 100644 index 00000000000..cd703c8318b --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets-978954575836872704_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:44 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "425", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/operations/2489408506990428160", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:44.690090Z", + "updateTime": "2026-08-14T17:30:44.690090Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationItems-2870129968774381568_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationItems-2870129968774381568_1.json new file mode 100644 index 00000000000..5cbffa248f4 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationItems-2870129968774381568_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:44 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "422", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/operations/6754289827664887808", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:44.503378Z", + "updateTime": "2026-08-14T17:30:44.503378Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns-3188830011155021824_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns-3188830011155021824_1.json new file mode 100644 index 00000000000..b2d2bf44a86 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns-3188830011155021824_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:44 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "422", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/operations/7108385348366893056", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:44.025614Z", + "updateTime": "2026-08-14T17:30:44.025614Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets-1357976025140559872_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets-1357976025140559872_1.json new file mode 100644 index 00000000000..4b3e22f051a --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets-1357976025140559872_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:43 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "422", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/operations/7220386000818667520", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:43.816777Z", + "updateTime": "2026-08-14T17:30:43.816777Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets-9104167384217812992_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets-9104167384217812992_1.json new file mode 100644 index 00000000000..39955db6773 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/delete-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets-9104167384217812992_1.json @@ -0,0 +1,30 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:44 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "422", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/operations/4892587943421542400", + "metadata": { + "@type": "type.googleapis.com/google.cloud.aiplatform.v1.DeleteOperationMetadata", + "genericMetadata": { + "createTime": "2026-08-14T17:30:44.270723Z", + "updateTime": "2026-08-14T17:30:44.270723Z" + } + }, + "done": true, + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7139656764730900480_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7139656764730900480_1.json new file mode 100644 index 00000000000..0e0aa7d1e97 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns-7139656764730900480_1.json @@ -0,0 +1,58 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:34 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1443", + "-content-encoding": "gzip", + "content-location": "https://us-central1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-central1/evaluationRuns/7139656764730900480?alt=json" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/7139656764730900480", + "displayName": "c7n-test-eval-run-central", + "metadata": { + "pipeline_id": "3047858440639610880" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/6420851038072340480" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "SUCCEEDED", + "evaluationResults": { + "summaryMetrics": { + "metrics": { + "model-under-test/exact_match/VARIANCE": 0, + "model-under-test/exact_match/PERCENTILE_P99": 1, + "model-under-test/exact_match/AVERAGE": 1, + "model-under-test/exact_match/STANDARD_DEVIATION": 0, + "model-under-test/exact_match/PERCENTILE_P95": 1, + "model-under-test/exact_match/MINIMUM": 1, + "model-under-test/exact_match/MAXIMUM": 1, + "model-under-test/exact_match/MEDIAN": 1, + "model-under-test/exact_match/PERCENTILE_P90": 1 + }, + "totalItems": 1 + }, + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/978954575836872704" + }, + "createTime": "2026-08-14T17:30:28.967873Z", + "completionTime": "2026-08-14T17:30:30.024033Z", + "evaluationSetSnapshot": "projects/cloud-custodian/locations/us-central1/evaluationSets/978954575836872704" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json new file mode 100644 index 00000000000..cefef7f4063 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json @@ -0,0 +1,60 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:43 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1470", + "-content-encoding": "gzip", + "content-location": "https://us-central1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-central1/evaluationRuns?alt=json" + }, + "body": { + "evaluationRuns": [ + { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/7139656764730900480", + "displayName": "c7n-test-eval-run-central", + "metadata": { + "pipeline_id": "3047858440639610880" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/6420851038072340480" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "SUCCEEDED", + "evaluationResults": { + "summaryMetrics": { + "metrics": { + "model-under-test/exact_match/VARIANCE": 0, + "model-under-test/exact_match/PERCENTILE_P99": 1, + "model-under-test/exact_match/AVERAGE": 1, + "model-under-test/exact_match/STANDARD_DEVIATION": 0, + "model-under-test/exact_match/PERCENTILE_P95": 1, + "model-under-test/exact_match/MINIMUM": 1, + "model-under-test/exact_match/MAXIMUM": 1, + "model-under-test/exact_match/MEDIAN": 1, + "model-under-test/exact_match/PERCENTILE_P90": 1 + }, + "totalItems": 1 + }, + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/978954575836872704" + }, + "createTime": "2026-08-14T17:30:28.967873Z" + } + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns-3188830011155021824_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns-3188830011155021824_1.json new file mode 100644 index 00000000000..7d6a1f53aac --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns-3188830011155021824_1.json @@ -0,0 +1,58 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:41 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1428", + "-content-encoding": "gzip", + "content-location": "https://us-east1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-east1/evaluationRuns/3188830011155021824?alt=json" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/evaluationRuns/3188830011155021824", + "displayName": "c7n-test-eval-run-east", + "metadata": { + "pipeline_id": "38034271868289024" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-east1/evaluationSets/9104167384217812992" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "SUCCEEDED", + "evaluationResults": { + "summaryMetrics": { + "metrics": { + "model-under-test/exact_match/VARIANCE": 0, + "model-under-test/exact_match/PERCENTILE_P99": 1, + "model-under-test/exact_match/AVERAGE": 1, + "model-under-test/exact_match/STANDARD_DEVIATION": 0, + "model-under-test/exact_match/PERCENTILE_P95": 1, + "model-under-test/exact_match/MINIMUM": 1, + "model-under-test/exact_match/MAXIMUM": 1, + "model-under-test/exact_match/MEDIAN": 1, + "model-under-test/exact_match/PERCENTILE_P90": 1 + }, + "totalItems": 1 + }, + "evaluationSet": "projects/cloud-custodian/locations/us-east1/evaluationSets/1357976025140559872" + }, + "createTime": "2026-08-14T17:30:36.452268Z", + "completionTime": "2026-08-14T17:30:38.580804Z", + "evaluationSetSnapshot": "projects/cloud-custodian/locations/us-east1/evaluationSets/1357976025140559872" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns_1.json new file mode 100644 index 00000000000..448ed346597 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/get-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns_1.json @@ -0,0 +1,60 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:43 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "1457", + "-content-encoding": "gzip", + "content-location": "https://us-east1-aiplatform.googleapis.com/v1/projects/cloud-custodian/locations/us-east1/evaluationRuns?alt=json" + }, + "body": { + "evaluationRuns": [ + { + "name": "projects/cloud-custodian/locations/us-east1/evaluationRuns/3188830011155021824", + "displayName": "c7n-test-eval-run-east", + "metadata": { + "pipeline_id": "38034271868289024" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-east1/evaluationSets/9104167384217812992" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "SUCCEEDED", + "evaluationResults": { + "summaryMetrics": { + "metrics": { + "model-under-test/exact_match/VARIANCE": 0, + "model-under-test/exact_match/PERCENTILE_P99": 1, + "model-under-test/exact_match/AVERAGE": 1, + "model-under-test/exact_match/STANDARD_DEVIATION": 0, + "model-under-test/exact_match/PERCENTILE_P95": 1, + "model-under-test/exact_match/MINIMUM": 1, + "model-under-test/exact_match/MAXIMUM": 1, + "model-under-test/exact_match/MEDIAN": 1, + "model-under-test/exact_match/PERCENTILE_P90": 1 + }, + "totalItems": 1 + }, + "evaluationSet": "projects/cloud-custodian/locations/us-east1/evaluationSets/1357976025140559872" + }, + "createTime": "2026-08-14T17:30:36.452268Z" + } + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_1.json new file mode 100644 index 00000000000..f6775df82bd --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationItems_1.json @@ -0,0 +1,35 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:28 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "424", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationItems/4635679561168715776", + "displayName": "c7n-test-eval-run-central-item", + "evaluationItemType": "REQUEST", + "evaluationRequest": { + "prompt": { + "text": "What is 2+2?" + }, + "goldenResponse": { + "text": "4" + }, + "candidateResponses": [ + { + "candidate": "model-under-test", + "text": "4" + } + ] + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json new file mode 100644 index 00000000000..3cae719befd --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationRuns_1.json @@ -0,0 +1,38 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:28 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "577", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationRuns/7139656764730900480", + "displayName": "c7n-test-eval-run-central", + "metadata": { + "pipeline_id": "3047858440639610880" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-central1/evaluationSets/6420851038072340480" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "PENDING", + "completionTime": "1970-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_1.json new file mode 100644 index 00000000000..27ed61a7c07 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-central1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-central1-evaluationSets_1.json @@ -0,0 +1,23 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:28 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "259", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-central1/evaluationSets/6420851038072340480", + "displayName": "c7n-test-eval-run-central-set", + "evaluationItems": [ + "projects/cloud-custodian/locations/us-central1/evaluationItems/4635679561168715776" + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationItems_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationItems_1.json new file mode 100644 index 00000000000..649afd0be25 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationItems_1.json @@ -0,0 +1,35 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:35 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "418", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/evaluationItems/2870129968774381568", + "displayName": "c7n-test-eval-run-east-item", + "evaluationItemType": "REQUEST", + "evaluationRequest": { + "prompt": { + "text": "What is 2+2?" + }, + "goldenResponse": { + "text": "4" + }, + "candidateResponses": [ + { + "candidate": "model-under-test", + "text": "4" + } + ] + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns_1.json new file mode 100644 index 00000000000..2af2e38a3c9 --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationRuns_1.json @@ -0,0 +1,38 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:36 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "566", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/evaluationRuns/3188830011155021824", + "displayName": "c7n-test-eval-run-east", + "metadata": { + "pipeline_id": "38034271868289024" + }, + "dataSource": { + "evaluationSet": "projects/cloud-custodian/locations/us-east1/evaluationSets/9104167384217812992" + }, + "evaluationConfig": { + "metrics": [ + { + "metric": "exact_match", + "computationBasedMetricSpec": { + "type": "EXACT_MATCH" + } + } + ] + }, + "state": "PENDING", + "completionTime": "1970-01-01T00:00:00Z" + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets_1.json b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets_1.json new file mode 100644 index 00000000000..c5de1f6b2ff --- /dev/null +++ b/tools/c7n_gcp/tests/data/flights/vertexai-evaluation-run-multi-location/post-us-east1-aiplatform.googleapis.com-v1-projects-cloud-custodian-locations-us-east1-evaluationSets_1.json @@ -0,0 +1,23 @@ +{ + "headers": { + "content-type": "application/json; charset=UTF-8", + "vary": "Origin, X-Origin, Referer", + "date": "Fri, 14 Aug 2026 17:30:35 GMT", + "server": "ESF", + "x-xss-protection": "0", + "x-frame-options": "SAMEORIGIN", + "x-content-type-options": "nosniff", + "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "transfer-encoding": "chunked", + "status": "200", + "content-length": "250", + "-content-encoding": "gzip" + }, + "body": { + "name": "projects/cloud-custodian/locations/us-east1/evaluationSets/9104167384217812992", + "displayName": "c7n-test-eval-run-east-set", + "evaluationItems": [ + "projects/cloud-custodian/locations/us-east1/evaluationItems/2870129968774381568" + ] + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/gcp_common.py b/tools/c7n_gcp/tests/gcp_common.py index 4d21888a435..5b2b2fd1bf0 100644 --- a/tools/c7n_gcp/tests/gcp_common.py +++ b/tools/c7n_gcp/tests/gcp_common.py @@ -1,10 +1,16 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import datetime import functools +import hashlib import json +import logging import os +import re import shutil +import time +import typing from pathlib import Path @@ -29,11 +35,228 @@ EVENT_DIR = os.path.join(os.path.dirname(__file__), 'data', 'events') +log = logging.getLogger('custodian.tests.gcp') + +EMAIL_RE = re.compile(r'[\w.+%-]+@[\w.-]+\.\w+') +PLACEHOLDER_EMAIL = 'user@example.com' +# RFC 5737 TEST-NET-2, reserved for documentation. +PLACEHOLDER_IP = '198.51.100.1' + + def event_data(fname): + """Load a recorded audit LogEntry fixture. + + Fixtures name the placeholder project (see ``AuditEventRecorder``). + When recording, put the live project back so the policy resolves its + resource against an account that actually has one. + """ with open(os.path.join(EVENT_DIR, fname)) as fh: + if C7N_FUNCTIONAL: + return json.loads(fh.read().replace(PROJECT_ID, get_default_project())) return json.load(fh) +def audit_event_recorder( + session_factory, + event_file: str, + method: str, + resource_name: typing.Optional[str] = None, + labels: typing.Optional[typing.Mapping[str, str]] = None, + start_time_skew_seconds: int = 60, + timeout: int = 120, + poll_interval: int = 5, +) -> 'AuditEventRecorder': + """Create a recorder for GCP audit LogEntry event fixtures. + + Construct it before triggering the API call, then call ``record()`` in + recording mode. Matching log entries are written under ``data/events``. + + See ``docs/source/gcp/examples/audit-event-recording.rst`` for usage, + filtering options, file naming, and caveats around multi-entry + operations and creation events. + """ + return AuditEventRecorder( + session_factory, + event_file, + method, + resource_name=resource_name, + labels=labels, + start_time_skew_seconds=start_time_skew_seconds, + timeout=timeout, + poll_interval=poll_interval, + ) + + +class AuditEventRecorder: + + def __init__( + self, + session_factory, + event_file: str, + method: str, + resource_name: typing.Optional[str] = None, + labels: typing.Optional[typing.Mapping[str, str]] = None, + start_time_skew_seconds: int = 60, + timeout: int = 120, + poll_interval: int = 5, + ) -> None: + self.session_factory = session_factory + self.event_file = event_file + self.method = method + self.resource_name = resource_name + self.labels = labels or {} + self.timeout = timeout + self.poll_interval = poll_interval + self.start_time = ( + datetime.datetime.now(datetime.timezone.utc) - + datetime.timedelta(seconds=start_time_skew_seconds) + ) + + def record(self) -> None: + self.project_id = self.session_factory().get_default_project() + deadline = time.time() + self.timeout + operations: dict = {} + seen_hashes: set = set() + while True: + entries = self._dedup_entries(seen_hashes, self._get_entries()) + if entries: + self._write_batch(entries, operations) + if all(s['complete'] for s in operations.values()): + return + if time.time() >= deadline: + incomplete = [ + op_id for op_id, state in operations.items() + if not state['complete'] + ] + if incomplete: + raise AssertionError( + 'Timed out recording {}, waiting on operations: {}' + .format(self.event_file, ', '.join(incomplete))) + raise AssertionError( + 'No GCP audit log entries matched {}'.format(self.event_file)) + time.sleep(self.poll_interval) + + def _dedup_entries(self, seen: set, entries: list[dict]) -> list[dict]: + """Update seen with each entry's hash. Return the entries not in seen. + + Cloud Logging queries are cumulative from a fixed start time, so a + later poll re-returns entries an earlier poll already saw. + """ + new_entries = [] + for entry in entries: + digest = hashlib.sha256( + json.dumps(entry, sort_keys=True).encode()).hexdigest() + if digest in seen: + continue + seen.add(digest) + new_entries.append(entry) + return new_entries + + def _write_batch(self, entries: list[dict], operations: dict) -> None: + """Write one poll batch, updating per-operation state. + + ``operations`` maps ``operation.id`` to its assigned file-name index + and whether its ``last`` entry has been seen. + """ + for entry in entries: + payload = json.dumps( + self._sanitize(entry), indent=2, sort_keys=True) + '\n' + operation = entry.get('operation') or {} + operation_id = operation.get('id') + if not operation_id: + self._write_entry(self.event_file, payload) + continue + state = operations.setdefault( + operation_id, {'index': len(operations), 'complete': False}) + self._write_entry( + self._operation_file_name(state['index'], operation), payload) + if operation.get('last'): + state['complete'] = True + + def _operation_file_name(self, index: int, operation: dict) -> str: + base, ext = os.path.splitext(self.event_file) + parts = [base] + if index > 0: + parts.append(str(index)) + if operation.get('first'): + parts.append('first') + if operation.get('last'): + parts.append('last') + return '-'.join(parts) + ext + + def _sanitize(self, value, key: str = ''): + """Replace the recording account's project id, emails and caller ip. + + The project id has to go because flight data is recorded against + the placeholder project (see ``recorder.py``), so an event naming + the real one would resolve its resource against a project that has + no recorded responses. Emails and the caller ip are the recording + developer's, and fixtures are committed. + """ + if isinstance(value, dict): + return {k: self._sanitize(v, k) for k, v in value.items()} + if isinstance(value, list): + return [self._sanitize(v, key) for v in value] + if not isinstance(value, str): + return value + if key == 'callerIp': + return PLACEHOLDER_IP + return EMAIL_RE.sub( + PLACEHOLDER_EMAIL, value.replace(self.project_id, PROJECT_ID)) + + def _get_entries(self) -> list[dict]: + session = self.session_factory() + client = session.client('logging', 'v2', 'entries') + entries = [] + for page in client.execute_paged_query( + 'list', {'body': self._query_body()}): + entries.extend(page.get('entries', [])) + return sorted( + entries, + key=lambda e: (e.get('timestamp', ''), e.get('insertId', '')), + ) + + def _query_body(self) -> dict: + project_id = self.project_id + log_name = 'projects/{}/logs/cloudaudit.googleapis.com%2Factivity'.format( + project_id) + filters = [ + 'logName = {}'.format(self._quote(log_name)), + 'protoPayload.methodName : {}'.format(self._quote(self.method)), + 'timestamp >= {}'.format(self._quote(self._format_time(self.start_time))), + ] + if self.resource_name: + filters.append( + 'protoPayload.resourceName : {}'.format(self._quote(self.resource_name))) + for k, v in self.labels.items(): + filters.append('resource.labels.{} = {}'.format(k, self._quote(v))) + return { + 'resourceNames': ['projects/{}'.format(project_id)], + 'filter': '\n'.join(filters), + 'orderBy': 'timestamp asc', + } + + def _write_entry(self, event_file: str, payload: str) -> None: + os.makedirs(EVENT_DIR, exist_ok=True) + path = os.path.join(EVENT_DIR, event_file) + index = 0 + while os.path.exists(path): + index += 1 + path = '{}-{}'.format(os.path.join(EVENT_DIR, event_file), index) + if index: + log.warning('GCP audit event fixture collision, wrote %s', path) + with open(path, 'w') as fh: + fh.write(payload) + + @staticmethod + def _format_time(value: datetime.datetime) -> str: + return value.isoformat().replace('+00:00', 'Z') + + @staticmethod + def _quote(value: str) -> str: + return '"{}"'.format(value.replace('\\', '\\\\').replace('"', '\\"')) + + class GoogleFlightRecorder(CustodianTestCore): data_dir = Path(__file__).parent.parent / 'tests' / 'data' / 'flights' diff --git a/tools/c7n_gcp/tests/terraform/disk_audit/main.tf b/tools/c7n_gcp/tests/terraform/disk_audit/main.tf new file mode 100644 index 00000000000..2b4b3e2c5f8 --- /dev/null +++ b/tools/c7n_gcp/tests/terraform/disk_audit/main.tf @@ -0,0 +1,38 @@ +resource "random_id" "suffix" { + byte_length = 2 +} + +resource "google_compute_region_disk" "default" { + name = "c7n-audit-regional-${terraform.workspace}-${random_id.suffix.hex}" + region = "us-central1" + type = "pd-ssd" + size = 10 + replica_zones = ["us-central1-a", "us-central1-b"] +} + +resource "google_compute_disk" "default" { + name = "c7n-audit-zonal-${terraform.workspace}-${random_id.suffix.hex}" + zone = "us-central1-a" + type = "pd-ssd" + size = 10 +} + +output "regional_disk_name" { + value = google_compute_region_disk.default.name + description = "Name of the test regional disk" +} + +output "region" { + value = google_compute_region_disk.default.region + description = "Region of the test regional disk" +} + +output "zonal_disk_name" { + value = google_compute_disk.default.name + description = "Name of the test zonal disk" +} + +output "zone" { + value = google_compute_disk.default.zone + description = "Zone of the test zonal disk" +} diff --git a/tools/c7n_gcp/tests/terraform/disk_audit/tf_resources.json b/tools/c7n_gcp/tests/terraform/disk_audit/tf_resources.json new file mode 100644 index 00000000000..dd7ca57ce3b --- /dev/null +++ b/tools/c7n_gcp/tests/terraform/disk_audit/tf_resources.json @@ -0,0 +1,136 @@ +{ + "pytest-terraform": 1, + "outputs": { + "region": { + "value": "us-central1", + "type": "string" + }, + "regional_disk_name": { + "value": "c7n-audit-regional-default-f5b3", + "type": "string" + }, + "zonal_disk_name": { + "value": "c7n-audit-zonal-default-f5b3", + "type": "string" + }, + "zone": { + "value": "us-central1-a", + "type": "string" + } + }, + "resources": { + "google_compute_disk": { + "default": { + "access_mode": "", + "architecture": null, + "async_primary_disk": [], + "create_snapshot_before_destroy": false, + "create_snapshot_before_destroy_prefix": null, + "creation_timestamp": "2026-08-20T12:49:39.162-07:00", + "deletion_policy": "DELETE", + "description": "", + "disk_encryption_key": [], + "disk_id": "4992374716928550077", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "enable_confidential_compute": false, + "guest_os_features": [], + "id": "projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "image": "", + "label_fingerprint": "vezUS-42LLM=", + "labels": null, + "last_attach_timestamp": "", + "last_detach_timestamp": "", + "licenses": [], + "name": "c7n-audit-zonal-default-f5b3", + "params": [], + "physical_block_size_bytes": 4096, + "project": "stkl-jim-fulton", + "provisioned_iops": 0, + "provisioned_throughput": 0, + "self_link": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a/disks/c7n-audit-zonal-default-f5b3", + "size": 10, + "snapshot": "", + "source_disk": "", + "source_disk_id": "", + "source_image_encryption_key": [], + "source_image_id": "", + "source_instant_snapshot": "", + "source_instant_snapshot_id": "", + "source_snapshot_encryption_key": [], + "source_snapshot_id": "", + "source_storage_object": null, + "storage_pool": "", + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null, + "type": "pd-ssd", + "users": [], + "zone": "us-central1-a" + } + }, + "google_compute_region_disk": { + "default": { + "access_mode": "", + "async_primary_disk": [], + "create_snapshot_before_destroy": false, + "create_snapshot_before_destroy_prefix": null, + "creation_timestamp": "2026-08-20T12:49:39.196-07:00", + "deletion_policy": "DELETE", + "description": "", + "disk_encryption_key": [], + "disk_id": "685703828320478397", + "effective_labels": { + "goog-terraform-provisioned": "true" + }, + "guest_os_features": [], + "id": "projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "image": "", + "label_fingerprint": "vezUS-42LLM=", + "labels": null, + "last_attach_timestamp": "", + "last_detach_timestamp": "", + "licenses": [], + "name": "c7n-audit-regional-default-f5b3", + "physical_block_size_bytes": 4096, + "project": "stkl-jim-fulton", + "provisioned_iops": 0, + "provisioned_throughput": 0, + "region": "us-central1", + "replica_zones": [ + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-a", + "https://www.googleapis.com/compute/v1/projects/cloud-custodian/zones/us-central1-b" + ], + "self_link": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/disks/c7n-audit-regional-default-f5b3", + "size": 10, + "snapshot": "", + "source_disk": "", + "source_disk_id": "", + "source_image_encryption_key": [], + "source_image_id": "", + "source_snapshot_encryption_key": [], + "source_snapshot_id": "", + "terraform_labels": { + "goog-terraform-provisioned": "true" + }, + "timeouts": null, + "type": "pd-ssd", + "users": [] + } + }, + "random_id": { + "suffix": { + "b64_std": "9bM=", + "b64_url": "9bM", + "byte_length": 2, + "dec": "62899", + "hex": "f5b3", + "id": "9bM", + "keepers": null, + "prefix": null + } + } + } +} \ No newline at end of file diff --git a/tools/c7n_gcp/tests/terraform/notebook_v2/main.tf b/tools/c7n_gcp/tests/terraform/notebook_v2/main.tf index 2599a8dc75a..795eb43a6b3 100644 --- a/tools/c7n_gcp/tests/terraform/notebook_v2/main.tf +++ b/tools/c7n_gcp/tests/terraform/notebook_v2/main.tf @@ -6,7 +6,7 @@ resource "random_id" "suffix" { resource "google_workbench_instance" "private_instance" { name = "c7n-notebook-private-${terraform.workspace}-${random_id.suffix.hex}" - location = "us-central1-a" + location = "us-east1-b" gce_setup { disable_public_ip = true @@ -15,7 +15,7 @@ resource "google_workbench_instance" "private_instance" { resource "google_workbench_instance" "public_instance" { name = "c7n-notebook-public-${terraform.workspace}-${random_id.suffix.hex}" - location = "us-central1-a" + location = "us-east1-b" gce_setup { disable_public_ip = false diff --git a/tools/c7n_gcp/tests/terraform/notebook_v2/tf_resources.json b/tools/c7n_gcp/tests/terraform/notebook_v2/tf_resources.json index fc90f60ab38..4c67ef2d397 100644 --- a/tools/c7n_gcp/tests/terraform/notebook_v2/tf_resources.json +++ b/tools/c7n_gcp/tests/terraform/notebook_v2/tf_resources.json @@ -4,18 +4,19 @@ "resources": { "google_workbench_instance": { "private_instance": { - "create_time": "2026-07-06T21:14:29.701611482Z", - "creator": "caleb.syring@sixfeetup.com", + "create_time": "2026-08-12T17:28:57.622710654Z", + "creator": "jim.fulton@sixfeetup.com", "deletion_policy": "DELETE", "desired_state": "ACTIVE", "disable_proxy_access": false, "effective_labels": { - "consumer-project-id": "stacklet-test-policies", - "consumer-project-number": "859150599087", + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", "goog-terraform-provisioned": "true", "notebooks-product": "workbench-instances", - "resource-name": "c7n-notebook-private-default-62ac" + "resource-name": "c7n-notebook-private-default-e84a" }, + "enable_deletion_protection": false, "enable_managed_euc": false, "enable_third_party_identity": false, "gce_setup": [ @@ -36,7 +37,8 @@ "disk_encryption": "GMEK", "disk_size_gb": "100", "disk_type": "", - "kms_key": "" + "kms_key": "", + "resource_policies": [] } ], "disable_public_ip": true, @@ -47,25 +49,27 @@ "enable-guest-attributes": "TRUE", "enable-jupyterlab4": "true", "enable-oslogin": "TRUE", - "instance-region": "us-central1", + "instance-region": "us-east1", + "new-proxy-agent-enabled": "true", "notebooks-api": "PROD", "notebooks-api-version": "v2", - "proxy-backend-id": "c1cccbd5b589747", + "proxy-backend-id": "18e7172261907cfe", "proxy-mode": "service_account", - "proxy-registration-url": "https://us-central1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", - "proxy-url": "c1cccbd5b589747-dot-us-central1.notebooks.googleusercontent.com", - "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-private-default-62ac:reportInfoSystem", - "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-private-default-62ac", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-url": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a:reportInfoSystem", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", "serial-port-logging-enable": "true", "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", - "version": "20260701-2130-rc0" + "version": "20260809-2130-rc0" }, + "min_cpu_platform": "Intel Broadwell", "network_interfaces": [ { "access_configs": [], "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", "nic_type": "", - "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/subnetworks/default" + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default" } ], "reservation_affinity": [ @@ -77,7 +81,7 @@ ], "service_accounts": [ { - "email": "859150599087-compute@developer.gserviceaccount.com", + "email": "693936050605-compute@developer.gserviceaccount.com", "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email" @@ -102,35 +106,36 @@ {} ], "health_state": "HEALTHY", - "id": "projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-private-default-62ac", + "id": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-private-default-e84a", "instance_id": null, "instance_owners": null, "labels": null, - "location": "us-central1-a", - "name": "c7n-notebook-private-default-62ac", - "project": "stacklet-test-policies", - "proxy_uri": "c1cccbd5b589747-dot-us-central1.notebooks.googleusercontent.com", + "location": "us-east1-b", + "name": "c7n-notebook-private-default-e84a", + "project": "stkl-jim-fulton", + "proxy_uri": "18e7172261907cfe-dot-us-east1.notebooks.googleusercontent.com", "state": "ACTIVE", "terraform_labels": { "goog-terraform-provisioned": "true" }, "timeouts": null, - "update_time": "2026-07-06T21:17:08.522978131Z", + "update_time": "2026-08-12T17:31:33.883494551Z", "upgrade_history": [] }, "public_instance": { - "create_time": "2026-07-06T21:14:29.722087079Z", - "creator": "caleb.syring@sixfeetup.com", + "create_time": "2026-08-12T17:28:57.651511852Z", + "creator": "jim.fulton@sixfeetup.com", "deletion_policy": "DELETE", "desired_state": "ACTIVE", "disable_proxy_access": false, "effective_labels": { - "consumer-project-id": "stacklet-test-policies", - "consumer-project-number": "859150599087", + "consumer-project-id": "stkl-jim-fulton", + "consumer-project-number": "693936050605", "goog-terraform-provisioned": "true", "notebooks-product": "workbench-instances", - "resource-name": "c7n-notebook-public-default-62ac" + "resource-name": "c7n-notebook-public-default-e84a" }, + "enable_deletion_protection": false, "enable_managed_euc": false, "enable_third_party_identity": false, "gce_setup": [ @@ -151,7 +156,8 @@ "disk_encryption": "GMEK", "disk_size_gb": "100", "disk_type": "", - "kms_key": "" + "kms_key": "", + "resource_policies": [] } ], "disable_public_ip": false, @@ -162,29 +168,31 @@ "enable-guest-attributes": "TRUE", "enable-jupyterlab4": "true", "enable-oslogin": "TRUE", - "instance-region": "us-central1", + "instance-region": "us-east1", + "new-proxy-agent-enabled": "true", "notebooks-api": "PROD", "notebooks-api-version": "v2", - "proxy-backend-id": "42ebbe1e0dc75006", + "proxy-backend-id": "4c6d45c45d3b5c10", "proxy-mode": "service_account", - "proxy-registration-url": "https://us-central1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", - "proxy-url": "42ebbe1e0dc75006-dot-us-central1.notebooks.googleusercontent.com", - "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-public-default-62ac:reportInfoSystem", - "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-public-default-62ac", + "proxy-registration-url": "https://us-east1.notebooks.cloud.google.com/tun/m/4592f092208ecc84946b8f8f8016274df1b36a14", + "proxy-url": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", + "report-event-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a:reportInfoSystem", + "resource-url": "https://notebooks.googleapis.com/v2/projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", "serial-port-logging-enable": "true", "shutdown-script": "/opt/deeplearning/bin/shutdown_script.sh", - "version": "20260701-2130-rc0" + "version": "20260809-2130-rc0" }, + "min_cpu_platform": "Intel Broadwell", "network_interfaces": [ { "access_configs": [ { - "external_ip": "34.44.21.60" + "external_ip": "34.24.11.45" } ], "network": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/networks/default", "nic_type": "", - "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-central1/subnetworks/default" + "subnet": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/regions/us-east1/subnetworks/default" } ], "reservation_affinity": [ @@ -196,7 +204,7 @@ ], "service_accounts": [ { - "email": "859150599087-compute@developer.gserviceaccount.com", + "email": "693936050605-compute@developer.gserviceaccount.com", "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/userinfo.email" @@ -221,31 +229,31 @@ {} ], "health_state": "HEALTHY", - "id": "projects/cloud-custodian/locations/us-central1-a/instances/c7n-notebook-public-default-62ac", + "id": "projects/cloud-custodian/locations/us-east1-b/instances/c7n-notebook-public-default-e84a", "instance_id": null, "instance_owners": null, "labels": null, - "location": "us-central1-a", - "name": "c7n-notebook-public-default-62ac", - "project": "stacklet-test-policies", - "proxy_uri": "42ebbe1e0dc75006-dot-us-central1.notebooks.googleusercontent.com", + "location": "us-east1-b", + "name": "c7n-notebook-public-default-e84a", + "project": "stkl-jim-fulton", + "proxy_uri": "4c6d45c45d3b5c10-dot-us-east1.notebooks.googleusercontent.com", "state": "ACTIVE", "terraform_labels": { "goog-terraform-provisioned": "true" }, "timeouts": null, - "update_time": "2026-07-06T21:17:07.483043670Z", + "update_time": "2026-08-12T17:31:34.414168879Z", "upgrade_history": [] } }, "random_id": { "suffix": { - "b64_std": "Yqw=", - "b64_url": "Yqw", + "b64_std": "6Eo=", + "b64_url": "6Eo", "byte_length": 2, - "dec": "25260", - "hex": "62ac", - "id": "Yqw", + "dec": "59466", + "hex": "e84a", + "id": "6Eo", "keepers": null, "prefix": null } diff --git a/tools/c7n_gcp/tests/test_cloudrun.py b/tools/c7n_gcp/tests/test_cloudrun.py index 7483c0c7a95..f4f7061a1ef 100644 --- a/tools/c7n_gcp/tests/test_cloudrun.py +++ b/tools/c7n_gcp/tests/test_cloudrun.py @@ -1,9 +1,153 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import pytest + +from freezegun import freeze_time + from gcp_common import BaseTest +from c7n.exceptions import PolicyExecutionError from c7n.utils import yaml_load +from c7n_gcp.actions.core import MethodAction +from c7n_gcp.resources.cloudrun import CloudRunJob, CloudRunService, knative_body + +# The root fields the api accepts, independent of the module under test. +SCHEMA_FIELDS = {'apiVersion', 'kind', 'metadata', 'spec', 'status'} +LOCATION = {'cloud.googleapis.com/location': 'us-central1'} + + +def listed_resource(api_version, kind, name): + "A resource as augment() and a value filter leave it once listed." + return { + 'apiVersion': api_version, + 'kind': kind, + 'metadata': { + 'name': name, + 'namespace': 'cloud-custodian', + 'labels': dict(LOCATION), + }, + 'spec': {'template': {}}, + 'status': {'observedGeneration': 1}, + 'labels': dict(LOCATION), + 'c7n:MatchedFilters': ['metadata.name'], + } + + +def capture_api_params(test): + """Record the params of every api call the policy's actions make.""" + captured = [] + invoke_api = MethodAction.invoke_api + + def record(action, client, op_name, params): + captured.append((op_name, params)) + return invoke_api(action, client, op_name, params) + + test.patch(MethodAction, 'invoke_api', record) + return captured + + +def assert_replace_body(body, labels): + "A replace body holds the schema fields and the merged labels, nothing else." + assert set(body) == SCHEMA_FIELDS + assert 'labels' not in body + assert 'c7n:MatchedFilters' not in body + assert body['metadata']['labels'] == labels + + +def assert_label_params(model, resource, expected_name): + "get_label_params addresses the resource and leaves it fit to read again." + all_labels = dict(LOCATION, environment='test') + params = model.get_label_params(resource, all_labels) + + assert params['name'] == expected_name + assert_replace_body(params['body'], all_labels) + # the action reads its current label state from the resource, so both the + # synthetic key and the metadata it came from have to survive the call + assert resource['labels'] == LOCATION + assert resource['metadata']['labels'] == LOCATION + + +class KnativeBodyTest(BaseTest): + + def test_keeps_only_the_schema_fields(self): + body = knative_body({ + 'apiVersion': 'serving.knative.dev/v1', + 'kind': 'Service', + 'metadata': {'name': 'hello'}, + 'spec': {}, + 'status': {}, + 'labels': {'env': 'test'}, + 'c7n:MatchedFilters': ['metadata.name'], + }) + assert set(body) == SCHEMA_FIELDS + + def test_drops_annotations_nested_in_spec(self): + # a list-item filter annotates the objects it matched in place + body = knative_body({ + 'metadata': {'name': 'hello'}, + 'spec': { + 'template': { + 'spec': { + 'containers': [{ + 'image': 'us-docker.pkg.dev/cloudrun/container/hello', + 'c7n:MatchedFilters': ['image'], + }], + }, + }, + }, + 'c7n.metrics': {'run.googleapis.com/request_count': []}, + }) + assert body['spec'] == { + 'template': { + 'spec': { + 'containers': [{ + 'image': 'us-docker.pkg.dev/cloudrun/container/hello'}], + }, + }, + } + + def test_keeps_user_annotations(self): + # a kubernetes annotation key may contain a dot, so only the colon form + # is recognized below the root - a replace deletes what the body omits + annotations = { + 'run.googleapis.com/ingress': 'all', + 'c7n.example.com/owner': 'platform-team', + } + body = knative_body({ + 'metadata': {'name': 'hello', 'annotations': dict(annotations)}, + 'spec': {'template': {'metadata': {'annotations': dict(annotations)}}}, + }) + assert body['metadata']['annotations'] == annotations + assert body['spec']['template']['metadata']['annotations'] == annotations + + def test_copies_rather_than_mutates(self): + resource = { + 'metadata': {'name': 'hello'}, + 'spec': {'containers': [{'c7n:MatchedFilters': ['image']}]}, + } + knative_body(resource)['metadata']['name'] = 'changed' + assert resource['metadata']['name'] == 'hello' + assert resource['spec']['containers'][0] == {'c7n:MatchedFilters': ['image']} + + def test_raises_on_fields_outside_the_schema(self): + with pytest.raises(PolicyExecutionError) as raised: + knative_body({ + 'kind': 'Service', + 'metadata': {'name': 'hello'}, + 'somethingNew': 'unrecognized', + }) + assert 'somethingNew' in str(raised.value) + assert 'hello' in str(raised.value) + + def test_accepts_the_synthetic_fields(self): + knative_body({ + 'metadata': {'name': 'hello'}, + 'labels': {'env': 'test'}, + 'c7n:MatchedFilters': ['metadata.name'], + 'c7n.metrics': {'run.googleapis.com/request_count': []}, + }) + class RunServiceTest(BaseTest): def test_query(self): @@ -28,11 +172,18 @@ def test_query_empty(self): resources = p.run() assert resources == [] + def test_label_params(self): + assert_label_params( + CloudRunService.resource_type, + listed_resource('serving.knative.dev/v1', 'Service', 'hello'), + 'projects/cloud-custodian/locations/us-central1/services/hello') + def test_set_labels(self): project_id = 'cloud-custodian' factory = self.replay_flight_data( "gcp-cloud-run-service-set-labels", project_id=project_id ) + captured = capture_api_params(self) p = self.load_policy( { 'name': 'cloud-run-svc-set-labels', @@ -53,6 +204,49 @@ def test_set_labels(self): assert len(resources) == 1 assert resources[0]['metadata']['name'] == 'hello' + assert len(captured) == 1 + op_name, params = captured.pop() + assert op_name == 'replaceService' + assert_replace_body(params['body'], { + 'cloud.googleapis.com/location': 'us-central1', + 'environment': 'test', + }) + + @freeze_time("2026-08-19") + def test_mark_for_op(self): + project_id = 'cloud-custodian' + factory = self.replay_flight_data( + "gcp-cloud-run-service-mark-for-op", project_id=project_id + ) + captured = capture_api_params(self) + p = self.load_policy( + { + 'name': 'cloud-run-svc-mark-for-op', + 'resource': 'gcp.cloud-run-service', + 'filters': [ + {'type': 'value', + 'key': 'metadata.name', + 'value': 'hello'} + ], + 'actions': [ + {'type': 'mark-for-op', + 'op': 'notify', + 'days': 2} + ] + }, + session_factory=factory, + ) + resources = p.run() + assert len(resources) == 1 + + assert len(captured) == 1 + op_name, params = captured.pop() + assert op_name == 'replaceService' + assert_replace_body(params['body'], { + 'cloud.googleapis.com/location': 'us-central1', + 'custodian_status': 'resource_policy-notify-2026_08_21__0_0', + }) + def test_filter(self): factory = self.replay_flight_data("gcp-cloud-run-service") @@ -103,11 +297,18 @@ def test_query(self): assert len(resources) == 1 assert resources[0]["metadata"]["name"] == "job" + def test_label_params(self): + assert_label_params( + CloudRunJob.resource_type, + listed_resource('run.googleapis.com/v1', 'Job', 'job'), + 'namespaces/cloud-custodian/jobs/job') + def test_set_labels(self): project_id = 'cloud-custodian' factory = self.replay_flight_data( "gcp-cloud-run-job-set-labels", project_id=project_id ) + captured = capture_api_params(self) p = self.load_policy( { 'name': 'cloud-run-job-set-labels', @@ -128,6 +329,14 @@ def test_set_labels(self): assert len(resources) == 1 assert resources[0]['metadata']['name'] == 'job' + assert len(captured) == 1 + op_name, params = captured.pop() + assert op_name == 'replaceJob' + assert_replace_body(params['body'], { + 'cloud.googleapis.com/location': 'us-central1', + 'environment': 'test', + }) + class RevisionServiceTest(BaseTest): def test_query(self): diff --git a/tools/c7n_gcp/tests/test_compute.py b/tools/c7n_gcp/tests/test_compute.py index c836f57826f..96933e5a949 100644 --- a/tools/c7n_gcp/tests/test_compute.py +++ b/tools/c7n_gcp/tests/test_compute.py @@ -1,13 +1,15 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import functools import re import time from c7n_gcp.resources.compute import Snapshot -from gcp_common import BaseTest, event_data +from gcp_common import BaseTest, audit_event_recorder, event_data from googleapiclient.errors import HttpError -from c7n_gcp.client import get_default_project +from c7n_gcp.client import Session, get_default_project +from c7n.utils import local_session from pytest_terraform import terraform @@ -455,6 +457,158 @@ def test_disk_no_snapshots_filter(self): self.assertEqual(len(resources), 1) self.assertEqual(resources[0]['name'], 'custodian-dev') + def test_label_regional_disk(self): + project_id = self.project_id + factory = self.replay_flight_data('disk-regional-label', project_id=project_id) + p = self.load_policy( + {'name': 'disk-label', + 'resource': 'gcp.disk', + 'filters': [{'name': 'c7n-regional-jenkins'}], + 'actions': [{'type': 'set-labels', + 'labels': {'test_label': 'test_value'}}]}, + session_factory=factory) + resources = p.run() + self.assertEqual(len(resources), 1) + session = local_session(p.resource_manager.session_factory) + client = session.client('compute', 'v1', 'regionDisks') + result = client.execute_query( + 'list', {'project': project_id, + 'filter': 'name = c7n-regional-jenkins', + 'region': resources[0]['region'].rsplit('/', 1)[-1]}) + self.assertEqual(result['items'][0]['labels']['test_label'], 'test_value') + + def test_regional_disk_snapshot(self): + factory = self.replay_flight_data('disk-regional-snapshot', project_id=self.project_id) + p = self.load_policy( + {'name': 'regional-disk-snapshot', + 'resource': 'gcp.disk', + 'filters': [ + {'name': 'c7n-regional-jenkins'}], + 'actions': ['snapshot']}, + session_factory=factory) + resources = p.run() + self.assertEqual(len(resources), 1) + + def test_regional_disk_delete(self): + project_id = self.project_id + resource_name = 'c7n-regional-jenkins' + factory = self.replay_flight_data('disk-regional-delete', project_id=project_id) + policy = self.load_policy( + {'name': 'regional-disk-delete', + 'resource': 'gcp.disk', + 'filters': [ + {'name': resource_name}], + 'actions': ['delete']}, + session_factory=factory) + resources = policy.run() + self.assertEqual(resources[0]['name'], resource_name) + + if self.recording: + time.sleep(10) + session = local_session(policy.resource_manager.session_factory) + client = session.client('compute', 'v1', 'regionDisks') + region = resources[0]['region'].rsplit('/', 1)[-1] + result = client.execute_query( + 'list', {'project': project_id, + 'filter': 'name = {}'.format(resource_name), + 'region': region}) + self.assertEqual(len(result.get('items', [])), 0) + + +@terraform('disk_audit') +def test_disk_audit_mode(test, disk_audit): + """gcp-audit resolution of zonal and regional disks, on create and update. + + Zonal disk events identify the disk by a numeric ``disk_id`` label, + regional ones carry no disk identity at all -- and a ``location`` label + rather than ``region`` -- so resolution goes through ``resourceName``. + """ + project_id = test.project_id + names = { + 'zonal': disk_audit.outputs['zonal_disk_name']['value'], + 'regional': disk_audit.outputs['regional_disk_name']['value'], + } + scopes = { + 'zonal': ('disks', {'zone': disk_audit.outputs['zone']['value']}), + 'regional': ('regionDisks', {'region': disk_audit.outputs['region']['value']}), + } + + # (base event file, disk scope, mutating method) + recordings = ( + ('disk-zonal-create.json', 'zonal', 'insert'), + ('disk-regional-create.json', 'regional', 'insert'), + ('disk-zonal-update.json', 'zonal', 'setLabels'), + ('disk-regional-update.json', 'regional', 'setLabels'), + ) + + # The files those recordings produce. Every entry of an operation is + # delivered to a deployed policy as its own event, so each is exercised. + events = ( + ('disk-zonal-create-first.json', 'zonal'), + ('disk-zonal-create-last.json', 'zonal'), + ('disk-regional-create-first.json', 'regional'), + ('disk-regional-create-last.json', 'regional'), + ('disk-zonal-update-first-last.json', 'zonal'), + ('disk-regional-update-first-last.json', 'regional'), + ) + + policy_session_factory = test.replay_flight_data( + 'disk-audit', project_id=project_id) + + if test.recording: + # Setup, not the behavior being replayed: mutating the disks + # produces the update events, and the recorder polls Cloud Logging + # for all four. A plain session keeps those responses -- which + # include the caller's email and ip -- out of the flight data. + setup_session_factory = functools.partial(Session, project_id=project_id) + setup_session = setup_session_factory() + for scope, name in names.items(): + component, loc = scopes[scope] + client = setup_session.client('compute', 'v1', component) + + # Updating labels is always two requests: + # 1. A get, for the labelFingerprint, to demonstrate that + # you are updating data that is current. + # 2. The actual update. + disk = client.execute_command( + 'get', {'project': project_id, 'disk': name, **loc}) + client.execute_command( + 'setLabels', + {'project': project_id, 'resource': name, **loc, + 'body': {'labels': {'c7n-audit': 'recorded'}, + 'labelFingerprint': disk['labelFingerprint']}}) + for event_file, scope, method in recordings: + # Terraform created both disks before this body ran, so the + # create queries need a window reaching back past that. + audit_event_recorder( + setup_session_factory, + event_file, + method='compute.{}.{}'.format(scopes[scope][0], method), + resource_name=names[scope], + start_time_skew_seconds=900, + ).record() + # Sessions and their http transports are cached globally, ignoring + # the factory asked for; without this the policy below reuses + # setup_session and records nothing. (Same reason it is built + # directly above rather than via local_session.) + test.cleanUp() + + policy = test.load_policy( + {'name': 'disk-audit', + 'resource': 'gcp.disk', + 'mode': { + 'type': 'gcp-audit', + 'methods': ['v1.compute.disks.insert', + 'v1.compute.disks.setLabels', + 'v1.compute.regionDisks.insert', + 'v1.compute.regionDisks.setLabels']}}, + session_factory=policy_session_factory) + exec_mode = policy.get_execution_mode() + + for event_file, scope in events: + [resource] = exec_mode.run(event_data(event_file), None) + assert resource['name'] == names[scope], event_file + class SnapshotTest(BaseTest): diff --git a/tools/c7n_gcp/tests/test_gcp_common.py b/tools/c7n_gcp/tests/test_gcp_common.py new file mode 100644 index 00000000000..75ebd840079 --- /dev/null +++ b/tools/c7n_gcp/tests/test_gcp_common.py @@ -0,0 +1,326 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +import json + +import gcp_common +from gcp_common import audit_event_recorder + + +class FakeLoggingClient: + """Yields one queued batch of entries, in pages, per query call.""" + + def __init__(self, batches, page_size=None): + self.batches = list(batches) + self.page_size = page_size + self.calls = [] + + def execute_paged_query(self, verb, arguments): + self.calls.append((verb, arguments)) + entries = self.batches.pop(0) if self.batches else [] + size = self.page_size or len(entries) or 1 + for start in range(0, len(entries), size): + yield {'entries': entries[start:start + size]} + + +class FakeSession: + + def __init__(self, client): + self.logging_client = client + + def get_default_project(self): + return 'test-project' + + def client(self, service, version, component): + assert (service, version, component) == ('logging', 'v2', 'entries') + return self.logging_client + + +def make_recorder( + tmp_path, monkeypatch, batches, event_file='foo.json', + page_size=None, **kw): + monkeypatch.setattr(gcp_common, 'EVENT_DIR', str(tmp_path)) + client = FakeLoggingClient(batches, page_size) + session = FakeSession(client) + kw.setdefault('poll_interval', 0) + recorder = audit_event_recorder( + lambda: session, event_file, method='CreateThing', **kw) + return recorder, client + + +def read(tmp_path, name): + return json.loads((tmp_path / name).read_text()) + + +def test_standalone_entry_written_and_stops_polling(tmp_path, monkeypatch): + entry = {'insertId': 'a', 'timestamp': '2025-01-01T00:00:00Z'} + recorder, client = make_recorder(tmp_path, monkeypatch, [[entry]]) + + recorder.record() + + assert read(tmp_path, 'foo.json') == entry + assert len(client.calls) == 1 + + +def test_first_then_last_pair_writes_both_and_stops(tmp_path, monkeypatch): + first = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'operation': {'id': 'op-1', 'first': True}, + } + last = { + 'insertId': 'b', + 'timestamp': '2025-01-01T00:00:01Z', + 'operation': {'id': 'op-1', 'last': True}, + } + recorder, client = make_recorder( + tmp_path, monkeypatch, [[first], [first, last]]) + + recorder.record() + + assert read(tmp_path, 'foo-first.json') == first + assert read(tmp_path, 'foo-last.json') == last + assert len(client.calls) == 2 + + +def test_dedup_entries_filters_seen_and_updates_seen(tmp_path, monkeypatch): + recorder, client = make_recorder(tmp_path, monkeypatch, []) + seen = set() + entry_a = {'insertId': 'a'} + entry_b = {'insertId': 'b'} + + first_pass = recorder._dedup_entries(seen, [entry_a, entry_b]) + second_pass = recorder._dedup_entries(seen, [entry_a, entry_b]) + + assert first_pass == [entry_a, entry_b] + assert second_pass == [] + + +def test_repolling_the_same_entry_is_not_a_collision(tmp_path, monkeypatch): + first = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'operation': {'id': 'op-1', 'first': True}, + } + last = { + 'insertId': 'b', + 'timestamp': '2025-01-01T00:00:01Z', + 'operation': {'id': 'op-1', 'last': True}, + } + # Cloud Logging queries are cumulative from a fixed start time, so a + # later poll re-returns entries an earlier poll already wrote. + recorder, client = make_recorder( + tmp_path, monkeypatch, [[first], [first], [first, last]]) + + recorder.record() + + assert sorted(p.name for p in tmp_path.iterdir()) == [ + 'foo-first.json', 'foo-last.json'] + + +def test_query_body_reflects_structured_filters(tmp_path, monkeypatch): + entry = {'insertId': 'a', 'timestamp': '2025-01-01T00:00:00Z'} + recorder, client = make_recorder( + tmp_path, monkeypatch, [[entry]], + resource_name='projects/test-project/things/thing-1', + labels={'database_id': 'db-1'}, + ) + + recorder.record() + + verb, arguments = client.calls[0] + assert verb == 'list' + body = arguments['body'] + assert body['resourceNames'] == ['projects/test-project'] + assert body['orderBy'] == 'timestamp asc' + assert 'protoPayload.methodName : "CreateThing"' in body['filter'] + assert ( + 'protoPayload.resourceName : ' + '"projects/test-project/things/thing-1"' + in body['filter'] + ) + assert 'resource.labels.database_id = "db-1"' in body['filter'] + assert 'timestamp >= "' in body['filter'] + + +def test_record_raises_after_timeout_with_no_matches(tmp_path, monkeypatch): + recorder, client = make_recorder( + tmp_path, monkeypatch, [], timeout=0) + + try: + recorder.record() + except AssertionError: + pass + else: + raise AssertionError('expected record() to raise') + + assert not list(tmp_path.iterdir()) + + +def test_second_distinct_operation_gets_index_suffix(tmp_path, monkeypatch): + op0_first = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'operation': {'id': 'op-0', 'first': True}, + } + op1_first = { + 'insertId': 'b', + 'timestamp': '2025-01-01T00:00:01Z', + 'operation': {'id': 'op-1', 'first': True}, + } + op0_last = { + 'insertId': 'c', + 'timestamp': '2025-01-01T00:00:02Z', + 'operation': {'id': 'op-0', 'last': True}, + } + op1_last = { + 'insertId': 'd', + 'timestamp': '2025-01-01T00:00:03Z', + 'operation': {'id': 'op-1', 'last': True}, + } + recorder, client = make_recorder( + tmp_path, monkeypatch, [[op0_first, op1_first, op0_last, op1_last]]) + + recorder.record() + + assert read(tmp_path, 'foo-first.json') == op0_first + assert read(tmp_path, 'foo-last.json') == op0_last + assert read(tmp_path, 'foo-1-first.json') == op1_first + assert read(tmp_path, 'foo-1-last.json') == op1_last + + +def test_collision_appends_index_after_extension(tmp_path, monkeypatch): + (tmp_path / 'foo.json').write_text('{"pre-existing": true}') + entry = {'insertId': 'a', 'timestamp': '2025-01-01T00:00:00Z'} + recorder, client = make_recorder(tmp_path, monkeypatch, [[entry]]) + + recorder.record() + + assert read(tmp_path, 'foo.json') == {'pre-existing': True} + assert read(tmp_path, 'foo.json-1') == entry + + +def test_other_operation_completing_first_does_not_stop_polling_early( + tmp_path, monkeypatch): + # A query filter without a narrow resource_name can match entries from + # more than one operation. Polling must not stop as soon as ANY tracked + # operation reaches its 'last' entry, or another operation matched by + # the same filter is silently left incomplete. + op0_first = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'operation': {'id': 'op-0', 'first': True}, + } + op1_first = { + 'insertId': 'b', + 'timestamp': '2025-01-01T00:00:01Z', + 'operation': {'id': 'op-1', 'first': True}, + } + op1_last = { + 'insertId': 'c', + 'timestamp': '2025-01-01T00:00:02Z', + 'operation': {'id': 'op-1', 'last': True}, + } + op0_last = { + 'insertId': 'd', + 'timestamp': '2025-01-01T00:00:03Z', + 'operation': {'id': 'op-0', 'last': True}, + } + # op-1 completes entirely within the first poll; op-0's 'last' entry + # only shows up on the second poll. + recorder, client = make_recorder( + tmp_path, monkeypatch, + [[op0_first, op1_first, op1_last], [op0_last]]) + + recorder.record() + + assert read(tmp_path, 'foo-first.json') == op0_first + assert read(tmp_path, 'foo-last.json') == op0_last + assert len(client.calls) == 2 + + +def test_entries_are_collected_across_pages(tmp_path, monkeypatch): + # entries.list defaults to 50 results per page, so a poll can span pages. + entries = [ + {'insertId': str(i), 'timestamp': '2025-01-01T00:00:0{}Z'.format(i)} + for i in range(3) + ] + recorder, client = make_recorder( + tmp_path, monkeypatch, [entries], page_size=1) + + recorder.record() + + assert sorted(p.name for p in tmp_path.iterdir()) == [ + 'foo.json', 'foo.json-1', 'foo.json-2'] + + +def test_record_raises_naming_the_incomplete_operation(tmp_path, monkeypatch): + first = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'operation': {'id': 'op-0', 'first': True}, + } + recorder, client = make_recorder( + tmp_path, monkeypatch, [[first]], timeout=0) + + try: + recorder.record() + except AssertionError as e: + assert 'op-0' in str(e) + else: + raise AssertionError('expected record() to raise') + + +def test_sanitizes_project_email_and_caller_ip(tmp_path, monkeypatch): + entry = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'logName': 'projects/test-project/logs/cloudaudit.googleapis.com%2Factivity', + 'resource': {'labels': {'project_id': 'test-project'}}, + 'protoPayload': { + 'authenticationInfo': { + 'principalEmail': 'dev@example.org', + 'principalSubject': 'user:dev@example.org', + }, + 'requestMetadata': {'callerIp': '71.33.198.228'}, + 'resourceName': 'projects/test-project/zones/us-central1-a/disks/d', + 'response': {'user': 'dev@example.org'}, + }, + } + recorder, client = make_recorder(tmp_path, monkeypatch, [[entry]]) + + recorder.record() + + written = read(tmp_path, 'foo.json') + payload = written['protoPayload'] + assert written['resource']['labels']['project_id'] == 'cloud-custodian' + assert written['logName'].startswith('projects/cloud-custodian/logs/') + assert payload['resourceName'] == ( + 'projects/cloud-custodian/zones/us-central1-a/disks/d') + assert payload['authenticationInfo'] == { + 'principalEmail': 'user@example.com', + 'principalSubject': 'user:user@example.com', + } + assert payload['response']['user'] == 'user@example.com' + assert payload['requestMetadata']['callerIp'] == '198.51.100.1' + + +def test_sanitize_leaves_other_projects_and_non_strings(tmp_path, monkeypatch): + entry = { + 'insertId': 'a', + 'timestamp': '2025-01-01T00:00:00Z', + 'protoPayload': { + 'request': { + 'sizeGb': 10, + 'sourceImage': 'projects/debian-cloud/global/images/family/debian-12', + }, + }, + } + recorder, client = make_recorder(tmp_path, monkeypatch, [[entry]]) + + recorder.record() + + request = read(tmp_path, 'foo.json')['protoPayload']['request'] + assert request['sourceImage'] == ( + 'projects/debian-cloud/global/images/family/debian-12') + assert request['sizeGb'] == 10 diff --git a/tools/c7n_gcp/tests/test_gcp_labels.py b/tools/c7n_gcp/tests/test_gcp_labels.py index 6c019515bf8..cc4c813898a 100644 --- a/tools/c7n_gcp/tests/test_gcp_labels.py +++ b/tools/c7n_gcp/tests/test_gcp_labels.py @@ -47,6 +47,78 @@ def test_schema_validate(self): ])) +class SetLabelsLookupTest(BaseTest): + """Resource lookups used as values inside the ``labels`` mapping.""" + + def _get_action(self, labels): + policy = self.load_policy( + get_policy([{'type': 'set-labels', 'labels': labels}])) + return policy.resource_manager.actions[0] + + def test_lookup_by_key_resolves(self): + action = self._get_action({'env': {'type': 'resource', 'key': 'name'}}) + self.assertEqual( + action.get_labels_to_add({'name': 'instance-1', 'labels': {}}), + {'env': 'instance-1'}) + + def test_lookup_miss_uses_default_value(self): + action = self._get_action( + {'env': {'type': 'resource', + 'key': 'doesnotexist', + 'default-value': 'production'}}) + self.assertEqual( + action.get_labels_to_add({'name': 'instance-1', 'labels': {}}), + {'env': 'production'}) + + def test_static_value_passthrough(self): + action = self._get_action({'env': 'test'}) + self.assertEqual( + action.get_labels_to_add({'name': 'instance-1', 'labels': {}}), + {'env': 'test'}) + + def test_conditional_default_writes_when_label_absent(self): + action = self._get_action( + {'owner': {'type': 'resource', 'default-value': 'platform'}}) + self.assertEqual( + action.get_labels_to_add({'name': 'instance-1', 'labels': {}}), + {'owner': 'platform'}) + + def test_conditional_default_skipped_when_label_present(self): + action = self._get_action( + {'owner': {'type': 'resource', 'default-value': 'platform'}}) + self.assertEqual( + action.get_labels_to_add( + {'name': 'instance-1', 'labels': {'owner': 'keep-me'}}), + {}) + + def test_conditional_default_leaves_existing_label_intact(self): + """The skipped label must survive the merge with current labels.""" + action = self._get_action( + {'owner': {'type': 'resource', 'default-value': 'platform'}, + 'env': 'test'}) + resource = {'name': 'instance-1', 'labels': {'owner': 'keep-me'}} + merged = action._merge_labels( + action._get_current_labels(resource), + action.get_labels_to_add(resource), + action.get_labels_to_delete(resource)) + self.assertEqual(merged, {'owner': 'keep-me', 'env': 'test'}) + + def test_schema_accepts_conditional_default(self): + self.assertTrue(self.load_policy(get_policy([ + {'type': 'set-labels', + 'labels': {'owner': {'type': 'resource', 'default-value': 'x'}}} + ]))) + + def test_schema_rejects_malformed_label_values(self): + for bad in ({'type': 'resource'}, + {'type': 'resource', 'ky': 'name'}, + {'foo': 'bar'}): + with self.assertRaises(Exception): + self.load_policy( + get_policy([{'type': 'set-labels', 'labels': {'x': bad}}]), + validate=True) + + class LabelDelayedActionTest(BaseTest): def test_schema_validate(self): diff --git a/tools/c7n_gcp/tests/test_notebook.py b/tools/c7n_gcp/tests/test_notebook.py index 040d85bd2d6..8ba578b2773 100644 --- a/tools/c7n_gcp/tests/test_notebook.py +++ b/tools/c7n_gcp/tests/test_notebook.py @@ -1,5 +1,7 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import time + from pytest_terraform import terraform from gcp_common import BaseTest @@ -25,7 +27,7 @@ def test_notebook_instance_query(self): ] -@terraform("notebook_v2") +@terraform("notebook_v2", scope="session") def test_notebook_v2(test, notebook_v2): notebook_name = notebook_v2["google_workbench_instance.public_instance.name"] @@ -56,3 +58,83 @@ def test_notebook_v2(test, notebook_v2): assert len(resources) == 1 assert resources[0]["name"].endswith(notebook_name) assert resources[0]["gceSetup"]["networkInterfaces"][0]["accessConfigs"][0]["externalIp"] + + +@terraform("notebook_v2", scope="session") +def test_notebook_v2_get(test, notebook_v2): + notebook_name = notebook_v2["google_workbench_instance.public_instance.name"] + + factory = test.replay_flight_data("test_notebook_v2_get") + policy = test.load_policy( + { + "name": "notebook-v2-get", + "resource": "gcp.notebook-v2", + "filters": [ + { + "type": "value", + "key": "name", + "op": "regex", + "value": f".*{notebook_name}$", + }, + ], + }, + session_factory=factory, + ) + + listed = policy.run() + assert len(listed) == 1 + + fetched = policy.resource_manager.get_resource( + {"resourceName": listed[0]["name"]} + ) + assert fetched["name"] == listed[0]["name"] + assert fetched["gceSetup"]["metadata"] == listed[0]["gceSetup"].get("metadata", {}) + + +@terraform("notebook_v2", scope="session") +def test_notebook_v2_update_metadata(test, notebook_v2): + notebook_name = notebook_v2["google_workbench_instance.public_instance.name"] + + factory = test.replay_flight_data("test_notebook_v2_update_metadata") + policy = test.load_policy( + { + "name": "notebook-v2-update-metadata", + "resource": "gcp.notebook-v2", + "filters": [ + { + "type": "value", + "key": "name", + "op": "regex", + "value": f".*{notebook_name}$", + }, + ], + "actions": [ + { + "type": "update-metadata", + "metadata": {"idle-timeout-seconds": "3600"}, + }, + ], + }, + session_factory=factory, + ) + + # notebooks.instances.list can lag briefly after instance creation. + # Replay uses recorded responses, so only sleep while recording live. + if test.recording: + time.sleep(30) + + resources = policy.run() + assert len(resources) == 1 + original_metadata = dict(resources[0]["gceSetup"].get("metadata", {})) + + # The patch call returns a long-running Operation -- give it time to + # finish before checking the result. + if test.recording: + time.sleep(30) + + fetched = policy.resource_manager.get_resource( + {"resourceName": resources[0]["name"]} + ) + assert fetched["gceSetup"]["metadata"]["idle-timeout-seconds"] == "3600" + for key, value in original_metadata.items(): + assert fetched["gceSetup"]["metadata"][key] == value diff --git a/tools/c7n_gcp/tests/test_query.py b/tools/c7n_gcp/tests/test_query.py index 3f16ba7ae74..5f0271e98eb 100644 --- a/tools/c7n_gcp/tests/test_query.py +++ b/tools/c7n_gcp/tests/test_query.py @@ -1,13 +1,48 @@ # Copyright The Cloud Custodian Authors. # SPDX-License-Identifier: Apache-2.0 +import os + +from c7n.config import Config from c7n.resources import load_resources -from c7n_gcp.query import GcpLocation +from c7n_gcp.query import config_regions, GcpLocation from c7n_gcp.provider import GoogleCloud from gcp_common import BaseTest +class ConfigRegionsTest(BaseTest): + + def test_no_explicit_region(self): + # real gcp cli run with no --region: commands.py seeds + # options.region = "" and, unlike aws, the gcp provider never + # expands per-policy regions (GoogleCloud.initialize_policies is a + # no-op), so config.region stays "". + self.assertEqual(config_regions(Config.empty(region="")), ()) + + def test_region_aws_default_sentinel(self): + # Config.empty()'s own default region must not be treated as an + # explicit gcp region, whether or not AWS_DEFAULT_REGION is set. + default_region = os.environ.get('AWS_DEFAULT_REGION', 'us-east-1') + self.assertEqual(config_regions(Config.empty(region=default_region)), ()) + + def test_explicit_region(self): + self.assertEqual( + config_regions(Config.empty(region="us-central1")), ("us-central1",)) + + def test_explicit_regions(self): + self.assertEqual( + config_regions(Config.empty(regions=("us-central1", "us-east1"))), + ("us-central1", "us-east1")) + + def test_regions_all(self): + self.assertEqual(config_regions(Config.empty(regions=("all",))), ()) + + def test_regions_all_overrides_other_entries(self): + self.assertEqual( + config_regions(Config.empty(regions=("us-central1", "all"))), ()) + + def test_gcp_resource_metadata_asset_type(): load_resources(('gcp.*',)) # asset inventory doesn't support these @@ -47,7 +82,8 @@ def test_gcp_resource_metadata_asset_type(): 'region', 'vertex-ai-publisher', # Synthetic resource (no asset inventory type) 'vertex-ai-publisher-model', # Catalog resource (no asset inventory type) - 'vertex-ai-location' + 'vertex-ai-location', + 'vertex-ai-evaluation-run', # No asset inventory type yet )) missing = set() for k, v in GoogleCloud.resources.items(): diff --git a/tools/c7n_gcp/tests/test_region.py b/tools/c7n_gcp/tests/test_region.py new file mode 100644 index 00000000000..4851cdaebf7 --- /dev/null +++ b/tools/c7n_gcp/tests/test_region.py @@ -0,0 +1,38 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 + +from gcp_common import BaseTest + +from c7n.config import Config +from c7n_gcp.region import Region + + +class RegionResourcesTest(BaseTest): + + def get_region(self, data=(), **config): + ctx = self.get_context(config=Config.empty(**config)) + return Region(ctx, data) + + def test_no_explicit_region_enumerates_all(self): + # A region-parented resource (e.g. dataproc-clusters) must still + # enumerate its parent regions when no --region was given, rather + # than collapsing to zero. + region = self.get_region(region="") + self.assertEqual(len(region.resources()), len(region.regions)) + + def test_resource_ids(self): + region = self.get_region() + self.assertEqual( + region.resources(resource_ids=('us-central1',)), + [{'name': 'us-central1'}]) + + def test_config_region(self): + region = self.get_region(region="us-central1") + self.assertEqual(region.resources(), [{'name': 'us-central1'}]) + + def test_data_query(self): + # RegionalResourceManager.get_parent_resource_query() resolves + # config.regions/config.region into this 'query' form before + # constructing the parent Region manager. + region = self.get_region(data={'query': [{'name': 'us-central1'}]}) + self.assertEqual(region.resources(), [{'name': 'us-central1'}]) diff --git a/tools/c7n_gcp/tests/test_vertexai.py b/tools/c7n_gcp/tests/test_vertexai.py index 02a2d3dd246..75d62b06685 100644 --- a/tools/c7n_gcp/tests/test_vertexai.py +++ b/tools/c7n_gcp/tests/test_vertexai.py @@ -151,6 +151,101 @@ def cleanup(self): pass +class VertexAIEvaluationRuns: + """Helper for creating/cleaning up ephemeral Vertex AI evaluation runs. + + Uses the computation-based EXACT_MATCH metric with a pre-supplied + prediction/reference pair, so the run completes by pure computation -- + no model inference -- making it fast, free, and deterministic. + """ + + TERMINAL_STATES = {'SUCCEEDED', 'FAILED', 'CANCELLED'} + + def __init__(self, test): + self.test = test + self.created = [] + + def _client(self, session, location, component): + return session.client( + 'aiplatform', 'v1', component, + client_options=ClientOptions( + api_endpoint=f'https://{location}-aiplatform.googleapis.com')) + + def create(self, location, display_name, prediction='4', reference='4', fail=False): + """Create an evaluation item, its evaluation set, and a run over it. + + By default the item has a matching prediction/reference, and the run + succeeds. Pass `fail=True` to omit the candidate response, which + produces a deterministic FAILED run (no metric score to aggregate). + """ + session = self.test.session_factory() + project = session.get_default_project() + parent = f'projects/{project}/locations/{location}' + + evaluation_request = { + 'prompt': {'text': 'What is 2+2?'}, + 'goldenResponse': {'text': reference}, + } + if not fail: + evaluation_request['candidateResponses'] = [ + {'candidate': 'model-under-test', 'text': prediction}] + + # Create an evaluation item: + items_client = self._client(session, location, 'projects.locations.evaluationItems') + item = items_client.execute_command( + 'create', + {'parent': parent, + 'body': { + 'displayName': f'{display_name}-item', + 'evaluationItemType': 'REQUEST', + 'evaluationRequest': evaluation_request, + }}) + self.created.append((items_client, item['name'])) + + # Create its evaluation set: + sets_client = self._client(session, location, 'projects.locations.evaluationSets') + eval_set = sets_client.execute_command( + 'create', + {'parent': parent, + 'body': {'displayName': f'{display_name}-set', 'evaluationItems': [item['name']]}}) + self.created.append((sets_client, eval_set['name'])) + + # Create a run over it + runs_client = self._client(session, location, 'projects.locations.evaluationRuns') + run = runs_client.execute_command( + 'create', + {'parent': parent, + 'body': { + 'displayName': display_name, + 'dataSource': {'evaluationSet': eval_set['name']}, + 'evaluationConfig': { + 'metrics': [{'metric': 'exact_match', + 'computationBasedMetricSpec': {'type': 'EXACT_MATCH'}}]}, + }}) + self.created.append((runs_client, run['name'])) + + for _ in range(6): + if run['state'] in self.TERMINAL_STATES: + break + if self.test.recording: + time.sleep(5) + run = runs_client.execute_query('get', {'name': run['name']}) + + # Track the run's auto-created results set for cleanup, if any. + results_set = run.get('evaluationResults', {}).get('evaluationSet') + if results_set: + self.created.append((sets_client, results_set)) + + return run + + def cleanup(self): + for client, name in reversed(self.created): + try: + client.execute_command('delete', {'name': name}) + except HttpError as e: + print(f'Warning: failed to delete {name} during cleanup: {e}') + + def get_test_model_id(project_id, location): """Get full model resource name for testing. @@ -263,6 +358,75 @@ def test_vertexai_model_resource_registered(test): 'projects.locations.models') +def test_vertexai_evaluation_run_resource_registered(test): + """Test that gcp.vertex-ai-evaluation-run resolves as a resource type.""" + policy = test.load_policy( + {'name': 'vertexai-evaluation-run-check', + 'resource': 'gcp.vertex-ai-evaluation-run'}) + assert policy.resource_manager.resource_type.component == ( + 'projects.locations.evaluationRuns') + + +def test_vertexai_evaluation_run_multi_location(test): + """Test querying Vertex AI Evaluation Runs across multiple locations.""" + test.session_factory = test.replay_flight_data('vertexai-evaluation-run-multi-location') + + runs = VertexAIEvaluationRuns(test) + test.addCleanup(runs.cleanup) + if test.recording: + runs.create('us-central1', 'c7n-test-eval-run-central') + runs.create('us-east1', 'c7n-test-eval-run-east') + + policy = test.load_policy( + {'name': 'vertexai-evaluation-runs-multi-location', + 'resource': 'gcp.vertex-ai-evaluation-run', + 'query': [ + {'location': 'us-central1'}, + {'location': 'us-east1'} + ]}, + session_factory=test.session_factory) + + resources = policy.run() + + assert len(resources) >= 2 + locations = {r['name'].split('/')[3] for r in resources} + assert 'us-central1' in locations + assert 'us-east1' in locations + + +def test_vertexai_evaluation_run_filtering(test): + """Test filtering Vertex AI Evaluation Runs on state. + + Uses a run that succeeds (matching prediction/reference) and one that + fails (no candidate response to score) to prove the filter actually + discriminates by state, not just returns everything. + """ + test.session_factory = test.replay_flight_data('vertexai-evaluation-run-filtering') + + runs = VertexAIEvaluationRuns(test) + test.addCleanup(runs.cleanup) + if test.recording: + runs.create('us-central1', 'c7n-test-eval-run-succeeded') + runs.create('us-central1', 'c7n-test-eval-run-failed', fail=True) + + policy = test.load_policy( + {'name': 'vertexai-evaluation-runs-failed', + 'resource': 'gcp.vertex-ai-evaluation-run', + 'query': [{'location': 'us-central1'}], + 'filters': [ + {'type': 'value', + 'key': 'state', + 'value': 'FAILED'} + ]}, + session_factory=test.session_factory) + + resources = policy.run() + + assert len(resources) >= 1 + assert all(r['state'] == 'FAILED' for r in resources) + assert not any(r['state'] == 'SUCCEEDED' for r in resources) + + @terraform('vertexai_dataset', scope='module') def test_vertexai_dataset_multi_location(test, vertexai_dataset): """Test querying Vertex AI Datasets across multiple locations.""" diff --git a/tools/c7n_kube/c7n_kube/query.py b/tools/c7n_kube/c7n_kube/query.py index e1d438a091c..a1589cacbf0 100644 --- a/tools/c7n_kube/c7n_kube/query.py +++ b/tools/c7n_kube/c7n_kube/query.py @@ -4,7 +4,7 @@ import logging from c7n.actions import ActionRegistry -from c7n.exceptions import PolicyValidationError +from c7n.exceptions import PolicyExecutionError, PolicyValidationError from c7n.filters import FilterRegistry from c7n.manager import ResourceManager from c7n.query import sources @@ -28,12 +28,34 @@ def filter(self, resource_manager, **params): return self._invoke_client_enum(client, enum_op, params, path) def _invoke_client_enum(self, client, enum_op, params, path): - res = getattr(client, enum_op)(**params) - if not isinstance(res, dict): - res = res.to_dict() - if path and path in res: - res = res.get(path) - return res + items = [] + params = dict(params) + first = True + # Deliberately unbounded, for consistency with c7n/query.py's own + # AWS paginator (which also has no page cap). + while True: + res = getattr(client, enum_op)(**params) + if not isinstance(res, dict): + res = res.to_dict() + if path and path in res: + items.extend(res[path]) + elif first: + # No path in the first response: return it unchanged (non-list + # response shape). + return res + else: + # A later page without the expected shape fails loud rather than + # silently dropping the items already accumulated from earlier pages. + raise PolicyExecutionError( + f"unexpected response on page after the first (missing " + f"{path!r}); {len(items)} item(s) already fetched would " + f"be silently dropped" + ) + first = False + token = res.get("metadata", {}).get("_continue") + if not token: + return items + params["_continue"] = token @sources.register("describe-kube") diff --git a/tools/c7n_kube/pyproject.toml b/tools/c7n_kube/pyproject.toml index 5b509e656ac..fb1dc4e3805 100644 --- a/tools/c7n_kube/pyproject.toml +++ b/tools/c7n_kube/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "kubernetes>=10.0.1", ] name = "c7n_kube" -version = "0.2.51a5+a83dda5c9" +version = "0.2.52a1+e4c099e03" description = "Cloud Custodian - Kubernetes Provider" readme = "readme.md" classifiers = [ diff --git a/tools/c7n_kube/tests/data/flights/TestQueryPagination.test_pagination_multi_page.yaml b/tools/c7n_kube/tests/data/flights/TestQueryPagination.test_pagination_multi_page.yaml new file mode 100644 index 00000000000..34fbca3cc92 --- /dev/null +++ b/tools/c7n_kube/tests/data/flights/TestQueryPagination.test_pagination_multi_page.yaml @@ -0,0 +1,104 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAPI-Generator/36.0.3/python + method: GET + uri: https://ghost/api/v1/configmaps?limit=2 + response: + body: + string: '{"kind":"ConfigMapList","apiVersion":"v1","metadata":{"resourceVersion":"154","continue":"eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6MTU0LCJzdGFydCI6Ii9jN24tdGVzdC9wZy10ZXN0LTAxXHUwMDAwIn0","remainingItemCount":4},"items":[{"metadata":{"name":"pg-test-00","namespace":"c7n-test","uid":"54608c06-7d50-42df-8cb2-796dbd93443d","resourceVersion":"76","creationTimestamp":"2026-09-03T12:30:05Z","annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k\":\"v\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"pg-test-00\",\"namespace\":\"c7n-test\"}}\n"},"managedFields":[{"manager":"kubectl-client-side-apply","operation":"Update","apiVersion":"v1","time":"2026-09-03T12:30:05Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:k":{}},"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}}}]},"data":{"k":"v"}},{"metadata":{"name":"pg-test-01","namespace":"c7n-test","uid":"1a531063-8971-4eb9-85ce-8af88de7bd98","resourceVersion":"77","creationTimestamp":"2026-09-03T12:30:05Z","annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k\":\"v\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"pg-test-01\",\"namespace\":\"c7n-test\"}}\n"},"managedFields":[{"manager":"kubectl-client-side-apply","operation":"Update","apiVersion":"v1","time":"2026-09-03T12:30:05Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:k":{}},"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}}}]},"data":{"k":"v"}}]} + + ' + headers: + Audit-Id: + - 2d187fa0-fb89-4cc6-bc5b-62ba1fef92cd + Cache-Control: + - no-cache, private + Content-Length: + - '1616' + Content-Type: + - application/json + Date: + - Thu, 03 Sep 2026 12:36:09 GMT + X-Kubernetes-Pf-Flowschema-Uid: + - 414213a9-2a93-4395-b483-485722a210db + X-Kubernetes-Pf-Prioritylevel-Uid: + - 8c8c53d3-90de-44b0-8def-95786b17074d + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAPI-Generator/36.0.3/python + method: GET + uri: https://ghost/api/v1/configmaps?continue=eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6MTU0LCJzdGFydCI6Ii9jN24tdGVzdC9wZy10ZXN0LTAxXHUwMDAwIn0&limit=2 + response: + body: + string: '{"kind":"ConfigMapList","apiVersion":"v1","metadata":{"resourceVersion":"154","continue":"eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6MTU0LCJzdGFydCI6ImM3bi10ZXN0L3BnLXRlc3QtMDNcdTAwMDAifQ","remainingItemCount":2},"items":[{"metadata":{"name":"pg-test-02","namespace":"c7n-test","uid":"3a6ab3ca-2c70-4daa-9992-6d9fc000ecb9","resourceVersion":"78","creationTimestamp":"2026-09-03T12:30:05Z","annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k\":\"v\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"pg-test-02\",\"namespace\":\"c7n-test\"}}\n"},"managedFields":[{"manager":"kubectl-client-side-apply","operation":"Update","apiVersion":"v1","time":"2026-09-03T12:30:05Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:k":{}},"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}}}]},"data":{"k":"v"}},{"metadata":{"name":"pg-test-03","namespace":"c7n-test","uid":"e925e4ab-c80a-42a2-b8b8-5908c323dd9b","resourceVersion":"79","creationTimestamp":"2026-09-03T12:30:05Z","annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k\":\"v\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"pg-test-03\",\"namespace\":\"c7n-test\"}}\n"},"managedFields":[{"manager":"kubectl-client-side-apply","operation":"Update","apiVersion":"v1","time":"2026-09-03T12:30:05Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:k":{}},"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}}}]},"data":{"k":"v"}}]} + + ' + headers: + Audit-Id: + - aefdaf29-2d35-4d3c-9b28-dcea6fc4519c + Cache-Control: + - no-cache, private + Content-Length: + - '1615' + Content-Type: + - application/json + Date: + - Thu, 03 Sep 2026 12:36:09 GMT + X-Kubernetes-Pf-Flowschema-Uid: + - 414213a9-2a93-4395-b483-485722a210db + X-Kubernetes-Pf-Prioritylevel-Uid: + - 8c8c53d3-90de-44b0-8def-95786b17074d + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - OpenAPI-Generator/36.0.3/python + method: GET + uri: https://ghost/api/v1/configmaps?continue=eyJ2IjoibWV0YS5rOHMuaW8vdjEiLCJydiI6MTU0LCJzdGFydCI6ImM3bi10ZXN0L3BnLXRlc3QtMDNcdTAwMDAifQ&limit=2 + response: + body: + string: '{"kind":"ConfigMapList","apiVersion":"v1","metadata":{"resourceVersion":"154"},"items":[{"metadata":{"name":"pg-test-04","namespace":"c7n-test","uid":"4ead77d6-a5f3-435c-946f-0a55d8c98dab","resourceVersion":"80","creationTimestamp":"2026-09-03T12:30:05Z","annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"data\":{\"k\":\"v\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"pg-test-04\",\"namespace\":\"c7n-test\"}}\n"},"managedFields":[{"manager":"kubectl-client-side-apply","operation":"Update","apiVersion":"v1","time":"2026-09-03T12:30:05Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:k":{}},"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}}}]},"data":{"k":"v"}},{"metadata":{"name":"kube-apiserver-legacy-service-account-token-tracking","namespace":"kube-system","uid":"ccf7d27a-31a5-497c-bd2e-592326643cff","resourceVersion":"61","creationTimestamp":"2026-09-03T12:29:45Z","managedFields":[{"manager":"kube-apiserver","operation":"Update","apiVersion":"v1","time":"2026-09-03T12:29:45Z","fieldsType":"FieldsV1","fieldsV1":{"f:data":{".":{},"f:since":{}}}}]},"data":{"since":"2026-09-03"}}]} + + ' + headers: + Audit-Id: + - b661a9c5-278f-4246-8daa-6ac182c3dc94 + Cache-Control: + - no-cache, private + Content-Length: + - '1217' + Content-Type: + - application/json + Date: + - Thu, 03 Sep 2026 12:36:09 GMT + X-Kubernetes-Pf-Flowschema-Uid: + - 414213a9-2a93-4395-b483-485722a210db + X-Kubernetes-Pf-Prioritylevel-Uid: + - 8c8c53d3-90de-44b0-8def-95786b17074d + status: + code: 200 + message: OK +version: 1 diff --git a/tools/c7n_kube/tests/test_query_pagination.py b/tools/c7n_kube/tests/test_query_pagination.py new file mode 100644 index 00000000000..47ccd6b021a --- /dev/null +++ b/tools/c7n_kube/tests/test_query_pagination.py @@ -0,0 +1,41 @@ +# Copyright The Cloud Custodian Authors. +# SPDX-License-Identifier: Apache-2.0 +from unittest.mock import MagicMock + +from common_kube import KubeTest + +from c7n.exceptions import PolicyExecutionError +from c7n_kube.query import ResourceQuery + + +class TestQueryPagination(KubeTest): + def test_pagination_multi_page(self): + # Recorded against a real kube-apiserver seeded with 6 ConfigMaps, + # queried with limit=2 (3 pages: 2, 2, 2 items). + factory = self.replay_flight_data() + p = self.load_policy( + {"name": "config-maps", "resource": "k8s.config-map"}, + session_factory=factory, + ) + manager = p.resource_manager + query = ResourceQuery(manager.session_factory) + resources = query.filter(manager, limit=2) + self.assertEqual(len(resources), 6) + + def test_pagination_shape_change_raises(self): + first_page = { + "metadata": {"_continue": "token"}, + "items": [{"metadata": {"name": "a"}}], + } + second_page = {"metadata": {}} + + client = MagicMock() + client.list_config_map_for_all_namespaces.side_effect = [first_page, second_page] + + query = ResourceQuery(session_factory=None) + with self.assertRaises(PolicyExecutionError) as ctx: + query._invoke_client_enum( + client, "list_config_map_for_all_namespaces", {"limit": 2}, "items" + ) + self.assertIn("1 item(s)", str(ctx.exception)) + self.assertIn("'items'", str(ctx.exception)) diff --git a/tools/c7n_left/pyproject.toml b/tools/c7n_left/pyproject.toml index 4c222699bb9..7d770f82af7 100644 --- a/tools/c7n_left/pyproject.toml +++ b/tools/c7n_left/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "tfparse<1.0,>=0.6", ] name = "c7n_left" -version = "0.3.38a5+a83dda5c9" +version = "0.3.39a1+e4c099e03" description = "Custodian policies for IAAC definitions" readme = "README.md" classifiers = [ diff --git a/tools/c7n_mailer/pyproject.toml b/tools/c7n_mailer/pyproject.toml index de29ab063bf..cdad0209883 100644 --- a/tools/c7n_mailer/pyproject.toml +++ b/tools/c7n_mailer/pyproject.toml @@ -20,7 +20,7 @@ dependencies = [ "types-six<2.0.0,>=1.16.10", ] name = "c7n_mailer" -version = "0.6.51a5+a83dda5c9" +version = "0.6.52a1+e4c099e03" description = "Cloud Custodian - Reference Mailer" readme = "README.md" classifiers = [ diff --git a/tools/c7n_oci/pyproject.toml b/tools/c7n_oci/pyproject.toml index 50d7344a951..0f82ea87326 100644 --- a/tools/c7n_oci/pyproject.toml +++ b/tools/c7n_oci/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "pyopenssl>=24" ] name = "c7n_oci" -version = "0.1.26a5+a83dda5c9" +version = "0.1.27a1+e4c099e03" description = "Cloud Custodian - OCI Support" readme = "readme.md" classifiers = [ diff --git a/tools/c7n_openstack/pyproject.toml b/tools/c7n_openstack/pyproject.toml index ffc769cc465..411f484d6da 100644 --- a/tools/c7n_openstack/pyproject.toml +++ b/tools/c7n_openstack/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "openstacksdk==0.52.0", ] name = "c7n_openstack" -version = "0.1.42a5+a83dda5c9" +version = "0.1.43a1+e4c099e03" description = "Cloud Custodian - OpenStack Provider" readme = "readme.md" classifiers = [ diff --git a/tools/c7n_org/c7n_org/orgaccounts.py b/tools/c7n_org/c7n_org/orgaccounts.py index 2118e46d677..e9b927b1087 100644 --- a/tools/c7n_org/c7n_org/orgaccounts.py +++ b/tools/c7n_org/c7n_org/orgaccounts.py @@ -151,7 +151,7 @@ def get_accounts_for_ou(client, ou, active, recursive=True, ignoredAccounts=()): continue if active: - if a['Status'] == 'ACTIVE': + if a['State'] == 'ACTIVE': results.append(a) else: results.append(a) diff --git a/tools/c7n_org/pyproject.toml b/tools/c7n_org/pyproject.toml index df70022ec5d..7a38056a451 100644 --- a/tools/c7n_org/pyproject.toml +++ b/tools/c7n_org/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "click>=8.0", ] name = "c7n_org" -version = "0.6.51a5+a83dda5c9" +version = "0.6.52a1+e4c099e03" description = "Cloud Custodian - Parallel Execution" readme = "README.md" classifiers = [ diff --git a/tools/c7n_policystream/pyproject.toml b/tools/c7n_policystream/pyproject.toml index 8f556f3226a..b39d4ac0a7b 100644 --- a/tools/c7n_policystream/pyproject.toml +++ b/tools/c7n_policystream/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "requests<3.0.0,>=2.22.0", ] name = "c7n_policystream" -version = "0.4.51a5+a83dda5c9" +version = "0.4.52a1+e4c099e03" description = "Cloud Custodian - Git Commits as Logical Policy Changes" readme = "README.md" classifiers = [ diff --git a/tools/c7n_sphinxext/pyproject.toml b/tools/c7n_sphinxext/pyproject.toml index bc195381bc4..b6e1bcc741b 100644 --- a/tools/c7n_sphinxext/pyproject.toml +++ b/tools/c7n_sphinxext/pyproject.toml @@ -15,7 +15,7 @@ dependencies = [ "sphinx-rtd-theme>=1.0.0", ] name = "c7n_sphinxext" -version = "1.1.51a5+a83dda5c9" +version = "1.1.52a1+e4c099e03" description = "Cloud Custodian - Sphinx Extensions" classifiers = [ "License :: OSI Approved :: Apache Software License", diff --git a/tools/c7n_tencentcloud/pyproject.toml b/tools/c7n_tencentcloud/pyproject.toml index e65bf880ae3..e54c112642b 100644 --- a/tools/c7n_tencentcloud/pyproject.toml +++ b/tools/c7n_tencentcloud/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "tencentcloud-sdk-python<4.0.0,>=3.0.783", ] name = "c7n_tencentcloud" -version = "0.1.34a5+a83dda5c9" +version = "0.1.35a1+e4c099e03" description = "Cloud Custodian - Tencent Cloud Provider" readme = "readme.md" diff --git a/tools/dev/license-check.py b/tools/dev/license-check.py index 3af38e4476c..d22d83f4bd2 100644 --- a/tools/dev/license-check.py +++ b/tools/dev/license-check.py @@ -5,6 +5,7 @@ accept = ( 'MIT', + 'MIT-0', 'BSD', 'Apache License 2.0', 'Apache License, Version 2.0', diff --git a/tools/ops/azure/functionslc.py b/tools/ops/azure/functionslc.py index 031cf874bf5..6e29b5eca89 100644 --- a/tools/ops/azure/functionslc.py +++ b/tools/ops/azure/functionslc.py @@ -38,7 +38,7 @@ def wait_for_remote_builds(deployments): while finished < total: for name, params in deployments.items(): try: - params['status'] = get_build_status(params['scm_uri']) + params['status'] = get_build_status(params['scm_uri'], params['token']) except Exception: params['status'] = DeploymentStatus.Active @@ -54,16 +54,18 @@ def wait_for_remote_builds(deployments): time.sleep(30) -def get_build_status(scm_uri): +def get_build_status(scm_uri, token): + headers = {'Authorization': 'Bearer %s' % token} + is_deploying_uri = '%s/api/isdeploying' % scm_uri - is_deploying = requests.get(is_deploying_uri).json()['value'] + is_deploying = requests.get(is_deploying_uri, headers=headers).json()['value'] if strtobool(is_deploying): return DeploymentStatus.Active # Get build status deployments_uri = '%s/deployments' % scm_uri - r = requests.get(deployments_uri).json() + r = requests.get(deployments_uri, headers=headers).json() if len(r) == 0: return DeploymentStatus.NotFound @@ -83,7 +85,6 @@ def cli(**kwargs): if p.provider_name == 'azure'], policy_config) session = policies.policies[0].session_factory() - web_client = session.client('azure.mgmt.web.WebSiteManagementClient') deployments = {} credentials_load_failed = 0 @@ -94,13 +95,15 @@ def cli(**kwargs): continue try: params = AzureFunctionMode(p).get_function_app_params() - creds = web_client.web_apps.begin_list_publishing_credentials( - params.function_app_resource_group_name, - params.function_app_name).result() - deployments[p.name] = {'scm_uri': creds.scm_uri, 'status': None} - log.info('Retrieved deployment credentials for %s policy', p.name) + app_name = params.function_app['name'] + scm_uri = 'https://{}.scm.azurewebsites.net'.format(app_name) + token_scope = session.cloud_endpoints.endpoints.resource_manager.rstrip('/') \ + + '/.default' + token = session.get_credentials().get_token(token_scope).token + deployments[p.name] = {'scm_uri': scm_uri, 'token': token, 'status': None} + log.info('Retrieved deployment token for %s policy', p.name) except Exception: - log.error('Unable to retrieve deployment credentials for %s policy', p.name) + log.error('Unable to retrieve deployment token for %s policy', p.name) credentials_load_failed += 1 wait_for_remote_builds(deployments) @@ -112,7 +115,7 @@ def cli(**kwargs): if params['status'] != DeploymentStatus.Succeeded: log.info('%s: %s', name, params['status']) if params['status'] == DeploymentStatus.Failed: - log.error('Build logs can be retrieved here: %s', params['scm_uri']) + log.error('Build logs can be retrieved here: %s/api/deployments', params['scm_uri']) fail += 1 else: not_found += 1 diff --git a/uv.lock b/uv.lock index 991222ccf38..f7a8f864af0 100644 --- a/uv.lock +++ b/uv.lock @@ -50,16 +50,16 @@ wheels = [ [[package]] name = "aiohappyeyeballs" -version = "2.6.2" +version = "2.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/33/c6/61a2d7b7572279226bb2e7f61d7a19ca7c90da0329c93fa0d560cbf288d8/aiohappyeyeballs-2.6.2.tar.gz", hash = "sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64", size = 22591, upload-time = "2026-05-20T15:12:24.631Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/eec0465c2f67b2664688d0240b3212d5196fd89e741df67ddb81f8d35658/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d", size = 24757, upload-time = "2026-07-01T17:11:55.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl", hash = "sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4", size = 15062, upload-time = "2026-05-20T15:12:23.328Z" }, + { url = "https://files.pythonhosted.org/packages/71/43/1947f06babed6b3f1d7f38b0c767f52df66bfb2bc10b468c4a7de9eceff2/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472", size = 15038, upload-time = "2026-07-01T17:11:54.055Z" }, ] [[package]] name = "aiohttp" -version = "3.14.1" +version = "3.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -72,126 +72,126 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/78/8ea7308cac6934de8c74a14f3d5f65d1c89287426688be79538d0e5c013d/aiohttp-3.14.1.tar.gz", hash = "sha256:307f2cff90a764d329e77040603fa032db89c5c24fdad50c4c15334cba744035", size = 7955794, upload-time = "2026-06-07T21:09:35.529Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/67/58ded4b3f2e10f94972d8928050c85330e249a31dd45a0e5f3c0e9c3fa05/aiohttp-3.14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8f6bb621e5863cfe8fe5ff5468002d200ec31f30f1280b259dc505b02595099e", size = 766140, upload-time = "2026-06-07T21:05:37.471Z" }, - { url = "https://files.pythonhosted.org/packages/18/68/4ae5b4e08943f316594bb68da89957d3baf5760588fa09509594bd777e4b/aiohttp-3.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f7215cb3933784f79ed20e5f050e15984f390424339b22375d5a53c933a0491", size = 519430, upload-time = "2026-06-07T21:05:40.751Z" }, - { url = "https://files.pythonhosted.org/packages/cb/c1/316c8f3549dbe5245f92bfd523ec6f32dd4d98cafe21df3f6a19b1184c75/aiohttp-3.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9d4e294455b23a68c9b8f042d0e8e377a265bcb15332753695f6e5b6819e0ce", size = 514406, upload-time = "2026-06-07T21:05:42.111Z" }, - { url = "https://files.pythonhosted.org/packages/5a/ee/fb0ac28684e8d753b83c8a4eebc19a5846912aa0a4daaabb6a9936363840/aiohttp-3.14.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b238af795833d5731d049d82bc84b768ae6f8f97f0495963b3ed9935c5901cc3", size = 1703649, upload-time = "2026-06-07T21:05:43.427Z" }, - { url = "https://files.pythonhosted.org/packages/3b/57/aa2beab673331f111885db8a7b69dfe3ab0e53e446a0ace18ca694b4dc58/aiohttp-3.14.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4e5e0ae56914ecdbf446493addefc0159053dd53962cef37d7839f37f73d505", size = 1675126, upload-time = "2026-06-07T21:05:44.897Z" }, - { url = "https://files.pythonhosted.org/packages/47/ea/dad128abe365e79be03b16ed464198ac73e0d257e8260c6f7d6f31cbef26/aiohttp-3.14.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:092e4ce3619a7c6dee52a6bdabda973d9b34b66781f840ce93c7e0cec30cf521", size = 1771558, upload-time = "2026-06-07T21:05:46.405Z" }, - { url = "https://files.pythonhosted.org/packages/63/f3/b5b4e10327cb85d34d24232c6b71b64602f190b3ccb238a043ac6b187dac/aiohttp-3.14.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb33777ea21e8b7ecde0e6fc84f598be0a1192eab1a63bc746d75aa75d38e7bd", size = 1856631, upload-time = "2026-06-07T21:05:47.844Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9d/93294c3045775c708ac8310eb3d3622a11d2951345ad590d532d62a1faa4/aiohttp-3.14.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23119f8fd4f5d16902ed459b63b100bcd269628075162bddac56cc7b5273b3fb", size = 1714139, upload-time = "2026-06-07T21:05:49.982Z" }, - { url = "https://files.pythonhosted.org/packages/29/c4/93067c85a0373492ce8e577435203c5947c454af074ac48ed4f3a1b9dd4a/aiohttp-3.14.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:57fc6745a4b7d0f5a9eb4f40a69718be6c0bc1b8368cc9fe89e90118719f4f42", size = 1588321, upload-time = "2026-06-07T21:05:51.431Z" }, - { url = "https://files.pythonhosted.org/packages/c4/39/9ff91aaf02af8b7b8222a987466da539f154c3e01732c22b5f5a20a8ee66/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6fd35beba67c4183b09375c5fff9accb47524191a244a99f95fd4472f5402c2b", size = 1670375, upload-time = "2026-06-07T21:05:53.109Z" }, - { url = "https://files.pythonhosted.org/packages/aa/e4/77452a3676b8d99ac1375f77691d6bf65ea6e9f4b201b82ef77c916dc767/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:672b9d65f42eb877f5c3f234a4547e4e1a226ca8c2eed879bb34670a0ce51192", size = 1690933, upload-time = "2026-06-07T21:05:54.902Z" }, - { url = "https://files.pythonhosted.org/packages/7d/84/b0059a7c7fc05ea23f3bc1596ba91c12f79588b9450564a24cac37536d0a/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:24ba13339fed9251d9b1a1bec8c7ab84c0d1675d79d33501e11f94f8b9a84e05", size = 1740798, upload-time = "2026-06-07T21:05:56.458Z" }, - { url = "https://files.pythonhosted.org/packages/8f/3a/e2a513ecbfc362591caa51a7f7e011b3bfc8938b388ae44cd95560d36999/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:94da27378da0610e341c4d30de29a191672683cc82b8f9556e8f7c7212a020fe", size = 1576412, upload-time = "2026-06-07T21:05:57.953Z" }, - { url = "https://files.pythonhosted.org/packages/a1/10/08f1654f538f93d36dcac66310a06eefce4641cdafca83f9f0a5317be254/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:52cdac9432d8b4a719f35094a818d95adcae0f0b4fe9b9b921909e0c87de9e7d", size = 1750199, upload-time = "2026-06-07T21:05:59.488Z" }, - { url = "https://files.pythonhosted.org/packages/99/e4/d91b70c57d8b8e9611e4a2e52238ca3698d3dc1c2efe25b7a9bf594ac584/aiohttp-3.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:672ac254412a24d0d0cf00a9e6c238877e4be5e5fa2d188832c1244f45f31966", size = 1699356, upload-time = "2026-06-07T21:06:01.131Z" }, - { url = "https://files.pythonhosted.org/packages/3d/f1/15340176f35ff61b95dbe34020bcf43f9e624a2d7bbac934715ff97d2033/aiohttp-3.14.1-cp310-cp310-win32.whl", hash = "sha256:2fe3607e71acc6ebb0ec8e492a247bf7a291226192dc0084236dfc12478916f6", size = 458939, upload-time = "2026-06-07T21:06:02.86Z" }, - { url = "https://files.pythonhosted.org/packages/c3/c2/a2f1ec5b37f903109e43ae2862268cfe4a67a60c1b2cf43169fcdff5995f/aiohttp-3.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:30099eda75a53c32efb0920e9c33c195314d2cc1c680fbfd30894932ac5f27df", size = 482583, upload-time = "2026-06-07T21:06:04.666Z" }, - { url = "https://files.pythonhosted.org/packages/d0/7a/7b56f6732ef79530afaa72aa335d41b67c8d79b946995f0b11ad72985435/aiohttp-3.14.1-cp310-cp310-win_arm64.whl", hash = "sha256:5a837f49d901f9e368651b676912bff1104ed8c1a83b280bcd7b29adccef5c9c", size = 453470, upload-time = "2026-06-07T21:06:06.322Z" }, - { url = "https://files.pythonhosted.org/packages/26/dd/bf526e6f0a1120dd6f2df2e97bacfe4d358f13d17a0ff5847301a1375a51/aiohttp-3.14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa00140699487bd435fde4342d85c94cb256b7cd3a5b9c3396c67f19922afda2", size = 765225, upload-time = "2026-06-07T21:06:07.957Z" }, - { url = "https://files.pythonhosted.org/packages/8f/e1/a2872aa55495a70f61310d411541c6ee23812d9a884e000c716e1bc3edbf/aiohttp-3.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c1af67559445498b502030c35c59db59966f47041ca9de5b4e707f86bd10b5f", size = 518743, upload-time = "2026-06-07T21:06:09.749Z" }, - { url = "https://files.pythonhosted.org/packages/5b/e7/c60c7b209e509cc787de3cea0550a518538cfc08003e1c1e14c1c63fff71/aiohttp-3.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d44ec478e713ee7f29b439f7eb8dc2b9d4079e11ae114d2c2ac3d5daf30516c8", size = 514139, upload-time = "2026-06-07T21:06:11.26Z" }, - { url = "https://files.pythonhosted.org/packages/5b/8d/614ace2f579702c9840ab1e1447fd8509e35b0b904f7196418fa2f57b25d/aiohttp-3.14.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3b1a184a9a8f548a6b73f1e26b96b052193e4b3175ed7342aaf1151a1f00a04", size = 1784088, upload-time = "2026-06-07T21:06:12.887Z" }, - { url = "https://files.pythonhosted.org/packages/49/e0/726e90f99542bf292f81a96a12cc4847deb86f3ccf62c6f4014a201f4d33/aiohttp-3.14.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5f2504bc0322437c9a1ff6d3333ca56c7477b727c995f036b976ae17b98372c8", size = 1737835, upload-time = "2026-06-07T21:06:14.564Z" }, - { url = "https://files.pythonhosted.org/packages/0b/4b/d176d5c4db9d33dacf0543102ea59503bc1d528af4cfd0b719949ca49389/aiohttp-3.14.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73f05ea02013e02512c3bf42714f1208c57168c779cc6fe23516e4543089d0a6", size = 1842801, upload-time = "2026-06-07T21:06:16.228Z" }, - { url = "https://files.pythonhosted.org/packages/dc/d6/5a99b563690ea0cbed912ae94a2ce33993a5709a651a3a4fe761e7dd973a/aiohttp-3.14.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:797457503c2d426bee06eef808d07b31ede30b65e054444e7de64cad0061b7af", size = 1929992, upload-time = "2026-06-07T21:06:17.947Z" }, - { url = "https://files.pythonhosted.org/packages/76/7f/a987b14a3859094b3cea3f4825219c3e5536242564af6e3f9c2f6c994eb2/aiohttp-3.14.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b821a1f7dedf7e37450654e620038ac3b2e81e8fa6ea269337e97101978ec730", size = 1786989, upload-time = "2026-06-07T21:06:19.677Z" }, - { url = "https://files.pythonhosted.org/packages/f1/1a/420e5c85a3e73349372ed22ce0b6af86bfa6ce16a4b20a64a2e94608c781/aiohttp-3.14.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4cd96b5ba05d67ed0cf00b5b405c8cd99586d8e3481e8ee0a831057591af7621", size = 1640129, upload-time = "2026-06-07T21:06:22.558Z" }, - { url = "https://files.pythonhosted.org/packages/a7/80/18a592ed3be0a402cc03670bd72ee1f8563ddbe1d8d5542dbf868f274136/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d459b98a932296c6f0e94f87511a0b1b90a8a02c30a50e60a297619cd5a58ee", size = 1756576, upload-time = "2026-06-07T21:06:24.8Z" }, - { url = "https://files.pythonhosted.org/packages/ec/0b/8b3d5713373858ff71a617daf6e3b0e81ad63e79d09a3cf2f6b6b983939c/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:764457a7be60825fb770a644852ff717bcbb5042f189f2bd16df61a81b3f6573", size = 1754668, upload-time = "2026-06-07T21:06:26.528Z" }, - { url = "https://files.pythonhosted.org/packages/9f/49/fd564575cf225821d7ba5a117cb8bc27213d8a7e1811162afb43ae077039/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f7a16ef45b081454ef844502d87a848876c490c4cb5c650c230f6ec79ed2c1e7", size = 1817019, upload-time = "2026-06-07T21:06:28.297Z" }, - { url = "https://files.pythonhosted.org/packages/ed/1b/e850c9ae6fc91356552ae668bb6c51e93fa29c8aef13398a10b56678557f/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2fbc3ed048b3475b9f0cbcb9978e9d2d3511acd91ead203af26ed9f0056004cf", size = 1631638, upload-time = "2026-06-07T21:06:30.242Z" }, - { url = "https://files.pythonhosted.org/packages/eb/94/3c337ba72451a89806ace6f75bddc92bafc5b8d53d90115a512858024b63/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bedb0cd073cc2dc035e30aeb99444389d3cd2113afe4ef9fcd23d439f5bade85", size = 1835660, upload-time = "2026-06-07T21:06:31.943Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9c/9c18cf367a0498212d9ba7daf990b504a5e8ae064cda4b504e2647c89c03/aiohttp-3.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b6feea921016eb3d4e04d65fc4e9ca402d1a3801f562aef94989f54694917af3", size = 1775698, upload-time = "2026-06-07T21:06:33.72Z" }, - { url = "https://files.pythonhosted.org/packages/b5/63/a251a9d2a6cb45065b2ddc0bde2b3dd10108740a9a42f632c66405a761a2/aiohttp-3.14.1-cp311-cp311-win32.whl", hash = "sha256:313701e488100074ce99850404ee36e741abf6330179fec908a1944ecf570126", size = 458386, upload-time = "2026-06-07T21:06:35.279Z" }, - { url = "https://files.pythonhosted.org/packages/17/ca/69274c51dcd6e8947d77b2806cf47a4a15f2c846e2cbeb1882547d3da283/aiohttp-3.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:03ab4530fdcb3a543a122ba4b65ac9919da9fe9f78a03d328a6e38ff962f7aa5", size = 483406, upload-time = "2026-06-07T21:06:36.824Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8a/c25904f77690c3688ec140f87591ef11a0cfe36bf3d5c0f1f38056fb62b3/aiohttp-3.14.1-cp311-cp311-win_arm64.whl", hash = "sha256:486f7d16ed54c39c2cbd7ca71fd8ba2b8bb7860df65bd7b6ed640bab96a38a8b", size = 452987, upload-time = "2026-06-07T21:06:38.371Z" }, - { url = "https://files.pythonhosted.org/packages/1d/21/151624b51cd92553d95424daf4bf19f19ce9be9002d19253e7e7ce67197b/aiohttp-3.14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d35143e27778b4bb0fb189562d7f275bff79c62ab8e98459717c0ea617ff2480", size = 757402, upload-time = "2026-06-07T21:06:40.311Z" }, - { url = "https://files.pythonhosted.org/packages/c2/82/280619e0bd7bf2454987e19282616e84762255dd9c8468f62382e8c191f1/aiohttp-3.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bcfb80a2cc36fba2534e5e5b5264dc7ae6fcd9bf15256da3e53d2f499e6fa29d", size = 512310, upload-time = "2026-06-07T21:06:42.207Z" }, - { url = "https://files.pythonhosted.org/packages/55/b2/2aac325583aaa1353045f96dffa586d8a34e8322e14a7ba49cffeb103ab4/aiohttp-3.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27fd7c91e51729b4f7e1577865fa6d34c9adccbc39aabe9000285b48af9f0ec2", size = 512448, upload-time = "2026-06-07T21:06:43.813Z" }, - { url = "https://files.pythonhosted.org/packages/8a/72/a60607cb849faa8af8a356c9329ea2eb6f395d49e82cc82ccba1fd8deb8f/aiohttp-3.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c567bf9eaf664280116a8688f63016e6b32db2505908e2bdaca1b6438142f2", size = 1766854, upload-time = "2026-06-07T21:06:45.391Z" }, - { url = "https://files.pythonhosted.org/packages/b5/d3/d9fe1c9ec7557ab4d0d82bebaa728c6418f0b93295ec2f4ab015f7710cc7/aiohttp-3.14.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f5e6ff2bdbb8f4cd3fbe41f99e25bbcd58e3bf9f13d3dd31a11e7917251cc77a", size = 1740884, upload-time = "2026-06-07T21:06:47.413Z" }, - { url = "https://files.pythonhosted.org/packages/c1/dc/f2cecfaf9337ba3e63f181500814ff502aa3d00d9c7ec93a9d23d10a27b2/aiohttp-3.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f73e01dc37122325caf079982621262f96d74823c179038a82fddfc50359264", size = 1810034, upload-time = "2026-06-07T21:06:50.165Z" }, - { url = "https://files.pythonhosted.org/packages/66/d7/2ff65c5e65c0d7476daf7e15c032e0805e36811185b9623e3238ad6c763e/aiohttp-3.14.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb2c0c80d431c0d03f2c7dbf125150fedd4f0de17366a7ca33f7ccb822391842", size = 1904054, upload-time = "2026-06-07T21:06:52.035Z" }, - { url = "https://files.pythonhosted.org/packages/20/9c/d445818389df371f56d141d881153ba23183c4735a03f7356ffb43f7757d/aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e6fc1a85fa7194a1a7d19f44e8609180f4a8eb5fa4c7ed8b4355f080fad235c", size = 1790278, upload-time = "2026-06-07T21:06:54.049Z" }, - { url = "https://files.pythonhosted.org/packages/4d/aa/bf04cb4d865fc6101c2229a294ad744973b72e513fdc5a6b791e6983d72a/aiohttp-3.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:686b6c0d3911ec387b444ddf5dc62fb7f7c0a7d5186a7861626496a5ab4aff95", size = 1591795, upload-time = "2026-06-07T21:06:55.911Z" }, - { url = "https://files.pythonhosted.org/packages/dc/b4/4dac0038960427ba832f6609dfb4ea5437d7fd80c72001b9e48f834f428b/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c6fa4dc7ad6f8109c70bb1499e589f76b0b792baf39f9b017eb92c8a81d0a199", size = 1728397, upload-time = "2026-06-07T21:06:57.777Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f9/7cd4e8ad7aa3b75f17d56bb5498dd604a93d4e6eece822ba0568c413fff0/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:87a5eea1b2a5e21e1ebdbb33ad4165359189327e63fc4e4894693e7f821ac817", size = 1766504, upload-time = "2026-06-07T21:07:00.009Z" }, - { url = "https://files.pythonhosted.org/packages/f9/df/fc01d9fcad0f73fed3f3d361f1f94f975947b50dff82919f6dc2bf4316cc/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c1421eb01d4fd608d88cc8290211d177a58532b55ad94076fb349c5bf467f0a", size = 1777806, upload-time = "2026-06-07T21:07:02.064Z" }, - { url = "https://files.pythonhosted.org/packages/41/09/47e2d090bddcc8fb4ccb4c314aadc32d7c5d9bb55f50f6ad1c92fc15d501/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:34b257ec41345c1e8f2df68fa908a7952f5de932723871eb633ecbbff396c9a4", size = 1580707, upload-time = "2026-06-07T21:07:03.942Z" }, - { url = "https://files.pythonhosted.org/packages/3d/36/f1a4ce904ae0b6930cfe9afc96d0896f7ec1a620c400405d63783bb95a9c/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:de538791a80e5d862addbc183f70f0158ac9b9bb872bb147f1fd2a683691e087", size = 1798121, upload-time = "2026-06-07T21:07:05.987Z" }, - { url = "https://files.pythonhosted.org/packages/70/0a/e0075ce9ca0279ee1d4f0c0b85f54fea02ebc83c3007651a72bece658fec/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f71173be42d3241d428f760122febb748de0623f44308a6f120d0dd9ec572e3", size = 1767580, upload-time = "2026-06-07T21:07:07.873Z" }, - { url = "https://files.pythonhosted.org/packages/3e/61/a0c0a8f327a9c52095cdd8e312391b00d3ed64ab6c72bb5c33d8ec251cf7/aiohttp-3.14.1-cp312-cp312-win32.whl", hash = "sha256:ec8dc383ee57ea3e883477dcca3f11b65d58199f1080acaf4cd6ad9a99698be4", size = 452771, upload-time = "2026-06-07T21:07:09.669Z" }, - { url = "https://files.pythonhosted.org/packages/df/d9/ea367c75f16ac9c6cdc8febb25e8318fa21a2b1bc8d6514d4b2d890bface/aiohttp-3.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2aa92c87868cd13674989f9ee83e5f9f7ea4237589b728048e1f0c8f6caa3271", size = 479873, upload-time = "2026-06-07T21:07:11.538Z" }, - { url = "https://files.pythonhosted.org/packages/03/64/8d96784a7851156db8a4c6c3f6f91042fdf39fb15a4cc38c8b3c14833c45/aiohttp-3.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:2c840c90759922cb5e6dda94596e079a30fb5a5ba548e7e0dc00574703940847", size = 448073, upload-time = "2026-06-07T21:07:13.637Z" }, - { url = "https://files.pythonhosted.org/packages/bc/97/bd137012dd97e1649162b099135a80e1fd59aaa807b2430fc448d1029aff/aiohttp-3.14.1-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:b3a03285a7f9c7b016324574a6d92a1c895da6b978cb8f1deee3ac72bc6da178", size = 506882, upload-time = "2026-06-07T21:07:15.501Z" }, - { url = "https://files.pythonhosted.org/packages/ef/79/e5cc690e9d922a66887ceeaca53a8ffd5a7b0be3816142b7abc433742d89/aiohttp-3.14.1-cp313-cp313-android_21_x86_64.whl", hash = "sha256:2a73f487ab8ef5abbb24b7aa9b73e98eaba9e9e031804ff2416f02eca315ccaf", size = 515270, upload-time = "2026-06-07T21:07:17.53Z" }, - { url = "https://files.pythonhosted.org/packages/fe/22/a73ccbf9dbd6e26dda0b24d5fd5db7da92ee3383a79f47677ffb834c5c5b/aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:915fbb7b41b115192259f8c9ae58f3ddc444d2b5579917270211858e606a4afd", size = 485841, upload-time = "2026-06-07T21:07:19.555Z" }, - { url = "https://files.pythonhosted.org/packages/3b/b9/57ed8eaf596321c2ad747bd480fb1700dbd7177c60dfc9e4c187f629662e/aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:7fb4bdf95b0561a79f259f9d28fbc109728c5ee7f27aff6391f0ca703a329abe", size = 492088, upload-time = "2026-06-07T21:07:21.581Z" }, - { url = "https://files.pythonhosted.org/packages/78/c0/5ebe5270a7c140d7c6f79dcb018640225f14d406c149e4eec04a7d82fe71/aiohttp-3.14.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1b9748363260121d2927704f5d4fc498150669ca3ae93625986ee89c8f80dcd4", size = 501564, upload-time = "2026-06-07T21:07:23.388Z" }, - { url = "https://files.pythonhosted.org/packages/75/7f/8cdaa24fc7983865e0915153b96a9ac5bcdd3548d64c5a27d17cecccad2d/aiohttp-3.14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:86a6dab78b0e43e2897a3bbe15745aa60dc5423ca437b7b0b164c069bf91b876", size = 751998, upload-time = "2026-06-07T21:07:25.046Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f4/c4227aacfacc5cb0cc2d119b65301d177912a6842cd64e120c47af76064f/aiohttp-3.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4dfd6e47d3c44c2279907607f73a4240b88c69eb8b90da7e2441a8045dfd21da", size = 510918, upload-time = "2026-06-07T21:07:27.28Z" }, - { url = "https://files.pythonhosted.org/packages/ab/01/a2d5f96cd4e74424864d30bc0a7e44d0a12dacdcfa91b5b2d1bd3dca6bf3/aiohttp-3.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:317acd9f8602858dc7d59679812c376c7f0b97bcbbf16e0d6237f54141d8a8a6", size = 508657, upload-time = "2026-06-07T21:07:29.252Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ed/3c0fb5c500fdd8e7ebc10d1889c04384fffa1a9163eac1356088ca9da1b1/aiohttp-3.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd869c427324e5cb15195793de951295710db28be7d818247f3097b4ab5d4b96", size = 1757907, upload-time = "2026-06-07T21:07:31.03Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ab/d4c924d9bd5be3050c226612413ce68cb54c70d2c31b661bfc8d9a5b6a70/aiohttp-3.14.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93b032b5ec3255473c143627d21a69ac74ae12f7f33974cb587c564d11b1066f", size = 1737565, upload-time = "2026-06-07T21:07:33.031Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/37326821ff779084020cdc33224d20b19f42f4183a500ff92022a739eda7/aiohttp-3.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f234b4deb12f3ad59127e037bc57c40c21e45b45282df7d3a55a0f409f595296", size = 1799018, upload-time = "2026-06-07T21:07:35.003Z" }, - { url = "https://files.pythonhosted.org/packages/b3/4f/6e947ba73e4ce09070761c05ed3a8ceb7c21f5e46798671d8b2aac0e4626/aiohttp-3.14.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9af6779bfb46abf124068327abcdf9ce95c9ef8287a3e8da76ccf2d0f16c28fa", size = 1894416, upload-time = "2026-06-07T21:07:36.956Z" }, - { url = "https://files.pythonhosted.org/packages/9d/6e/dbf1d0625dc711fb2851f4f3c3055c39ed58bae92082d8c627dbe6013736/aiohttp-3.14.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:faccab372e66bc76d5731525e7f1143c922271725b9d38c9f97edcc66266b451", size = 1783881, upload-time = "2026-06-07T21:07:39.063Z" }, - { url = "https://files.pythonhosted.org/packages/44/c2/5e25098a67268ed369483ae7d1a58bd0a13d03aab860d2a0e4a6eb25b046/aiohttp-3.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f380468b09d2a81633ee863b0ec5648d364bd17bb8ecfb8c2f387f7ac1faf42c", size = 1587572, upload-time = "2026-06-07T21:07:41.058Z" }, - { url = "https://files.pythonhosted.org/packages/2a/bd/cf9cee17e140f942a3de73e658a543aa8fbf35a5fc67a9d2538d52d77f0b/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:97e704dcd26271f5bda3fa07c3ce0fb76d6d3f8659f4baa1a24442cc9ba177ca", size = 1722137, upload-time = "2026-06-07T21:07:43.014Z" }, - { url = "https://files.pythonhosted.org/packages/89/6d/5684f8c59045c96f81a18cefbc1fbbd79d25b88f1c622f2a5c5c08fcb632/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:269b76ac5394092b95bc4a098f4fc6c191c083c3bd12775d1e30e663132f6a09", size = 1755953, upload-time = "2026-06-07T21:07:45.933Z" }, - { url = "https://files.pythonhosted.org/packages/a8/40/35caf3170f8359760740a7d9aa0fff2e344bef98e1d1186f5a0f6dec17e6/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0b3e614340c889d575451696374c9d17affd54cd607ca0babed8f8c37b9397", size = 1766479, upload-time = "2026-06-07T21:07:48.047Z" }, - { url = "https://files.pythonhosted.org/packages/6d/a1/b0c61e7a137f0d81de49a82023a6df73c3c16d6fefb0f8e4a93d21639002/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5663ee9257cfa1add7253a7da3035a02f31b6600ec48261585e1800a81533080", size = 1580077, upload-time = "2026-06-07T21:07:50.069Z" }, - { url = "https://files.pythonhosted.org/packages/0b/41/194ea4623693009fcefebef7aef63c141754f153e9cd0d39d3b9e36c175c/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:603a2c834142172ffddc054067f5ec0ca65d57a0aa98a71bc81952573208e345", size = 1791688, upload-time = "2026-06-07T21:07:52.106Z" }, - { url = "https://files.pythonhosted.org/packages/ba/45/4de841f005cfe1fd63e2a2fe011262c515e2a62aa6994b15947e7d717ac9/aiohttp-3.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cb21957bb8aca671c1765e32f58164cf0c50e6bf41c0bbbd16da20732ecaf588", size = 1761094, upload-time = "2026-06-07T21:07:54.113Z" }, - { url = "https://files.pythonhosted.org/packages/e4/ae/dbce10533d3896d544d5053939ed75b7dc31a1b0973d959b1b5ae21028d6/aiohttp-3.14.1-cp313-cp313-win32.whl", hash = "sha256:e509a55f681e6158c20f70f102f9cf61fb20fbc382272bc6d94b7343f2582780", size = 452662, upload-time = "2026-06-07T21:07:56.06Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d9/0bf1a19362c32f06229da5e7ddfcec91f93474d6307f7a2d3135e9c674dc/aiohttp-3.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:1ac8531b638959718e18c2207fbfe297819875da46a740b29dfa29beba64355a", size = 479748, upload-time = "2026-06-07T21:07:58.319Z" }, - { url = "https://files.pythonhosted.org/packages/22/0a/62e7232dc9484fbec112ceb32efb6a624cc7994ec6e2b019286f17c4e8f2/aiohttp-3.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:250d14af67f6b6a1a4a811049b1afa69d61d617fca6bf33149b3ab1a6dbcf7b8", size = 447723, upload-time = "2026-06-07T21:08:00.154Z" }, - { url = "https://files.pythonhosted.org/packages/c4/a1/5fafa04e1ca91ddb47608699d60649c1c6db3cf41c99e78fc4056f9513db/aiohttp-3.14.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:7c106c26852ca1c2047c6b80384f17100b4e439af276f21ef3d4e2f450ae7e15", size = 508531, upload-time = "2026-06-07T21:08:02.093Z" }, - { url = "https://files.pythonhosted.org/packages/fa/2e/bfa02f699d87ffc86d5959270b28f1cb410add3ccaced8ed2e0b8a5238fc/aiohttp-3.14.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:20205f7f5ade7aaec9f4b500549bbc071b046453aed72f9c06dcab87896a83e8", size = 514718, upload-time = "2026-06-07T21:08:04.476Z" }, - { url = "https://files.pythonhosted.org/packages/85/a5/9594ad6289eebbc97d167c44213d557807f90e59115caad24de21ad2c3b1/aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:62a759436b29e677181a9e76bab8b8f689a29cb9c535f45f7c48c9c830d3f8c3", size = 487918, upload-time = "2026-06-07T21:08:06.377Z" }, - { url = "https://files.pythonhosted.org/packages/b4/61/16a32c36c3c49edec122a3dc811f2057df2f94d3b14aa107c8017d981618/aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:2964cbf553df4d7a57348da44d961d871895fc1ee4e8c322b2a95612c7b17fba", size = 494014, upload-time = "2026-06-07T21:08:08.263Z" }, - { url = "https://files.pythonhosted.org/packages/9b/89/3ebcf96ed99c05bec9c434aaac6963fd3cbab4a786ae739908a144d9ce44/aiohttp-3.14.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:237651caadc3a59badd39319c54642b5299e9cc98a3a194310e55d5bb9f5e397", size = 502398, upload-time = "2026-06-07T21:08:10.244Z" }, - { url = "https://files.pythonhosted.org/packages/fd/3d/b74870a0c2d40c355928cd5b96c7a11fa821b8a40fc41365e64479b151fb/aiohttp-3.14.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:896e12dfdbbab9d8f7e16d2b28c6769a60126fa92095d1ebf9473d02593a2448", size = 758018, upload-time = "2026-06-07T21:08:12.447Z" }, - { url = "https://files.pythonhosted.org/packages/d3/66/f42f5c984d99e49c6cff5f26f590750f2e2f7ef1fcfb99966ab5be1b632e/aiohttp-3.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d03f281ed22579314ba00821ce20115a7c0ac430660b4cc05704a3f818b3e004", size = 512462, upload-time = "2026-06-07T21:08:14.624Z" }, - { url = "https://files.pythonhosted.org/packages/e9/a7/248e1aebe0c7810b0271e021a0f2a5eb6e78a051885b3c9df49f42a5802d/aiohttp-3.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07eabb979d236335fed927e137a928c9adfb7df3b9ec7aa31726f133a62be983", size = 512824, upload-time = "2026-06-07T21:08:16.572Z" }, - { url = "https://files.pythonhosted.org/packages/26/97/2aa0e5ba0727dc3bd5aaebb7ccbc510f7dfb7fb961ec87497cd496635ab1/aiohttp-3.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4fe1f1087cbadb280b5e1bb054a4f00d1423c74d6626c5e48400d871d34ecefe", size = 1749898, upload-time = "2026-06-07T21:08:18.635Z" }, - { url = "https://files.pythonhosted.org/packages/00/8d/e97f6c96c891d457c8479d92a514ba194d0412f981d72c70341ee18488ed/aiohttp-3.14.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:367a9314fdc79dab0fac96e216cb41dd73c85bdca85306ce8999118ba7e0f333", size = 1710114, upload-time = "2026-06-07T21:08:20.892Z" }, - { url = "https://files.pythonhosted.org/packages/6f/e6/aa8d7e863048c8fceb5cd6ce74017311cec3ead07847387e12265fb4444e/aiohttp-3.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a24f677ebe83749039e7bdf862ff0bbb16818ae4193d4ef96505e269375bcce0", size = 1802541, upload-time = "2026-06-07T21:08:23.044Z" }, - { url = "https://files.pythonhosted.org/packages/83/a8/72193137de57fda4ebfae4563182d082c8856e3b6e9871d0b46f028fb369/aiohttp-3.14.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c83afe0ba876be7e943d2e0ba645809ad441575d2840c895c21ee5de93b9377a", size = 1875776, upload-time = "2026-06-07T21:08:25.288Z" }, - { url = "https://files.pythonhosted.org/packages/a0/18/938441025db6769a3464596b2410af3afde0b21eb2f204c6f766f68af4bd/aiohttp-3.14.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:634e385930fb6d2d479cf3aa66515955863b77a5e3c2b5894ca259a25b308602", size = 1760329, upload-time = "2026-06-07T21:08:27.363Z" }, - { url = "https://files.pythonhosted.org/packages/60/29/bf2496b4065e76e09fe48015aaffe5ce161d8f089b06ac6982070f653076/aiohttp-3.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeea07c4397bbc57719c4eed8f9c284874d4f175f9b6d57f7a1546b976d455ca", size = 1587293, upload-time = "2026-06-07T21:08:29.805Z" }, - { url = "https://files.pythonhosted.org/packages/49/a2/2136674d52123b1354bd05dd5753c318db47dc0c927cc70b27bab3755456/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:335c0cc3e3545ce98dcb9cfcb836f40c3411f43fa03dab757597d80c89af8a35", size = 1714756, upload-time = "2026-06-07T21:08:32.094Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b9/e5fd2e6f915503081c0f9b1e8540947037929c70c191da2e4d54b31a21a1/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:ae6be797afdef264e8a84864a85b196ca06045586481b3df8a967322fd2fa844", size = 1721052, upload-time = "2026-06-07T21:08:34.167Z" }, - { url = "https://files.pythonhosted.org/packages/63/5a/2833e324a2263e104e31e2e91bc5bbee81bc499afd32203faee048a883f0/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:8560b4d712474335d08907db7973f71912d3a9a8f1dee992ec06b5d2fe359496", size = 1766888, upload-time = "2026-06-07T21:08:36.95Z" }, - { url = "https://files.pythonhosted.org/packages/57/fa/dea6511870913162f3b2e8c42a7614eb203a4540b8c2da43e0bfb0548f3c/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7edd08e0a5deb1e8564a2fcd8f4561014a3f05252334671bbf55ddd47db0e5", size = 1581679, upload-time = "2026-06-07T21:08:39.292Z" }, - { url = "https://files.pythonhosted.org/packages/14/bd/3cf0d55e71784b33534e9710a67d382d900598b4787fbce6cc7317f8c42a/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:b6ff7fcee63287ae57b5df3e4f5957ce032122802509246dec1a5bcc55904c95", size = 1782021, upload-time = "2026-06-07T21:08:41.407Z" }, - { url = "https://files.pythonhosted.org/packages/c1/af/14bb5843eccbe234f4dfb78ab73e549d99727247e62ae5d62cbd22eaf5b0/aiohttp-3.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6ffbb2f4ec1ceaff7e07d43922954da26b223d188bf30658e561b98e23089444", size = 1742574, upload-time = "2026-06-07T21:08:43.795Z" }, - { url = "https://files.pythonhosted.org/packages/f2/1e/fbeb7af9210a67ac0f9c9bec0f8f4568497924e33137a3d5b48e1cf85f3f/aiohttp-3.14.1-cp314-cp314-win32.whl", hash = "sha256:a9875b46d910cff3ea2f5962f9d266b465459fe634e22556ab9bd6fc1192eea0", size = 457773, upload-time = "2026-06-07T21:08:46.168Z" }, - { url = "https://files.pythonhosted.org/packages/f0/2b/13e8d741a9ec5db7d900c060554cf8352ab85e44e2a4469ebb9d377bda17/aiohttp-3.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:af8b4b81a960eeaf1234971ac3cd0ba5901f3cd42eae42a46b4d089a8b492719", size = 485001, upload-time = "2026-06-07T21:08:48.401Z" }, - { url = "https://files.pythonhosted.org/packages/df/30/491acfa2c4d6c3ff59c49a14fc1b50be3241e25bbb0c84c09e2da4d11395/aiohttp-3.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:cf4491381b1b57425c315a56a439251b1bdac07b2275f19a8c44bc57744532ec", size = 453809, upload-time = "2026-06-07T21:08:50.7Z" }, - { url = "https://files.pythonhosted.org/packages/34/e3/19dbe1a1f4cc6230eb9e314de7fe68053b0992f9302b27d12141a0b5db53/aiohttp-3.14.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:819c054312f1af92947e6a55883d1b66feefab11531a7fc45e0fb9b63880b5c2", size = 793320, upload-time = "2026-06-07T21:08:52.775Z" }, - { url = "https://files.pythonhosted.org/packages/7f/20/1b7182219ba1b108430d6e4dc53d25ae02dcfcf5a045b33af4e8c5167527/aiohttp-3.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10ee9c1753a8f706345b22496c79fbddb5be0599e0823f3738b1534058e25340", size = 529077, upload-time = "2026-06-07T21:08:55Z" }, - { url = "https://files.pythonhosted.org/packages/b9/c8/14ce60ec31a2e5f5274bb17d383a6f7a3aabca31ac04eee05585bbadab16/aiohttp-3.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1601cc37baf5750ccacae618ec2daf020769581695550e3b654a911f859c563d", size = 532476, upload-time = "2026-06-07T21:08:57.176Z" }, - { url = "https://files.pythonhosted.org/packages/7e/02/9ac85e081e53da2e061b02fa7758fe0a12d17b8ce2d1f5e6c7cb76730328/aiohttp-3.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d6e0ac9da31c9c04c84e1c0182ad8d6df35965a85cae29cd71d089621b3ae94", size = 1922347, upload-time = "2026-06-07T21:08:59.563Z" }, - { url = "https://files.pythonhosted.org/packages/c0/3e/d3ba07a0ab38b5389e10bec4362d21e10a4f667cba2d79ba30837b3a5059/aiohttp-3.14.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e8f2d660c350b3d0e259c7a7e3d9b7fc8b41210cbcc3d4a7076ff0a5e5c2fdc", size = 1786465, upload-time = "2026-06-07T21:09:01.909Z" }, - { url = "https://files.pythonhosted.org/packages/0b/cb/e2ee978a00cfb2df829704a69528b18154eba5939f45bc1efa8f33aee4c5/aiohttp-3.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4691802dda97be727f79d86818acaad7eb8e9252626a1d6b519fedbb92d5e251", size = 1909423, upload-time = "2026-06-07T21:09:04.357Z" }, - { url = "https://files.pythonhosted.org/packages/73/5d/1430334858b1022b58ae50399a918f0bd6fe8fa7fa183598d657ff61e040/aiohttp-3.14.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c389c482a7e9b9dc3ee2701ac46c4125297a3818875b9c305ddb603c04828fd1", size = 2001906, upload-time = "2026-06-07T21:09:06.722Z" }, - { url = "https://files.pythonhosted.org/packages/66/4e/560c7472d3d198a23aa5c8b19a5115bf6a9b77b7d3e4bb363da320430ad2/aiohttp-3.14.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc0cacab7ba4e56f0f81c82a98c09bed2f39c940107b03a34b168bdf7597edd3", size = 1877095, upload-time = "2026-06-07T21:09:09.011Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f1/4745806578d447db4a784a8591e2dae3afdfc2bcb96f8f81271b13df6543/aiohttp-3.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:979ed4717f59b8bb12e3963378fa285d93d367e15bcd66c721311826d3c44a6c", size = 1676222, upload-time = "2026-06-07T21:09:11.461Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c9/48255813cca749a229ef0ab476004ec623728ad79a9c0840616f6c076325/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:38e1e7daaea81df51c952e18483f323d878499a1e2bfe564790e0f9701d6f203", size = 1842922, upload-time = "2026-06-07T21:09:14.118Z" }, - { url = "https://files.pythonhosted.org/packages/3d/c0/bbd054e2bee909f529523a5af3891052606af5143c09f5f183ec3b234676/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:4132e72c608fe9fecb8f409113567605915b83e9bdd3ea56538d2f9cd35002f1", size = 1825035, upload-time = "2026-06-07T21:09:16.447Z" }, - { url = "https://files.pythonhosted.org/packages/a8/ae/90395d4376deceb74e09ec26b6adf7d2015a6f8802d6d84446af860fef04/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:eefd9cc9b6d4a2db5f00a26bc3e4f9acf71926a6ec557cd56c9c6f27c290b665", size = 1849512, upload-time = "2026-06-07T21:09:18.742Z" }, - { url = "https://files.pythonhosted.org/packages/93/bd/fb25f3049957553d4ce0ba6ae480aa2f592a6985497fca590837d16c1be0/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b165790117eea512d7f3fb22f1f6dad3d55a7189571993eb015591c1401276d1", size = 1668571, upload-time = "2026-06-07T21:09:21.458Z" }, - { url = "https://files.pythonhosted.org/packages/3f/22/7f73303d64dd567ff3addca90b556690ed1233a47b8f55d242fb90af3681/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:ed09c7eb1c391271c2ed0314a51903e72a3acb653d5ccfc264cdf3ef11f8269d", size = 1881159, upload-time = "2026-06-07T21:09:23.813Z" }, - { url = "https://files.pythonhosted.org/packages/44/be/0474c5a8b5640e1e4aa1923430a91f4151be82e511373fe764189b89aef5/aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:99abd37084b82f5830c635fddd0b4993b9742a66eb746dacf433c8590e8f9e3c", size = 1841409, upload-time = "2026-06-07T21:09:26.207Z" }, - { url = "https://files.pythonhosted.org/packages/7b/3c/bb4a7cba26956cb3da4553cc2056cf67be5b5ff6e6d8fa4fbdff73bfb7ae/aiohttp-3.14.1-cp314-cp314t-win32.whl", hash = "sha256:47ddf841cdecc810749921d25606dee45857d12d2ad5ddb7b5bd7eab12e4b365", size = 494166, upload-time = "2026-06-07T21:09:28.505Z" }, - { url = "https://files.pythonhosted.org/packages/8a/84/ec80c2c1f66a952555a9f86df6b33af65108a6febfa0471b69013a12f807/aiohttp-3.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5e78b522b7a6e27e0b25d19b247b75039ac4c94f99823e3c9e53ae1603a9f7e9", size = 530255, upload-time = "2026-06-07T21:09:30.843Z" }, - { url = "https://files.pythonhosted.org/packages/2a/71/6e22be134a4061ada85a92951b842f2657f17d926b727f3f94c56ae963d6/aiohttp-3.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:90d53f1609c29ccc2193945ef732428382a28f78d0456ae4d3daf0d48b74f0f6", size = 469640, upload-time = "2026-06-07T21:09:33.028Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, + { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, + { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, + { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, + { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, + { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, + { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, + { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, + { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, + { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, + { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, + { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, + { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, + { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, + { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, + { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, + { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, + { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, + { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, + { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, + { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, + { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, + { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, + { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, + { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, + { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, + { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, + { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, + { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, + { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, + { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, + { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, + { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, + { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, + { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, + { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, + { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, + { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, + { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, + { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, + { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, + { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, + { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, + { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, + { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, + { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, + { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, + { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, + { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, + { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, + { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, + { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, + { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, + { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, + { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, + { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, + { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, + { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, + { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, + { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, + { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, + { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, + { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, + { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, + { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, + { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, + { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, + { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, + { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, + { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, + { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, + { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, + { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, + { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, + { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, + { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, + { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, + { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, + { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, + { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, + { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, + { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, + { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, + { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, + { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, + { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, + { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, ] [[package]] @@ -218,11 +218,11 @@ wheels = [ [[package]] name = "annotated-types" -version = "0.7.0" +version = "0.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, ] [[package]] @@ -257,11 +257,11 @@ wheels = [ [[package]] name = "argcomplete" -version = "3.6.3" +version = "3.7.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/38/61/0b9ae6399dd4a58d8c1b1dc5a27d6f2808023d0b5dd3104bb99f45a33ff6/argcomplete-3.6.3.tar.gz", hash = "sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c", size = 73754, upload-time = "2025-10-20T03:33:34.741Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/6f/5a73f04007ca950701765949209f068da628bd11f9c2da287278ce91e0ee/argcomplete-3.7.2.tar.gz", hash = "sha256:aad8b69a0b9969edb62db0d1752354c0d50717b10e0cbb00e2a958381b9fc6b9", size = 74473, upload-time = "2026-08-06T04:53:21.662Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl", hash = "sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce", size = 43846, upload-time = "2025-10-20T03:33:33.021Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/551ee6af426af84ca33e02622be722925c196608e9127d731ef17c47f06e/argcomplete-3.7.2-py3-none-any.whl", hash = "sha256:6029205678bdd9c1c728a155f5f9ecf5812393f969eef58807641a2bc2aa5b19", size = 43294, upload-time = "2026-08-06T04:53:20.246Z" }, ] [[package]] @@ -360,14 +360,14 @@ wheels = [ [[package]] name = "azure-functions" -version = "1.24.0" +version = "1.25.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1d/be/5535830e0658e9668093941b3c33b0ea03eceadbf6bd6b7870aa37ef071a/azure_functions-1.24.0.tar.gz", hash = "sha256:18ea1607c7a7268b7a1e1bd0cc28c5cc57a9db6baaacddb39ba0e9f865728187", size = 134495, upload-time = "2025-10-06T19:08:08.612Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/eb/745418bd7ae135068a88dcd2e0b3cefd526068a7bbe55cc29d5fb5919080/azure_functions-1.25.0.tar.gz", hash = "sha256:3c737657110b6cfd14e6871515ab66c377b9ceecaca8dcbf5b391d2433424756", size = 143938, upload-time = "2026-08-05T19:12:50.176Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/76/e6c5809ee0295e882b6c9ad595896748e33989d353b67316a854f65fb754/azure_functions-1.24.0-py3-none-any.whl", hash = "sha256:32b12c2a219824525849dd92036488edeb70d306d164efd9e941f10f9ac0a91c", size = 108341, upload-time = "2025-10-06T19:08:07.128Z" }, + { url = "https://files.pythonhosted.org/packages/a8/21/9374de0e429e7a45090c097111fbbcdea019e726b252cbb35428a816ed1c/azure_functions-1.25.0-py3-none-any.whl", hash = "sha256:0d01e52c0871a01a65911bc163a0dfd7f09725ba43cea17a09909cc5d298c1d2", size = 113831, upload-time = "2026-08-05T19:12:51.567Z" }, ] [[package]] @@ -445,16 +445,16 @@ wheels = [ [[package]] name = "azure-keyvault-secrets" -version = "4.11.0" +version = "4.11.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "azure-core" }, { name = "isodate" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f1/b8/03c7b4edd1e3355ad5fffb70e68af70cd09542963f45cf3a2aa9fb3930b5/azure_keyvault_secrets-4.11.0.tar.gz", hash = "sha256:ac14727b9159cca353173ec5a454d8d7b192a6f2f5e7eb540f9fbcf914fa0ca0", size = 112291, upload-time = "2026-04-17T00:52:12.422Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/ee/c875370169d708fdfa2302078d8506cc8df40645f46c2b8cc7466d7cb1f6/azure_keyvault_secrets-4.11.1.tar.gz", hash = "sha256:23b11cbecf4525081121e68a82d7f3a4211556f6dbb4ddbb390a94db8b72c938", size = 115813, upload-time = "2026-08-12T16:40:52.468Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/76/41c513917c0e8dc68de0c33578c6a0668b4a09eb4dc3e2782d382dc2947f/azure_keyvault_secrets-4.11.0-py3-none-any.whl", hash = "sha256:d8543b710423569bd00ada2a2533fe83d52d8e1fe026e1c47f41a3bc0fc73ef5", size = 103148, upload-time = "2026-04-17T00:52:13.796Z" }, + { url = "https://files.pythonhosted.org/packages/57/79/32aa77853e694711233a2f36af9ad0a7eaae2cc5e57804055192a3a0eac2/azure_keyvault_secrets-4.11.1-py3-none-any.whl", hash = "sha256:a5745d17d56061130cc56aa53c02c783e5d597031faf551b1873948461e8e700", size = 103733, upload-time = "2026-08-12T16:40:53.777Z" }, ] [[package]] @@ -613,6 +613,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/ba/554194c2287d7fd53257de27898f1d391090e6f2fe54f888c109c90a6592/azure_mgmt_compute-34.1.0-py3-none-any.whl", hash = "sha256:5de9c4ba12a79c69e2db3d880f93869a0a80e5c99d8232dbebf6c19b1ada3638", size = 2021492, upload-time = "2025-03-24T03:32:43.181Z" }, ] +[[package]] +name = "azure-mgmt-consumption" +version = "10.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "azure-common" }, + { name = "azure-mgmt-core" }, + { name = "msrest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/a9/f8c817e67a9005752b0c11cc289fd2334c4f1c9287b0cc8b4abd220e4101/azure-mgmt-consumption-10.0.0.zip", hash = "sha256:06a086436c1737f77ab86894d51f5973b6e0fa5edf56558e4c296589ebab9130", size = 157978, upload-time = "2022-06-21T02:17:29.927Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/99/75a22c84941348dc9d0cbb95fe63c2adb8545543236c207817a439027648/azure_mgmt_consumption-10.0.0-py3-none-any.whl", hash = "sha256:507059238cba2dcafc19866c24c53c5e145cafd721a39ab8c605590a3f169e81", size = 138711, upload-time = "2022-06-21T02:17:27.597Z" }, +] + [[package]] name = "azure-mgmt-containerinstance" version = "7.0.0" @@ -1016,6 +1030,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/fc/ad0ed59dd1d24f2cd3e831f2ecb427be563e10de38b69b2ff555de81ef63/azure_mgmt_policyinsights-1.0.1-py3-none-any.whl", hash = "sha256:de91f6bdcfb0878edad9f4a3832d9b168ec4a01cd4219b51b84f158b41ce9928", size = 100862, upload-time = "2026-05-19T08:21:21.949Z" }, ] +[[package]] +name = "azure-mgmt-privatedns" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "azure-mgmt-core" }, + { name = "isodate" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/1f/5b79c8677553ca55ab2f09386b9a080adf0b69ea396d928a2a88fcaf069c/azure_mgmt_privatedns-2.0.0.tar.gz", hash = "sha256:e064d222115382493c76be1096e4d8300eb31a9ef45c198aa1919933cb90a124", size = 80136, upload-time = "2026-07-29T09:25:22.926Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/fe/ee58e51a6c28b1dd2eca5fc2e1c0fd0d12edafc4bd94d2683b59d724daab/azure_mgmt_privatedns-2.0.0-py3-none-any.whl", hash = "sha256:c04bfaab7bbfaf2c432dcf4ced18ea0373032f2c87f66d78c17f83baf5930644", size = 82952, upload-time = "2026-07-29T09:25:23.915Z" }, +] + [[package]] name = "azure-mgmt-rdbms" version = "10.2.0b17" @@ -1448,30 +1476,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.43.37" +version = "1.43.78" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fa/8b/281ca08c796322a36a639b76c714dc4c4323cab4563a492e6a923aa5f15d/boto3-1.43.37.tar.gz", hash = "sha256:cf7e75963229b337d1b0e37c46de6f3c2c2290d186157729c8e7afb12909bfc0", size = 112674, upload-time = "2026-06-29T20:29:39.273Z" } +sdist = { url = "https://files.pythonhosted.org/packages/be/55/e026c943f7f1ed6d2f5e6035713f21233bbe9ee975008662dc64ca0d4ced/boto3-1.43.78.tar.gz", hash = "sha256:2fa59116e298171ef59e7600a8be6c01177faef8af4b9a4314b7a57a04009ada", size = 112679, upload-time = "2026-08-21T19:37:36.84Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/48/c740abb7ba90d89ef63cf766c8e07d72e6422b3cf68aa4dccf0a83efed93/boto3-1.43.37-py3-none-any.whl", hash = "sha256:f409f931e836f2f24e168e8f93901010cb8055c7f2ddcfcfbd72b25f8c4e306c", size = 140032, upload-time = "2026-06-29T20:29:36.409Z" }, + { url = "https://files.pythonhosted.org/packages/e3/55/288b1f0d987e15db0417f5ea43da564bfa042063f508c259eec893134628/boto3-1.43.78-py3-none-any.whl", hash = "sha256:893f06a171469618e17de78dc927aca6e74fcf45a70d2c5918e9ac9919e96cc9", size = 140028, upload-time = "2026-08-21T19:37:35.358Z" }, ] [[package]] name = "botocore" -version = "1.43.37" +version = "1.43.78" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c4/a8/3409b5df7e6a562be82e409ba5a976e7ac3df8d5567552c23d44b367a40b/botocore-1.43.37.tar.gz", hash = "sha256:46a7982815579cfe8c7851036b1f51237e35e7937456341df55bc5c36a316145", size = 15646119, upload-time = "2026-06-29T20:29:25.452Z" } +sdist = { url = "https://files.pythonhosted.org/packages/67/71/490aaa384855bf3b69405ded52ae77a0e5f4eeb2165044fa65466c4d3a73/botocore-1.43.78.tar.gz", hash = "sha256:e8238d22c1e1342025d75d2e33d154a375e7caad0fc67f77d77faa2d82668b94", size = 15982895, upload-time = "2026-08-21T19:37:32.402Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/64/49313b38d675f4004fb736d2a4293b72504eac5380fc21b6e4a8660824ad/botocore-1.43.37-py3-none-any.whl", hash = "sha256:8b7e8408aa7eca7dca9ae9824fb7677daf64d40ed675366ed7b9248470d08757", size = 15333748, upload-time = "2026-06-29T20:29:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5b/b7c5c22767c0e8eb4bb2bd0a972d77bd0be3dd9908e15d4487094a31fa4b/botocore-1.43.78-py3-none-any.whl", hash = "sha256:ddd020493235e264b3bd12606f239a3d3b2dd7cfb1d25a0691061183c290c228", size = 15677214, upload-time = "2026-08-21T19:37:28.894Z" }, ] [[package]] @@ -1488,7 +1516,7 @@ wheels = [ [[package]] name = "c7n" -version = "0.9.52a5+a83dda5c9" +version = "0.9.53a1+e4c099e03" source = { editable = "." } dependencies = [ { name = "argcomplete" }, @@ -1577,7 +1605,7 @@ lint = [ [[package]] name = "c7n-awscc" -version = "0.1.37a5+a83dda5c9" +version = "0.1.38a1+e4c099e03" source = { editable = "tools/c7n_awscc" } dependencies = [ { name = "boto3" }, @@ -1602,7 +1630,7 @@ dev = [{ name = "pytest" }] [[package]] name = "c7n-azure" -version = "0.7.51a5+a83dda5c9" +version = "0.7.52a1+e4c099e03" source = { editable = "tools/c7n_azure" } dependencies = [ { name = "adal" }, @@ -1628,6 +1656,7 @@ dependencies = [ { name = "azure-mgmt-cdn" }, { name = "azure-mgmt-cognitiveservices" }, { name = "azure-mgmt-compute" }, + { name = "azure-mgmt-consumption" }, { name = "azure-mgmt-containerinstance" }, { name = "azure-mgmt-containerregistry" }, { name = "azure-mgmt-containerservice" }, @@ -1654,6 +1683,7 @@ dependencies = [ { name = "azure-mgmt-msi" }, { name = "azure-mgmt-network" }, { name = "azure-mgmt-policyinsights" }, + { name = "azure-mgmt-privatedns" }, { name = "azure-mgmt-rdbms" }, { name = "azure-mgmt-recoveryservices" }, { name = "azure-mgmt-recoveryservicesbackup" }, @@ -1718,6 +1748,7 @@ requires-dist = [ { name = "azure-mgmt-cdn", specifier = ">=12.0.0,<13.0.0" }, { name = "azure-mgmt-cognitiveservices", specifier = ">=13.7.0,<14.0.0" }, { name = "azure-mgmt-compute", specifier = ">=34.1.0,<35.0.0" }, + { name = "azure-mgmt-consumption", specifier = ">=10.0.0,<11.0.0" }, { name = "azure-mgmt-containerinstance", specifier = ">=7.0.0,<8.0.0" }, { name = "azure-mgmt-containerregistry", specifier = ">=14.0.0,<15.0.0" }, { name = "azure-mgmt-containerservice", specifier = ">=15.0.0,<16.0.0" }, @@ -1744,6 +1775,7 @@ requires-dist = [ { name = "azure-mgmt-msi", specifier = ">=1.0.0,<2.0.0" }, { name = "azure-mgmt-network", specifier = ">=28.0.0,<29.0.0" }, { name = "azure-mgmt-policyinsights", specifier = ">=1.0.0,<2.0.0" }, + { name = "azure-mgmt-privatedns", specifier = ">=2.0.0,<3.0.0" }, { name = "azure-mgmt-rdbms", specifier = "==10.2.0b17" }, { name = "azure-mgmt-recoveryservices", specifier = ">=3.1.0,<4.0.0" }, { name = "azure-mgmt-recoveryservicesbackup", specifier = ">=7.0.0,<8.0.0" }, @@ -1785,7 +1817,7 @@ dev = [ [[package]] name = "c7n-gcp" -version = "0.4.51a5+a83dda5c9" +version = "0.4.52a1+e4c099e03" source = { editable = "tools/c7n_gcp" } dependencies = [ { name = "c7n" }, @@ -1826,7 +1858,7 @@ dev = [ [[package]] name = "c7n-kube" -version = "0.2.51a5+a83dda5c9" +version = "0.2.52a1+e4c099e03" source = { editable = "tools/c7n_kube" } dependencies = [ { name = "c7n" }, @@ -1855,7 +1887,7 @@ dev = [ [[package]] name = "c7n-left" -version = "0.3.38a5+a83dda5c9" +version = "0.3.39a1+e4c099e03" source = { editable = "tools/c7n_left" } dependencies = [ { name = "c7n" }, @@ -1888,7 +1920,7 @@ dev = [ [[package]] name = "c7n-mailer" -version = "0.6.51a5+a83dda5c9" +version = "0.6.52a1+e4c099e03" source = { editable = "tools/c7n_mailer" } dependencies = [ { name = "boto3" }, @@ -1954,7 +1986,7 @@ dev = [ [[package]] name = "c7n-oci" -version = "0.1.26a5+a83dda5c9" +version = "0.1.27a1+e4c099e03" source = { editable = "tools/c7n_oci" } dependencies = [ { name = "c7n" }, @@ -1979,7 +2011,7 @@ dev = [{ name = "pytest" }] [[package]] name = "c7n-openstack" -version = "0.1.42a5+a83dda5c9" +version = "0.1.43a1+e4c099e03" source = { editable = "tools/c7n_openstack" } dependencies = [ { name = "c7n" }, @@ -2006,7 +2038,7 @@ dev = [ [[package]] name = "c7n-org" -version = "0.6.51a5+a83dda5c9" +version = "0.6.52a1+e4c099e03" source = { editable = "tools/c7n_org" } dependencies = [ { name = "c7n" }, @@ -2029,14 +2061,14 @@ dev = [{ name = "pytest" }] [[package]] name = "c7n-policystream" -version = "0.4.51a5+a83dda5c9" +version = "0.4.52a1+e4c099e03" source = { editable = "tools/c7n_policystream" } dependencies = [ { name = "boto3" }, { name = "c7n" }, { name = "click" }, { name = "pygit2", version = "1.18.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "pygit2", version = "1.19.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pygit2", version = "1.20.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pyyaml" }, { name = "requests" }, ] @@ -2065,7 +2097,7 @@ dev = [ [[package]] name = "c7n-sphinxext" -version = "1.1.51a5+a83dda5c9" +version = "1.1.52a1+e4c099e03" source = { editable = "tools/c7n_sphinxext" } dependencies = [ { name = "c7n" }, @@ -2092,7 +2124,7 @@ requires-dist = [ [[package]] name = "c7n-tencentcloud" -version = "0.1.34a5+a83dda5c9" +version = "0.1.35a1+e4c099e03" source = { editable = "tools/c7n_tencentcloud" } dependencies = [ { name = "c7n" }, @@ -2125,198 +2157,284 @@ dev = [ [[package]] name = "certifi" -version = "2026.6.17" +version = "2026.7.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, ] [[package]] name = "cffi" -version = "2.0.0" +version = "2.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" }, - { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" }, - { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" }, - { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" }, - { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" }, - { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" }, - { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" }, - { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" }, - { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" }, - { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" }, - { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" }, - { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" }, - { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, - { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, - { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, - { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, - { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, - { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, - { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, - { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, - { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, - { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, - { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, - { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, - { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, - { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, - { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, - { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, - { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, - { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, - { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, - { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, - { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, - { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, - { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, - { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, - { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, - { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, - { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, - { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, - { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, - { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, - { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, - { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, - { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, - { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, - { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, - { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, - { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, - { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, - { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, - { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, - { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, - { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, - { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, - { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, - { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, - { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, - { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, - { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, - { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/d2/2cde336b375f55c76ca670f0be3978cc048e31e24f3b4d7ce8473150a388/cffi-2.1.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:baed1e86cc735622097354b9d1281406caf42ff42a886d29faa8e8d1630333be", size = 183779, upload-time = "2026-08-03T21:19:15.602Z" }, + { url = "https://files.pythonhosted.org/packages/94/1a/4b2f7c92293ba05cbd4a9a1b28faaf0326272d9488e6354657571c48a7aa/cffi-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca82be1a1d406ecfe1d25dc16cb33488e5a16bf4438c9fb590484ea29d92478b", size = 184178, upload-time = "2026-08-03T21:19:16.67Z" }, + { url = "https://files.pythonhosted.org/packages/17/0b/ba385d8ccedf926c3cd06e8e2f327027da5afe5f0eb30f1f7bc43ac55125/cffi-2.1.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:42e2f76b9455f5a9a844f770bf3e200ed3da0e15f5df3db9c31fe80b04b3d004", size = 211037, upload-time = "2026-08-03T21:19:17.705Z" }, + { url = "https://files.pythonhosted.org/packages/a3/b9/0f2e58b2cefa33255bff36935d42b13180fe559bba82596540eb404bde7d/cffi-2.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5a59cc1c4442bc3d5c703bf720b51138d0bfc173618807c9ee2490a7541dd3d9", size = 218652, upload-time = "2026-08-03T21:19:18.735Z" }, + { url = "https://files.pythonhosted.org/packages/37/15/180e0dab27b9312c7479003d14c9e547634b7dcb934e2cc4650e1b131a7a/cffi-2.1.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:9f8d177621de5cb38ee3e731eda45d421db093ec0739f46a5594babda7987a98", size = 205422, upload-time = "2026-08-03T21:19:19.96Z" }, + { url = "https://files.pythonhosted.org/packages/18/d4/03026f0c850cbbaa9030750490225b4a7f4d524ea4df72c3cc740a90f4ef/cffi-2.1.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:75f80557d1389eddbd0de2681f6a390a0c5338c31ddaa821381c203fc3fd50d9", size = 205444, upload-time = "2026-08-03T21:19:21.246Z" }, + { url = "https://files.pythonhosted.org/packages/75/77/60bebf6f818bec84210ac5b6979ce4eeadce6fbbaabc9c7ab23e506d1ce5/cffi-2.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:194cffa889098ced9976c3fc6340305e43f6303657d298da55366907c05c22d6", size = 218742, upload-time = "2026-08-03T21:19:22.523Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ae/679bf47e73fd77b352171727f07de559a003f14de5d02b904a6ec1fa73ca/cffi-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5bb4e7ea95dcd6a014a6fef62e62467d67d8e582326443f3d68e71d6320a9fcf", size = 221054, upload-time = "2026-08-03T21:19:23.694Z" }, + { url = "https://files.pythonhosted.org/packages/09/b8/eefc0e06913b70aa153bf74c946094a18f58fd4aff11b7f372bfdfdca050/cffi-2.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3d22a20b1fb1632cc72c22f95f7b0d2961c3e1c235f245ba4c606c4771035659", size = 213489, upload-time = "2026-08-03T21:19:24.922Z" }, + { url = "https://files.pythonhosted.org/packages/6f/13/4e56852824a03cdf68523a35686f1c28eacd4bd30a7b0a78e682e6e6e1d3/cffi-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1dea0e4d7d4f11f619fe8c1d76caf49e24405b4b5743c0e3be16a500ecd930c9", size = 220241, upload-time = "2026-08-03T21:19:26.214Z" }, + { url = "https://files.pythonhosted.org/packages/99/7f/040f9e163e4acac3ee3d85b02d00b2576e7ca980d8785f0a3a5f1a9bf7f5/cffi-2.1.1-cp310-cp310-win32.whl", hash = "sha256:7ce713ace7c0e4520535b42b77eaa742c16dab813978064913e5a3cf82973b41", size = 174578, upload-time = "2026-08-03T21:19:27.338Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0b/644a2ec1a4eaba49c2939410bb1eb1d25b09d6d0582f5d2f95c537043725/cffi-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:a48d62ab9d6f4f98c983223a547af44be6ca3691074c31cecced6facd3ba2dc1", size = 185082, upload-time = "2026-08-03T21:19:28.409Z" }, + { url = "https://files.pythonhosted.org/packages/70/d2/16d99a0c4948febc0ebd133a13b2f688ff7f8cb04da971e1128872ce0c03/cffi-2.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12", size = 183838, upload-time = "2026-08-03T21:19:29.637Z" }, + { url = "https://files.pythonhosted.org/packages/cd/95/31b535a9f0220ae9f357de4a08d57ce89cb417653c2fd9f075f50822a388/cffi-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1", size = 184168, upload-time = "2026-08-03T21:19:30.764Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5a/4707a0dc1f203f5dde5a907b0d4e3c25d71120241048bd5bc6f1bb9d4e71/cffi-2.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0", size = 211805, upload-time = "2026-08-03T21:19:31.867Z" }, + { url = "https://files.pythonhosted.org/packages/ad/66/c19feabb28485b6e0bbaaafa90837a1ef5d302e90f2178bd33f17a49879b/cffi-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813", size = 218716, upload-time = "2026-08-03T21:19:32.896Z" }, + { url = "https://files.pythonhosted.org/packages/a7/92/500760486c8baab49a7a8a58ba7fc3355ec3974b454b8a09e528efde9e1d/cffi-2.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990", size = 205569, upload-time = "2026-08-03T21:19:34.142Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a7/a67c733254d6e7373f7822f8082d8d6beade791e0cf12a7611f376fa61c7/cffi-2.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af", size = 204907, upload-time = "2026-08-03T21:19:35.174Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a4/4399daaf8f7dfee9d7c3327fdb0426ee041cc63edc358b93911ceb2bfc7a/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632", size = 217807, upload-time = "2026-08-03T21:19:36.286Z" }, + { url = "https://files.pythonhosted.org/packages/28/f7/dabe6da2466ecbd82dc62e7342dc6b1065dad990c06f00f0ede9ebf2a0ed/cffi-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd", size = 221252, upload-time = "2026-08-03T21:19:37.416Z" }, + { url = "https://files.pythonhosted.org/packages/ce/87/616202d8e51342c07d2534c510111c4cc37201775ce8f60802c9335d1edd/cffi-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a", size = 214214, upload-time = "2026-08-03T21:19:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c6/ab025d75d2c26c19b087c0124e75ee31cb65032f4fe345d356d8c507ab97/cffi-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa", size = 219408, upload-time = "2026-08-03T21:19:39.809Z" }, + { url = "https://files.pythonhosted.org/packages/db/e2/7e8109f65445bdc673a7b54f02c677de462db75674220fd1335efc8eb598/cffi-2.1.1-cp311-cp311-win32.whl", hash = "sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3", size = 174470, upload-time = "2026-08-03T21:19:41.246Z" }, + { url = "https://files.pythonhosted.org/packages/73/c0/77ba02423c2f7d7091143c45cd49e0e6575c4c1967394bb542bd923a9b74/cffi-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0", size = 185096, upload-time = "2026-08-03T21:19:42.615Z" }, + { url = "https://files.pythonhosted.org/packages/7c/47/9f1f85f9672ceda4984dc6c4f8824e8558992a2972c3d3c81fb8eb28d4ba/cffi-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455", size = 179941, upload-time = "2026-08-03T21:19:43.747Z" }, + { url = "https://files.pythonhosted.org/packages/10/69/43965eccfdead3b9220015fd1320e117be8c6ed01a62ffab76eeb752f5d5/cffi-2.1.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0", size = 184821, upload-time = "2026-08-03T21:19:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/54/7d/16e5a096677b5e313ca80cd5e5170efa3ea44624a82bb111925522da64b1/cffi-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf", size = 184719, upload-time = "2026-08-03T21:19:46.129Z" }, + { url = "https://files.pythonhosted.org/packages/56/e6/8941622732edec876dd17d0453dce07317ae96db34f2ec1436c9d3785986/cffi-2.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a", size = 214799, upload-time = "2026-08-03T21:19:47.218Z" }, + { url = "https://files.pythonhosted.org/packages/44/de/f98430906df1545ffde0d543dd124a7a439bc2cd32b36b9c53f805df7333/cffi-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890", size = 222389, upload-time = "2026-08-03T21:19:48.331Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5b/717f1526b9957b34456313c31645c5b82b8fb5c3fe9e4752999be7128bfc/cffi-2.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50", size = 210249, upload-time = "2026-08-03T21:19:49.543Z" }, + { url = "https://files.pythonhosted.org/packages/64/b3/f8aa4f3e34986c7e4ec45072d1b1b9dd295b6b18007b45518d79726dd725/cffi-2.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e", size = 208775, upload-time = "2026-08-03T21:19:50.918Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/dceb9dd5b231e1da801793f8acc9f3c52a7e1afe40bb1aae37e02b0faad5/cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf", size = 221822, upload-time = "2026-08-03T21:19:52.054Z" }, + { url = "https://files.pythonhosted.org/packages/a0/d2/6cd24ae3be000a634109c247d1475d62e5616d0dc78c82770942ec384248/cffi-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517", size = 225232, upload-time = "2026-08-03T21:19:53.109Z" }, + { url = "https://files.pythonhosted.org/packages/cb/52/3fa190537004dd7f0ab860a6dc7c0175b8667f68d1e618a46f5498d30250/cffi-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735", size = 223597, upload-time = "2026-08-03T21:19:54.515Z" }, + { url = "https://files.pythonhosted.org/packages/80/fb/0bb75b7039588c074b37ae99f40d9bfddf990ecb2fbc346ebccd2e56b9be/cffi-2.1.1-cp312-cp312-win32.whl", hash = "sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e", size = 175292, upload-time = "2026-08-03T21:19:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/d9/79/615cc094e2fb508cade7de88d3b4f6c4ec2bab695c97bce9153dc65aadf5/cffi-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a", size = 185919, upload-time = "2026-08-03T21:19:56.89Z" }, + { url = "https://files.pythonhosted.org/packages/70/c6/d0ea84713fe46b243a436a18fcd47d639732747e21635c8a27191b06dc30/cffi-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80", size = 180093, upload-time = "2026-08-03T21:19:58.155Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" }, + { url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" }, + { url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" }, + { url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" }, + { url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" }, + { url = "https://files.pythonhosted.org/packages/d3/7b/d6bbf82b8b96e7391438898c42f5bd96dd02030fd5b64937d248220003e2/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c", size = 194064, upload-time = "2026-08-03T21:20:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/94/e6/bcc91b283be94735e268487a054004f0aa19947b6348fa367db53230abc8/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb", size = 196720, upload-time = "2026-08-03T21:20:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/d9/99/c4b0c17cacdc9c3b8f280026286a9826d6a208c0f047591a3c3ce99b91fd/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54", size = 184964, upload-time = "2026-08-03T21:20:19.708Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a9/9db617d05d7367c1ad0ab00b3aa6e6f9281edd689b4ee9ea0e5a84e89c97/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72", size = 184962, upload-time = "2026-08-03T21:20:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/67/b8/b42132ca113dc567d37684437b46ca1dafc885902b02a110a02d5b511857/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1", size = 222328, upload-time = "2026-08-03T21:20:22.118Z" }, + { url = "https://files.pythonhosted.org/packages/80/10/c5c0cbf0a657aecf59ef511409734230bf556f05a0d6c9eed7aa5c0a0166/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062", size = 209985, upload-time = "2026-08-03T21:20:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6c/bfa0b87b03b9238148beca990292843c9396ba069b54496596594173de7b/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03", size = 208530, upload-time = "2026-08-03T21:20:24.628Z" }, + { url = "https://files.pythonhosted.org/packages/e9/02/4e7d553a7ac4b4238b38b3c1b80d486e9d4436f8d2acbf87a0997fe3f402/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96", size = 221525, upload-time = "2026-08-03T21:20:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/82/1d/a4aaf9babd75acb4d5f223bff71533bee748dd770a382619a798960ee9ba/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527", size = 225053, upload-time = "2026-08-03T21:20:26.985Z" }, + { url = "https://files.pythonhosted.org/packages/81/10/5dc0e7bdd18e22107054288283380fc97a06ae3f1656a106908d666a3c88/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13", size = 223213, upload-time = "2026-08-03T21:20:28.277Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/d0061c364cde06ee43168a0d076ac1da512cbc380d44767b844ba34fe2b6/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c", size = 177682, upload-time = "2026-08-03T21:20:44.288Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1c3e01e3ba14c39f6d10bfbac52753b7e22259e38088e5cfe1d704918690/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48", size = 187949, upload-time = "2026-08-03T21:20:45.623Z" }, + { url = "https://files.pythonhosted.org/packages/87/5b/da4e39efe18eeb89cf580ea9cfc66b6a7c3eadb808fc0cc1d3a295cb5a5d/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836", size = 182947, upload-time = "2026-08-03T21:20:46.955Z" }, + { url = "https://files.pythonhosted.org/packages/23/59/40338bf421c5accea1d45158170c87006ef1cd371b05c077e76476949728/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3", size = 188504, upload-time = "2026-08-03T21:20:29.495Z" }, + { url = "https://files.pythonhosted.org/packages/7d/47/5ecf1023850036e674c77ec4de86182d309ae344e39e7cba984b7df5d647/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2", size = 188259, upload-time = "2026-08-03T21:20:31.291Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9c/92934c3bea9f785b23eba304538c0b4d37a2a96d2431eb3a1bc87a11aa19/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94", size = 223864, upload-time = "2026-08-03T21:20:32.571Z" }, + { url = "https://files.pythonhosted.org/packages/4d/45/ba4c93527bc38616a8bd36488acb69a2212d60486794f0c1f318949bbb76/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc", size = 211538, upload-time = "2026-08-03T21:20:33.808Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/b6ef565e452acb932fb0cb5443f44a78efbd1233e566f02b5a83855e9115/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29", size = 210688, upload-time = "2026-08-03T21:20:34.974Z" }, + { url = "https://files.pythonhosted.org/packages/9a/95/eff5f0cee78d2eabc7eebffec40d3fc1876b5f3c95582e018bb4b99601f2/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676", size = 223803, upload-time = "2026-08-03T21:20:36.564Z" }, + { url = "https://files.pythonhosted.org/packages/fa/01/579d39fb8bef00a335a23d83757b44feb24cd6345a2c451b64cb67b9c362/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e", size = 226763, upload-time = "2026-08-03T21:20:37.816Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b0/0b44f47c60b01b57b6e2bbd92343f13a85a1d93bc46ccf6e47e244acd99c/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f", size = 225688, upload-time = "2026-08-03T21:20:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d2/3b7176cb570a1d3e27faf67b72f591af508036e0d8b2be2ef9af9e8c84bb/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4", size = 182868, upload-time = "2026-08-03T21:20:40.388Z" }, + { url = "https://files.pythonhosted.org/packages/56/78/31f00c1bcd97c9bbf55f1bfdf5bc809a5de8887473e90bb9960dca825e80/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e", size = 194104, upload-time = "2026-08-03T21:20:41.725Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1b/58496f2ed0a35de575250c02a43ab3cc2c04d494a88fed31c1cabc0fd176/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5", size = 186402, upload-time = "2026-08-03T21:20:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8f/9ebe220eab48a093d1a5a5e339ab0dc7316eef3bb04d63c42f0251b61f50/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d", size = 194043, upload-time = "2026-08-03T21:20:48.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/69/844bad3ece306c4782c2ecb93597035b6690d48704b803914c199da1e8b3/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b", size = 196737, upload-time = "2026-08-03T21:20:49.457Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8a/af668013284634733f02d683458a0728739c7d6ddb5e14cb0c20832266fe/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4", size = 184933, upload-time = "2026-08-03T21:20:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8", size = 185002, upload-time = "2026-08-03T21:20:52.173Z" }, + { url = "https://files.pythonhosted.org/packages/e2/31/9e1313b0a6e30e91b3b3d3fff51ae99c857c07738e3afcce1f7334e1b7ab/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6", size = 222271, upload-time = "2026-08-03T21:20:53.462Z" }, + { url = "https://files.pythonhosted.org/packages/50/e3/f6234a833e6e08c7007003074723c406559eecf9b48dfc97471e5a8eb7a0/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80", size = 209919, upload-time = "2026-08-03T21:20:54.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fc/5f74e293fced6edb51af3a46c4ccf6c23c9943774ecb375ddbd522c76add/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779", size = 208529, upload-time = "2026-08-03T21:20:56.066Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/29e6d01b388bef055ecd6ca8244b3f4d336bd09e92d5d892187b9601084e/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399", size = 221630, upload-time = "2026-08-03T21:20:57.336Z" }, + { url = "https://files.pythonhosted.org/packages/a4/18/fa7f1f6857d5eb88a4ca99ffcbfb7c387a287ccc154c64a73e86314745d7/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688", size = 225134, upload-time = "2026-08-03T21:20:58.675Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9f/e8e3dfa04a1b4c241f8c91faacad872b4d4efd051d49764ad4e2fd4b9fea/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7", size = 223197, upload-time = "2026-08-03T21:20:59.968Z" }, + { url = "https://files.pythonhosted.org/packages/f8/7e/8debeb04f1ab9fe2a6963964cd6f1aaf7192627b83926586a6a4e089c9fa/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac", size = 177683, upload-time = "2026-08-03T21:21:14.901Z" }, + { url = "https://files.pythonhosted.org/packages/e0/31/5158704cc474ab65c1647932e88be78dc0873f47130e253be38bcaf13d01/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960", size = 187897, upload-time = "2026-08-03T21:21:16.108Z" }, + { url = "https://files.pythonhosted.org/packages/cc/4b/b3a2da8570c704ffc0f9762cdc3ec0f02c8573798e0b5cf7f11c82bbb70f/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1", size = 182935, upload-time = "2026-08-03T21:21:17.271Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ef/5443574510a1207e6f6bc38ba6e1f1de36cb48fef07b2728bb896a21f430/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc", size = 188464, upload-time = "2026-08-03T21:21:01.163Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ae/a56fa8c4686ad50e148fcbc8d3ae0d03915ff5c30d795058988c24118cef/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab", size = 188262, upload-time = "2026-08-03T21:21:02.382Z" }, + { url = "https://files.pythonhosted.org/packages/53/b2/6187f46f2912276a3ae284076109cc5c8680482f11f766ccf26db4a86427/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e", size = 223779, upload-time = "2026-08-03T21:21:03.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f6/c3ad28bd19f77047a03084424fbd4cbe997303267c14423737324be0385d/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358", size = 211520, upload-time = "2026-08-03T21:21:04.863Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cd/ccac9013a5bd9fd764de118674ab9c805b5ca10c19270d90ee273f8b2240/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231", size = 210673, upload-time = "2026-08-03T21:21:06.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/86/2976131c639aead931c5bee5aba67e4b09fbeb8018b6f282f70803f923a7/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6", size = 223835, upload-time = "2026-08-03T21:21:07.539Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0c/33a7aeab2f9c76918c52e084beb39c570db3588133412929e8ec06fab90b/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94", size = 226705, upload-time = "2026-08-03T21:21:08.774Z" }, + { url = "https://files.pythonhosted.org/packages/e3/26/2cde30fdde421130bfc18f70395731a6e6b2053c6a1978a5258ff04e72fa/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5", size = 225539, upload-time = "2026-08-03T21:21:09.911Z" }, + { url = "https://files.pythonhosted.org/packages/6d/cd/a361394c94b2129d604bb846f624a8e88255a3ee33129c434a00d715e64f/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66", size = 182707, upload-time = "2026-08-03T21:21:11.226Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b5/ba2b299993c26577d529b6ae29841f9e15b9fcf004d65f423f4fcf94ade9/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3", size = 193772, upload-time = "2026-08-03T21:21:12.39Z" }, + { url = "https://files.pythonhosted.org/packages/aa/29/35e016098c814cd93de9cd320c66b5bfba14dc6ecedd3cb518fa7c408c69/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692", size = 186360, upload-time = "2026-08-03T21:21:13.636Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d", size = 315182, upload-time = "2026-04-02T09:25:40.673Z" }, - { url = "https://files.pythonhosted.org/packages/24/47/b192933e94b546f1b1fe4df9cc1f84fcdbf2359f8d1081d46dd029b50207/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8", size = 209329, upload-time = "2026-04-02T09:25:42.354Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b4/01fa81c5ca6141024d89a8fc15968002b71da7f825dd14113207113fabbd/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790", size = 231230, upload-time = "2026-04-02T09:25:44.281Z" }, - { url = "https://files.pythonhosted.org/packages/20/f7/7b991776844dfa058017e600e6e55ff01984a063290ca5622c0b63162f68/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc", size = 225890, upload-time = "2026-04-02T09:25:45.475Z" }, - { url = "https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393", size = 216930, upload-time = "2026-04-02T09:25:46.58Z" }, - { url = "https://files.pythonhosted.org/packages/e2/ab/b18f0ab31cdd7b3ddb8bb76c4a414aeb8160c9810fdf1bc62f269a539d87/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153", size = 202109, upload-time = "2026-04-02T09:25:48.031Z" }, - { url = "https://files.pythonhosted.org/packages/82/e5/7e9440768a06dfb3075936490cb82dbf0ee20a133bf0dd8551fa096914ec/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af", size = 214684, upload-time = "2026-04-02T09:25:49.245Z" }, - { url = "https://files.pythonhosted.org/packages/71/94/8c61d8da9f062fdf457c80acfa25060ec22bf1d34bbeaca4350f13bcfd07/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34", size = 212785, upload-time = "2026-04-02T09:25:50.671Z" }, - { url = "https://files.pythonhosted.org/packages/66/cd/6e9889c648e72c0ab2e5967528bb83508f354d706637bc7097190c874e13/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1", size = 203055, upload-time = "2026-04-02T09:25:51.802Z" }, - { url = "https://files.pythonhosted.org/packages/92/2e/7a951d6a08aefb7eb8e1b54cdfb580b1365afdd9dd484dc4bee9e5d8f258/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752", size = 232502, upload-time = "2026-04-02T09:25:53.388Z" }, - { url = "https://files.pythonhosted.org/packages/58/d5/abcf2d83bf8e0a1286df55cd0dc1d49af0da4282aa77e986df343e7de124/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53", size = 214295, upload-time = "2026-04-02T09:25:54.765Z" }, - { url = "https://files.pythonhosted.org/packages/47/3a/7d4cd7ed54be99973a0dc176032cba5cb1f258082c31fa6df35cff46acfc/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616", size = 227145, upload-time = "2026-04-02T09:25:55.904Z" }, - { url = "https://files.pythonhosted.org/packages/1d/98/3a45bf8247889cf28262ebd3d0872edff11565b2a1e3064ccb132db3fbb0/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a", size = 218884, upload-time = "2026-04-02T09:25:57.074Z" }, - { url = "https://files.pythonhosted.org/packages/ad/80/2e8b7f8915ed5c9ef13aa828d82738e33888c485b65ebf744d615040c7ea/charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374", size = 148343, upload-time = "2026-04-02T09:25:58.199Z" }, - { url = "https://files.pythonhosted.org/packages/35/1b/3b8c8c77184af465ee9ad88b5aea46ea6b2e1f7b9dc9502891e37af21e30/charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943", size = 159174, upload-time = "2026-04-02T09:25:59.322Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/feb40dca40dbb21e0a908801782d9288c64fc8d8e562c2098e9994c8c21b/charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008", size = 147805, upload-time = "2026-04-02T09:26:00.756Z" }, - { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" }, - { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" }, - { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" }, - { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" }, - { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" }, - { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" }, - { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" }, - { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" }, - { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" }, - { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" }, - { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" }, - { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" }, - { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" }, - { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" }, - { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" }, - { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" }, - { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" }, - { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" }, - { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" }, - { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" }, - { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" }, - { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" }, - { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" }, - { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" }, - { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" }, - { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" }, - { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" }, - { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" }, - { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, - { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, - { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, - { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, - { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, - { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, - { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, - { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, - { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, - { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, - { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, - { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, - { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, - { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, - { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, - { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, - { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, - { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, - { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, - { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, - { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, - { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, - { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, - { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, - { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, - { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, - { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, - { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, - { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, - { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, - { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, - { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, - { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, - { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, - { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, - { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, - { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, - { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, - { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, +version = "3.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/3f/143b048436775b0f76ac3eec145c019e8173ccc2885c8f20319b996d5e83/charset_normalizer-3.5.1.tar.gz", hash = "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3", size = 171764, upload-time = "2026-08-15T08:20:44.807Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/aa/554e2614f38fc34c58ff1d0911ae8535ad2516440d5482d76fe59f1088b0/charset_normalizer-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa", size = 369072, upload-time = "2026-08-15T08:16:22.964Z" }, + { url = "https://files.pythonhosted.org/packages/03/6d/439231dfc3ccfa6f8c06477b7da2219cbd41a2de3d49084df8ec7b5100f2/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda", size = 251142, upload-time = "2026-08-15T08:16:24.81Z" }, + { url = "https://files.pythonhosted.org/packages/55/53/7d819bd23a00ef45039146fa2cce1daa2f0771e758c5653ee1f6edac91ed/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45", size = 240714, upload-time = "2026-08-15T08:16:26.392Z" }, + { url = "https://files.pythonhosted.org/packages/b2/2c/45847198c16f4b38090cc7423b2b6a9008e438704d8ab413211832498d31/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab", size = 279637, upload-time = "2026-08-15T08:16:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/69/2b/d8be3523ddf9f0b0f3e56d1359034aa10653a4d11564c697f802b4775766/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a", size = 276543, upload-time = "2026-08-15T08:16:29.399Z" }, + { url = "https://files.pythonhosted.org/packages/32/cd/4f564b8f132de25db594efc706897069f016790cea63a5669c9df2675f64/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3", size = 261644, upload-time = "2026-08-15T08:16:30.722Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e3/38b975422534a608f98c360e79c2f07c763d66dd4272300d45fb1fee54b0/charset_normalizer-3.5.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb", size = 259609, upload-time = "2026-08-15T08:16:32.248Z" }, + { url = "https://files.pythonhosted.org/packages/87/bd/fbc24d825c66f1c74f6ccdea3742c3d8354a4888e86d1315a197fee69061/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f", size = 252457, upload-time = "2026-08-15T08:16:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2d/918d0e98a0e679469ed05bb2d90c2088b4d315bb612969d8499f76fb5210/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea", size = 242240, upload-time = "2026-08-15T08:16:35.396Z" }, + { url = "https://files.pythonhosted.org/packages/20/c8/c36f6e0b2dfec351bd38cbc05362697e58bcd073d7dbd95154290c9714ce/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f", size = 280308, upload-time = "2026-08-15T08:16:36.825Z" }, + { url = "https://files.pythonhosted.org/packages/ca/7b/311b3e02e8c4092400c449c850a760d8c45d900983c83a70cc07208c551d/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182", size = 258679, upload-time = "2026-08-15T08:16:38.22Z" }, + { url = "https://files.pythonhosted.org/packages/b9/90/082cc45599c392f28c036a497f49e0634041a785fc3849c80ccf396d096f/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa", size = 277221, upload-time = "2026-08-15T08:16:39.62Z" }, + { url = "https://files.pythonhosted.org/packages/58/ad/b9aecf38d805cbcf84fa94f14c5d972a16561e20296a11dc799a5dcf3763/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818", size = 263799, upload-time = "2026-08-15T08:16:40.885Z" }, + { url = "https://files.pythonhosted.org/packages/b7/23/b38a20598d5a825f85d9d7636860e56ff0db1479f86497a6e485aa9326f7/charset_normalizer-3.5.1-cp310-cp310-win32.whl", hash = "sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20", size = 182037, upload-time = "2026-08-15T08:16:42.198Z" }, + { url = "https://files.pythonhosted.org/packages/d2/21/83fffb77864408b8bf0fe1ca603926401d6f8775a8e150b39aacc9958f8a/charset_normalizer-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d", size = 206030, upload-time = "2026-08-15T08:16:43.787Z" }, + { url = "https://files.pythonhosted.org/packages/86/2e/b93135b5034b1157fb29554b0d06d4844ce62282f0e0a14036f93d7ee2e7/charset_normalizer-3.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5", size = 185092, upload-time = "2026-08-15T08:16:45.177Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b6/034f6802e9c3f6418966cfabb7db8c9252cc2429c5098f41cc43af804149/charset_normalizer-3.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30", size = 363585, upload-time = "2026-08-15T08:16:46.646Z" }, + { url = "https://files.pythonhosted.org/packages/d5/fa/6a7e2a7c4b5451912b8c417732df79574354443592a88d616de03da66ae5/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488", size = 251189, upload-time = "2026-08-15T08:16:48.287Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c8/ab42b07cfd82e919f427fcfaa7c41abae8242833ad1aad66d42bae40b669/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22", size = 239724, upload-time = "2026-08-15T08:16:49.67Z" }, + { url = "https://files.pythonhosted.org/packages/e7/80/b9348b5d3041209f98b4cdad7655766369233f1d533f4f4f7558e9717bec/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731", size = 280078, upload-time = "2026-08-15T08:16:51.228Z" }, + { url = "https://files.pythonhosted.org/packages/82/38/083a24028304bc85bb9e376fed801178423dcbb67495f73b6ea0624e1894/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c", size = 276650, upload-time = "2026-08-15T08:16:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/0d/35/731ac04aa0a097fc1c97f0994c375bdb230c6c96619db794208fe664e9ce/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8", size = 262325, upload-time = "2026-08-15T08:16:54.085Z" }, + { url = "https://files.pythonhosted.org/packages/f5/28/c2028e7021fb89c6e56868ed0e387b8e9aa811abdd2ab3208d6578d2c930/charset_normalizer-3.5.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486", size = 261140, upload-time = "2026-08-15T08:16:55.604Z" }, + { url = "https://files.pythonhosted.org/packages/28/f0/0c0ceec6d98b7daa62e361e418135d59685811d79ba11529aad5cdf15e84/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f", size = 252791, upload-time = "2026-08-15T08:16:57.103Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3e/48f4cd187b1c33189d86039e9cbe4f92c05454175504b44ff81806d4d1bf/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c", size = 240730, upload-time = "2026-08-15T08:16:58.418Z" }, + { url = "https://files.pythonhosted.org/packages/42/85/f9e22af69af67c54cce42be9455d9c81294f918b4ccc454db01f66efcac2/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18", size = 280791, upload-time = "2026-08-15T08:16:59.918Z" }, + { url = "https://files.pythonhosted.org/packages/fd/4c/9044135f42127630b6fa742feb51256353f6ab87a78f2fdd1de3de955a7f/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5", size = 259598, upload-time = "2026-08-15T08:17:01.421Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ed/1dd7cfebb4e75812934c49ca3b79757d11948053f7937ab7070c151f3c55/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b", size = 278217, upload-time = "2026-08-15T08:17:02.782Z" }, + { url = "https://files.pythonhosted.org/packages/bf/eb/239c84503cc9e3ba6eb34686a24bc66e84f3924efdd7e38e751a19f6bc10/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6", size = 263417, upload-time = "2026-08-15T08:17:04.216Z" }, + { url = "https://files.pythonhosted.org/packages/37/ab/4e4510e1e288478e2c8333131d1c1382382ba8cd2165053c79e39d1da961/charset_normalizer-3.5.1-cp311-cp311-win32.whl", hash = "sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b", size = 181774, upload-time = "2026-08-15T08:17:05.58Z" }, + { url = "https://files.pythonhosted.org/packages/e3/57/32f0ccea59e8612057c61d6fd22ef2cb63cca93c9fe594094919696ac170/charset_normalizer-3.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9", size = 206653, upload-time = "2026-08-15T08:17:07.075Z" }, + { url = "https://files.pythonhosted.org/packages/17/d4/b65c433fc521e58b5f54293982a5e51c05cb5f2dd3f1c7a6acb65b75324e/charset_normalizer-3.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10", size = 185630, upload-time = "2026-08-15T08:17:08.502Z" }, + { url = "https://files.pythonhosted.org/packages/30/27/78873dc8b6a56357517b74b6bb9568b80450e7bb4f6ef7e3fa9d22aa0bd7/charset_normalizer-3.5.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f", size = 344456, upload-time = "2026-08-15T08:17:10.072Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4c/be49ada26b1f0232d57aa89bbebf997a5cc2332a5616b6eca26ff680044d/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa", size = 238530, upload-time = "2026-08-15T08:17:11.563Z" }, + { url = "https://files.pythonhosted.org/packages/76/84/6f1290fa07ae6978d3960caa3eb1b8019bf9284ab7c2297b00c099ef4250/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369", size = 230200, upload-time = "2026-08-15T08:17:12.919Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a0/47b18adeed31c8f16ba9700f32c1b18594cfa09f47eb672a488c273c22bf/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893", size = 262222, upload-time = "2026-08-15T08:17:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/38/fe/341861ac118dae06f3ec0eb487488af52128f2ef2faf0b11003944d22259/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0", size = 258951, upload-time = "2026-08-15T08:17:16.158Z" }, + { url = "https://files.pythonhosted.org/packages/6f/89/bb5108dc6c3651dca963f2b0a3ba19bbcb370c94e1b6d3e0e844a58e6dca/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08", size = 248801, upload-time = "2026-08-15T08:17:17.683Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ba/ef83ae3aca816393decfa3530976f38a79812d707b80b580ac33b83f9877/charset_normalizer-3.5.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada", size = 244070, upload-time = "2026-08-15T08:17:19.191Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0b/c5292a2462d69b7378ea89793bbb5b2b6fcf6f7dd6d1667f9619094ad553/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9", size = 240110, upload-time = "2026-08-15T08:17:20.547Z" }, + { url = "https://files.pythonhosted.org/packages/46/22/111e5be3b740d5c2a5bfcedb3d237b6591e5c2e82ae9d6ffcb121fe0909c/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e", size = 232836, upload-time = "2026-08-15T08:17:21.895Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d2/d2aad6fe0dbb44b194bf3becb60f5a0ac48446ade999a47fe7bb41eb09a7/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6", size = 262712, upload-time = "2026-08-15T08:17:23.727Z" }, + { url = "https://files.pythonhosted.org/packages/35/5a/337e4663a5eae6de99db940ee8066d4145caafb61327db62deda15313cce/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf", size = 242977, upload-time = "2026-08-15T08:17:25.157Z" }, + { url = "https://files.pythonhosted.org/packages/ca/85/f82f8a92e31c7519410e2e1afdc630f28ec47490ce2c09a11c1a43cbb459/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71", size = 260207, upload-time = "2026-08-15T08:17:26.602Z" }, + { url = "https://files.pythonhosted.org/packages/b7/52/643d11ffd60e9ac2fd1fb87e167a19285b9eefeff4a40e63c87cbfbeab36/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573", size = 250562, upload-time = "2026-08-15T08:17:27.971Z" }, + { url = "https://files.pythonhosted.org/packages/62/16/46556278c2168d12df9da7fede5dc6fc70e60301b26a82bbeec238c9cfe3/charset_normalizer-3.5.1-cp312-cp312-win32.whl", hash = "sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2", size = 178507, upload-time = "2026-08-15T08:17:29.277Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7a/4c6c298171e6b3e745633180ff59350fc0ca0db1ffd28df1e369e0579f71/charset_normalizer-3.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2", size = 200551, upload-time = "2026-08-15T08:17:30.668Z" }, + { url = "https://files.pythonhosted.org/packages/cd/d7/eb95a042f0dd22e304b0b6472b154f3546a1a039a9ee89ccb2a7f61591fc/charset_normalizer-3.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a", size = 180700, upload-time = "2026-08-15T08:17:32.028Z" }, + { url = "https://files.pythonhosted.org/packages/bc/61/2cb6ad133dbbb449fa2d37ccae973232f4827e799af258d15e589a3d1e9e/charset_normalizer-3.5.1-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9", size = 211584, upload-time = "2026-08-15T08:17:33.597Z" }, + { url = "https://files.pythonhosted.org/packages/18/57/a305c968be1ca13f3dd1b32f445877e97addf55d80b65c7cb35fac82b777/charset_normalizer-3.5.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491", size = 223359, upload-time = "2026-08-15T08:17:35.022Z" }, + { url = "https://files.pythonhosted.org/packages/09/0a/d3646670292ce8d8f8cc11ac067d44885e697a5591f57a9221128da5e7b3/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7", size = 194464, upload-time = "2026-08-15T08:17:36.452Z" }, + { url = "https://files.pythonhosted.org/packages/de/93/d51ec556e01042fed6f993ea859311bc7917b466684182fbbceb6ca24762/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e", size = 197676, upload-time = "2026-08-15T08:17:37.819Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a0/562247944386f7d4ef94467e84876600cc1e0f1b93239aaa9213d2bc3cbd/charset_normalizer-3.5.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d", size = 340473, upload-time = "2026-08-15T08:17:39.303Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/1d994be1b93d41e9502b8b0460eaa88a1dd8df335df415db87d6c3e91ab2/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a", size = 240156, upload-time = "2026-08-15T08:17:40.66Z" }, + { url = "https://files.pythonhosted.org/packages/09/53/27923ce5cc6cbccb832037b27dca98882d9c53e9b69e866bbbef4aae7fc8/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe", size = 228246, upload-time = "2026-08-15T08:17:42.003Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/5a97e84d63af1d55c07439cb80e56d99a8efb4295700eb4e18c0d1615d2c/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac", size = 263660, upload-time = "2026-08-15T08:17:43.627Z" }, + { url = "https://files.pythonhosted.org/packages/7a/c2/071575791dcc88316c0a9a65ce38897a82e4cfe4a325f0f7fe1b1ac47bcf/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e", size = 260354, upload-time = "2026-08-15T08:17:45.094Z" }, + { url = "https://files.pythonhosted.org/packages/fb/af/63240b0c0248c075c2535a1f1bd992821d8251b9f173abc13329661d09e4/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3", size = 250638, upload-time = "2026-08-15T08:17:46.496Z" }, + { url = "https://files.pythonhosted.org/packages/4d/66/70dfad64f15be09c15ccfee81330a7e515895dbe296dd23114e9a231268a/charset_normalizer-3.5.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876", size = 244583, upload-time = "2026-08-15T08:17:47.963Z" }, + { url = "https://files.pythonhosted.org/packages/c0/24/ef36367d38b9ddd4bccbf72888c342e8de1f5ae506fa0b2dcf970e2732a1/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6", size = 242038, upload-time = "2026-08-15T08:17:49.481Z" }, + { url = "https://files.pythonhosted.org/packages/db/ab/55e683ba0fff2e43adafc10daa3001eac90fdaa419a97227d5a7067eedde/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2", size = 233677, upload-time = "2026-08-15T08:17:50.845Z" }, + { url = "https://files.pythonhosted.org/packages/bd/67/0f40eaf8d1b6e7cf15e82382a2965efaca787fc1c2794b7021d37aaf5036/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591", size = 264491, upload-time = "2026-08-15T08:17:52.61Z" }, + { url = "https://files.pythonhosted.org/packages/5c/64/12b4c2a11ee8df4fcc518c78b0d93e3a92bd3d5253d1617ce74ff0e8c7ef/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c", size = 245196, upload-time = "2026-08-15T08:17:54.023Z" }, + { url = "https://files.pythonhosted.org/packages/37/2e/651d910af6d0fba325eee1cda37ec5443462ed25360e666c144166eb6091/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c", size = 261660, upload-time = "2026-08-15T08:17:55.491Z" }, + { url = "https://files.pythonhosted.org/packages/90/c6/b09e05e6db7f64338e0dc067c79577b1138da86c1e38369096851d96be88/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f", size = 252618, upload-time = "2026-08-15T08:17:57.025Z" }, + { url = "https://files.pythonhosted.org/packages/76/4e/362d4f9fdcdf5556fb2aa3ce7d4a58ebce03ed1ff03aa1d9aca8d02f13f3/charset_normalizer-3.5.1-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4", size = 140362, upload-time = "2026-08-15T08:17:58.425Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d4/703be739b26acce318bd29eb3b25b7209e1b1f527f9eae3d1f1f01fdde2b/charset_normalizer-3.5.1-cp313-cp313-win32.whl", hash = "sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3", size = 177755, upload-time = "2026-08-15T08:18:00.037Z" }, + { url = "https://files.pythonhosted.org/packages/8a/33/56d97ade41c8db611e727168c52ae46c9224c362ec28d4b65d7e9869e8da/charset_normalizer-3.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6", size = 199295, upload-time = "2026-08-15T08:18:01.506Z" }, + { url = "https://files.pythonhosted.org/packages/5b/75/5b20dd1e6573a01a08158fe104104fa2c8abf941745596954185726cd46c/charset_normalizer-3.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0", size = 179856, upload-time = "2026-08-15T08:18:02.929Z" }, + { url = "https://files.pythonhosted.org/packages/29/cd/2b812ce5e888f1ce69a5350281e58aab07ae64a958ecae8912f30865718e/charset_normalizer-3.5.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8", size = 212318, upload-time = "2026-08-15T08:18:04.403Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4a/a6ee107430768a5334e6d63f31f148a04a1a491ef161a1ac9415a73f2fa8/charset_normalizer-3.5.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102", size = 224897, upload-time = "2026-08-15T08:18:05.997Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d9/35ae3f64f29d0179c35c3baefe575904df2913dde519129c7f75995a2b1d/charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5", size = 194848, upload-time = "2026-08-15T08:18:07.397Z" }, + { url = "https://files.pythonhosted.org/packages/74/76/f2fc7380f056cc273a53af37f50d08ad54b2c59f61078f31432edcf1c2bd/charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3", size = 198163, upload-time = "2026-08-15T08:18:08.989Z" }, + { url = "https://files.pythonhosted.org/packages/e9/40/095ce62fa078483cccc1fa2b36e6bc9580b85422a20ee9f925341c50e44f/charset_normalizer-3.5.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c", size = 341823, upload-time = "2026-08-15T08:18:10.458Z" }, + { url = "https://files.pythonhosted.org/packages/f1/5a/0e58b1c04a1596e0256f407274a92d5fb2ee21324409d1fab1da48a65b5b/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0", size = 242458, upload-time = "2026-08-15T08:18:11.989Z" }, + { url = "https://files.pythonhosted.org/packages/22/95/b4618ce912e6db0b1aae89ba788e38e8a7eba0f3025cc66e8c0699f977b2/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96", size = 226717, upload-time = "2026-08-15T08:18:13.401Z" }, + { url = "https://files.pythonhosted.org/packages/8a/76/c681192bbda3d55356db5dadd64381d5202b37c6b598fcda5282e88b5d3d/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc", size = 266111, upload-time = "2026-08-15T08:18:14.961Z" }, + { url = "https://files.pythonhosted.org/packages/88/be/55127bfca72c0cff6c022488d140d7c5b04c771e3b72e9bdb4836d54979d/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f", size = 263128, upload-time = "2026-08-15T08:18:16.515Z" }, + { url = "https://files.pythonhosted.org/packages/e0/91/39c3af510b0aa32bbda03374259200f28430febfd1bf5e511fe765282ce5/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90", size = 251240, upload-time = "2026-08-15T08:18:18.127Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a5/cbe418bbc6ecdfc3e05a0116002897c4b403a5e838d697e64c78e9f0190d/charset_normalizer-3.5.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506", size = 245282, upload-time = "2026-08-15T08:18:19.625Z" }, + { url = "https://files.pythonhosted.org/packages/cc/a4/689bb42e8e7cd492f3cb64907c6bc00ad247ec9a3628cd3f8eed126e8ae1/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5", size = 244597, upload-time = "2026-08-15T08:18:21.121Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ce/9962938e179cf9f699d3f1e7b3114b5d7642dee6a893745229f9dd04f274/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e", size = 231376, upload-time = "2026-08-15T08:18:22.57Z" }, + { url = "https://files.pythonhosted.org/packages/85/54/46000450ada53bd9eac5429a2c8c54cd2d9b39c0c255f229aea9af0948a5/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5", size = 266715, upload-time = "2026-08-15T08:18:24.235Z" }, + { url = "https://files.pythonhosted.org/packages/3d/bb/618749d70f792b44252a777bf89bfb86823b9bbc1ea13fe8ce759b07f38a/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3", size = 245848, upload-time = "2026-08-15T08:18:25.726Z" }, + { url = "https://files.pythonhosted.org/packages/7e/3f/ffb64458527c7668031d5eb095d978de561958dc9f5b53f8e488a533e603/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3", size = 264521, upload-time = "2026-08-15T08:18:27.193Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ab/74a55fd803916a35ac461daf002708191aac19b546b80dc8cabfedc63d98/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36", size = 253054, upload-time = "2026-08-15T08:18:28.568Z" }, + { url = "https://files.pythonhosted.org/packages/a0/2a/6a9034b7d3c60b17499afb482df5878bf9fa20b50cc3887d5ef017a833db/charset_normalizer-3.5.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7", size = 140580, upload-time = "2026-08-15T08:18:30.214Z" }, + { url = "https://files.pythonhosted.org/packages/f3/46/1d362e1a00d035d66b9869e1281eee115907f7e390a16a07824ab5737360/charset_normalizer-3.5.1-cp314-cp314-win32.whl", hash = "sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b", size = 180325, upload-time = "2026-08-15T08:18:31.877Z" }, + { url = "https://files.pythonhosted.org/packages/7a/7c/4938c329b6a9d446f6a59aa2092ff7118f274209b5ed0e26893d1d30a63c/charset_normalizer-3.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b", size = 204175, upload-time = "2026-08-15T08:18:33.466Z" }, + { url = "https://files.pythonhosted.org/packages/ac/33/eeb384dbd8dec570661354592f4f2e1b2fcc92585624d146a000caf53841/charset_normalizer-3.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687", size = 184123, upload-time = "2026-08-15T08:18:34.913Z" }, + { url = "https://files.pythonhosted.org/packages/1c/6c/c73fa9d5a85f6ab05395de61c5f6984e0a9ff40bb5ff888d46dff02526c6/charset_normalizer-3.5.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348", size = 381682, upload-time = "2026-08-15T08:18:36.349Z" }, + { url = "https://files.pythonhosted.org/packages/30/c7/63565f860921457feba93bae6c86fb7746deb4cffeed2f375cb845318146/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef", size = 240826, upload-time = "2026-08-15T08:18:37.887Z" }, + { url = "https://files.pythonhosted.org/packages/06/ae/7ae8807410dfa33f8e6f1715740adeaafa8a816cc4cb33508f54b1f7c896/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885", size = 227861, upload-time = "2026-08-15T08:18:39.315Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a3/887c1642f0da26000b0e0652d91071113c0e72cea33952e225cf589f49a9/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375", size = 260758, upload-time = "2026-08-15T08:18:40.88Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/e6f5b9a3d0e55b0ef7505cd3765cdd48f22db89994c947b316f52f801fd8/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1", size = 259950, upload-time = "2026-08-15T08:18:42.351Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ee/e4e10a94d51cd1ee638aa7e00b65399e6b2a4e8376ab6d2eac9f95586671/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65", size = 249329, upload-time = "2026-08-15T08:18:43.914Z" }, + { url = "https://files.pythonhosted.org/packages/c4/25/d5f4198819e6059735a84e8d0bfb72dc33976da67b97adcd3fb5a5e07ec6/charset_normalizer-3.5.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5", size = 243137, upload-time = "2026-08-15T08:18:45.368Z" }, + { url = "https://files.pythonhosted.org/packages/a5/e9/e925ca7569cf9fb9701fd82503fee73eea5268fdb856bdd64947092d3daa/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af", size = 242820, upload-time = "2026-08-15T08:18:46.842Z" }, + { url = "https://files.pythonhosted.org/packages/34/17/672c251a888ed2aebcdd2fe830ad0104e25ff83c43f5c4f9c15e9fc6853c/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1", size = 230504, upload-time = "2026-08-15T08:18:48.353Z" }, + { url = "https://files.pythonhosted.org/packages/3f/fc/f6a85abebd42ce4da2f1db0aa56cc6a0df1995e318b3875d14401b8381d1/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9", size = 263087, upload-time = "2026-08-15T08:18:49.859Z" }, + { url = "https://files.pythonhosted.org/packages/98/66/7c42677e739ba66746b297e2046918d793078094dc239e1e72768cffccc6/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a", size = 243269, upload-time = "2026-08-15T08:18:51.601Z" }, + { url = "https://files.pythonhosted.org/packages/de/d8/a50b79237f417af10f8c2a501ce8d1ca87829a22e69117891ca4ba20a69e/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032", size = 258766, upload-time = "2026-08-15T08:18:53.23Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1d/0fc91aeaeb3c83b748f532399ce67cf84604b48297405d740000f7a9e786/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e", size = 250814, upload-time = "2026-08-15T08:18:54.768Z" }, + { url = "https://files.pythonhosted.org/packages/ae/10/3d8c777cf9024615295aa1b808324ad5b4a77855869c00824bad74ffaf8a/charset_normalizer-3.5.1-cp314-cp314t-win32.whl", hash = "sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4", size = 191074, upload-time = "2026-08-15T08:18:56.305Z" }, + { url = "https://files.pythonhosted.org/packages/4d/81/ae557d3c44d1a1d688696d60563413a0866a91b7ebc50f20df838be3d8c8/charset_normalizer-3.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00", size = 216476, upload-time = "2026-08-15T08:18:57.889Z" }, + { url = "https://files.pythonhosted.org/packages/27/e9/61c01fb8b804692569c036b3fc50495814502dcf13a60649c6055390b02c/charset_normalizer-3.5.1-cp314-cp314t-win_arm64.whl", hash = "sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f", size = 194115, upload-time = "2026-08-15T08:18:59.418Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4e/8544831ef59d8f27ce92c80871380fdacc8076a8a56ed62f82e54f991333/charset_normalizer-3.5.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af", size = 342048, upload-time = "2026-08-15T08:19:01.054Z" }, + { url = "https://files.pythonhosted.org/packages/7f/a6/e3b46852424246065355644f4fb6dbccc0239a42a2eee27ecfc8957f0bcd/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8", size = 242997, upload-time = "2026-08-15T08:19:02.492Z" }, + { url = "https://files.pythonhosted.org/packages/03/3b/0cc9a26777334ab2f2e3089b948bbf4e4fe72ea70b897715ef6415043ec8/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90", size = 237014, upload-time = "2026-08-15T08:19:03.943Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c2/027335f0aa337a2a2e121bac1ad88c4f02ba6053ea0926802784f3db11af/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20", size = 266174, upload-time = "2026-08-15T08:19:05.598Z" }, + { url = "https://files.pythonhosted.org/packages/86/d3/e367787febe4e74769dec0f406f2c3c8d1b955fce5aee1fd0f94e8367a45/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449", size = 263361, upload-time = "2026-08-15T08:19:07.251Z" }, + { url = "https://files.pythonhosted.org/packages/af/3d/391b193eb9f3e84b02f9314088c386debdc0debee843535aaea2e2c6715d/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a", size = 252143, upload-time = "2026-08-15T08:19:08.816Z" }, + { url = "https://files.pythonhosted.org/packages/2e/57/de221f1745a90d418199761967e2776bfe2c275a1194220985e8c1d37833/charset_normalizer-3.5.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0", size = 252086, upload-time = "2026-08-15T08:19:10.255Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e3/d119f86a01f9331e8186175f24873b1d74a7ee9e2e4b4d68f9947dae5afd/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e", size = 245231, upload-time = "2026-08-15T08:19:11.807Z" }, + { url = "https://files.pythonhosted.org/packages/26/de/d8e48c135ae480879539cdb179c8d3b50c7879497d75dd899b5763b69cee/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2", size = 241546, upload-time = "2026-08-15T08:19:13.416Z" }, + { url = "https://files.pythonhosted.org/packages/67/c4/217755fd1abc50d326c252922cd642002758095a81ff45010337b8b3ef65/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626", size = 267033, upload-time = "2026-08-15T08:19:14.981Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d7/34d8e404e358d2adcc5a228c2134643af00104c8fb0bf525f3688d756f05/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5", size = 252045, upload-time = "2026-08-15T08:19:16.618Z" }, + { url = "https://files.pythonhosted.org/packages/5e/fa/40414471acf0aa0692ca77305aa00e434fcd8288f0941c93c30e9a5f8f2f/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774", size = 264866, upload-time = "2026-08-15T08:19:18.101Z" }, + { url = "https://files.pythonhosted.org/packages/32/90/fcc850bae791abd2e0c041847f13e270aa08692a79f3e00de6d2dce1cb50/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7", size = 253932, upload-time = "2026-08-15T08:19:19.734Z" }, + { url = "https://files.pythonhosted.org/packages/af/af/53afe99068b3c10b4cbae592a52ef72a7c92c0188440e83ee3a078fd8f75/charset_normalizer-3.5.1-cp315-cp315-win32.whl", hash = "sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9", size = 180320, upload-time = "2026-08-15T08:19:21.37Z" }, + { url = "https://files.pythonhosted.org/packages/c9/bc/f46a132041b29e4a8779ed712d3df1bf112e94ca8de58b66d7ec2c0cf8b9/charset_normalizer-3.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712", size = 204174, upload-time = "2026-08-15T08:19:23.088Z" }, + { url = "https://files.pythonhosted.org/packages/a1/5d/9ed554480eda8e447b673648628fdc29574d23dbad01fe11837adedd1cae/charset_normalizer-3.5.1-cp315-cp315-win_arm64.whl", hash = "sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7", size = 184126, upload-time = "2026-08-15T08:19:24.471Z" }, + { url = "https://files.pythonhosted.org/packages/3b/32/9b8929bf384061ee1fe5d9c27c6f9776d3d824039ad4e14c88ec00c7808e/charset_normalizer-3.5.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663", size = 381441, upload-time = "2026-08-15T08:19:26.038Z" }, + { url = "https://files.pythonhosted.org/packages/96/10/e9aa7923d3ddac652c99a1c5f7be494e737e151566a44abe018daf757f2c/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11", size = 241742, upload-time = "2026-08-15T08:19:27.532Z" }, + { url = "https://files.pythonhosted.org/packages/28/53/a2d249ebddf47b889a100c0bdcb61a2f9dbb8bc24ef325cc062e4f476877/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc", size = 235298, upload-time = "2026-08-15T08:19:29.274Z" }, + { url = "https://files.pythonhosted.org/packages/7d/07/469f78af590f7d5cd48e20d8dbfa3d66deeff9ba37768c04d886b5afd45c/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a", size = 262500, upload-time = "2026-08-15T08:19:30.955Z" }, + { url = "https://files.pythonhosted.org/packages/55/66/3bb56a47f7dcba014055b1a1d33c6f08bbe9c1e74dba154cfa25f90ae885/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4", size = 258888, upload-time = "2026-08-15T08:19:32.458Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c1/2adc2800903fb013210349313b710a5376856578d9e33e6b9a1d8b36714a/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004", size = 250243, upload-time = "2026-08-15T08:19:33.94Z" }, + { url = "https://files.pythonhosted.org/packages/95/b5/a18d0dd1157ab655cc2cb14a545f4a4784bbad70ab3502412e36097502d9/charset_normalizer-3.5.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b", size = 249871, upload-time = "2026-08-15T08:19:35.413Z" }, + { url = "https://files.pythonhosted.org/packages/ad/c3/525f508cd1e58d0450ac55ed40ac75bc3a97482c59def5278456a5fbf03c/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263", size = 243580, upload-time = "2026-08-15T08:19:36.886Z" }, + { url = "https://files.pythonhosted.org/packages/7c/c1/49a91fe7e97c8140094ca5c64161ab623a70d9f636bf834eace14048acb5/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee", size = 239807, upload-time = "2026-08-15T08:19:38.392Z" }, + { url = "https://files.pythonhosted.org/packages/d3/58/56a48c296601274c4689b864a8e2dfb209b81dfcb39472753ce95eea662b/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c", size = 264083, upload-time = "2026-08-15T08:19:39.856Z" }, + { url = "https://files.pythonhosted.org/packages/10/4c/dc48409274a1817ff349711d26c62aa0c597df865d4d69ef79160c859193/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e", size = 250317, upload-time = "2026-08-15T08:19:41.53Z" }, + { url = "https://files.pythonhosted.org/packages/81/58/d325912115caec62d6bdd77bbab5e0b7da5d234a9f20affdffcbcb530d0b/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d", size = 258173, upload-time = "2026-08-15T08:19:43.07Z" }, + { url = "https://files.pythonhosted.org/packages/34/f7/b13b1ccae2c8ec63980d13be1890eb73f8aeabbfce02a24aabc0908788f5/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61", size = 251960, upload-time = "2026-08-15T08:19:44.587Z" }, + { url = "https://files.pythonhosted.org/packages/1e/25/ed3f9919c5aef8cc818be1f972f565f7610d7b2076b8ebb98839516ffc3c/charset_normalizer-3.5.1-cp315-cp315t-win32.whl", hash = "sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f", size = 191186, upload-time = "2026-08-15T08:19:46.293Z" }, + { url = "https://files.pythonhosted.org/packages/69/d5/43c2b3e9d8267092b913eb8b0603f0f71993c395632886bd37a7223f96cf/charset_normalizer-3.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb", size = 215947, upload-time = "2026-08-15T08:19:47.853Z" }, + { url = "https://files.pythonhosted.org/packages/a8/76/9aad3e9c8865e5e0efa9a7f6f81c37a67635a985145ecd44528a81e088ee/charset_normalizer-3.5.1-cp315-cp315t-win_arm64.whl", hash = "sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a", size = 193909, upload-time = "2026-08-15T08:19:49.383Z" }, + { url = "https://files.pythonhosted.org/packages/5b/97/fb4e82231aba271ffd775a1b4993b0defc4e3059f286ae41d9433409fe85/charset_normalizer-3.5.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2", size = 331467, upload-time = "2026-08-15T08:19:50.959Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2f/fe3f187327aac18e2d54e9d2b08e15d27bf9b642d9e51c219f130fc34d1a/charset_normalizer-3.5.1-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99", size = 253057, upload-time = "2026-08-15T08:19:52.654Z" }, + { url = "https://files.pythonhosted.org/packages/d7/c7/9e48cee5c161fe24da823b61bf381921d77cb994a0a4de148e95018c1984/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2", size = 240930, upload-time = "2026-08-15T08:19:54.163Z" }, + { url = "https://files.pythonhosted.org/packages/49/e0/716601f3cc69be7b198951150c75ead1ece33c3c8036ff6ffa46029659a0/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235", size = 230822, upload-time = "2026-08-15T08:19:55.807Z" }, + { url = "https://files.pythonhosted.org/packages/d3/05/71bfc5caa0abcc45aea1f6a4d50ac68e59605ddc7666fe8494f4cd229665/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598", size = 260037, upload-time = "2026-08-15T08:19:57.312Z" }, + { url = "https://files.pythonhosted.org/packages/c3/92/de7e32ed05341e7a9c4c877c318418197b7f2d66a3b68d561bf2ac57ca3e/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96", size = 255097, upload-time = "2026-08-15T08:19:59.056Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7b/ade0a122600319dfa0b1000ab0f9731c94a817904cf3c5de408c73a4ede7/charset_normalizer-3.5.1-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962", size = 250166, upload-time = "2026-08-15T08:20:00.612Z" }, + { url = "https://files.pythonhosted.org/packages/75/9c/019fbb9f4834491a160951349b1a3714439376f66e5f7cf18b4f18f0c7aa/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3", size = 241821, upload-time = "2026-08-15T08:20:02.321Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b8/11d4840bfc99330cc7fbcc2681ee5a044553a6e77655508d8f9b2bff7b34/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950", size = 232529, upload-time = "2026-08-15T08:20:04.008Z" }, + { url = "https://files.pythonhosted.org/packages/18/96/2b3a21492d9f65171ac75d872f5018260013d00bfa0ff70ec9f179148cbd/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8", size = 260348, upload-time = "2026-08-15T08:20:05.877Z" }, + { url = "https://files.pythonhosted.org/packages/d6/aa/a69a2028e8bd052476c245460ab19d7de595de084dd968f2d75cd50c3e25/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031", size = 247234, upload-time = "2026-08-15T08:20:07.487Z" }, + { url = "https://files.pythonhosted.org/packages/35/8a/3d130aeabcaf3d2466af76b7b141c08d9e89c9016ab4b7cdd0f7dc2d1c62/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072", size = 256917, upload-time = "2026-08-15T08:20:09.142Z" }, + { url = "https://files.pythonhosted.org/packages/80/c2/a7379b840292d0c1ab9fbd17d1f3967aa81794dc95bc74be8999d7fedcf7/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d", size = 254846, upload-time = "2026-08-15T08:20:10.727Z" }, + { url = "https://files.pythonhosted.org/packages/01/65/d43b714731bb2f40d4053dfa00ecfc1c5a301f8e3316c5db3a09af59fe94/charset_normalizer-3.5.1-cp37-abi3-win32.whl", hash = "sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc", size = 174216, upload-time = "2026-08-15T08:20:12.334Z" }, + { url = "https://files.pythonhosted.org/packages/35/4f/b911ed898b26a09789eba9c9200c999aff6c61b4bafaf4838e56d1a1e1a3/charset_normalizer-3.5.1-cp37-abi3-win_amd64.whl", hash = "sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959", size = 199764, upload-time = "2026-08-15T08:20:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/f0/a7/920baf467bfd9bf689f3b318340f37aee4572a71f162bd8db51da55ba4fa/charset_normalizer-3.5.1-cp37-abi3-win_arm64.whl", hash = "sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e", size = 287318, upload-time = "2026-08-15T08:20:15.551Z" }, + { url = "https://files.pythonhosted.org/packages/cc/61/d01fc49b8dea277640b55a9e15960dbca9fdc8c9fde18e572d39c59f4019/charset_normalizer-3.5.1-py3-none-any.whl", hash = "sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6", size = 68658, upload-time = "2026-08-15T08:20:43.306Z" }, ] [[package]] @@ -2376,100 +2494,130 @@ wheels = [ [[package]] name = "coverage" -version = "7.14.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/91/0a7c28934e50d8ac9a7b117712d176f2953c3170bccced5eaacfa3e96175/coverage-7.14.3.tar.gz", hash = "sha256:1a7563a443f3d53fdeb040ec8c9f7466aed7ca3dc5891aa09d3ca3625fa4387f", size = 924398, upload-time = "2026-06-22T23:10:25.584Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/bd/b01188f0de73ee8b6597cf20c63fccd898ad31405772f15165cb61a62c00/coverage-7.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:360bec1f58e7243e3405d3bdf7a1a8115aa9b448d54dc7cd6f7b7e0e9406b62e", size = 220378, upload-time = "2026-06-22T23:07:38.925Z" }, - { url = "https://files.pythonhosted.org/packages/33/eb/f7aa3cb46500b709070c8d12335446971ec8b8c2ea155fea05d2000b4b1f/coverage-7.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed68faa5e85de2f3e400bc3f122e5c82735a58c8bb24b9f63a2215954ba17b2d", size = 220895, upload-time = "2026-06-22T23:07:41.536Z" }, - { url = "https://files.pythonhosted.org/packages/c3/c0/b41b8499fc9060ca40ad2a197d301155be1ead398f0f0bfdb27b2b4a660f/coverage-7.14.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:830c1fca669c572dec37ce9c838224ee45aac5be0f6961edf871e82e49d6537c", size = 247631, upload-time = "2026-06-22T23:07:43.244Z" }, - { url = "https://files.pythonhosted.org/packages/da/bb/e9ecea1307c6a549c223842cccbd5d55193cc27b82f26338782d4355047c/coverage-7.14.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a64caee2193563601dbaaa55fe2dcf597debef04a2f8f1fa8a07aa4bb7ac7a1e", size = 249460, upload-time = "2026-06-22T23:07:45.147Z" }, - { url = "https://files.pythonhosted.org/packages/59/cb/3821542809b7b726296fd364ed1c23d10a5770f1469957010c3b4bc5d408/coverage-7.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0096fd7559178f0cc9cf088f2dbd2a02ef85bacaa69732c633517286b4494610", size = 251324, upload-time = "2026-06-22T23:07:46.875Z" }, - { url = "https://files.pythonhosted.org/packages/76/27/f34f66f0ff152189ccc7b3f0582cf7909e239cb3b8c214362ed2149719b8/coverage-7.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6197e5a00183c11a8ce7c6abd18be1a9189fd8399084ffc95196f4f0db4f2137", size = 253237, upload-time = "2026-06-22T23:07:48.352Z" }, - { url = "https://files.pythonhosted.org/packages/22/81/aa363fa95d14fc892bd5de80edadc8d7cce584a0f6376f6336e492618e67/coverage-7.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7dfe427045520d6abca33687dfef767b4f635015893a1816c5decb12eb72ce18", size = 248344, upload-time = "2026-06-22T23:07:49.896Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/dc8a149441a3fea611cbbaf46bb12099adbe08f69903df1794581b0504b8/coverage-7.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9a3f142070eb7b82fc4085a55d887396f9c4e21250bccebe2ba22502c45b9647", size = 249365, upload-time = "2026-06-22T23:07:51.464Z" }, - { url = "https://files.pythonhosted.org/packages/f8/a2/0004127deee122e020be24a4d86ce72fa14ae28198811b945aabf91293b5/coverage-7.14.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64b2055bb6e0dc945af35cdeceb3633e6ed9273475ef3af85592410fd6803803", size = 247369, upload-time = "2026-06-22T23:07:53.064Z" }, - { url = "https://files.pythonhosted.org/packages/1e/72/3654c004f4df4f0c5a9643d9abaed5b26e5d3c1d0ecabe788786cb425efa/coverage-7.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1551b4caac3e3ec9f2bfcec6bf3776e01c0edbdd2e240431a50ca1a1aac72c27", size = 251182, upload-time = "2026-06-22T23:07:54.789Z" }, - { url = "https://files.pythonhosted.org/packages/a5/2f/7bdcdf1e7c4d0632648852768063c25582a0a747bb5f8036a04e211e7eb7/coverage-7.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:583d50d59142f8549470bd6390471d0fe8b8c8d69d6a0f28ac71e05380cef640", size = 247639, upload-time = "2026-06-22T23:07:56.254Z" }, - { url = "https://files.pythonhosted.org/packages/03/dc/0e01b071f69021d262a51ce39345dd6bc194465db0acfc7b34fd89e6b787/coverage-7.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0bb8a6bc7015efdf8a928753b25da1b9ca2d6f24ef04d2ee0688e486f32aae7", size = 248242, upload-time = "2026-06-22T23:07:57.692Z" }, - { url = "https://files.pythonhosted.org/packages/1c/51/08279e6ebe3479bf705db5fdc1a968e44ba1567e4cbc567f76b45f5e646e/coverage-7.14.3-cp310-cp310-win32.whl", hash = "sha256:d48400185564042287dc487c1f016a3397f18ab4f4c5d5ec36edc218f7ffa35b", size = 222431, upload-time = "2026-06-22T23:07:59.094Z" }, - { url = "https://files.pythonhosted.org/packages/40/2f/5c56670781fee5722ef0c415a74750c9a033bfacdb9d07b1493a0308108d/coverage-7.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:eadea7aba74e40adee867a8c0eec17b820b061d308a4b014f7a0e118c2b0aa61", size = 223059, upload-time = "2026-06-22T23:08:00.662Z" }, - { url = "https://files.pythonhosted.org/packages/f1/24/efb17eb94018dd3415d0e8a76a4786a866e8964aa9c50f033399d23939c2/coverage-7.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e574801e1d643561594aa021206c46d80b257e9853087090ba97bed8b0a509d3", size = 220501, upload-time = "2026-06-22T23:08:02.182Z" }, - { url = "https://files.pythonhosted.org/packages/76/93/32f1bfca6cdd34259c8af42820a034b7a28dfb44969a13ed38c17e0ba5b0/coverage-7.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f82b6bb7d75a2613e85d07cefa3a8c973d0544a8993337f6e2728e4a1e94c305", size = 221008, upload-time = "2026-06-22T23:08:03.701Z" }, - { url = "https://files.pythonhosted.org/packages/eb/88/0d0f974855ff905d15a64f7873d00bdc4182e2736267486c6634f4af293c/coverage-7.14.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a2335ea5fed26af2e831094964fa3f8fae60b45f7e37fcc2d3b615b2add3ad87", size = 251420, upload-time = "2026-06-22T23:08:05.211Z" }, - { url = "https://files.pythonhosted.org/packages/39/7f/117dd2ec65e4140576f8ef991d88220f9b806769f7a8c20e0550c0f924e2/coverage-7.14.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fbb8c3a98e779013786ae01d229662aeacbc77100efbd3f2f245219ace5af700", size = 253331, upload-time = "2026-06-22T23:08:06.672Z" }, - { url = "https://files.pythonhosted.org/packages/87/55/f0bd6d6538e3f16829fb8a44b6c0d2fe9da638bbfdd6a20f8b5da8f4fa81/coverage-7.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac082660de8f429ba0ea363595abb838998570b9a7546777c60f413ab902bbde", size = 255441, upload-time = "2026-06-22T23:08:08.208Z" }, - { url = "https://files.pythonhosted.org/packages/1e/98/aa71f7879019c846a8a9662579ea4484b0202cf1e252ffeed647075e7eca/coverage-7.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ac012839ff7e396030f1e94e10553a431d14e4de2ab65cb3acb72bbd5628ca2", size = 257398, upload-time = "2026-06-22T23:08:09.749Z" }, - { url = "https://files.pythonhosted.org/packages/f3/4f/5fd367e59844190f5965015d7bee899e67a89d13eb2760118479bf836f2f/coverage-7.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5952f8c1bda2a5347154450379316e6dfa4d934d62ca35f6784451e6f55074fb", size = 251558, upload-time = "2026-06-22T23:08:11.37Z" }, - { url = "https://files.pythonhosted.org/packages/8f/de/5383a6ee5a6376701fe07d980fa8e4a66c0c377fead16712720340d701a3/coverage-7.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8cf0f2509acb4619e2471a1951089054dd58ebea7a912066d2ea56dd4c24ca4a", size = 253134, upload-time = "2026-06-22T23:08:13.04Z" }, - { url = "https://files.pythonhosted.org/packages/01/99/09542b1a99f788e3daec7f0fadc288821e71aca9ea298d51bfa1ba79fed5/coverage-7.14.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2e41fd3aab806770008279a93879b0924b16247e09ab537c043d08bbca53b4ab", size = 251195, upload-time = "2026-06-22T23:08:14.606Z" }, - { url = "https://files.pythonhosted.org/packages/02/9d/722fe8c13f0fbb064491b9e8656e56a606286792e5068c47ca1042e773e8/coverage-7.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f0a47095963cfe054e0df178daca95aec21e680d6076da807c3add28dfe920f7", size = 254959, upload-time = "2026-06-22T23:08:16.431Z" }, - { url = "https://files.pythonhosted.org/packages/fb/58/943627179ff1d82da9e54d0a5b0bb907bb19cf19515599ccd921de50b469/coverage-7.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a090cbf9521e78ffdb2fcf448b72902afe9f5923ff6a12d5c0d0120200348af9", size = 250914, upload-time = "2026-06-22T23:08:18.03Z" }, - { url = "https://files.pythonhosted.org/packages/a5/d4/803efcbf9ae5567454a0c71e983589529448e2704ee0da2dc0163d482f18/coverage-7.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d310baf69a4fbe8a098ce727e4808a34866ac718a6f759ae659cbd3221358bc", size = 251824, upload-time = "2026-06-22T23:08:19.704Z" }, - { url = "https://files.pythonhosted.org/packages/32/79/3f78ea9563132746eed5cecb75d2e576f9d8fec45a47242b5ae0950b82a3/coverage-7.14.3-cp311-cp311-win32.whl", hash = "sha256:74fdd718d88fe144f4579b8747873a07ec3f04cb837d5faec5a25d9e22fa31a8", size = 222594, upload-time = "2026-06-22T23:08:21.311Z" }, - { url = "https://files.pythonhosted.org/packages/85/22/9ebbc5a2ab42ac5d0eea1f48648629e1de9bbe41ec243ed6b93d55a5a53f/coverage-7.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:cc96aa922e21d4bc5d5ed3c915cef27dfcbc13686f47d5e378d647fbfba655a2", size = 223073, upload-time = "2026-06-22T23:08:23.318Z" }, - { url = "https://files.pythonhosted.org/packages/71/af/69d5fcc16cb555153f99cec5467922f226be0369f7335a9506856d2a7bd0/coverage-7.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:c66f9f9d4f1e9712eb9b1de5310f881d4e2188cfcba5065e1a8490f38687f2c4", size = 222617, upload-time = "2026-06-22T23:08:25.054Z" }, - { url = "https://files.pythonhosted.org/packages/bd/b0/8a911f6ffe6974dac4df95b468ab9a2899d0e59f0f99a489afeec39f00bc/coverage-7.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3d74ff26299c4879ce3a4d826f9d3d4d556fd285fde7bbce3c0ef5a8ab1cec24", size = 220672, upload-time = "2026-06-22T23:08:26.621Z" }, - { url = "https://files.pythonhosted.org/packages/36/16/0fc0cb52538783dbbae0934b834f5a58fd5354380ee6cad4a07b15dc845d/coverage-7.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:96150a9cf3468ea20f0bc5d0e21b3df8972c31480ef90fa7614b773cc6429665", size = 221035, upload-time = "2026-06-22T23:08:28.372Z" }, - { url = "https://files.pythonhosted.org/packages/77/e2/421ccfbb48335ac49e93301478cf5d623b0c2bf1c0cadd8e2b2fc6c0c710/coverage-7.14.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:27d07a46500ba23515b838dbcf52512026af04090755cf6cc64166d88c9b9a1a", size = 252540, upload-time = "2026-06-22T23:08:30.226Z" }, - { url = "https://files.pythonhosted.org/packages/06/c2/05b8c890097c61a7f4406b35396b997a635200ded0339eda83dfbe526c5f/coverage-7.14.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:621e13c6108234d7960aaf5762ab5c3c00f33c30c15af06dcbff0c73bf112727", size = 255274, upload-time = "2026-06-22T23:08:31.876Z" }, - { url = "https://files.pythonhosted.org/packages/dc/be/b6d9efe447f8ba3c3c854195f326bd64c54b907d936cd2fdebf8767ec72e/coverage-7.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b60ca6d8af70473491a15a343cbabab2e8f9ea66a4376e81c7aa24876a6f977", size = 256389, upload-time = "2026-06-22T23:08:33.843Z" }, - { url = "https://files.pythonhosted.org/packages/d4/3c/f26e50acc429e608bc534ac06f0a3c169019c798178ec5e9de3dbc0df9c9/coverage-7.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c90a7cdd5e380e1ce02f19792e2ac2fbfbf177e35a27e69fd3e873b30d895c0c", size = 258648, upload-time = "2026-06-22T23:08:35.481Z" }, - { url = "https://files.pythonhosted.org/packages/9e/a2/01c1fabf816c8e1dae197e258edf878a3d3ddc86fbda34b76e5794277d8f/coverage-7.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5d788e5fd55347eef06ca0732c77d04a264de67e8ff24631270cdff3767a60cf", size = 252949, upload-time = "2026-06-22T23:08:37.562Z" }, - { url = "https://files.pythonhosted.org/packages/89/c6/941166dd79c31fd44a13063780ae8d552eee0089a0a0930b9bdb7df554ed/coverage-7.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62c7f79db2851c95ef020e5d28b97afde3daf9f7febcd35b53e05638f729063f", size = 254310, upload-time = "2026-06-22T23:08:39.174Z" }, - { url = "https://files.pythonhosted.org/packages/10/31/80b1fd028201a961033ce95be3cd1e39e521b3762e6b4a1ac1616cb291e7/coverage-7.14.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:90f7608aeb5d9b60b523b9fb2a4ee1973867cc4865a3f26fe6c7577073b70205", size = 252453, upload-time = "2026-06-22T23:08:40.84Z" }, - { url = "https://files.pythonhosted.org/packages/5f/85/c3d9addd94c4b524f3f4af0232075f5fe7170ce99a1386edff803e5934db/coverage-7.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1e3b91f9c4740aeb571ecf82e5e8d8e4ab62d34fcb5a5d4e5baa38c6f7d2857c", size = 256522, upload-time = "2026-06-22T23:08:42.494Z" }, - { url = "https://files.pythonhosted.org/packages/91/14/e5a0575f73795af3a7a9ae13dadf812e17d32422896839987dc3f86947e1/coverage-7.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c946099774a7699de03cbd0ff0a64e21aed4525eed9d959adde4afe6d15758ef", size = 252023, upload-time = "2026-06-22T23:08:44.243Z" }, - { url = "https://files.pythonhosted.org/packages/38/9b/9652ee531937ce3b8a63a8896885b2b4a2d56adc30e53c9540c666286d88/coverage-7.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16b206e521feb8b7133a45754643dead0538489cf8b783b90cf5f4e3299625fd", size = 253893, upload-time = "2026-06-22T23:08:46.113Z" }, - { url = "https://files.pythonhosted.org/packages/b1/05/42678841c8c38e4b08bdfc48269f5a16dfbf5806000fe6a89b4cece3c691/coverage-7.14.3-cp312-cp312-win32.whl", hash = "sha256:ea3169c7116eb6cdf7608c6c7da9ecfcb3da40688e3a510fac2d1d2bafd6dc35", size = 222734, upload-time = "2026-06-22T23:08:47.858Z" }, - { url = "https://files.pythonhosted.org/packages/df/87/07a4fcee55177a25f1b52331a8e92cf4f2c53b1a9c75ce2981fd59c684ad/coverage-7.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:7ea52fc08f007bcc494d4bb3df3851e95843d881860ba38fe2c64dc100db5e7d", size = 223266, upload-time = "2026-06-22T23:08:49.494Z" }, - { url = "https://files.pythonhosted.org/packages/aa/34/2b8b66a989282ea7b370beb49f50bab29470dc30bb0b03935b6b802782f7/coverage-7.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:8cec0ad652ec57790970d817490105bd917d783c2f7b38d6b58a0ca312e1a336", size = 222655, upload-time = "2026-06-22T23:08:51.766Z" }, - { url = "https://files.pythonhosted.org/packages/a9/83/7fefbf5df23ed2b7f489907564a7b34b9b07098128e12e0fdfa92626e456/coverage-7.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47968988b367990ae4ab17523790c38cd125e02c6bfd379b6022be2d40bdc38c", size = 220699, upload-time = "2026-06-22T23:08:53.522Z" }, - { url = "https://files.pythonhosted.org/packages/31/e6/38c3653ff6d56d704b29241362387ca824e38e15b76fdcb7096538195790/coverage-7.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0ee68f5c34812780f3a7063382c0a9fcbb99985b7ddcdcaa626e4f3fb2e0783a", size = 221068, upload-time = "2026-06-22T23:08:55.571Z" }, - { url = "https://files.pythonhosted.org/packages/20/86/4f5c45d51c5cd10a128933f0fd235393c9146abbfd2ce2dfa68b3267ead3/coverage-7.14.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fa9e5c6857a7e80fa22ace5cf3550ae392bbfc322f1d8dd2d2d5a8be38cec027", size = 252060, upload-time = "2026-06-22T23:08:57.464Z" }, - { url = "https://files.pythonhosted.org/packages/82/50/dfce42eff2cecabcd5a9bbad5489449c87db3415f408d23ffee417ce01f6/coverage-7.14.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98a0859b0e98e43e1178a9402e19c8127766b14f7109a374d976e5a62c0e5c73", size = 254657, upload-time = "2026-06-22T23:08:59.453Z" }, - { url = "https://files.pythonhosted.org/packages/ba/d2/639ceb1bc8038fd0d66768278d5dc22df3391918b8278c2a21aa2602a531/coverage-7.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69918344541ed9c8368566c2adc03c0e33d4550d7faa87d1b35e49b6a3286ea9", size = 255892, upload-time = "2026-06-22T23:09:01.291Z" }, - { url = "https://files.pythonhosted.org/packages/8b/96/002094a10e113512500dc1e10430a449417e17b0f90f7d496bcb820208b7/coverage-7.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b7f300ac92cd4b570724c8ffbbd0c130fee298d2447f41d5a3abf58976fae1de", size = 258026, upload-time = "2026-06-22T23:09:03.017Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ec/286a5d2fad9c4bee59bd724feeb7d5bf8303c6c9200b51d1dd945a9c72b0/coverage-7.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11a7ec9f97ab950f4c5af62229befc7faf208fdbc0116d3902d7e306cf2c5abd", size = 252285, upload-time = "2026-06-22T23:09:04.773Z" }, - { url = "https://files.pythonhosted.org/packages/d9/7d/a17753a0b12dd48d0d50f5fab079ad99d3be1eac790494d89f3a417ca0b9/coverage-7.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a571bd889cd36c5922ce8e42e059f9d37d02301531d11374afa4c87a578625d5", size = 254023, upload-time = "2026-06-22T23:09:06.513Z" }, - { url = "https://files.pythonhosted.org/packages/86/ef/a76c6ceba6a2c313f905310abf2701d534cada22d372db11731831e9e209/coverage-7.14.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de76caefc8deabb0dd1678b6a980be97d14c8d87e213ac194dbf8b09e96d63fb", size = 251989, upload-time = "2026-06-22T23:09:08.382Z" }, - { url = "https://files.pythonhosted.org/packages/d9/39/353013a75fec0fb49f7553519f9d52b4441e902e5178c93f38eb6c07cedb/coverage-7.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d20a15c622194234161535459affa8f7905830391c9ccfa060d495dbfe3a1c7f", size = 256144, upload-time = "2026-06-22T23:09:10.369Z" }, - { url = "https://files.pythonhosted.org/packages/29/0e/613878555d734def11c5b20a2701a15cb3781b9e9ea749da27c5f436e928/coverage-7.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b488bd4b23397db62e7a9459129d01ff06a846582a732efd24834b24a6ada498", size = 251808, upload-time = "2026-06-22T23:09:12.057Z" }, - { url = "https://files.pythonhosted.org/packages/af/76/359c058c9cfdcf1e8b107663881225b03b364a320017eda24a2a66e55102/coverage-7.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a3693b4153394d265f44fb855fdc80e72403024d4d6f91c4871b334d028e4e0", size = 253579, upload-time = "2026-06-22T23:09:13.858Z" }, - { url = "https://files.pythonhosted.org/packages/1d/d9/4ba2f060933a30ebe363cef9f67a365b0a317e580c0d5d9169d56a73ef1c/coverage-7.14.3-cp313-cp313-win32.whl", hash = "sha256:338b19131ab1a6b767b462bfcbaa692e7ae22f24463e39d49b02a83410ff6b37", size = 222741, upload-time = "2026-06-22T23:09:15.636Z" }, - { url = "https://files.pythonhosted.org/packages/76/e8/196ebc25d8f34c06d43a6e9c8513c9266ef8dbf3b5672beb1a00cf5e29fa/coverage-7.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:b3d77f7f196abdef7e01415de1bce09f216189e83e58159cfeef2b92d0464994", size = 223283, upload-time = "2026-06-22T23:09:17.478Z" }, - { url = "https://files.pythonhosted.org/packages/7c/af/51d2aac6417523a286f10fb25f09eb9518a84df9f1151e93ff6871f34849/coverage-7.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:e6230e688c7c3e65cedd41a774eb4ec221adc6bfee13768231015b702d5e4150", size = 222678, upload-time = "2026-06-22T23:09:19.7Z" }, - { url = "https://files.pythonhosted.org/packages/61/56/14e3b97facbfa1304dd19e676e26599ad359f04714bed32f7f1c5a88efdc/coverage-7.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:605ab2b566a22bd94834529d66d295c364aba84afd3e5498285c7a524017b1fc", size = 220741, upload-time = "2026-06-22T23:09:21.616Z" }, - { url = "https://files.pythonhosted.org/packages/12/1d/db378b5cca433b90b893f26dab728b280ddd89f272a1fdfed4aeaa05c686/coverage-7.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3c2134809e80fac091bfed18a6991b5a5eb5df5ae32b17ac4f4f99864b73dd7", size = 221068, upload-time = "2026-06-22T23:09:23.452Z" }, - { url = "https://files.pythonhosted.org/packages/47/f0/3f8421b20d9c4fcd39be9a8ca3c3fda8bc204b44efbd09fede153afd3e2f/coverage-7.14.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c02efd507227bde9969cab0db8f48890eb3b5dcad6afac57a4792df4133543ce", size = 252117, upload-time = "2026-06-22T23:09:25.458Z" }, - { url = "https://files.pythonhosted.org/packages/27/ca/59ea35fb99743549ec8b37eff141ece4431fea590c89e536ed8032ef45cf/coverage-7.14.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1bb93c2aa61d2a5b38f1526546d95cf4132cb681e541a337bf8dfd092be816e5", size = 254622, upload-time = "2026-06-22T23:09:27.523Z" }, - { url = "https://files.pythonhosted.org/packages/c8/25/ec6de51ae7493b92a1cf74d1b763121c29636759167e2a593ba4db5881e4/coverage-7.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f502e948e03e866538048bba081c075caaa62e5bda6ea5b7432e45f587eb462a", size = 255968, upload-time = "2026-06-22T23:09:29.43Z" }, - { url = "https://files.pythonhosted.org/packages/5d/05/c8bfc77823f42b4664fb25842f13b567022f6f84a4c83c8ecbb16734b7cb/coverage-7.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9973ef2463f8e6cfb61a6324126bb3e17d67a85f22f58d856e583ea2e3ca6501", size = 258284, upload-time = "2026-06-22T23:09:31.397Z" }, - { url = "https://files.pythonhosted.org/packages/f6/15/1d1b242027124a32b26ef01f82018b8c4ef34ef174aa6aeba7b1eeef48e8/coverage-7.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9be4e7d4c5ca0427889f8f9d614bd630c2be741b1de7699bca3b2b6c0e41003e", size = 252143, upload-time = "2026-06-22T23:09:33.256Z" }, - { url = "https://files.pythonhosted.org/packages/74/b6/d2a9842fd2a5d7d27f1ac851c043a734a494ad75402c5331db3da79ed691/coverage-7.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a574912f3bde4b0619f6e97d01aa590b70998859244793769eb3a6df78ee56d3", size = 253976, upload-time = "2026-06-22T23:09:35.351Z" }, - { url = "https://files.pythonhosted.org/packages/fd/30/e1600ddf7e226db5558bb5323d2186fff00f505c4b764643ec89ce5d8175/coverage-7.14.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e343fb086c9cd780b38622fea7c369acd64c1a0724312149b5d769c387a2b1f5", size = 251942, upload-time = "2026-06-22T23:09:37.313Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2c/9159de64f9dd648e324328d588a44cfab1e331eb5259ce1141afe2a92dfb/coverage-7.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3c68df8e61f1e09633fefc7538297145623957a048534368c9d212782aa5e845", size = 256220, upload-time = "2026-06-22T23:09:39.165Z" }, - { url = "https://files.pythonhosted.org/packages/91/67/b7f536cc2c124f48e91b22fbb741d2261f4e3d310faf6f76007f47566e5d/coverage-7.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3e5b550a128419373c2f6cec28a244207013ef15f5cbcff6a5ca09d1dfaaf027", size = 251756, upload-time = "2026-06-22T23:09:41.056Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ec/f3718038e2d4860c715a55428377ca7f6c75872caf98cabd982e1d76967d/coverage-7.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2bfc4dd0a912329eccc7484a7d0b2a38032b38c40663b1e1ac595f10c457954b", size = 253413, upload-time = "2026-06-22T23:09:43.306Z" }, - { url = "https://files.pythonhosted.org/packages/b8/a5/91f11efeef89b3cc9b30461128db15b0511ef813ab889a7b7ab636b3a497/coverage-7.14.3-cp314-cp314-win32.whl", hash = "sha256:0423d64c013057a06e70f070f073cec4b0cbc7d2b27f3c7007292f2ff1d52965", size = 222946, upload-time = "2026-06-22T23:09:45.261Z" }, - { url = "https://files.pythonhosted.org/packages/58/fd/98ac9f524d9ec378de831c034dbdeb544ca7ef7d2d9c9996daf232a037fd/coverage-7.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:92c22e19ce64ca3f2ad751f16f14df1468b4c231bd6af97185063a9c292a0cb3", size = 223436, upload-time = "2026-06-22T23:09:47.177Z" }, - { url = "https://files.pythonhosted.org/packages/b4/a0/7cd612d650a772a0ae80144443406bf61981c896c3d57c9e6e79fb2cdbd1/coverage-7.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:41de778bd41780586e2b04912079c73089ab5d839624e28db3bdb26de638da92", size = 222861, upload-time = "2026-06-22T23:09:49.384Z" }, - { url = "https://files.pythonhosted.org/packages/55/57/017353fab573779c0d00448e47d102edd36c792f7b6f233a4d89a7a08384/coverage-7.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8427f370ca67db4c975d2a26acfc0e5783ca0b52444dbc50278ace0f35445949", size = 221474, upload-time = "2026-06-22T23:09:51.417Z" }, - { url = "https://files.pythonhosted.org/packages/69/92/90cf1f1a5c468a9c1b7ba2716e0e205293ad9b02f5f573a6de4318b15ba1/coverage-7.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8e88f335544a47e22ae2e45b344772925ec65166555c958720d5ed971880891", size = 221738, upload-time = "2026-06-22T23:09:53.487Z" }, - { url = "https://files.pythonhosted.org/packages/a4/c0/4df964fa539f8399fd7679c09c472d73744de334686fd3f01e3a2465ce4e/coverage-7.14.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:beaab199b9e5ceaf5a225e16a9d4df136f2a1eae0a5c20de1e277c8a5225f388", size = 263101, upload-time = "2026-06-22T23:09:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/06/76/e5d33b2576ae3bf2be2058cd1cae57774b61e400f2c3c58f3783dc2ffb4a/coverage-7.14.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3ff255799f5a1676c71c1c32ec01fd043aa09d57b3d95764b24992757184784", size = 265225, upload-time = "2026-06-22T23:09:57.904Z" }, - { url = "https://files.pythonhosted.org/packages/61/d2/e52419afe391a39ba27fdefaf0737d8e34bf03faef6ab3b3006545bbd0d0/coverage-7.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:878832eaac515b62decfa76965aed558775f86bf1fc8cca76993c0c84ae31aed", size = 267643, upload-time = "2026-06-22T23:09:59.938Z" }, - { url = "https://files.pythonhosted.org/packages/58/7a/f2625d8d5006b6b20fba5afaef00b24a763fe96476ea798a3076cbc1f84e/coverage-7.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:611e62cb9386096d81b63e0a05330750268617231e7bd598e1fe77482a2c58a5", size = 268762, upload-time = "2026-06-22T23:10:01.943Z" }, - { url = "https://files.pythonhosted.org/packages/7d/bf/908024006bba57127354d74e938954b9c3cd765cc2e0412dc9c37b415cda/coverage-7.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:02c41de2a88011b893050fc9830267d927a50a215f7ad5ec17349db7090ccf26", size = 262208, upload-time = "2026-06-22T23:10:03.954Z" }, - { url = "https://files.pythonhosted.org/packages/34/a0/d4f9296441b909817442fdb26bd77a698f08272ec683a7394b00eb2e47a0/coverage-7.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:526ce9721116af23b1065089f0b75046fe521e7772ab94b641cd66b7a0421889", size = 265096, upload-time = "2026-06-22T23:10:05.936Z" }, - { url = "https://files.pythonhosted.org/packages/e8/da/4ae4f3f4e477b56a4ce1e5c48a35eff38a94b50130ce5bdc897024741cfc/coverage-7.14.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e4ed44705ca4bead6fc977a8b741f2145608289b33c8a9b42a95d0f15aedbf4d", size = 262699, upload-time = "2026-06-22T23:10:07.973Z" }, - { url = "https://files.pythonhosted.org/packages/d8/7a/6927148073ff32856d78baa77b4ddc07a9be7e90020f9db0661c4ca523a1/coverage-7.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2415902f385a23dcc4ccd26e0ba803249a169af6a930c003a4c715eeb9a5444e", size = 266433, upload-time = "2026-06-22T23:10:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/f7/a7/774f658dbe9c4c3f5daa86a87e0459ac3832e4e3cc67affe078547f727b9/coverage-7.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b75ee850fc2d7c831e883220c445b035f2224de2ba6103f1e56dbd237ab913f7", size = 261547, upload-time = "2026-06-22T23:10:12.191Z" }, - { url = "https://files.pythonhosted.org/packages/3d/14/a0c18c0376c43cbf973f43ef6ca20019c950597180e6396232f7b6a27102/coverage-7.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dc9b4e35e7c3920e925ba7f14886fd5fbe481232754624e832ddba66c7535635", size = 263859, upload-time = "2026-06-22T23:10:14.492Z" }, - { url = "https://files.pythonhosted.org/packages/10/ac/43a3d0f460af524b131a6191805bc5d18b806ab4e828fbf82e8c8c3af446/coverage-7.14.3-cp314-cp314t-win32.whl", hash = "sha256:7b27c822a8161afbe48e99f1adfb098d270ae7e0f7d7b0555ce110529bdb69cc", size = 223250, upload-time = "2026-06-22T23:10:16.758Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5f/d5e5c56b0712e96ce8f69fe7dbf229ff938b437bc50862743c8a0d2cea84/coverage-7.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:39e1dbbb6ff2c338e0196a482558a792a1de3aa64261196f5cdb3da016ad9cda", size = 224082, upload-time = "2026-06-22T23:10:19.23Z" }, - { url = "https://files.pythonhosted.org/packages/62/35/947cbd5be1d3bcbbdc43d6791de8a56c6501903311d42915ae06a82815f0/coverage-7.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:68520c90babfa2d560eca6d497921ed3a4f469623bd709733124491b2aa8ef3f", size = 223400, upload-time = "2026-06-22T23:10:21.24Z" }, - { url = "https://files.pythonhosted.org/packages/eb/e3/a0aa32bfa3a081951f60a23bc0e7b512891ef0eecda1153cf1d8ba36c6b1/coverage-7.14.3-py3-none-any.whl", hash = "sha256:fb7e18afb6e903c1a92401a2f0501ac277dca527bb9ca6fe1f691a8a0026a0e8", size = 212469, upload-time = "2026-06-22T23:10:23.405Z" }, +version = "7.15.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/c3/4f2195f512fb172aa425a8803a874b2baa9ba7f80ff7b6080998761fc701/coverage-7.15.4.tar.gz", hash = "sha256:0548198fff07ccf4faf469520bce1c2eceb1ce3e62891921138dec10907f9d00", size = 936952, upload-time = "2026-08-06T13:50:24.442Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/70/b052a519a584663a7bd052841a2debe11c8309ec49a7786340003f9c0a02/coverage-7.15.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d0be6daac4cce6b8c8dc65886bae1b082ddbca4da8e5cbb5e15166acf253e264", size = 222245, upload-time = "2026-08-06T13:46:55.253Z" }, + { url = "https://files.pythonhosted.org/packages/67/39/892fa511aba3d1c3c8f49509a0ff5c71eab9f9f88d08e1a38da395821660/coverage-7.15.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b24e078eabcd6a9caa8b0713f9bc1eeb310bcc960a29d45a3b4fcd4b16d5b11d", size = 222762, upload-time = "2026-08-06T13:46:57.848Z" }, + { url = "https://files.pythonhosted.org/packages/9f/95/b2c724ce1e64bc23cb5b1d7eeffa9548dc3d811f7a6297b2d01607f4e062/coverage-7.15.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cfe20cc8cf8821d4fe54f89106cbf06aa27f37b5bbe3535568065a81539b4150", size = 249498, upload-time = "2026-08-06T13:46:59.012Z" }, + { url = "https://files.pythonhosted.org/packages/0b/4f/b1973f67a1382af65b572a31ed692f8e490a6ad707191eab59148376832a/coverage-7.15.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:83cf06cdd687677742caff1a9134833b7a8b75f111519d2cb0e0ba1b9a851e15", size = 251328, upload-time = "2026-08-06T13:47:00.764Z" }, + { url = "https://files.pythonhosted.org/packages/a2/09/03efa6722a132abcac91b32a60b64b240dd707c189c64eee697e48992c96/coverage-7.15.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8fa4de68e2a752468ff14b4e15db7def689a71be759e826a31ccecbef69c5fd0", size = 253194, upload-time = "2026-08-06T13:47:01.976Z" }, + { url = "https://files.pythonhosted.org/packages/45/63/8299201d9c80fb65551ce99c966cab83d706ec4066ac999bef08201346de/coverage-7.15.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4dff9daa47d83120c3ec38ce921214242944a832aa04e903e50b5b7ebac8972d", size = 255106, upload-time = "2026-08-06T13:47:03.281Z" }, + { url = "https://files.pythonhosted.org/packages/ee/16/26fd8a691eb8d9a230128685f6d23309d7402cb030aa553001788c8c50fc/coverage-7.15.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a093fd37229918976f602aa07aa59e0973cde82186f220c8e197f721f5be0ce4", size = 250177, upload-time = "2026-08-06T13:47:04.713Z" }, + { url = "https://files.pythonhosted.org/packages/ad/ef/3c7556f33783a0a566e01443ca62bd8eb2cdfe22d271efdc02e08beb5654/coverage-7.15.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:317db01a2cb02552fd67e2b1cca77a4b528a2a277176c5e0bf2cecbb639d3f54", size = 251234, upload-time = "2026-08-06T13:47:06.104Z" }, + { url = "https://files.pythonhosted.org/packages/29/49/640a34043edac950738f36a3567832db5731d4cb2ed84b59cdb89c6bccbf/coverage-7.15.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8ee3838dcb656602c3b51e16aed9bfb0822f8d8d6d1c5966d32ec8c104be8e20", size = 249237, upload-time = "2026-08-06T13:47:07.467Z" }, + { url = "https://files.pythonhosted.org/packages/48/f5/e80f212669dd1be954ff844f883ef11a437ef4fd0089c6e0effc7b66b15d/coverage-7.15.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:425920379052ff1fe465268f3361d35804a241bbdd5a1b592c8cb60df4c52325", size = 253050, upload-time = "2026-08-06T13:47:08.748Z" }, + { url = "https://files.pythonhosted.org/packages/c7/e9/e5da0fe39f7fde1bca9edc09c60921bb5fdba4cec7db5bbad41ddfd8c230/coverage-7.15.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:69bb2400abef928e365ea7d4d9925169ada78ed2295546780002d4b65de3df88", size = 249508, upload-time = "2026-08-06T13:47:10.072Z" }, + { url = "https://files.pythonhosted.org/packages/7d/38/41bf25774a0c8bba6b467f917cb1c9a0a2605e02dc93aad489fc7050ed59/coverage-7.15.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:81661f82d302484e3119e7c80c519c02fa9bcc2a6b339baf67d67bc89c580f04", size = 250110, upload-time = "2026-08-06T13:47:11.35Z" }, + { url = "https://files.pythonhosted.org/packages/89/6e/26f2e54b79acc29d179ee4272922625aedb69198c4eb61f7ff4f098f3c78/coverage-7.15.4-cp310-cp310-win32.whl", hash = "sha256:cb476b2e828ecb71cb6b6a928d23fd20a7ddb501188022dae1c37499149cc338", size = 224294, upload-time = "2026-08-06T13:47:12.753Z" }, + { url = "https://files.pythonhosted.org/packages/7b/06/9a318fc3ae040d4d6cb2d86101c6aa963fab20899a5c58666adf52cde0ca/coverage-7.15.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fc2130bf37df31852a8384f12601563a45a0024bccc6624f38355cba7a8d360", size = 224919, upload-time = "2026-08-06T13:47:14.17Z" }, + { url = "https://files.pythonhosted.org/packages/2a/66/edcec7d7a0b524aa8923e22925fde6fe50ce005a113dca13ae1581455c4c/coverage-7.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbac5abad70df71019988f83f26ac7092ff2642975def4429e98dc7585ef3490", size = 222367, upload-time = "2026-08-06T13:47:15.578Z" }, + { url = "https://files.pythonhosted.org/packages/e6/c6/ab8de429e2e8548faf58ec7e1674a4ce00414b4113942d3fe87109cf0f68/coverage-7.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:357a173465c7ce028d07a95cc2b63b5bf59f50ecdd5ad75c5cbb78ada984048e", size = 222874, upload-time = "2026-08-06T13:47:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/be/c4/3b7b49587e8a6b9af79b3eb468d443d6042b6d65b47aa26586846a0d6566/coverage-7.15.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:21b803935e2efc3acebe9697197a294fccf5dc4e5382bd6369542ff7a7d2a1d7", size = 253287, upload-time = "2026-08-06T13:47:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/fb/65/ec03b743a2a229c72cc1eff3e57be9d3564e9c6b4d5aba2d70744a3fc0d8/coverage-7.15.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7a2b580774a4786c1053157c0165e04476e03ff293993d7c148eee784a94bae6", size = 255199, upload-time = "2026-08-06T13:47:19.765Z" }, + { url = "https://files.pythonhosted.org/packages/41/4b/5163729e4b6582d61975cfd3ccab45b4ec53e21cf156d9941cb025188468/coverage-7.15.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9464451c4efffe8d47ace5a540b10b0dc10e879066290f8600872b7f54a419d", size = 257308, upload-time = "2026-08-06T13:47:21.206Z" }, + { url = "https://files.pythonhosted.org/packages/86/08/2167a0f08fb87d702fa423a48578a32865464b7c9e1db3911ad7812ab414/coverage-7.15.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de602f34123c2f4af1c1869c6dbbbd60da6d5983bf01937367295d135cccbfce", size = 259268, upload-time = "2026-08-06T13:47:22.503Z" }, + { url = "https://files.pythonhosted.org/packages/1e/e5/68eebae3053dbd48508edea559c21b23fbdf3460784f91370c83a86a6acd/coverage-7.15.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6879ded16a27f3eeca19b900c147e81616e7054db451471a611b2755ee5249f7", size = 253392, upload-time = "2026-08-06T13:47:23.88Z" }, + { url = "https://files.pythonhosted.org/packages/1a/46/fd4ced40a2b691c774e515c9b69500bfa64c7960b67fcee4b2f6fad97fc3/coverage-7.15.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:986be58c3ab54aae8d3496a6225eea74f760fdbe739b38bd442c7e8d133aa53b", size = 255001, upload-time = "2026-08-06T13:47:25.469Z" }, + { url = "https://files.pythonhosted.org/packages/53/25/ae2e5fa710bb6957a9aadeb9e3598d3b3e4af6587ce857ad42e8639a3f30/coverage-7.15.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c6103639613fe6c1e989082948419bc77a2d26b6c825c99d7fad25f7d3d87afc", size = 253061, upload-time = "2026-08-06T13:47:26.845Z" }, + { url = "https://files.pythonhosted.org/packages/d7/31/67ddc0365db2c6e93ac8580bc4bbc50f65273262f973f63ebcdbc15c0495/coverage-7.15.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3af93dddb5659276c63bc16ac6466ac2033a70ca816097bbc06345b8ccdf571", size = 256831, upload-time = "2026-08-06T13:47:28.217Z" }, + { url = "https://files.pythonhosted.org/packages/f6/78/82b8fd18f57fb13f12d98fe874995bb2c4f9f17be8aff762c426323fdb96/coverage-7.15.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b10075e5421d04265766a6d1dac809bbeb8a946fbb23c8f82c227409b2190719", size = 252781, upload-time = "2026-08-06T13:47:29.712Z" }, + { url = "https://files.pythonhosted.org/packages/0a/eb/6c74ef4dd12b252e573c49bdef9e2ac265bf3dbb79b8d7feb3266e084e9e/coverage-7.15.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a67a9f78b2942d87ba8ce3059c642164d2aedd65337377fb52fe9803656bc5c7", size = 253692, upload-time = "2026-08-06T13:47:31.192Z" }, + { url = "https://files.pythonhosted.org/packages/5a/66/eb9aed1c3fd2d36ee00eb173f434b14fa607fc056739c9a89ff4244010ea/coverage-7.15.4-cp311-cp311-win32.whl", hash = "sha256:69484d1aca26e322e1c3ce03f09341e84524ababad2d7202161738d83cc9f82e", size = 224461, upload-time = "2026-08-06T13:47:32.572Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6d/81fa4161dfb3ed9d74e40d58647eff83a56b7612e78352581280fce2f477/coverage-7.15.4-cp311-cp311-win_amd64.whl", hash = "sha256:63fd6fcd1dd6e158f7eb78606e72933b3f6d01e7b747f99c6c12d764307a0fdc", size = 224937, upload-time = "2026-08-06T13:47:34.205Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c1/d8dacf683c6cad3cf85ce68fd3774a6774ec402128822fdfaed920f11e6a/coverage-7.15.4-cp311-cp311-win_arm64.whl", hash = "sha256:ea82116c9893fa89e929b7f197ee5a1950a76e91cc5c85ba503fc02379d04890", size = 224479, upload-time = "2026-08-06T13:47:36.118Z" }, + { url = "https://files.pythonhosted.org/packages/1d/48/bc8d4ba7b37551a767bd863f15b3f80182b271c2f55975356f5f7dbe94c2/coverage-7.15.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4fedd1f7f428f9fe83b1ead5e7cc87a43427be31aadafbac3ac0636dc7abb22", size = 222543, upload-time = "2026-08-06T13:47:37.562Z" }, + { url = "https://files.pythonhosted.org/packages/20/dd/88d6f83f1fffc974a3691a34a97951c5b12df7512a6782c5963883cbc058/coverage-7.15.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37e2f0cdf58e2e1fed4e4d5a8f8786ae2f7eb80b478016876667dc4a01d60a97", size = 222905, upload-time = "2026-08-06T13:47:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/bd/5c/54ee0d4748585bb0acab9891cd8d92f2d3593165b4e59fc9de113bfb3140/coverage-7.15.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb55d0e70bb15f2e81477613627286581414693d74ac7963c93a790dd453ca9d", size = 254407, upload-time = "2026-08-06T13:47:40.488Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3f/f0642a372f494bd0d7dad3b497083b910194a5f1c88be2c94fef707c3b59/coverage-7.15.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:899b9da30f3c6c336566e3707495bb23e8302d39d862f01fa78c48b99b9437e2", size = 257145, upload-time = "2026-08-06T13:47:41.931Z" }, + { url = "https://files.pythonhosted.org/packages/71/17/8b46d0ed68251016002ec972c8fc0119961a765d0984cafb8bf317c43758/coverage-7.15.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d15715e8c46552827e5e4f30a35575a2dbcad14454cf3284c54483946bd16931", size = 258257, upload-time = "2026-08-06T13:47:43.527Z" }, + { url = "https://files.pythonhosted.org/packages/30/b8/8498a0e72d0adbe15477dd07463d2b3bb2c9f6a4815e8589e50939e2c3ae/coverage-7.15.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:002a438859f7b430bc99afeaf01a6d187dad1d0dc907b64cdeffc632a5db8fd8", size = 260517, upload-time = "2026-08-06T13:47:45.121Z" }, + { url = "https://files.pythonhosted.org/packages/41/e1/7dce19c3bdb1e3dd63e769508216500edad81bd5f69a26d724e32aceaf78/coverage-7.15.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e4193a04b518f7968f3099755f5509ee7cccc6dc2b92a6b14841934d22e222c9", size = 254785, upload-time = "2026-08-06T13:47:46.541Z" }, + { url = "https://files.pythonhosted.org/packages/dd/b1/e1494703c675a2561723cd9b89f45c9168782c31280c611b1f767851e57c/coverage-7.15.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e98dcc55d572b38e69d117da7e8e8efb8500f1f5eaf81ecd460a63220790b839", size = 256176, upload-time = "2026-08-06T13:47:48.155Z" }, + { url = "https://files.pythonhosted.org/packages/73/76/a5629d270fb638a43a4b10466f51e2f49d532c1aa4da2913cbbb150bbe0a/coverage-7.15.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:af6c538498ce66c10d3fd541c2a8d5b03da5850355add34e6cba564210cb9e72", size = 254321, upload-time = "2026-08-06T13:47:49.757Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4f/9c44447218435d5766b911534f9d798144a5560f85e9a54ebe5f3f5d19f9/coverage-7.15.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1d10025d96ea89fc2f73714dbc4cbd433fe012c1ac9e23f895d7728b238b6e52", size = 258390, upload-time = "2026-08-06T13:47:51.248Z" }, + { url = "https://files.pythonhosted.org/packages/de/36/c1e127616fb3fa18a9ff71e76c417f2fd7424332a4870015ac224ef4c039/coverage-7.15.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d802e1947603162ded419bff83ac7489820355d2b856dfb09206574e3a37ac0c", size = 253894, upload-time = "2026-08-06T13:47:52.816Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b9/fdb92c8ae7a8bb9b850cc253b7b3b9c8526f68130002048b5671cd510d09/coverage-7.15.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2de40895718f91951b86712b4c5b694acaf9a0a49be13874896f599a1eed3f4", size = 255763, upload-time = "2026-08-06T13:47:54.296Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c0/a7d51b2587c7bdb76e71b0896d2565bf7d60436b5122fc83e511adb1f7cd/coverage-7.15.4-cp312-cp312-win32.whl", hash = "sha256:5c3431b2161279b7db5c2a1aa58ae02e5cb8c3c42d93a5094be3f5537bd5b11b", size = 224597, upload-time = "2026-08-06T13:47:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/49/b9/5c5f80cc55f5acaaca6dee677626bfcec8c87204a7809b438b08e84f4571/coverage-7.15.4-cp312-cp312-win_amd64.whl", hash = "sha256:6befeab5fb2b51c958ca4ac6c5d141a1e8240f4f76e46350f1911963deda49cd", size = 225135, upload-time = "2026-08-06T13:47:57.52Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/2a4561f89ff6bf7c925c287d0f2cce8bdf139c3a33735c87e3203401cf94/coverage-7.15.4-cp312-cp312-win_arm64.whl", hash = "sha256:67bc345491ab55b837277d76f5775d057e8c7f1ac44d890d8c2c82adde258c6f", size = 224515, upload-time = "2026-08-06T13:47:58.977Z" }, + { url = "https://files.pythonhosted.org/packages/f1/84/651a9310859673aaa3b3203f1aa1641ca60fcf2494683e1c9474c7172780/coverage-7.15.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c705b28feb2775dc82a25f1d473a370bc37ff93f5177f4e29ce2425f560f6921", size = 222565, upload-time = "2026-08-06T13:48:00.796Z" }, + { url = "https://files.pythonhosted.org/packages/82/f9/4dcf700137e8af550670f4d74d1b63828ce93e1e2b05e5f10710eb2ea987/coverage-7.15.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ff205ab5e3ecc670f6a4dd19d9cbf12ede53dd41cfc1e15716ec961ea6d314e", size = 222936, upload-time = "2026-08-06T13:48:02.391Z" }, + { url = "https://files.pythonhosted.org/packages/07/4a/612ff1e780b3fbfd637486f542f84adc5503873d8b5d279dec1ffeef9414/coverage-7.15.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5172326e861a38b48b48befca15e0f477a26b283337a33a739c8fed229934e36", size = 253926, upload-time = "2026-08-06T13:48:04.382Z" }, + { url = "https://files.pythonhosted.org/packages/b0/04/d1cff1c2ead4708a6a79c01d3736b6a25bd38a36678398f72a8dd33dfad9/coverage-7.15.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:12b59c90084e3234fb11184886bf4a40f4f16a8c8f867be2e087b81f8e8868d4", size = 256523, upload-time = "2026-08-06T13:48:05.996Z" }, + { url = "https://files.pythonhosted.org/packages/b9/80/d34e13fb4b293cbdb9665838cf5522077b8ad14ef947550631a4bced36a5/coverage-7.15.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349062d66f00b40fa2c1c222438bad25fabf755631b5d82937fe985c8008615c", size = 257759, upload-time = "2026-08-06T13:48:08.036Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e7/2c5fe7636fdb0732fe0f09f308a5b066864078b7fc61f6678e8478554f2e/coverage-7.15.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4256ced708e598e05209bc1a8ab4074e04a51dba4c62fb45926a229af675ace7", size = 259890, upload-time = "2026-08-06T13:48:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/92/28/9689f0858dfff59c2ea688938ab9fa2925631235df67126a42b6c5c70ae1/coverage-7.15.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d80f974b20782d9612c8b4c9beeca867074c7cf4079d1419843fa25a26428b25", size = 254121, upload-time = "2026-08-06T13:48:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e2/785077c230c157243eb5aa9a26c3be260ecd02001bead54a3cada3df8e03/coverage-7.15.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e179f19bfe1d31f8eeeaa12990194d761c4f62f0759661000bca6cd8729f40b", size = 255891, upload-time = "2026-08-06T13:48:13.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/90/e20371b17b40f912f21305c2db2f30efa3de306f7320fc916804872c85a4/coverage-7.15.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8bc16bb47b7679670eceff71d78bfb7d6e5b143f6c2cd117487ec7c75e0d4b78", size = 253859, upload-time = "2026-08-06T13:48:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/05/49/25371987ee459a5f67c0427fb75c74f9358e65f2c71fe75bf41c1b6c5fcb/coverage-7.15.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd685005cd2c4200adfc14cf39a603b9320efab3f18a8f7f156d20c9cc3345f", size = 258011, upload-time = "2026-08-06T13:48:16.464Z" }, + { url = "https://files.pythonhosted.org/packages/30/6e/32e67467f6154bf4f1c4f63b05acc5097cba4237d45bbeeea446b52e8ac1/coverage-7.15.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:337399ad2c93b3acd2a937627dae8b3e86b66707cd3d3e856347999aadf1ef8d", size = 253676, upload-time = "2026-08-06T13:48:18.493Z" }, + { url = "https://files.pythonhosted.org/packages/03/c1/8b24192e89286399765155251f99ee9f070a9d637109018ac23d99b99f6f/coverage-7.15.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:96e257121228ec5cd2bb919276e94ac11074471bc37d68dbae0e8308cce15fff", size = 255453, upload-time = "2026-08-06T13:48:20.057Z" }, + { url = "https://files.pythonhosted.org/packages/16/6f/8b41ebdf67c87854e17c035336a90f1cfbad0c14c2a584301be6ff148718/coverage-7.15.4-cp313-cp313-win32.whl", hash = "sha256:c65a9e0dfc6143491879da4e13b5e30f8be192055de508d737fb14601edbd22c", size = 224605, upload-time = "2026-08-06T13:48:21.655Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e2/2946c7f0b42b152ecb21ff1bdad72e3d301e790c0c487e4a86e8c9f69347/coverage-7.15.4-cp313-cp313-win_amd64.whl", hash = "sha256:2ff8f5e9b8f7a94f0c11c45631eee103dbcb7d63274edd12c56efe1be690b3b4", size = 225148, upload-time = "2026-08-06T13:48:23.376Z" }, + { url = "https://files.pythonhosted.org/packages/9e/83/3f4a69957f48ae7a0aba76c34743f88963d607b19e03f3f8e66f91cae0f9/coverage-7.15.4-cp313-cp313-win_arm64.whl", hash = "sha256:6e0a8a5083b096487d6cfced94cdd514d8f5db6f113610fb36c0620edb1028cf", size = 224536, upload-time = "2026-08-06T13:48:25.117Z" }, + { url = "https://files.pythonhosted.org/packages/ea/ac/748cf29eeb2d6be34a3176ce26a4f49e38085ee08e8935f05f6f26ed7e0f/coverage-7.15.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:770e9325ab5ea6d56f77e59b29ecfe0ac20b57a82a601876f90494a4dda0386f", size = 222608, upload-time = "2026-08-06T13:48:26.806Z" }, + { url = "https://files.pythonhosted.org/packages/0b/02/1abbf5c984677b0aa439cdacaccbf38d248939d8ef8fe1cc7a50d73edb77/coverage-7.15.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d12b33a3a50a1676b7784dc8d00a0c6d66a9f2add4b85a041c19b6a7e53ef23c", size = 222940, upload-time = "2026-08-06T13:48:28.432Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e1/ff8f9f53d9fcf586125b55d0b1f04ec1c14955fee41e83d5814bee141bb5/coverage-7.15.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5669c8378ebde86f5def7a25d29586631b58acc27ffde04399f678f3dfc6e082", size = 253985, upload-time = "2026-08-06T13:48:29.995Z" }, + { url = "https://files.pythonhosted.org/packages/a1/26/595759762e514e81be1d7d01ed03444303bcd152226a6529998d253f9201/coverage-7.15.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff97a14362eef486483ed44042ca2027ea257df6ff768e62358ee0c9776925ac", size = 256492, upload-time = "2026-08-06T13:48:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/24/68/b79aabac54d482be23b5fcdd4f4662bff24a78edc4ee29201726929936d5/coverage-7.15.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a325e815318638aed1655d9c06e6d7c2d3d46c09231ce988070428a8762d734", size = 257837, upload-time = "2026-08-06T13:48:33.186Z" }, + { url = "https://files.pythonhosted.org/packages/09/0f/bf7f297885a5bf6fd71e5782404e0ff059ca09e8711ceb3a08544abde45a/coverage-7.15.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:474223409d88eb20d2d6a0d37ea60e8647a65a90cc008dc1f0410af5f64f1e0d", size = 260152, upload-time = "2026-08-06T13:48:34.75Z" }, + { url = "https://files.pythonhosted.org/packages/fd/f1/296744e854ff8368542343457414380465e9ceefb9192342feb9d3bc461d/coverage-7.15.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f2f62ae3cd189dd2e13aece758c57b3eecbd27be070dbd4cbd10936049e5dbf", size = 253978, upload-time = "2026-08-06T13:48:36.434Z" }, + { url = "https://files.pythonhosted.org/packages/55/b0/bbdb2e9057493e66220a2e149ca2d301ba0e3a58a83bd6b90de9826d16f3/coverage-7.15.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:39ece820e29e0a2ba34b3ecb3be83c27e997eed8926f2ba6fe7ce7a0bda5843b", size = 255846, upload-time = "2026-08-06T13:48:38.317Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/38015b2b6d21258713bd17e76b59d033b191efb5703589cffd037dfbca20/coverage-7.15.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f21b56dcace11dfe013014201f577dcd592b2a9b72182d930361b47cf6f73f25", size = 253808, upload-time = "2026-08-06T13:48:39.993Z" }, + { url = "https://files.pythonhosted.org/packages/0b/64/0d515c1e60ee6fbfd1a0e79c07cd87d388a233b7adc37758735677203808/coverage-7.15.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:93a3a0b662abcc10c73a47cbc72cd60f63618d6989fb2d1286e50eacd974f303", size = 258081, upload-time = "2026-08-06T13:48:41.971Z" }, + { url = "https://files.pythonhosted.org/packages/91/71/04d9e7a3642146c6351338aef4ef85ab11dbbb54744c13245caba1aad1c0/coverage-7.15.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:141fae2cabf5569b782c10afc4c850ce10f618c13f8db54765cba99cc839da1f", size = 253624, upload-time = "2026-08-06T13:48:43.731Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a7/6c28b74c81ebff66987b0e2522ba5cffa3e90b0c33cb6a2eb264d4ee8cf1/coverage-7.15.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:81294c7e6ab30c5f74c0353b11b2fd6320e72d9bee6ac73b357caa8b916323a5", size = 255280, upload-time = "2026-08-06T13:48:45.58Z" }, + { url = "https://files.pythonhosted.org/packages/52/af/bc19996a7014b98d7bbb0f0939453c67074af65784a3aa16a789a07381fa/coverage-7.15.4-cp314-cp314-win32.whl", hash = "sha256:7bbd7d6418e0dab31a206af5203bd43ae36edb8e7fba1940b055d3e9249290d7", size = 224768, upload-time = "2026-08-06T13:48:47.525Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/219484e476d6e101ba0a444852579e05f5b75c37c611a42ed1190f73ef62/coverage-7.15.4-cp314-cp314-win_amd64.whl", hash = "sha256:f0204ed122758782970526057093f448051a39db9d810d4e344bb87a3546f425", size = 225259, upload-time = "2026-08-06T13:48:49.513Z" }, + { url = "https://files.pythonhosted.org/packages/b7/66/fa77daf4e383e5f776dac62c2409b6af81910ae6fe326bd5170dba74cc63/coverage-7.15.4-cp314-cp314-win_arm64.whl", hash = "sha256:9e71e7bc71c686a123347ae47a0de33a175e797a85bb57b791492adf4eec8ed8", size = 224684, upload-time = "2026-08-06T13:48:51.235Z" }, + { url = "https://files.pythonhosted.org/packages/58/5b/f03bf0ce362bbf3f785fa5219620d00778d4ac6fc9e407734828e9c672f6/coverage-7.15.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7c922735321eef3f87c280a3d39afff6b646723a2880b862cda4ac7a093b8aa8", size = 223338, upload-time = "2026-08-06T13:48:52.896Z" }, + { url = "https://files.pythonhosted.org/packages/0f/76/e77d0ae22501831cc9f92193e8a957a5caa1dd177f90a6d1d9b106242d92/coverage-7.15.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f41c17c4668a655ce96d090d8d5ffdc24ef64b5a02f9753884d08483e8a4a41a", size = 223609, upload-time = "2026-08-06T13:48:54.688Z" }, + { url = "https://files.pythonhosted.org/packages/82/1a/b1f089da8d38ac612fa2dd6dc7f4a1a7657d12f3e261d2996edd3a838d0b/coverage-7.15.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:46822e9b6ff1c6a72b518c162c44a8f45a61a1d609c51084bf5b16c023c5037b", size = 264970, upload-time = "2026-08-06T13:48:56.403Z" }, + { url = "https://files.pythonhosted.org/packages/bf/31/e66d98d6e9c7fcc88470f1e234eaf6b1950dc0dfbf797f7282c1c861da24/coverage-7.15.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d6f4955b73b5445271379a59e3792b0d978f42d4a01e0cf7a67d9c33a3bb0a5", size = 267088, upload-time = "2026-08-06T13:48:58.41Z" }, + { url = "https://files.pythonhosted.org/packages/59/a1/ae94eb2c541add426378408379f233591e069040b1e2cdb33df9498a0682/coverage-7.15.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3fc9e047706fb4a9abb54f719d3aa643e80e5bb3818182c40aee01ac0f0247ba", size = 269508, upload-time = "2026-08-06T13:49:00.42Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c7/88a10694a1c6a213569766aba9f25847b28155d4ac731b13226db216356d/coverage-7.15.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05e491d4f3165d62d4f5c8fd48dfeabf2ae8f42cbbd484319af33ea851b78982", size = 270629, upload-time = "2026-08-06T13:49:02.234Z" }, + { url = "https://files.pythonhosted.org/packages/b3/34/d8b8232e5e55169933b59aabcef2fedfa4b9d8897361bb80fcbda146505f/coverage-7.15.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:226c66e80ec0598d3b9b4874123df167ccca342aca8714f77cac6829688ee09c", size = 264043, upload-time = "2026-08-06T13:49:04.102Z" }, + { url = "https://files.pythonhosted.org/packages/7e/35/58b009dbf8c471c7224716478b9fed4a7e1af15320e1ed41660978504663/coverage-7.15.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac41cc14bebda0dbfb0628036b7f75706935c95bcc07fefe9a0f93614aa60a57", size = 266963, upload-time = "2026-08-06T13:49:05.821Z" }, + { url = "https://files.pythonhosted.org/packages/62/aa/57fbda1b42c892968273c56b6ee9dc0f1310850859230a507bc7873b1f65/coverage-7.15.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8af623e5cd92080acddd02b38f2f406a2c3a0893c38950b211890361448fbf26", size = 264569, upload-time = "2026-08-06T13:49:07.706Z" }, + { url = "https://files.pythonhosted.org/packages/98/8a/360e6e7f24d477b7e889703af0afa878d15b6d4d8d2a822b2835c169a879/coverage-7.15.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07545711d4f0f32852a18f18ad11f76f0109909d09e78b9008b4cfc67e829429", size = 268299, upload-time = "2026-08-06T13:49:09.587Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/6f701261aee21b6b5fa8f7872229406dc917e125069448292223bf213606/coverage-7.15.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a0865421cfdc53654b342d515e5a233187590882d20b95752150e53f65460017", size = 263413, upload-time = "2026-08-06T13:49:11.604Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0f/6f04036edc260ed425af83e834f627fad48941ce97b50bfe6edd8b6fa623/coverage-7.15.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:460115e32ee40566476db5048f9bec1e842c127ad8e6f8be745aad3ac9cbc839", size = 265725, upload-time = "2026-08-06T13:49:13.38Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ce/d19b5d4d5c49a7bfb925fd74310fee7d28bc99520ac3367ccbc54e662518/coverage-7.15.4-cp314-cp314t-win32.whl", hash = "sha256:cbde877ef9dd7baf272b9bfef2b8a25edd45d9170fc326951dd20eb480335e85", size = 225079, upload-time = "2026-08-06T13:49:15.265Z" }, + { url = "https://files.pythonhosted.org/packages/26/bb/7aa1b3b173faee0679037ca950bbbe1247273656697994d8d13f80f8d4b4/coverage-7.15.4-cp314-cp314t-win_amd64.whl", hash = "sha256:3da9e92d1c551fd7563833e9ade686efb0c4b7363ab7681a94283958c950bf5e", size = 225911, upload-time = "2026-08-06T13:49:17.279Z" }, + { url = "https://files.pythonhosted.org/packages/81/1c/4ea9e47426d80038d9222db3c4534cb6021a74b237d3ff97ffd33b6600dd/coverage-7.15.4-cp314-cp314t-win_arm64.whl", hash = "sha256:3a54f5a0d85050c73a38f6793090ee83974531e67fe5e57a1da9bee11398aa5e", size = 225219, upload-time = "2026-08-06T13:49:19.293Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c4/dc5d2ac8f9142e7ec7de66e7bf0591db29d78955a040bd915870d9c0e657/coverage-7.15.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2c9872e4d9dc5d3cf616bf4b382f5a00359305a5be666a3dd0b5cdb4e49597f9", size = 222604, upload-time = "2026-08-06T13:49:21.279Z" }, + { url = "https://files.pythonhosted.org/packages/70/39/33e63df81fe2ee100897451841c821467635923e58e37c6bd4b46dd8106c/coverage-7.15.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:e101dbb4b9b72f0cddd8cdc8c9c5b47f456766f5e0ac82dbfb75e5c55409b78a", size = 222944, upload-time = "2026-08-06T13:49:23.187Z" }, + { url = "https://files.pythonhosted.org/packages/99/1f/ef3ffb5557febc75a0d97aa459d0266d7d741110265121cc6d8539343d44/coverage-7.15.4-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7d1abebdb047729e852b9c77a00497dfbeb11eb3a117e037d7dbc3ac8e5f5c54", size = 254050, upload-time = "2026-08-06T13:49:25.008Z" }, + { url = "https://files.pythonhosted.org/packages/6f/f5/1f0f6f77698c3601ca0ae7431e34b24c62ca2f06fecb23b73ed1f651d2be/coverage-7.15.4-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d28a4a899354d0ea6214cc59b4fa19eefbce1b9ff1688ab579acf49e894bd3fb", size = 256967, upload-time = "2026-08-06T13:49:26.896Z" }, + { url = "https://files.pythonhosted.org/packages/03/7a/2ed9bed79925f4367c83c77f66a89e5ca7229c288d2d19ad5f36d1ca0070/coverage-7.15.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffb3c2aacea411cc7e1d27712490c11108e2de1d39019ae32915493a59a8b9ed", size = 258587, upload-time = "2026-08-06T13:49:28.692Z" }, + { url = "https://files.pythonhosted.org/packages/45/8c/fa34044f71b7cc4ecb6da9c2408770959b0591fa9b5fb6fb6bca38f94298/coverage-7.15.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9447978a92f405d301123cfd39ff49895490efb769a758fe2734c7f631bf8ce", size = 260785, upload-time = "2026-08-06T13:49:30.472Z" }, + { url = "https://files.pythonhosted.org/packages/4f/54/d5727ce36b4524a7394ab9f5f1df378e1f23affcdab01037dc8655185cc7/coverage-7.15.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:050467a7983b8e2fe7dd41a78bb30c3e7f8c0b8cafda14b1c46f8b5e3cf2dd3c", size = 254545, upload-time = "2026-08-06T13:49:32.271Z" }, + { url = "https://files.pythonhosted.org/packages/dc/e6/6e3783e576719590194bdffb6dd6d85490801785b7c331e35a245d8cb8b5/coverage-7.15.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d003b7a5708ddad5c206c79607a6b92abb6fc13c57d99d8a4468cc03a2941ced", size = 256682, upload-time = "2026-08-06T13:49:34.089Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f2/bacdbde18b69ed2de424fcf64d9fb0a4913753d4f0eca8bae9daad69f4bd/coverage-7.15.4-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c38efe30fd74e5c19e9433f11fb1f5dc9c6522770971b7c6145bbaa413dc8800", size = 254560, upload-time = "2026-08-06T13:49:36.052Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a3/1fb927196e3477c1b48831169ab58ba08f451ba87ae311ff1de68b26a616/coverage-7.15.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:1f4f826d70f772ab8b0c052329580d7fe8b8abd191e4ce0c8f81aec6614665d3", size = 258792, upload-time = "2026-08-06T13:49:38.01Z" }, + { url = "https://files.pythonhosted.org/packages/41/58/30d4c149c69053de0edfe325614c1d28d508f62b1783e0e4a234d2e49136/coverage-7.15.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4a4bf917c9953f57c957be31c1cd504e3bd2f34d4a352b9d391a3025336f6768", size = 253968, upload-time = "2026-08-06T13:49:39.934Z" }, + { url = "https://files.pythonhosted.org/packages/89/e4/77f639371b918aad30dda4051f95404b43578f7f2e2f87ba73e02ed1ff37/coverage-7.15.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1c9bf40ebef178a45192c75c4964760bb261b0e6ad725da5fc4c93f674f19753", size = 255893, upload-time = "2026-08-06T13:49:41.825Z" }, + { url = "https://files.pythonhosted.org/packages/5c/62/13be29b3ddab35f14c87967a4820a05106d2a3eccb4fa4ff550bf30b75e0/coverage-7.15.4-cp315-cp315-win32.whl", hash = "sha256:43619d04c3671792d2c4706ae8bf45e265dc87bbd4078189ef8b847ea1e74be2", size = 224768, upload-time = "2026-08-06T13:49:44.08Z" }, + { url = "https://files.pythonhosted.org/packages/a1/70/af0c6be0f964af6954f6b74bc109b0dbca02824696d2520fb17fe1ab06e3/coverage-7.15.4-cp315-cp315-win_amd64.whl", hash = "sha256:be619439dbcd31a2eab10b32de9fff62c26ed4bab69dc32b8363fdaaa0882809", size = 225242, upload-time = "2026-08-06T13:49:45.899Z" }, + { url = "https://files.pythonhosted.org/packages/4f/2d/f3bd3aab899fc9efc18b53133ee68f5f98574ef480649b23e12962226387/coverage-7.15.4-cp315-cp315-win_arm64.whl", hash = "sha256:def597967dafc2e8d97c9097ea453c464e0bb8ed38f193a43070f10dc623bb6d", size = 224674, upload-time = "2026-08-06T13:49:48.322Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ca/f69251cd63eabc6438321aea22148754cce758a26bde07dd490e3fe7cfc5/coverage-7.15.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c7dbc748ac8a1e3e59a2b28bea47675e6e778081dbbf081bde0d75def2fcbe1d", size = 223333, upload-time = "2026-08-06T13:49:50.293Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a7/037b53b2885b0d8447064432491a4d5a1014cd9f97a594d53acd0c04541a/coverage-7.15.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:2413074a5ecbb61a01a7888fc72db0ca324d13588c5b38bc0dd8564cdcdfea26", size = 223630, upload-time = "2026-08-06T13:49:52.637Z" }, + { url = "https://files.pythonhosted.org/packages/80/4f/152b8a4779ae90da11bb24f7467df8a59f0be48a5c52acb856325ca48289/coverage-7.15.4-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4e6f6f632b7b2f714bf7a1346e8f97b650ee71f3c298aaad42a2ab60f0f07645", size = 264489, upload-time = "2026-08-06T13:49:54.52Z" }, + { url = "https://files.pythonhosted.org/packages/10/2d/84b4b9e0e1dd6528a51920ff7031f35b789382e467a28ec6a5a578cb8812/coverage-7.15.4-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8df457da2249d3c75ca2e5e835d59c725abfe92d27fdff6cd99eed85b51d5e9a", size = 267567, upload-time = "2026-08-06T13:49:56.721Z" }, + { url = "https://files.pythonhosted.org/packages/53/fc/ba01cc25299f9f8a2c8b02d3b28c53f3543d9fbfbe4e74fa2760b48f163e/coverage-7.15.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:050f66a08805acb5b8a23c6d4a517b1ecf82c08e81ed0e4bd727df065e5c6624", size = 270123, upload-time = "2026-08-06T13:49:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d0/db2647cbf40b14f8c308f94ff7bf89c06d564e59f396906edf50086ec788/coverage-7.15.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1587fb771d1ccceef708fdde1e5af8c7ed24b486b61d13a321acb7d8145390aa", size = 271107, upload-time = "2026-08-06T13:50:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4d2d17924552c458bb4f77dd631f0e3bc92fbbdf2d2d916cd4b33bbfd5b1/coverage-7.15.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8b4f1c3a69ca580f3fbd6b2046915f536d7f586874f25c1bb23add2a3c88d50f", size = 264955, upload-time = "2026-08-06T13:50:03.023Z" }, + { url = "https://files.pythonhosted.org/packages/ee/de/dc010c7a3691f396d93bbc26bfcafa1c2a3a351cd520470f15faf5795bd5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:ffb58d7eff5b7f6ecc6fa21d6288ab7f968a212cb67d682c269c09b9eba3b66f", size = 267949, upload-time = "2026-08-06T13:50:05.557Z" }, + { url = "https://files.pythonhosted.org/packages/78/ea/dc96a11375e83c045c2f7c61fb6918277cfe9401db7c0f7b1d111a84b2e5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:d9df165544774574ee004b953023d1bebada1894a80b1052a43d798b0f676e67", size = 264421, upload-time = "2026-08-06T13:50:07.612Z" }, + { url = "https://files.pythonhosted.org/packages/c8/86/b77131a0f9503ce461cd577076147d7a9040f0c5dda772686f729e2cc9cb/coverage-7.15.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:f9de0a24a4079b53e523b5c5e2c5945ec251ab486652659955187cf255a259bc", size = 269121, upload-time = "2026-08-06T13:50:09.58Z" }, + { url = "https://files.pythonhosted.org/packages/24/24/944bc35007862955e7ebf05754e645419dcf5d7526c52735cfa2715e8ebf/coverage-7.15.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:150089274bdc9f940628552cb92844e0223c987f1902ab8efe9f45a2ec758d88", size = 264565, upload-time = "2026-08-06T13:50:11.722Z" }, + { url = "https://files.pythonhosted.org/packages/c7/cc/a3bb9f93e7e740659163e2ea584f8196ddcd2c456a5dbe15f6c50105fec1/coverage-7.15.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:a58a94fed5da6997d258e8f7668c1e195fbd04a691d781b7558f1e468f9e68bc", size = 266522, upload-time = "2026-08-06T13:50:13.786Z" }, + { url = "https://files.pythonhosted.org/packages/49/dd/e0e40f3560d878d888c580698ff5ad1179f5e1c3ac949684ef66b41a3817/coverage-7.15.4-cp315-cp315t-win32.whl", hash = "sha256:ebd5a6d8466ff30836572f3ba2cae8a5e8f85029b1c6d5e2ed338dc472a5166a", size = 225068, upload-time = "2026-08-06T13:50:15.825Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7e/37732ea80eebc30e976e4cdab15c190bc42d96959a42e38ddf6f8c60468f/coverage-7.15.4-cp315-cp315t-win_amd64.whl", hash = "sha256:288bde2a2d7ab6b6c2d7252fcde8b524387f2d970bdba9658fc6f8bbcaef0f9b", size = 225895, upload-time = "2026-08-06T13:50:17.928Z" }, + { url = "https://files.pythonhosted.org/packages/c6/08/1e00f7923eaaba45fb3d51dd794125fc766304b1df264f3a9c6557bfb30e/coverage-7.15.4-cp315-cp315t-win_arm64.whl", hash = "sha256:68be5e1de60ff13c9095bbec0e5a7fa45b33b101752215b91345ea1f61c4a278", size = 225213, upload-time = "2026-08-06T13:50:19.981Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d9/e70c286c979378f061d8266e279b686ab0b0b688e1fe0af864684f23a77d/coverage-7.15.4-py3-none-any.whl", hash = "sha256:964730a1e9de9c0cf11be6a1a3c79ce419c34882842abd256086ba4698705e84", size = 214332, upload-time = "2026-08-06T13:50:22.192Z" }, ] [package.optional-dependencies] @@ -2479,70 +2627,78 @@ toml = [ [[package]] name = "crc32c" -version = "2.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/4c/4e40cc26347ac8254d3f25b9f94710b8e8df24ee4dddc1ba41907a88a94d/crc32c-2.7.1.tar.gz", hash = "sha256:f91b144a21eef834d64178e01982bb9179c354b3e9e5f4c803b0e5096384968c", size = 45712, upload-time = "2024-09-24T06:20:17.553Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/f8/2c5cc5b8d16c76a66548283d74d1f4979c8970c2a274e63f76fbfaa0cf4e/crc32c-2.7.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1fd1f9c6b50d7357736676278a1b8c8986737b8a1c76d7eab4baa71d0b6af67f", size = 49668, upload-time = "2024-09-24T06:18:02.204Z" }, - { url = "https://files.pythonhosted.org/packages/35/52/cdebceaed37a5657ee4864881da0f29f4036867dfb79bb058d38d4d737f3/crc32c-2.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:805c2be1bc0e251c48439a62b0422385899c15289483692bc70e78473c1039f1", size = 37151, upload-time = "2024-09-24T06:18:04.173Z" }, - { url = "https://files.pythonhosted.org/packages/1e/33/6476918b4cac85a18e32dc754e9d653b0dcd96518d661cbbf91bf8aec8cc/crc32c-2.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f4333e62b7844dfde112dbb8489fd2970358eddc3310db21e943a9f6994df749", size = 35370, upload-time = "2024-09-24T06:18:05.468Z" }, - { url = "https://files.pythonhosted.org/packages/ad/fd/8972a70d7c39f37240f554c348fd9e15a4d8d0a548b1bc3139cd4e1cfb66/crc32c-2.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f0fadc741e79dc705e2d9ee967473e8a061d26b04310ed739f1ee292f33674f", size = 54110, upload-time = "2024-09-24T06:18:06.758Z" }, - { url = "https://files.pythonhosted.org/packages/35/be/0b045f84c7acc36312a91211190bf84e73a0bbd30f21cbaf3670c4dba9b2/crc32c-2.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91ced31055d26d59385d708bbd36689e1a1d604d4b0ceb26767eb5a83156f85d", size = 51792, upload-time = "2024-09-24T06:18:07.767Z" }, - { url = "https://files.pythonhosted.org/packages/8c/e2/acaabbc172b7c45ec62f273cd2e214f626e2b4324eca9152dea6095a26f4/crc32c-2.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36ffa999b72e3c17f6a066ae9e970b40f8c65f38716e436c39a33b809bc6ed9f", size = 52884, upload-time = "2024-09-24T06:18:09.449Z" }, - { url = "https://files.pythonhosted.org/packages/60/40/963ba3d2ec0d8e4a2ceaf90e8f9cb10911a926fe75d4329e013a51343122/crc32c-2.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e80114dd7f462297e54d5da1b9ff472e5249c5a2b406aa51c371bb0edcbf76bd", size = 53888, upload-time = "2024-09-24T06:18:11.039Z" }, - { url = "https://files.pythonhosted.org/packages/f2/b8/8a093b9dc1792b2cec9805e1428e97be0338a45ac9fae2fd5911613eacb1/crc32c-2.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:676f5b46da268b5190f9fb91b3f037a00d114b411313664438525db876adc71f", size = 52098, upload-time = "2024-09-24T06:18:12.522Z" }, - { url = "https://files.pythonhosted.org/packages/26/76/a254ddb4ae83b545f6e08af384d62268a99d00f5c58a468754f8416468ce/crc32c-2.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8d0e660c9ed269e90692993a4457a932fc22c9cc96caf79dd1f1a84da85bb312", size = 52716, upload-time = "2024-09-24T06:18:14.118Z" }, - { url = "https://files.pythonhosted.org/packages/b6/cb/6062806e5b6cb8d9af3c62945a5a07fa22c3b4dc59084d2fa2e533f9aaa1/crc32c-2.7.1-cp310-cp310-win32.whl", hash = "sha256:17a2c3f8c6d85b04b5511af827b5dbbda4e672d188c0b9f20a8156e93a1aa7b6", size = 38363, upload-time = "2024-09-24T06:18:15.603Z" }, - { url = "https://files.pythonhosted.org/packages/7f/a9/dc935e26c8d7bd4722bc1312ed88f443e6e36816b46835b4464baa3f7c6d/crc32c-2.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3208764c29688f91a35392073229975dd7687b6cb9f76b919dae442cabcd5126", size = 39795, upload-time = "2024-09-24T06:18:17.182Z" }, - { url = "https://files.pythonhosted.org/packages/45/8e/2f37f46368bbfd50edfc11b96f0aa135699034b1b020966c70ebaff3463b/crc32c-2.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19e03a50545a3ef400bd41667d5525f71030488629c57d819e2dd45064f16192", size = 49672, upload-time = "2024-09-24T06:18:18.032Z" }, - { url = "https://files.pythonhosted.org/packages/ed/b8/e52f7c4b045b871c2984d70f37c31d4861b533a8082912dfd107a96cf7c1/crc32c-2.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c03286b1e5ce9bed7090084f206aacd87c5146b4b10de56fe9e86cbbbf851cf", size = 37155, upload-time = "2024-09-24T06:18:19.373Z" }, - { url = "https://files.pythonhosted.org/packages/25/ee/0cfa82a68736697f3c7e435ba658c2ef8c997f42b89f6ab4545efe1b2649/crc32c-2.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:80ebbf144a1a56a532b353e81fa0f3edca4f4baa1bf92b1dde2c663a32bb6a15", size = 35372, upload-time = "2024-09-24T06:18:20.983Z" }, - { url = "https://files.pythonhosted.org/packages/aa/92/c878aaba81c431fcd93a059e9f6c90db397c585742793f0bf6e0c531cc67/crc32c-2.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96b794fd11945298fdd5eb1290a812efb497c14bc42592c5c992ca077458eeba", size = 54879, upload-time = "2024-09-24T06:18:23.085Z" }, - { url = "https://files.pythonhosted.org/packages/5b/f5/ab828ab3907095e06b18918408748950a9f726ee2b37be1b0839fb925ee1/crc32c-2.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df7194dd3c0efb5a21f5d70595b7a8b4fd9921fbbd597d6d8e7a11eca3e2d27", size = 52588, upload-time = "2024-09-24T06:18:24.463Z" }, - { url = "https://files.pythonhosted.org/packages/6a/2b/9e29e9ac4c4213d60491db09487125db358cd9263490fbadbd55e48fbe03/crc32c-2.7.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d698eec444b18e296a104d0b9bb6c596c38bdcb79d24eba49604636e9d747305", size = 53674, upload-time = "2024-09-24T06:18:25.624Z" }, - { url = "https://files.pythonhosted.org/packages/79/ed/df3c4c14bf1b29f5c9b52d51fb6793e39efcffd80b2941d994e8f7f5f688/crc32c-2.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e07cf10ef852d219d179333fd706d1c415626f1f05e60bd75acf0143a4d8b225", size = 54691, upload-time = "2024-09-24T06:18:26.578Z" }, - { url = "https://files.pythonhosted.org/packages/0c/47/4917af3c9c1df2fff28bbfa6492673c9adeae5599dcc207bbe209847489c/crc32c-2.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d2a051f296e6e92e13efee3b41db388931cdb4a2800656cd1ed1d9fe4f13a086", size = 52896, upload-time = "2024-09-24T06:18:28.174Z" }, - { url = "https://files.pythonhosted.org/packages/1b/6f/26fc3dda5835cda8f6cd9d856afe62bdeae428de4c34fea200b0888e8835/crc32c-2.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1738259802978cdf428f74156175da6a5fdfb7256f647fdc0c9de1bc6cd7173", size = 53554, upload-time = "2024-09-24T06:18:29.104Z" }, - { url = "https://files.pythonhosted.org/packages/56/3e/6f39127f7027c75d130c0ba348d86a6150dff23761fbc6a5f71659f4521e/crc32c-2.7.1-cp311-cp311-win32.whl", hash = "sha256:f7786d219a1a1bf27d0aa1869821d11a6f8e90415cfffc1e37791690d4a848a1", size = 38370, upload-time = "2024-09-24T06:18:30.013Z" }, - { url = "https://files.pythonhosted.org/packages/c9/fb/1587c2705a3a47a3d0067eecf9a6fec510761c96dec45c7b038fb5c8ff46/crc32c-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:887f6844bb3ad35f0778cd10793ad217f7123a5422e40041231b8c4c7329649d", size = 39795, upload-time = "2024-09-24T06:18:31.324Z" }, - { url = "https://files.pythonhosted.org/packages/1d/02/998dc21333413ce63fe4c1ca70eafe61ca26afc7eb353f20cecdb77d614e/crc32c-2.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f7d1c4e761fe42bf856130daf8b2658df33fe0ced3c43dadafdfeaa42b57b950", size = 49568, upload-time = "2024-09-24T06:18:32.425Z" }, - { url = "https://files.pythonhosted.org/packages/9c/3e/e3656bfa76e50ef87b7136fef2dbf3c46e225629432fc9184fdd7fd187ff/crc32c-2.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:73361c79a6e4605204457f19fda18b042a94508a52e53d10a4239da5fb0f6a34", size = 37019, upload-time = "2024-09-24T06:18:34.097Z" }, - { url = "https://files.pythonhosted.org/packages/0b/7d/5ff9904046ad15a08772515db19df43107bf5e3901a89c36a577b5f40ba0/crc32c-2.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afd778fc8ac0ed2ffbfb122a9aa6a0e409a8019b894a1799cda12c01534493e0", size = 35373, upload-time = "2024-09-24T06:18:35.02Z" }, - { url = "https://files.pythonhosted.org/packages/4d/41/4aedc961893f26858ab89fc772d0eaba91f9870f19eaa933999dcacb94ec/crc32c-2.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56ef661b34e9f25991fface7f9ad85e81bbc1b3fe3b916fd58c893eabe2fa0b8", size = 54675, upload-time = "2024-09-24T06:18:35.954Z" }, - { url = "https://files.pythonhosted.org/packages/d6/63/8cabf09b7e39b9fec8f7010646c8b33057fc8d67e6093b3cc15563d23533/crc32c-2.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:571aa4429444b5d7f588e4377663592145d2d25eb1635abb530f1281794fc7c9", size = 52386, upload-time = "2024-09-24T06:18:36.896Z" }, - { url = "https://files.pythonhosted.org/packages/79/13/13576941bf7cf95026abae43d8427c812c0054408212bf8ed490eda846b0/crc32c-2.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c02a3bd67dea95cdb25844aaf44ca2e1b0c1fd70b287ad08c874a95ef4bb38db", size = 53495, upload-time = "2024-09-24T06:18:38.099Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b6/55ffb26d0517d2d6c6f430ce2ad36ae7647c995c5bfd7abce7f32bb2bad1/crc32c-2.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99d17637c4867672cb8adeea007294e3c3df9d43964369516cfe2c1f47ce500a", size = 54456, upload-time = "2024-09-24T06:18:39.051Z" }, - { url = "https://files.pythonhosted.org/packages/c2/1a/5562e54cb629ecc5543d3604dba86ddfc7c7b7bf31d64005b38a00d31d31/crc32c-2.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4a400ac3c69a32e180d8753fd7ec7bccb80ade7ab0812855dce8a208e72495f", size = 52647, upload-time = "2024-09-24T06:18:40.021Z" }, - { url = "https://files.pythonhosted.org/packages/48/ec/ce4138eaf356cd9aae60bbe931755e5e0151b3eca5f491fce6c01b97fd59/crc32c-2.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:588587772e55624dd9c7a906ec9e8773ae0b6ac5e270fc0bc84ee2758eba90d5", size = 53332, upload-time = "2024-09-24T06:18:40.925Z" }, - { url = "https://files.pythonhosted.org/packages/5e/b5/144b42cd838a901175a916078781cb2c3c9f977151c9ba085aebd6d15b22/crc32c-2.7.1-cp312-cp312-win32.whl", hash = "sha256:9f14b60e5a14206e8173dd617fa0c4df35e098a305594082f930dae5488da428", size = 38371, upload-time = "2024-09-24T06:18:42.711Z" }, - { url = "https://files.pythonhosted.org/packages/ae/c4/7929dcd5d9b57db0cce4fe6f6c191049380fc6d8c9b9f5581967f4ec018e/crc32c-2.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:7c810a246660a24dc818047dc5f89c7ce7b2814e1e08a8e99993f4103f7219e8", size = 39805, upload-time = "2024-09-24T06:18:43.6Z" }, - { url = "https://files.pythonhosted.org/packages/bf/98/1a6d60d5b3b5edc8382777b64100343cb4aa6a7e172fae4a6cfcb8ebbbd9/crc32c-2.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:24949bffb06fc411cc18188d33357923cb935273642164d0bb37a5f375654169", size = 49567, upload-time = "2024-09-24T06:18:44.485Z" }, - { url = "https://files.pythonhosted.org/packages/4f/56/0dd652d4e950e6348bbf16b964b3325e4ad8220470774128fc0b0dd069cb/crc32c-2.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2d5d326e7e118d4fa60187770d86b66af2fdfc63ce9eeb265f0d3e7d49bebe0b", size = 37018, upload-time = "2024-09-24T06:18:45.434Z" }, - { url = "https://files.pythonhosted.org/packages/47/02/2bd65fdef10139b6a802d83a7f966b7750fe5ffb1042f7cbe5dbb6403869/crc32c-2.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ba110df60c64c8e2d77a9425b982a520ccdb7abe42f06604f4d98a45bb1fff62", size = 35374, upload-time = "2024-09-24T06:18:46.304Z" }, - { url = "https://files.pythonhosted.org/packages/a9/0d/3e797d1ed92d357a6a4c5b41cea15a538b27a8fdf18c7863747eb50b73ad/crc32c-2.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c277f9d16a3283e064d54854af0976b72abaa89824955579b2b3f37444f89aae", size = 54641, upload-time = "2024-09-24T06:18:47.207Z" }, - { url = "https://files.pythonhosted.org/packages/a7/d3/4ddeef755caaa75680c559562b6c71f5910fee4c4f3a2eb5ea8b57f0e48c/crc32c-2.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881af0478a01331244e27197356929edbdeaef6a9f81b5c6bacfea18d2139289", size = 52338, upload-time = "2024-09-24T06:18:49.31Z" }, - { url = "https://files.pythonhosted.org/packages/01/cf/32f019be5de9f6e180926a50ee5f08648e686c7d9a59f2c5d0806a77b1c7/crc32c-2.7.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:724d5ff4d29ff093a983ae656be3307093706d850ea2a233bf29fcacc335d945", size = 53447, upload-time = "2024-09-24T06:18:50.296Z" }, - { url = "https://files.pythonhosted.org/packages/b2/8b/92f3f62f3bafe8f7ab4af7bfb7246dc683fd11ec0d6dfb73f91e09079f69/crc32c-2.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2416c4d88696ac322632555c0f81ab35e15f154bc96055da6cf110d642dbc10", size = 54484, upload-time = "2024-09-24T06:18:51.311Z" }, - { url = "https://files.pythonhosted.org/packages/98/b2/113a50f8781f76af5ac65ffdb907e72bddbe974de8e02247f0d58bc48040/crc32c-2.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:60254251b88ec9b9795215f0f9ec015a6b5eef8b2c5fba1267c672d83c78fc02", size = 52703, upload-time = "2024-09-24T06:18:52.488Z" }, - { url = "https://files.pythonhosted.org/packages/b4/6c/309229e9acda8cf36a8ff4061d70b54d905f79b7037e16883ce6590a24ab/crc32c-2.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:edefc0e46f3c37372183f70338e5bdee42f6789b62fcd36ec53aa933e9dfbeaf", size = 53367, upload-time = "2024-09-24T06:18:53.49Z" }, - { url = "https://files.pythonhosted.org/packages/b5/2a/6c6324d920396e1bd9f3efbe8753da071be0ca52bd22d6c82d446b8d6975/crc32c-2.7.1-cp313-cp313-win32.whl", hash = "sha256:813af8111218970fe2adb833c5e5239f091b9c9e76f03b4dd91aaba86e99b499", size = 38377, upload-time = "2024-09-24T06:18:54.487Z" }, - { url = "https://files.pythonhosted.org/packages/db/a0/f01ccfab538db07ef3f6b4ede46357ff147a81dd4f3c59ca6a34c791a549/crc32c-2.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:7d9ede7be8e4ec1c9e90aaf6884decbeef10e3473e6ddac032706d710cab5888", size = 39803, upload-time = "2024-09-24T06:18:55.419Z" }, - { url = "https://files.pythonhosted.org/packages/1b/80/61dcae7568b33acfde70c9d651c7d891c0c578c39cc049107c1cf61f1367/crc32c-2.7.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db9ac92294284b22521356715784b91cc9094eee42a5282ab281b872510d1831", size = 49386, upload-time = "2024-09-24T06:18:56.813Z" }, - { url = "https://files.pythonhosted.org/packages/1e/f1/80f17c089799ab2b4c247443bdd101d6ceda30c46d7f193e16b5ca29c5a0/crc32c-2.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8fcd7f2f29a30dc92af64a9ee3d38bde0c82bd20ad939999427aac94bbd87373", size = 36937, upload-time = "2024-09-24T06:18:57.77Z" }, - { url = "https://files.pythonhosted.org/packages/63/42/5fcfc71a3de493d920fd2590843762a2749981ea56b802b380e5df82309d/crc32c-2.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5c056ef043393085523e149276a7ce0cb534b872e04f3e20d74d9a94a75c0ad7", size = 35292, upload-time = "2024-09-24T06:18:58.676Z" }, - { url = "https://files.pythonhosted.org/packages/03/de/fef962e898a953558fe1c55141644553e84ef4190693a31244c59a0856c7/crc32c-2.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03a92551a343702629af91f78d205801219692b6909f8fa126b830e332bfb0e0", size = 54223, upload-time = "2024-09-24T06:18:59.675Z" }, - { url = "https://files.pythonhosted.org/packages/21/14/fceca1a6f45c0a1814fe8602a65657b75c27425162445925ba87438cad6b/crc32c-2.7.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb9424ec1a8ca54763155a703e763bcede82e6569fe94762614bb2de1412d4e1", size = 51588, upload-time = "2024-09-24T06:19:00.938Z" }, - { url = "https://files.pythonhosted.org/packages/13/3b/13d40a7dfbf9ef05c84a0da45544ee72080dca4ce090679e5105689984bd/crc32c-2.7.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88732070f6175530db04e0bb36880ac45c33d49f8ac43fa0e50cfb1830049d23", size = 52678, upload-time = "2024-09-24T06:19:02.661Z" }, - { url = "https://files.pythonhosted.org/packages/36/09/65ffc4fb9fa60ff6714eeb50a92284a4525e5943f0b040b572c0c76368c1/crc32c-2.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:57a20dfc27995f568f64775eea2bbb58ae269f1a1144561df5e4a4955f79db32", size = 53847, upload-time = "2024-09-24T06:19:03.705Z" }, - { url = "https://files.pythonhosted.org/packages/24/71/938e926085b7288da052db7c84416f3ce25e71baf7ab5b63824c7bcb6f22/crc32c-2.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f7186d098bfd2cff25eac6880b7c7ad80431b90610036131c1c7dd0eab42a332", size = 51860, upload-time = "2024-09-24T06:19:04.726Z" }, - { url = "https://files.pythonhosted.org/packages/3c/d8/4526d5380189d6f2fa27256c204100f30214fe402f47cf6e9fb9a91ab890/crc32c-2.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:55a77e29a265418fa34bef15bd0f2c60afae5348988aaf35ed163b4bbf93cf37", size = 52508, upload-time = "2024-09-24T06:19:05.731Z" }, - { url = "https://files.pythonhosted.org/packages/19/30/15f7e35176488b77e5b88751947d321d603fccac273099ace27c7b2d50a6/crc32c-2.7.1-cp313-cp313t-win32.whl", hash = "sha256:ae38a4b6aa361595d81cab441405fbee905c72273e80a1c010fb878ae77ac769", size = 38319, upload-time = "2024-09-24T06:19:07.233Z" }, - { url = "https://files.pythonhosted.org/packages/19/c4/0b3eee04dac195f4730d102d7a9fbea894ae7a32ce075f84336df96a385d/crc32c-2.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:eee2a43b663feb6c79a6c1c6e5eae339c2b72cfac31ee54ec0209fa736cf7ee5", size = 39781, upload-time = "2024-09-24T06:19:08.182Z" }, - { url = "https://files.pythonhosted.org/packages/7f/e0/14d392075db47c53a3890aa110e3640b22fb9736949c47b13d5b5e4599f7/crc32c-2.7.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2e83fedebcdeb80c19e76b7a0e5103528bb062521c40702bf34516a429e81df3", size = 36448, upload-time = "2024-09-24T06:19:50.456Z" }, - { url = "https://files.pythonhosted.org/packages/03/27/f1dab3066c90e9424d22bc942eecdc2e77267f7e805ddb5a2419bbcbace6/crc32c-2.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30004a7383538ef93bda9b22f7b3805bc0aa5625ab2675690e1b676b19417d4b", size = 38184, upload-time = "2024-09-24T06:19:51.466Z" }, - { url = "https://files.pythonhosted.org/packages/2c/f3/479acfa99803c261cdd6b44f37b55bd77bdbce6163ec1f51b2014b095495/crc32c-2.7.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a01b0983aa87f517c12418f9898ecf2083bf86f4ea04122e053357c3edb0d73f", size = 38256, upload-time = "2024-09-24T06:19:52.486Z" }, - { url = "https://files.pythonhosted.org/packages/7b/31/4edb9c45457c54d51ca539f850761f31b7ab764177902b6f3247ff8c1b75/crc32c-2.7.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb2b963c42128b38872e9ed63f04a73ce1ff89a1dfad7ea38add6fe6296497b8", size = 37868, upload-time = "2024-09-24T06:19:54.159Z" }, - { url = "https://files.pythonhosted.org/packages/a6/b0/5680db08eff8f2116a4f9bd949f8bbe9cf260e1c3451228f54c60b110d79/crc32c-2.7.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cdd5e576fee5d255c1e68a4dae4420f21e57e6f05900b38d5ae47c713fc3330d", size = 39826, upload-time = "2024-09-24T06:19:55.4Z" }, +version = "2.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/66/7e97aa77af7cf6afbff26e3651b564fe41932599bc2d3dce0b2f73d4829a/crc32c-2.8.tar.gz", hash = "sha256:578728964e59c47c356aeeedee6220e021e124b9d3e8631d95d9a5e5f06e261c", size = 48179, upload-time = "2025-10-17T06:20:13.61Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c4/a0/28b4686a8db0bb0f77970f4c6ccede90d1d5740a1d4b4703bd54c3e75655/crc32c-2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2c0f4eb01fe7c0a3e3f973a418e04d52101bb077dd77626fd80c658ec60aaf95", size = 66321, upload-time = "2025-10-17T06:18:53.543Z" }, + { url = "https://files.pythonhosted.org/packages/76/1f/1697f5b8b770f715ed9b264d79e36b4f77ae0527f81f3c749ef08937a32e/crc32c-2.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6baefcfbca82b1a9678455416da24f18629769a76920c640d5a538620a7d12bb", size = 62985, upload-time = "2025-10-17T06:18:54.97Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/333cfa5ffa8d5779733aced2b984b5e5139b4a8ceaa2c6bc563e9a1092f3/crc32c-2.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d7f959fcf6c5aad1c4a653ee1a50f05760dab1d1c35d98ec4d7f0f68643f7612", size = 61517, upload-time = "2025-10-17T06:18:55.795Z" }, + { url = "https://files.pythonhosted.org/packages/e1/d8/362a009e8140dd926a153b44d56753e3aa7cb50aca243779a84adadbff11/crc32c-2.8-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9bb678507a4e4cf3f0506607b046ecc4ed1c58a19e08a3fb3c2d25441c480bf1", size = 79385, upload-time = "2025-10-17T06:18:56.598Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0d4ea3aa71ffb15f1285669d23024cc40779388ce32157d339dc2584491c/crc32c-2.8-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1a16f7ffa4c242a909558565567cbba95148603717b53538ea299c98da68e7a9", size = 80965, upload-time = "2025-10-17T06:18:57.384Z" }, + { url = "https://files.pythonhosted.org/packages/20/44/d77657aaca4a2c0283f2356a3da6f8e91b003567bb8f09daaf540cbf192f/crc32c-2.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0184369aad562d801f91f454c81f56b9ecb966f6b96684c4d6cf82fc8741d2ad", size = 79993, upload-time = "2025-10-17T06:18:58.503Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c0/07017a93ebf85d9408028b7e03ef96d5c6bfb14cb77cfe90d35eedcc1501/crc32c-2.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:86d2eeb5f0189bd803720abe7387019328ea34c4acde62999e5723f789bc316b", size = 79243, upload-time = "2025-10-17T06:18:59.273Z" }, + { url = "https://files.pythonhosted.org/packages/c7/1a/b3c5ac4cf2fd1f82395173d0bd8e1a15d09f0bc1eccdf10ea7f8caaccd67/crc32c-2.8-cp310-cp310-win32.whl", hash = "sha256:51da61904a9e753780a2e6011885677d601db1fa840be4b68799643a113e6f08", size = 64888, upload-time = "2025-10-17T06:19:00.089Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f2/60c45fc7bb2221d3c93c7a872e921be591f40d45228fe46f879b1d8c0424/crc32c-2.8-cp310-cp310-win_amd64.whl", hash = "sha256:b2d6a1f2500daaf2e4b08f97ad0349aa2eff5faaaa5fd3350314a26eade334cd", size = 66639, upload-time = "2025-10-17T06:19:00.974Z" }, + { url = "https://files.pythonhosted.org/packages/dc/0b/5e03b22d913698e9cc563f39b9f6bbd508606bf6b8e9122cd6bf196b87ea/crc32c-2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e560a97fbb96c9897cb1d9b5076ef12fc12e2e25622530a1afd0de4240f17e1f", size = 66329, upload-time = "2025-10-17T06:19:01.771Z" }, + { url = "https://files.pythonhosted.org/packages/6b/38/2fe0051ffe8c6a650c8b1ac0da31b8802d1dbe5fa40a84e4b6b6f5583db5/crc32c-2.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6762d276d90331a490ef7e71ffee53b9c0eb053bd75a272d786f3b08d3fe3671", size = 62988, upload-time = "2025-10-17T06:19:02.953Z" }, + { url = "https://files.pythonhosted.org/packages/3e/30/5837a71c014be83aba1469c58820d287fc836512a0cad6b8fdd43868accd/crc32c-2.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:60670569f5ede91e39f48fb0cb4060e05b8d8704dd9e17ede930bf441b2f73ef", size = 61522, upload-time = "2025-10-17T06:19:03.796Z" }, + { url = "https://files.pythonhosted.org/packages/ca/29/63972fc1452778e2092ae998c50cbfc2fc93e3fa9798a0278650cd6169c5/crc32c-2.8-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:711743da6ccc70b3c6718c328947b0b6f34a1fe6a6c27cc6c1d69cc226bf70e9", size = 80200, upload-time = "2025-10-17T06:19:04.617Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3a/60eb49d7bdada4122b3ffd45b0df54bdc1b8dd092cda4b069a287bdfcff4/crc32c-2.8-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5eb4094a2054774f13b26f21bf56792bb44fa1fcee6c6ad099387a43ffbfb4fa", size = 81757, upload-time = "2025-10-17T06:19:05.496Z" }, + { url = "https://files.pythonhosted.org/packages/f5/63/6efc1b64429ef7d23bd58b75b7ac24d15df327e3ebbe9c247a0f7b1c2ed1/crc32c-2.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fff15bf2bd3e95780516baae935ed12be88deaa5ebe6143c53eb0d26a7bdc7b7", size = 80830, upload-time = "2025-10-17T06:19:06.621Z" }, + { url = "https://files.pythonhosted.org/packages/e1/eb/0ae9f436f8004f1c88f7429e659a7218a3879bd11a6b18ed1257aad7e98b/crc32c-2.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c0e11e3826668121fa53e0745635baf5e4f0ded437e8ff63ea56f38fc4f970a", size = 80095, upload-time = "2025-10-17T06:19:07.381Z" }, + { url = "https://files.pythonhosted.org/packages/9e/81/4afc9d468977a4cd94a2eb62908553345009a7c0d30e74463a15d4b48ec3/crc32c-2.8-cp311-cp311-win32.whl", hash = "sha256:38f915336715d1f1353ab07d7d786f8a789b119e273aea106ba55355dfc9101d", size = 64886, upload-time = "2025-10-17T06:19:08.497Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e8/94e839c9f7e767bf8479046a207afd440a08f5c59b52586e1af5e64fa4a0/crc32c-2.8-cp311-cp311-win_amd64.whl", hash = "sha256:60e0a765b1caab8d31b2ea80840639253906a9351d4b861551c8c8625ea20f86", size = 66639, upload-time = "2025-10-17T06:19:09.338Z" }, + { url = "https://files.pythonhosted.org/packages/b6/36/fd18ef23c42926b79c7003e16cb0f79043b5b179c633521343d3b499e996/crc32c-2.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:572ffb1b78cce3d88e8d4143e154d31044a44be42cb3f6fbbf77f1e7a941c5ab", size = 66379, upload-time = "2025-10-17T06:19:10.115Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b8/c584958e53f7798dd358f5bdb1bbfc97483134f053ee399d3eeb26cca075/crc32c-2.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cf827b3758ee0c4aacd21ceca0e2da83681f10295c38a10bfeb105f7d98f7a68", size = 63042, upload-time = "2025-10-17T06:19:10.946Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/6f2af0ec64a668a46c861e5bc778ea3ee42171fedfc5440f791f470fd783/crc32c-2.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:106fbd79013e06fa92bc3b51031694fcc1249811ed4364ef1554ee3dd2c7f5a2", size = 61528, upload-time = "2025-10-17T06:19:11.768Z" }, + { url = "https://files.pythonhosted.org/packages/17/8b/4a04bd80a024f1a23978f19ae99407783e06549e361ab56e9c08bba3c1d3/crc32c-2.8-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6dde035f91ffbfe23163e68605ee5a4bb8ceebd71ed54bb1fb1d0526cdd125a2", size = 80028, upload-time = "2025-10-17T06:19:12.554Z" }, + { url = "https://files.pythonhosted.org/packages/21/8f/01c7afdc76ac2007d0e6a98e7300b4470b170480f8188475b597d1f4b4c6/crc32c-2.8-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e41ebe7c2f0fdcd9f3a3fd206989a36b460b4d3f24816d53e5be6c7dba72c5e1", size = 81531, upload-time = "2025-10-17T06:19:13.406Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/8f78c5a8cc66486be5f51b6f038fc347c3ba748d3ea68be17a014283c331/crc32c-2.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecf66cf90266d9c15cea597d5cc86c01917cd1a238dc3c51420c7886fa750d7e", size = 80608, upload-time = "2025-10-17T06:19:14.223Z" }, + { url = "https://files.pythonhosted.org/packages/db/86/fad1a94cdeeeb6b6e2323c87f970186e74bfd6fbfbc247bf5c88ad0873d5/crc32c-2.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:59eee5f3a69ad0793d5fa9cdc9b9d743b0cd50edf7fccc0a3988a821fef0208c", size = 79886, upload-time = "2025-10-17T06:19:15.345Z" }, + { url = "https://files.pythonhosted.org/packages/d5/db/1a7cb6757a1e32376fa2dfce00c815ea4ee614a94f9bff8228e37420c183/crc32c-2.8-cp312-cp312-win32.whl", hash = "sha256:a73d03ce3604aa5d7a2698e9057a0eef69f529c46497b27ee1c38158e90ceb76", size = 64896, upload-time = "2025-10-17T06:19:16.457Z" }, + { url = "https://files.pythonhosted.org/packages/bf/8e/2024de34399b2e401a37dcb54b224b56c747b0dc46de4966886827b4d370/crc32c-2.8-cp312-cp312-win_amd64.whl", hash = "sha256:56b3b7d015247962cf58186e06d18c3d75a1a63d709d3233509e1c50a2d36aa2", size = 66645, upload-time = "2025-10-17T06:19:17.235Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d8/3ae227890b3be40955a7144106ef4dd97d6123a82c2a5310cdab58ca49d8/crc32c-2.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:36f1e03ee9e9c6938e67d3bcb60e36f260170aa5f37da1185e04ef37b56af395", size = 66380, upload-time = "2025-10-17T06:19:18.009Z" }, + { url = "https://files.pythonhosted.org/packages/bd/8b/178d3f987cd0e049b484615512d3f91f3d2caeeb8ff336bb5896ae317438/crc32c-2.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b2f3226b94b85a8dd9b3533601d7a63e9e3e8edf03a8a169830ee8303a199aeb", size = 63048, upload-time = "2025-10-17T06:19:18.853Z" }, + { url = "https://files.pythonhosted.org/packages/f2/a1/48145ae2545ebc0169d3283ebe882da580ea4606bfb67cf4ca922ac3cfc3/crc32c-2.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6e08628bc72d5b6bc8e0730e8f142194b610e780a98c58cb6698e665cb885a5b", size = 61530, upload-time = "2025-10-17T06:19:19.974Z" }, + { url = "https://files.pythonhosted.org/packages/06/4b/cf05ed9d934cc30e5ae22f97c8272face420a476090e736615d9a6b53de0/crc32c-2.8-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:086f64793c5ec856d1ab31a026d52ad2b895ac83d7a38fce557d74eb857f0a82", size = 80001, upload-time = "2025-10-17T06:19:20.784Z" }, + { url = "https://files.pythonhosted.org/packages/15/ab/4b04801739faf36345f6ba1920be5b1c70282fec52f8280afd3613fb13e2/crc32c-2.8-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcf72ee7e0135b3d941c34bb2c26c3fc6bc207106b49fd89aaafaeae223ae209", size = 81543, upload-time = "2025-10-17T06:19:21.557Z" }, + { url = "https://files.pythonhosted.org/packages/a9/1b/6e38dde5bfd2ea69b7f2ab6ec229fcd972a53d39e2db4efe75c0ac0382ce/crc32c-2.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8a717dd9c3fd777d9bc6603717eae172887d402c4ab589d124ebd0184a83f89e", size = 80644, upload-time = "2025-10-17T06:19:22.325Z" }, + { url = "https://files.pythonhosted.org/packages/ce/45/012176ffee90059ae8ec7131019c71724ea472aa63e72c0c8edbd1fad1d7/crc32c-2.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0450bb845b3c3c7b9bdc0b4e95620ec9a40824abdc8c86d6285c919a90743c1a", size = 79919, upload-time = "2025-10-17T06:19:23.101Z" }, + { url = "https://files.pythonhosted.org/packages/f0/2b/f557629842f9dec2b3461cb3a0d854bb586ec45b814cea58b082c32f0dde/crc32c-2.8-cp313-cp313-win32.whl", hash = "sha256:765d220bfcbcffa6598ac11eb1e10af0ee4802b49fe126aa6bf79f8ddb9931d1", size = 64896, upload-time = "2025-10-17T06:19:23.88Z" }, + { url = "https://files.pythonhosted.org/packages/d0/db/fd0f698c15d1e21d47c64181a98290665a08fcbb3940cd559e9c15bda57e/crc32c-2.8-cp313-cp313-win_amd64.whl", hash = "sha256:171ff0260d112c62abcce29332986950a57bddee514e0a2418bfde493ea06bb3", size = 66646, upload-time = "2025-10-17T06:19:24.702Z" }, + { url = "https://files.pythonhosted.org/packages/db/b9/8e5d7054fe8e7eecab10fd0c8e7ffb01439417bdb6de1d66a81c38fc4a20/crc32c-2.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b977a32a3708d6f51703c8557008f190aaa434d7347431efb0e86fcbe78c2a50", size = 66203, upload-time = "2025-10-17T06:19:25.872Z" }, + { url = "https://files.pythonhosted.org/packages/55/5f/cc926c70057a63cc0c98a3c8a896eb15fc7e74d3034eadd53c94917c6cc3/crc32c-2.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7399b01db4adaf41da2fb36fe2408e75a8d82a179a9564ed7619412e427b26d6", size = 62956, upload-time = "2025-10-17T06:19:26.652Z" }, + { url = "https://files.pythonhosted.org/packages/a1/8a/0660c44a2dd2cb6ccbb529eb363b9280f5c766f1017bc8355ed8d695bd94/crc32c-2.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4379f73f9cdad31958a673d11a332ec725ca71572401ca865867229f5f15e853", size = 61442, upload-time = "2025-10-17T06:19:27.74Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5a/6108d2dfc0fe33522ce83ba07aed4b22014911b387afa228808a278e27cd/crc32c-2.8-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2e68264555fab19bab08331550dab58573e351a63ed79c869d455edd3b0aa417", size = 79109, upload-time = "2025-10-17T06:19:28.535Z" }, + { url = "https://files.pythonhosted.org/packages/84/1e/c054f9e390090c197abf3d2936f4f9effaf0c6ee14569ae03d6ddf86958a/crc32c-2.8-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b48f2486727b8d0e7ccbae4a34cb0300498433d2a9d6b49cb13cb57c2e3f19cb", size = 80987, upload-time = "2025-10-17T06:19:29.305Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ad/1650e5c3341e4a485f800ea83116d72965030c5d48ccc168fcc685756e4d/crc32c-2.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ecf123348934a086df8c8fde7f9f2d716d523ca0707c5a1367b8bb00d8134823", size = 79994, upload-time = "2025-10-17T06:19:30.109Z" }, + { url = "https://files.pythonhosted.org/packages/d7/3b/f2ed924b177729cbb2ab30ca2902abff653c31d48c95e7b66717a9ca9fcc/crc32c-2.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e636ac60f76de538f7a2c0d0f3abf43104ee83a8f5e516f6345dc283ed1a4df7", size = 79046, upload-time = "2025-10-17T06:19:30.894Z" }, + { url = "https://files.pythonhosted.org/packages/4b/80/413b05ee6ace613208b31b3670c3135ee1cf451f0e72a9c839b4946acc04/crc32c-2.8-cp313-cp313t-win32.whl", hash = "sha256:8dd4a19505e0253892e1b2f1425cc3bd47f79ae5a04cb8800315d00aad7197f2", size = 64837, upload-time = "2025-10-17T06:19:32.03Z" }, + { url = "https://files.pythonhosted.org/packages/3b/1b/85eddb6ac5b38496c4e35c20298aae627970c88c3c624a22ab33e84f16c7/crc32c-2.8-cp313-cp313t-win_amd64.whl", hash = "sha256:4bb18e4bd98fb266596523ffc6be9c5b2387b2fa4e505ec56ca36336f49cb639", size = 66574, upload-time = "2025-10-17T06:19:33.143Z" }, + { url = "https://files.pythonhosted.org/packages/aa/df/50e9079b532ff53dbfc0e66eed781374bd455af02ed5df8b56ad538de4ff/crc32c-2.8-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3a3b2e4bcf7b3ee333050e7d3ff38e2ba46ea205f1d73d8949b248aaffe937ac", size = 66399, upload-time = "2025-10-17T06:19:34.279Z" }, + { url = "https://files.pythonhosted.org/packages/5a/2e/67e3b0bc3d30e46ea5d16365cc81203286387671e22f2307eb41f19abb9c/crc32c-2.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:445e559e66dff16be54f8a4ef95aa6b01db799a639956d995c5498ba513fccc2", size = 63044, upload-time = "2025-10-17T06:19:35.062Z" }, + { url = "https://files.pythonhosted.org/packages/36/ea/1723b17437e4344ed8d067456382ecb1f5b535d83fdc5aaebab676c6d273/crc32c-2.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bf3040919e17afa5782e01b1875d6a05f44b8f19c05f211d8b9f8a1deb8bbd9c", size = 61541, upload-time = "2025-10-17T06:19:36.204Z" }, + { url = "https://files.pythonhosted.org/packages/4c/6a/cbec8a235c5b46a01f319939b538958662159aec0ed3a74944e3a6de21f1/crc32c-2.8-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5607ab8221e1ffd411f64aa40dbb6850cf06dd2908c9debd05d371e1acf62ff3", size = 80139, upload-time = "2025-10-17T06:19:37.351Z" }, + { url = "https://files.pythonhosted.org/packages/21/31/d096722fe74b692d6e8206c27da1ea5f6b2a12ff92c54a62a6ba2f376254/crc32c-2.8-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f5db4f16816926986d3c94253314920689706ae13a9bf4888b47336c6735ce", size = 81736, upload-time = "2025-10-17T06:19:38.16Z" }, + { url = "https://files.pythonhosted.org/packages/f6/a2/f75ef716ff7e3c22f385ba6ef30c5de80c19a21ebe699dc90824a1903275/crc32c-2.8-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70b0153c4d418b673309d3529334d117e1074c4a3b2d7f676e430d72c14de67b", size = 80795, upload-time = "2025-10-17T06:19:38.948Z" }, + { url = "https://files.pythonhosted.org/packages/d8/94/6d647a12d96ab087d9b8eacee3da073f981987827d57c7072f89ffc7b6cd/crc32c-2.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c8933531442042438753755a5c8a9034e4d88b01da9eb796f7e151b31a7256c", size = 80042, upload-time = "2025-10-17T06:19:39.725Z" }, + { url = "https://files.pythonhosted.org/packages/cd/dc/32b8896b40a0afee7a3c040536d0da5a73e68df2be9fadd21770fd158e16/crc32c-2.8-cp314-cp314-win32.whl", hash = "sha256:cdc83a3fe6c4e5df9457294cfd643de7d95bd4e9382c1dd6ed1e0f0f9169172c", size = 64914, upload-time = "2025-10-17T06:19:40.527Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b4/4308b27d307e8ecaf8dd1dcc63bbb0e47ae1826d93faa3e62d1ee00ee2d5/crc32c-2.8-cp314-cp314-win_amd64.whl", hash = "sha256:509e10035106df66770fe24b9eb8d9e32b6fb967df17744402fb67772d8b2bc7", size = 66723, upload-time = "2025-10-17T06:19:42.449Z" }, + { url = "https://files.pythonhosted.org/packages/90/d5/a19d2489fa997a143bfbbf971a5c9a43f8b1ba9e775b1fb362d8fb15260c/crc32c-2.8-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:864359a39777a07b09b28eb31337c0cc603d5c1bf0fc328c3af736a8da624ec0", size = 66201, upload-time = "2025-10-17T06:19:43.273Z" }, + { url = "https://files.pythonhosted.org/packages/98/c2/5f82f22d2c1242cb6f6fe92aa9a42991ebea86de994b8f9974d9c1d128e2/crc32c-2.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:14511d7cfc5d9f5e1a6c6b64caa6225c2bdc1ed00d725e9a374a3e84073ce180", size = 62956, upload-time = "2025-10-17T06:19:44.099Z" }, + { url = "https://files.pythonhosted.org/packages/9b/61/3d43d33489cf974fb78bfb3500845770e139ae6d1d83473b660bd8f79a6c/crc32c-2.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:918b7999b52b5dcbcea34081e9a02d46917d571921a3f209956a9a429b2e06e5", size = 61443, upload-time = "2025-10-17T06:19:44.89Z" }, + { url = "https://files.pythonhosted.org/packages/52/6d/f306ce64a352a3002f76b0fc88a1373f4541f9d34fad3668688610bab14b/crc32c-2.8-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cc445da03fc012a5a03b71da1df1b40139729e6a5571fd4215ab40bfb39689c7", size = 79106, upload-time = "2025-10-17T06:19:45.688Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b7/1f74965dd7ea762954a69d172dfb3a706049c84ffa45d31401d010a4a126/crc32c-2.8-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e3dde2ec59a8a830511d72a086ead95c0b0b7f0d418f93ea106244c5e77e350", size = 80983, upload-time = "2025-10-17T06:19:46.792Z" }, + { url = "https://files.pythonhosted.org/packages/1b/50/af93f0d91ccd61833ce77374ebfbd16f5805f5c17d18c6470976d9866d76/crc32c-2.8-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:61d51681a08b6a2a2e771b7f0cd1947fb87cb28f38ed55a01cb7c40b2ac4cdd8", size = 80009, upload-time = "2025-10-17T06:19:47.619Z" }, + { url = "https://files.pythonhosted.org/packages/ee/fa/94f394beb68a88258af694dab2f1284f55a406b615d7900bdd6235283bc4/crc32c-2.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:67c0716c3b1a02d5235be649487b637eed21f2d070f2b3f63f709dcd2fefb4c7", size = 79066, upload-time = "2025-10-17T06:19:48.409Z" }, + { url = "https://files.pythonhosted.org/packages/91/c6/a6050e0c64fd73c67a97da96cb59f08b05111e00b958fb87ecdce99f17ac/crc32c-2.8-cp314-cp314t-win32.whl", hash = "sha256:2e8fe863fbbd8bdb6b414a2090f1b0f52106e76e9a9c96a413495dbe5ebe492a", size = 64869, upload-time = "2025-10-17T06:19:49.197Z" }, + { url = "https://files.pythonhosted.org/packages/08/1f/c7735034e401cb1ea14f996a224518e3a3fa9987cb13680e707328a7d779/crc32c-2.8-cp314-cp314t-win_amd64.whl", hash = "sha256:20a9cfb897693eb6da19e52e2a7be2026fd4d9fc8ae318f086c0d71d5dd2d8e0", size = 66633, upload-time = "2025-10-17T06:19:50.003Z" }, + { url = "https://files.pythonhosted.org/packages/a7/1d/dd926c68eb8aac8b142a1a10b8eb62d95212c1cf81775644373fe7cceac2/crc32c-2.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5833f4071da7ea182c514ba17d1eee8aec3c5be927d798222fbfbbd0f5eea02c", size = 62345, upload-time = "2025-10-17T06:20:09.39Z" }, + { url = "https://files.pythonhosted.org/packages/51/be/803404e5abea2ef2c15042edca04bbb7f625044cca879e47f186b43887c2/crc32c-2.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:1dc4da036126ac07b39dd9d03e93e585ec615a2ad28ff12757aef7de175295a8", size = 61229, upload-time = "2025-10-17T06:20:10.236Z" }, + { url = "https://files.pythonhosted.org/packages/fc/3a/00cc578cd27ed0b22c9be25cef2c24539d92df9fa80ebd67a3fc5419724c/crc32c-2.8-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:15905fa78344654e241371c47e6ed2411f9eeb2b8095311c68c88eccf541e8b4", size = 64108, upload-time = "2025-10-17T06:20:11.072Z" }, + { url = "https://files.pythonhosted.org/packages/6b/bc/0587ef99a1c7629f95dd0c9d4f3d894de383a0df85831eb16c48a6afdae4/crc32c-2.8-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c596f918688821f796434e89b431b1698396c38bf0b56de873621528fe3ecb1e", size = 64815, upload-time = "2025-10-17T06:20:11.919Z" }, + { url = "https://files.pythonhosted.org/packages/73/42/94f2b8b92eae9064fcfb8deef2b971514065bd606231f8857ff8ae02bebd/crc32c-2.8-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8d23c4fe01b3844cb6e091044bc1cebdef7d16472e058ce12d9fadf10d2614af", size = 66659, upload-time = "2025-10-17T06:20:12.766Z" }, ] [[package]] @@ -2553,71 +2709,71 @@ sdist = { url = "https://files.pythonhosted.org/packages/6b/b0/e595ce2a2527e169c [[package]] name = "cryptography" -version = "49.0.0" +version = "50.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" }, - { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" }, - { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" }, - { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" }, - { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" }, - { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" }, - { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" }, - { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" }, - { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" }, - { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" }, - { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" }, - { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" }, - { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" }, - { url = "https://files.pythonhosted.org/packages/ec/9e/db72b3ae7fc9cfad53e630e56c6ae83b9b6ff0bf3718ffb8012d20b3aabf/cryptography-49.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:73a205dce83953d131a4aa1e0fd917a2fd1c5b1eef251e9d7152efefcbf5caf7", size = 4013892, upload-time = "2026-06-12T20:02:10.735Z" }, - { url = "https://files.pythonhosted.org/packages/86/12/c48a424f38db03027be9f7ed5c7dc5de9933dbee992865f98b13727a009d/cryptography-49.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:196ecd6a36e4e9aa10270393bb98d8df88fccee0bf1e5128b91ae4eb4375896d", size = 4678835, upload-time = "2026-06-12T20:02:48.743Z" }, - { url = "https://files.pythonhosted.org/packages/68/28/8a3ad4653662c93fc44dc4e5d8fd374c25c42e07b34bbfbadf49cf57a5a8/cryptography-49.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7abcee80084cda3f7691f3eb1ce480d8df49cec637b429aa35986c1de71738aa", size = 4697239, upload-time = "2026-06-12T20:02:56.03Z" }, - { url = "https://files.pythonhosted.org/packages/a8/b2/2193fc74f81aee4f9b62733133b73b5176718932ed8f2e4b03fa040480a6/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:4ae387c9cb68ea569ca17e490d66d8142b81c3cc814bf179974b7d146e490bbb", size = 4685593, upload-time = "2026-06-12T20:02:50.666Z" }, - { url = "https://files.pythonhosted.org/packages/47/f1/1d3eaa243bfc5de4a187b22aa8c048b3e4980bfbe830ac46e6bac2e66947/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:f37d847238971164fdbc68ade6f6574aecc9c0af714190e2083429ff68f4ce9d", size = 5289961, upload-time = "2026-06-12T20:01:46.468Z" }, - { url = "https://files.pythonhosted.org/packages/58/39/2d51306721330c486495853eda1c567880ff036de15a14c4b74f399934af/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c2bc30226390d60ea19d9f82b19db005fe0452154a23c1c410c12ea801e43561", size = 4731145, upload-time = "2026-06-12T20:02:16.832Z" }, - { url = "https://files.pythonhosted.org/packages/17/50/983e838c7fd0d87fd8c969bcdd328edaf5f756e38df5281637424c155873/cryptography-49.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:07cab27cc7b7e0fd28e5e26bb9eeedde5c135c868b46de4a27845abe94af6122", size = 4321719, upload-time = "2026-06-12T20:02:52.611Z" }, - { url = "https://files.pythonhosted.org/packages/a7/f5/8f571d7e27c55bce9f76f026143bcb1e040a4233149ecca0bea5fa5dd5f7/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:b20133d204d2bb56ba047642199603876c872026ca53e79c35b83772ab2cc505", size = 4685209, upload-time = "2026-06-12T20:02:07.282Z" }, - { url = "https://files.pythonhosted.org/packages/e7/84/0e27016a6fc5a0886f797018b26aa42f40c09a82332bff77822a451deaaa/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b970c6da94d5bb18629db453d14f2a1300f6bf59b61e9b82377931ef95504866", size = 5246285, upload-time = "2026-06-12T20:01:32.439Z" }, - { url = "https://files.pythonhosted.org/packages/11/2d/5e1fb307cb5931881516b464c98774b3f2c36b5d4bb9a2830253cf553cad/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d8ecde755e2e91bf773fc94e8c9d730cd7f2007004cb492263a794ec3899a1c8", size = 4730441, upload-time = "2026-06-12T20:02:01.469Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c0/bff5a02ee731d207d6a1ed51732549d8c53d2bc8da1d10ec6f2844201d68/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e3fb64c420688e5319ae25113a354015abbd8dffbfbc41781a1ea66fc7622ac3", size = 4815869, upload-time = "2026-06-12T20:01:36.574Z" }, - { url = "https://files.pythonhosted.org/packages/b9/26/814681d14248d95d73d5c3eea0c39a94eb8302df966f670a2c60de90974b/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32703d93296f5c1f4b53349ad3a250c2cae0fdecd3a3dd5d47e616d8d616af27", size = 4960948, upload-time = "2026-06-12T20:02:18.688Z" }, - { url = "https://files.pythonhosted.org/packages/4c/fe/93ecac273d3738939d023612ad12cca9a3740a5345d69fda04134c43fd96/cryptography-49.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:33cd0565932807baddb67b96dbee92f2c374b5c89dee09fd74079aeb8c8dba61", size = 3799153, upload-time = "2026-06-12T20:01:39.059Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" }, - { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" }, - { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" }, - { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" }, - { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" }, - { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" }, - { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" }, - { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" }, - { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" }, - { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" }, - { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" }, - { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" }, - { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" }, - { url = "https://files.pythonhosted.org/packages/63/d3/4a83af35d65e3fad632c926fad684c193ea4398569ccb0bbbc7fe8f5dc9a/cryptography-49.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fc1e275c2f1d97b1a6450b8b0ea3ebfa6e087a611c2b26cb2404d48588abab7b", size = 3993685, upload-time = "2026-06-12T20:02:14.883Z" }, - { url = "https://files.pythonhosted.org/packages/d6/a7/f9dac0ab7f80368c56993a7bf638ef9935f825c91902798481fac0898138/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83782480a4a9da4d0feb51950131ba32e12e70813848b3343f6e18c28a66838", size = 4676239, upload-time = "2026-06-12T20:02:28.793Z" }, - { url = "https://files.pythonhosted.org/packages/d7/70/2ba3769dd0ae167e2f33dfa9592d45db6ff9a61d62ca1a5b3d1bdd09068f/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b39efa323140595abd3ecca8529d321ae50f55f3aa3ba9cc81ea56a6011953d5", size = 4715584, upload-time = "2026-06-12T20:01:27.495Z" }, - { url = "https://files.pythonhosted.org/packages/94/64/2923570ac1c0bd3a737aa366ac3abbbbde273042308b8cde95e2364a6e6a/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b47db11c2c3525083296069b98ac5221907455e989ae0c2e3008bde851921615", size = 4675885, upload-time = "2026-06-12T20:01:55.49Z" }, - { url = "https://files.pythonhosted.org/packages/ab/f8/614dc7e051418cfe53d55173c1e24c6b0085e89996fe90508c2fdf769aef/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:084ef1af862eb07ec46d25f68689f2102a9fc0e05ce7b80f14f5fe51e4eef0f6", size = 4715449, upload-time = "2026-06-12T20:02:05.469Z" }, - { url = "https://files.pythonhosted.org/packages/aa/50/a9caea39ad19c431c1a3f8a31114df65b260cdfe67786b6c7e7c040c4c44/cryptography-49.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be9fcb48a55f023493482827d4f459bd263cc20efde64f204b97c123201850c6", size = 3783731, upload-time = "2026-06-12T20:02:43.319Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/de/41/6cbdcf9142d00fe82836fbb51e503e58088575cf7a0fe1dbff6695bf0840/cryptography-50.0.0.tar.gz", hash = "sha256:eeac2acb5a20ed25e0ad6d1df9891a520b78b404266b6d11778f25d5d691a6c9", size = 880201, upload-time = "2026-07-31T14:25:10.11Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/5c/59086b4aac5e879d38ddbcf74e4be7ade89cebc3eb199a55da998c3bb46a/cryptography-50.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:031e2d5dd4bb9caa3ca9c82e5a197fd8ae680232cee62603d1a813f3f07e3d03", size = 4001252, upload-time = "2026-07-31T14:23:33.331Z" }, + { url = "https://files.pythonhosted.org/packages/57/ef/8f2df13c7216bcad3e1c74e07f6e193d93e998e114f524a53877c9af27ad/cryptography-50.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd9192b7b70c573d7f214eb1ae35e00d359f6f5e4b27c7e21e30de1fc6204645", size = 4719554, upload-time = "2026-07-31T14:23:35.611Z" }, + { url = "https://files.pythonhosted.org/packages/d9/41/029086c34d91052fc3b88bcc8056f709a7c915c7a23b235a54eb800b1c97/cryptography-50.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:06a32a980526a6ab9a4b9bf8f7385800791e2bb960903cb6b530e4817509a3b7", size = 4702130, upload-time = "2026-07-31T14:23:37.635Z" }, + { url = "https://files.pythonhosted.org/packages/7d/ff/b6ce0954962e7f7b969f850a883744197bb3910bdfd7b6da162eab7d9f68/cryptography-50.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a1b30560f2acc95aa8b2e06e716a13dbfc97314747b80d9707e307f77b40d6b3", size = 4725244, upload-time = "2026-07-31T14:23:39.471Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/63a1027cb7fec360a182208e1b7767d5aa1fe57be3d6aa856e69a321edc0/cryptography-50.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:8d89f3976b10b4ce31118de72329025f70d2c6ead14a8217c5514dd2c6d5a78f", size = 5342265, upload-time = "2026-07-31T14:23:41.286Z" }, + { url = "https://files.pythonhosted.org/packages/6b/72/a1116d683a6d7ece94590013882515de087edf9ef0e6292aae615a44df73/cryptography-50.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b42a28c1844fd9de8f3f7d540e36b66f3a9c83fceac7170ebc7a6a19edd9dcae", size = 4734609, upload-time = "2026-07-31T14:23:43.139Z" }, + { url = "https://files.pythonhosted.org/packages/15/37/36a9c479bbe49acea2636c7fd3360d20f7b7e079c300352011c44850b181/cryptography-50.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:900131fafd8aead39ac7dd3a7e833be754c17a95cfd91221636949fe4eb0aa8a", size = 4356517, upload-time = "2026-07-31T14:23:44.939Z" }, + { url = "https://files.pythonhosted.org/packages/32/98/8a151d64367204cbc63ec65d37502f1d9c53cf4bfc6ec3c532614dbec60d/cryptography-50.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:07949c449a1abcf60d1ee6e88956d89404c7df3c8258f46589e912988e551987", size = 4724529, upload-time = "2026-07-31T14:23:46.93Z" }, + { url = "https://files.pythonhosted.org/packages/22/f6/ec13b470172126464a86bf54d2294a46d29837fc51ba3e45d4047946fb5e/cryptography-50.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:f89831ef99dd7dd169ab06d63a831adb9e20a87aac6d380266bbda5823349169", size = 5299852, upload-time = "2026-07-31T14:23:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/da/3a/f05e32c99d440c9bb891ea0e36c9091891e36be5a9a87ab2ee6ea20729f6/cryptography-50.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:82148ec5bddac30b51a5b3c1945075f896fa022cb93f8e4a01e9f6ee95292c5f", size = 4734462, upload-time = "2026-07-31T14:23:50.861Z" }, + { url = "https://files.pythonhosted.org/packages/ca/dc/bd72b26be8953f80625f63151efd38eee71c76ca6cf591c08ff34615a79e/cryptography-50.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1489e263a8048bb8b6a8bac662eb2d402ea5d2b7b4699b72f385f1e2772db105", size = 4852708, upload-time = "2026-07-31T14:23:52.715Z" }, + { url = "https://files.pythonhosted.org/packages/27/20/c930314a2ab476d15dec966ec87e2e9637bb02b06106b12c0396c57bb603/cryptography-50.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7cec5b856506da6defb290f30c9ee687d5f5e8cb0bd3f6459dde43b0b4fa40ef", size = 5004179, upload-time = "2026-07-31T14:23:54.887Z" }, + { url = "https://files.pythonhosted.org/packages/32/2e/c9db68a0c4bfa28e310707527c0ee3a2bd254104d2e02e68f368e197aa4c/cryptography-50.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:bd1c592e4d5974f0d08d4888e432157adba757c66da0246918e43677fafa2d30", size = 3840395, upload-time = "2026-07-31T14:23:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c3/fb/951032a3bf22a5697c83183fb6294a4843772947a70e616c57b3ff5f522e/cryptography-50.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:49e7d93abdbd2990caced757e5fade25302f719c3c8fb6e6fff2dde98999fc41", size = 3989258, upload-time = "2026-07-31T14:23:58.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/67/91eb047e69c5e845f2f14b8a2e4a1aab0f283cb885531e9e22c8adb176bc/cryptography-50.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:19736989797678c6af1e55cd49055cdbcb55d8f6b5583ac5335f933aba9101dc", size = 4700648, upload-time = "2026-07-31T14:24:00.702Z" }, + { url = "https://files.pythonhosted.org/packages/30/82/85f0f7425c856b9f96459411eb12e74ef72df9caf6f8f15bf23a33ff131f/cryptography-50.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80b63928fa35083b33966ce1efb70e5b9607181e49dcd1c22c8c005e319f667f", size = 4682442, upload-time = "2026-07-31T14:24:02.538Z" }, + { url = "https://files.pythonhosted.org/packages/1a/28/b555a365adff1cca2fbe7b9e487d68a40de6bc67ff2cb587473eb43de0e7/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:d58c3db7cd6eed54e6c06744db55456b65ebd7492ddeae9c1e93cfca7aa857d3", size = 4707596, upload-time = "2026-07-31T14:24:04.394Z" }, + { url = "https://files.pythonhosted.org/packages/72/d8/f52538140cc719df62a01cf87d1c7142318d235817109d6f4054d7c352d6/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:df2a58a472f332225671c35b0a830208b86d004f82baa8530fa3782c85646533", size = 5314552, upload-time = "2026-07-31T14:24:06.31Z" }, + { url = "https://files.pythonhosted.org/packages/38/14/6120e5bd7c5aa022ad15424ba4d5c5269d0d9448ed4d55e492ea91e3c1c4/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11b74db56cdbe3cdee6e3f6982ecb70334fa10dce99ed58bf7894aaaa3b2a037", size = 4717113, upload-time = "2026-07-31T14:24:08.349Z" }, + { url = "https://files.pythonhosted.org/packages/fa/71/190bf38c3ee2e0f8efc9860ae100c9df4169742eef274b91e7aa1cb133b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f59e38625469987d7ef6d495323c55e7db6c212eaf6112267e0d3b565a2e9c9f", size = 4338580, upload-time = "2026-07-31T14:24:10.227Z" }, + { url = "https://files.pythonhosted.org/packages/3a/63/504ccfbbe61fd8aa983f7f146399cdf034c72c2fc55f5b2dfdcdcdb20c99/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ecfed7367f965a0328cfbdd70da860f15441f002f613185668c6e6ebf5a0ac11", size = 4707038, upload-time = "2026-07-31T14:24:12.169Z" }, + { url = "https://files.pythonhosted.org/packages/01/77/2cf79bbfc4d12ca106437a6e170d6aaa01a373e93093118aaaef0e801bd4/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:9aa87839c383bdbab6ef865787a1fb877af8dd03464c4400322726feaaadfc6d", size = 5273110, upload-time = "2026-07-31T14:24:14.38Z" }, + { url = "https://files.pythonhosted.org/packages/e5/45/8aae2972c520145377ea3559a605a899bebe227bf070b33cdb445929a9b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:6ba6a53445bd3cfa809ef3ef5f1589aa6ba08784a1d962bf47d0940e871dab1c", size = 4716439, upload-time = "2026-07-31T14:24:16.415Z" }, + { url = "https://files.pythonhosted.org/packages/7b/20/4fe50b619a48c2525cc46e2dbc1ac490708d704be5d467bdaac6dc955682/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3f5735ffe4996d28b809371756219f5354864902a3b9e7c0b9ee87041209fc9c", size = 4837383, upload-time = "2026-07-31T14:24:18.553Z" }, + { url = "https://files.pythonhosted.org/packages/92/91/3a31366e183343d3703f8995c095f5734676bd6938118047e50fcf279eb4/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1b4a266766514614f8aa60416e71f2fc6e575d36e7bdc90f644fadb2f4b75b95", size = 4985772, upload-time = "2026-07-31T14:24:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/74/9a/02ffe35b2853d121689871eb5dce862092562b3a1ed5cc98f1aaed441506/cryptography-50.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:12b9c6996425c76ea6c457ace4f3073e715b8c545add07cd1a8f3a4f90691269", size = 3816291, upload-time = "2026-07-31T14:24:22.125Z" }, + { url = "https://files.pythonhosted.org/packages/03/37/73d005be173aff344af30e9fd2a576575cb2391a7101d9cd3842e1fa8cce/cryptography-50.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ccdc4a71a4dabae05de219404f9f4abc38e3b58422177ff93d0da05967dafa07", size = 4036009, upload-time = "2026-07-31T14:24:24.122Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c6/7a6202a534e32103a285b7834a120869557fe198d51d7cfe59754c8bda9c/cryptography-50.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:910e1d2668e7de9648f2bcee30e180db2a6b15c30f887d7c4c93ddf96e3992e3", size = 4745252, upload-time = "2026-07-31T14:24:26.118Z" }, + { url = "https://files.pythonhosted.org/packages/85/4f/0fa8c2f4428198f15d9ff8d63400e27afbf94ce833f6108da1eb3753f945/cryptography-50.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a91296cb61e8df6f86d0c19cc4068228da256bf59bf86049fbd821084565327f", size = 4728939, upload-time = "2026-07-31T14:24:27.994Z" }, + { url = "https://files.pythonhosted.org/packages/d1/63/54dd723490ba2dc09b299682c10b38db38f159728bcaae8c591b8af2f22d/cryptography-50.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e722f16708d854fe924790e051061f6704a472c3bac347b6fd88033ea8dd0dc5", size = 4748483, upload-time = "2026-07-31T14:24:30.254Z" }, + { url = "https://files.pythonhosted.org/packages/1d/dd/7c77d26285cc7f6991efce64a0f5b4f9383bfa5dd8c5033003eaf7db4cdb/cryptography-50.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d764dcf130c428ef66786f866dd750f53182bc608813489915e9fc106bb0c82f", size = 5367599, upload-time = "2026-07-31T14:24:32.457Z" }, + { url = "https://files.pythonhosted.org/packages/46/c9/f60aed34c013f317f92817b6c171c2d22a78270fa41109bd4b08af26b194/cryptography-50.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:105110f43a471dbd0060b9c9516cb8a6a79233631a04cc2ba16f28323ac6e025", size = 4762647, upload-time = "2026-07-31T14:24:34.599Z" }, + { url = "https://files.pythonhosted.org/packages/be/f3/f9a0173b139372c3a48ed98154b45cc6b9de17c789d5ab552e621c293609/cryptography-50.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:828743d939e9629bc267b8e2d08d8bb67cd4319c771a33d4b18b22dd8fb7440a", size = 4385197, upload-time = "2026-07-31T14:24:36.647Z" }, + { url = "https://files.pythonhosted.org/packages/d8/36/83bb81f6e569bc38e1e4a7bc80f29b46bb9601920bc455fc8e888f5d5742/cryptography-50.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a8183b489dc1f7f80f135780fadc1108f14b31b8a40411c7a5b17425f65f28b", size = 4748095, upload-time = "2026-07-31T14:24:39.493Z" }, + { url = "https://files.pythonhosted.org/packages/6b/16/d3008eff98c764979865834c3d386d4fd041b5f52e7f34fc29ac1a5eb515/cryptography-50.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6e7d61120573a7f2cd94cc095f9e81f6967c61ccdf194285aa143ecec8e0b708", size = 5325948, upload-time = "2026-07-31T14:24:41.556Z" }, + { url = "https://files.pythonhosted.org/packages/9c/f8/d97f9603efda3888187bfdb893f26c41be4735c10631d05d284ee6b047c4/cryptography-50.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:37fdb0d0111f1e2ff07139dfb79f1b49531f8e213c46f1163dd7642979b58c47", size = 4762400, upload-time = "2026-07-31T14:24:43.636Z" }, + { url = "https://files.pythonhosted.org/packages/64/a2/4615c8f7d81a00b1d6e6afe19f694e1543582349fb5f4076f6cb5dc36485/cryptography-50.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87f62a3d3b9888ed0fdde100ec06aa61ca9cd44bad9057d1dff9a516b5f5bb9", size = 4878208, upload-time = "2026-07-31T14:24:45.522Z" }, + { url = "https://files.pythonhosted.org/packages/d2/1a/efcfb02f91407149a0dacffffab791f7e19bf6385f63b3666dc8b5e5c9c8/cryptography-50.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:65c2c3add92b45fd0709db8594536aea39c2a67af0e27ffcf049c498501140b7", size = 5037050, upload-time = "2026-07-31T14:24:47.697Z" }, + { url = "https://files.pythonhosted.org/packages/57/30/4a22984d4f1bdfb8c054f07a92bc176b97a3134cc1d6c4b3bffb1f3688b4/cryptography-50.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:d24fead1d4d076e1bfb006dcec392074a3cd8d7b4fc8a595aa64073b2b7a96ba", size = 3874135, upload-time = "2026-07-31T14:24:50.085Z" }, + { url = "https://files.pythonhosted.org/packages/9d/3e/e54cde8c01631a5a8226ccd617eab9e57fd5cfdad90f1a9e6bb570794631/cryptography-50.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5e34edd123674534acd70147f0ca331eaa2c74e6325fb2028c886aa26ba0b68c", size = 3963170, upload-time = "2026-07-31T14:24:51.968Z" }, + { url = "https://files.pythonhosted.org/packages/01/b6/0b9e125e90f3d2dcf599a218a899cda7326a3158cfa258723f0b398b08f6/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8eb5e1172eb569ea8a872796576e6a67c276351728b6455d5beb01242b027c6a", size = 4692441, upload-time = "2026-07-31T14:24:53.743Z" }, + { url = "https://files.pythonhosted.org/packages/53/c9/a5151588710785a96d7bc4de27d4cd62f263bbbcb203cfe29df537eb6505/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:910d11e1a385c654bf738bf3e6b8e6ed5de0f5610fcae2be9e5b398d8081d20e", size = 4699810, upload-time = "2026-07-31T14:24:55.746Z" }, + { url = "https://files.pythonhosted.org/packages/c7/1a/15b92b25eb6ce3089cd49377ae990a0f3ad485a510f968aed1f19dbdcdf2/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:62598a8a57f815db4c6259a4e97d857dab56697e7de8e8ab02352ab74da1995d", size = 4691924, upload-time = "2026-07-31T14:24:58.082Z" }, + { url = "https://files.pythonhosted.org/packages/62/15/219075012ab13e8905f3cd572204f4acb4b111df787104346b9bc0cea789/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:07479a1cb08219ab719147e742e76090c9c773321959bb94946fffdd397a6437", size = 4699593, upload-time = "2026-07-31T14:24:59.951Z" }, + { url = "https://files.pythonhosted.org/packages/8e/b5/c2c5fce26f0ee40d21bafe7f191d29a34b35a65ac4fe8a1191d1983612e9/cryptography-50.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c99c003e088647b8a5b7c145d6f78c335f6348332b62e142d411c4b63d1460b9", size = 3813796, upload-time = "2026-07-31T14:25:02.298Z" }, ] [[package]] name = "datadog" -version = "0.52.2" +version = "0.53.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e4/44/3a285d5964203e414d89c3f41f1aeb71f9b8f17a8fc19ad18e1df5e65b4e/datadog-0.52.2.tar.gz", hash = "sha256:a74b1704ce37f3d9a0c36b1a87127c45032171726a01960bd210a549f1400849", size = 374430, upload-time = "2026-06-25T08:15:19.024Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/4a/8c61a6bd82be61a7b2a1f9dd77104f52299aa81d377fe6a35f9477167361/datadog-0.53.0.tar.gz", hash = "sha256:9f69a18089c852e20edff7e55226a6f4ca9749e162cfa4ae88c949dd722ebef8", size = 378021, upload-time = "2026-07-24T15:11:56.572Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/54/6df7d5b1563504374ca676b45ff0370fad98190a3a0747eff98a7599e8c8/datadog-0.52.2-py2.py3-none-any.whl", hash = "sha256:60fcc90ee7be3b767af878de4d5a6774a80c386cde1f15e900e66e42d2c6aaf9", size = 137083, upload-time = "2026-06-25T08:15:17.708Z" }, + { url = "https://files.pythonhosted.org/packages/da/83/1fda660aef15fa7f80fc9ad0f056d45dbe8dd09b1774a9cd6c4cfc6cf24d/datadog-0.53.0-py2.py3-none-any.whl", hash = "sha256:e42467bad752c4739a232986e4ebdb8e4690134e901965557f2eaff0f40eb177", size = 138980, upload-time = "2026-07-24T15:11:55.221Z" }, ] [[package]] @@ -2640,16 +2796,16 @@ wheels = [ [[package]] name = "docker" -version = "7.1.0" +version = "7.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pywin32", marker = "sys_platform == 'win32'" }, { name = "requests" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/91/9b/4a2ea29aeba62471211598dac5d96825bb49348fa07e906ea930394a83ce/docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c", size = 117834, upload-time = "2024-05-23T11:13:57.216Z" } +sdist = { url = "https://files.pythonhosted.org/packages/88/7f/731ff914b0255d3d065f45fd4e626d4b8c95dbcbaada049f337a6ac16410/docker-7.2.0.tar.gz", hash = "sha256:cebb93773d334f778e023a7ee352a8d6e13ab1bd3b863a4d4a59dec897df43ac", size = 118731, upload-time = "2026-07-09T14:53:46.39Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0", size = 147774, upload-time = "2024-05-23T11:13:55.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/23/529140fe1aab80fc6992f93a706deec709140a6397439139a054e1515c45/docker-7.2.0-py3-none-any.whl", hash = "sha256:a3f45fdeb9165e2d25d9a1d02ddf3bc70fb572cf5ebbf9b58558c22caf29b71f", size = 148775, upload-time = "2026-07-09T14:53:45.224Z" }, ] [package.optional-dependencies] @@ -2672,7 +2828,8 @@ version = "1.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "decorator" }, - { name = "stevedore" }, + { name = "stevedore", version = "5.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "stevedore", version = "5.9.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/c8/301ff89746e76745b937606df4753c032787c59ecb37dd4d4250bddc8929/dogpile_cache-1.5.0.tar.gz", hash = "sha256:849c5573c9a38f155cd4173103c702b637ede0361c12e864876877d0cd125eec", size = 947962, upload-time = "2025-10-11T17:35:36.898Z" } @@ -2724,16 +2881,16 @@ wheels = [ [[package]] name = "fakeredis" -version = "2.36.2" +version = "2.37.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "redis" }, { name = "sortedcontainers" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0a/ed/86ed74d8829c3bc565025c1c9efaf8518c9165fbf8c9cc2c026c8ed21bd9/fakeredis-2.36.2.tar.gz", hash = "sha256:c37a0b307fae3f27ec7c19e59519e57b8c52782e00303df9075361b5ba441be6", size = 213336, upload-time = "2026-06-17T13:25:38.934Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/5e/fce3355d20d37dc18f7f4c422653ac69cabffa019afaaf607e26704fb829/fakeredis-2.37.1.tar.gz", hash = "sha256:9045851b0a9fe56312696aadc82435141aa43a193cab462d372c8fb583a7c087", size = 238182, upload-time = "2026-08-18T15:22:01.676Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/4d/e6e40f93031adbf654d34e542bd396e9f3bc1c6209b40c920d58c9e1317a/fakeredis-2.36.2-py3-none-any.whl", hash = "sha256:84cbb9c74ca8946c0d2499daadf3a5d0bfe3cfbac71e3398316d1a1eab3421c4", size = 141039, upload-time = "2026-06-17T13:25:36.638Z" }, + { url = "https://files.pythonhosted.org/packages/7b/e0/fe1c760abd9e9cb5dfbce057b6582cb1ac36dfd8b5ce202e1445605c922d/fakeredis-2.37.1-py3-none-any.whl", hash = "sha256:f15c41be151c1e9206416dece764369a4dedb6b1341df3734c3c2c000e405508", size = 152738, upload-time = "2026-08-18T15:22:00.1Z" }, ] [[package]] @@ -2871,7 +3028,7 @@ wheels = [ [[package]] name = "google-api-core" -version = "2.31.0" +version = "2.34.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-auth" }, @@ -2880,9 +3037,9 @@ dependencies = [ { name = "protobuf" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/22/155cadf1d49272a9cf48f3168c0f3874fa13397297e611a5ea00cd093880/google_api_core-2.31.0.tar.gz", hash = "sha256:2be84ee0f584c48e6bde1b36766e23348b361fb7e55e56135fc76ce1c397f9c2", size = 176492, upload-time = "2026-06-03T14:52:17.257Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/7c/9be3903e3d45415e8ca493c75f8990a0f6f579d168015d44c379350d0ab0/google_api_core-2.34.0.tar.gz", hash = "sha256:98a779fe72de956eb1c9c2f47ff4c4432a668ece1a002ec38bed07ec2698ae59", size = 187953, upload-time = "2026-08-06T06:23:58.128Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/40/9bdbb60b03a332bd45acb8703da08bbc27d991d35286b62e42acc86d243a/google_api_core-2.31.0-py3-none-any.whl", hash = "sha256:ef79fb3784c71cbac89cbd03301ba0c8fb8ad2aa95d7f9204dd9628f7adf59ab", size = 173102, upload-time = "2026-06-03T14:51:26.729Z" }, + { url = "https://files.pythonhosted.org/packages/bc/c1/a8a92ae1bc4b1a8f804c776d7d3f0c771b78a62c3ad4df1be41b3fd8c767/google_api_core-2.34.0-py3-none-any.whl", hash = "sha256:cdf9c67e7ca2402d86ccbfde5f2503fc83e3cc3f58cc78456ae96cad24a6d2de", size = 180545, upload-time = "2026-08-06T06:22:47.502Z" }, ] [package.optional-dependencies] @@ -2893,7 +3050,7 @@ grpc = [ [[package]] name = "google-api-python-client" -version = "2.198.0" +version = "2.199.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -2902,35 +3059,35 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/53/0cd38e3a29d72ce45e27feba2ce1cd8049d69af9c48cb14fb164f1be9133/google_api_python_client-2.198.0.tar.gz", hash = "sha256:dfe3e16fb241af6e9c460a33f65085b3450e05cea09364f6b5d8997fb7e43e2a", size = 15060142, upload-time = "2026-06-25T14:32:42.953Z" } +sdist = { url = "https://files.pythonhosted.org/packages/13/ff/c58d475046b552754a5ee24d98912506b07ea7ac7f0a434b327ad194ca32/google_api_python_client-2.199.0.tar.gz", hash = "sha256:8150816e22e01b36aa4b7523cdc1a2d2164e81c4de8a9b338785d7ecb4390ec2", size = 15394941, upload-time = "2026-08-20T21:38:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/92/0fc9e7a09eb240c31b879bd8d2e43f81ed1f86c4798b79ead4a083921ab3/google_api_python_client-2.198.0-py3-none-any.whl", hash = "sha256:fabac935474e817da5e662ff61bf7139439d6f92b32d332a7318a2d45931e03e", size = 15644203, upload-time = "2026-06-25T14:32:39.963Z" }, + { url = "https://files.pythonhosted.org/packages/b5/42/c443badc33d972ee0e0adcd481c32a71f15d3e04c23a7a3d758e4018c633/google_api_python_client-2.199.0-py3-none-any.whl", hash = "sha256:1d2fa0e7f9d68f063b1a9ff7ed290d6e6c93176260487bf3a991e41534ca23a3", size = 15991965, upload-time = "2026-08-20T21:38:37.274Z" }, ] [[package]] name = "google-auth" -version = "2.55.1" +version = "2.56.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "pyasn1-modules" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/6f/f3f4ac177c67bbee8fe8e88f2ab4f36af88c44a096e165c5217accf6e5d3/google_auth-2.55.1.tar.gz", hash = "sha256:fb2d9b730f2c9b8d326ec8d7222f21aef2ead15bf0513793d6442485d87af0a1", size = 349527, upload-time = "2026-06-25T23:39:27.182Z" } +sdist = { url = "https://files.pythonhosted.org/packages/db/4c/fa42116a48bab3f7a143cf5042ecff7df9c8b73f8a376203cd534d1dc966/google_auth-2.56.3.tar.gz", hash = "sha256:40e229fc901f0a305b553050e5fce562d509bee0435be053abfa91582b51b90c", size = 367110, upload-time = "2026-08-06T06:24:01.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/1d/f6d3ca1ad0725f2e08a1c6915640748a52de2e66596160a4d53b010cccf0/google_auth-2.55.1-py3-none-any.whl", hash = "sha256:eada68dfd52b3b81191827601e2a0c3fa12540c818534b630ddc5355769c3995", size = 252349, upload-time = "2026-06-25T23:38:52.946Z" }, + { url = "https://files.pythonhosted.org/packages/bc/b3/6117b2f24065cd7e2c4f140e9a193e215f089ca8ba314cf91eb9d0b7fe0a/google_auth-2.56.3-py3-none-any.whl", hash = "sha256:8ec438808f813ad034535000261eed1067475d229d05bbf4216e78c3f2362e53", size = 259116, upload-time = "2026-08-06T06:22:51.788Z" }, ] [[package]] name = "google-auth-httplib2" -version = "0.4.0" +version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-auth" }, { name = "httplib2" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/b3/f192c8bc7e41e0ebdbd95afcae4783417a34b6a6af62d22daf22c3fd38fc/google_auth_httplib2-0.4.0.tar.gz", hash = "sha256:d5b030a204b7a4b4d553ba9ca701b62481ee2b74419325580be70f7d85ffed35", size = 11161, upload-time = "2026-05-07T08:03:46.878Z" } +sdist = { url = "https://files.pythonhosted.org/packages/11/46/79983cb738f0eb14e6ab4f43457aa9652f8d46bc4376b178f676b68c5c37/google_auth_httplib2-0.4.1.tar.gz", hash = "sha256:125b1bb4fcfdd2d97f19b673c1f46f831603d0acaffe415c8a35dadb312552a1", size = 11158, upload-time = "2026-08-06T06:24:00.452Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/be/954c35a62b9e31de66b0a43c225c9b6bb9e0f98d6b1dc110a2308e3644f5/google_auth_httplib2-0.4.0-py3-none-any.whl", hash = "sha256:8e55cfafa3358cba85f6cad4a886138e88e158d71e7e5c9ee5936a5c1507fb91", size = 9529, upload-time = "2026-05-07T08:02:12.375Z" }, + { url = "https://files.pythonhosted.org/packages/68/8a/96410d0c3e02b584d1e7f5d4000b2e1710855650b226cd0601f2b154940a/google_auth_httplib2-0.4.1-py3-none-any.whl", hash = "sha256:67088a8387dc3f66016a690634f1cb9b7a48a31406f8998e088efc64203e7a12", size = 9529, upload-time = "2026-08-06T06:22:50.53Z" }, ] [[package]] @@ -2951,33 +3108,33 @@ wheels = [ [[package]] name = "google-cloud-audit-log" -version = "0.6.0" +version = "0.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "googleapis-common-protos" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/01/46/b971191224557091cc865b47d527e61da180e33b9397904bdefdae1dcacd/google_cloud_audit_log-0.6.0.tar.gz", hash = "sha256:4dd343683c0bb31187ebef3426803f13159e950fbea3fe60a864855cfed959b8", size = 44674, upload-time = "2026-06-03T14:52:48.095Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/d1/fd23bd634ef7e2a1e27c6cf16f6dfa8b44c09d383044641cfef5d21ef9d9/google_cloud_audit_log-0.6.1.tar.gz", hash = "sha256:4aba72b45dc15344da1b2d8981320050fe39cfe80432f38e7318aa2e477c5bf2", size = 44688, upload-time = "2026-08-06T06:24:04.508Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/99/27c70286bfa3503e43f845578ed5c2ab30c0cc68e525c168286f05f9a51c/google_cloud_audit_log-0.6.0-py3-none-any.whl", hash = "sha256:8c5ecbc341ad3b3daf776981f6d7fd7ab5ff5a29c5dce3172c669b570e0f6717", size = 44853, upload-time = "2026-06-03T14:52:03.775Z" }, + { url = "https://files.pythonhosted.org/packages/92/db/af25d04b2e67c1dc49e00bf59e58a45962cf27f12f04b8dfca8753009971/google_cloud_audit_log-0.6.1-py3-none-any.whl", hash = "sha256:981b2ac69e69fe8ed0eb71998d8520a746d5db9bdfad0f088ab4b4628702824e", size = 44853, upload-time = "2026-08-06T06:22:56.144Z" }, ] [[package]] name = "google-cloud-core" -version = "2.6.0" +version = "2.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, { name = "google-auth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/dd/1eef226e470369b26824a505c34482c0b493bc35fe8e0c6b003b5feca21a/google_cloud_core-2.6.0.tar.gz", hash = "sha256:e76149739f90fac1fc6757c09f47eaccb3145b54adbd7759b0f7c4b235f46c83", size = 36001, upload-time = "2026-05-07T08:04:04.124Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/c6/9d7d9ed6703eb35306ca7bf381fb66ba8d978c61a1b550a2e1730a4c4ce8/google_cloud_core-2.6.1.tar.gz", hash = "sha256:1e044b131f2ae097b92312fa195164b0aeb6dc6a88e00231e1210516314c420c", size = 36017, upload-time = "2026-08-06T06:24:18.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/4a/98da8930ab109c73d9a5d13782a9ebb81ea8c111f6d534a567b71d23e52b/google_cloud_core-2.6.0-py3-none-any.whl", hash = "sha256:6d63ac8e5eca6d9e4319d0a1e2265fadcd7f1049904378caecfa01cf52dd869e", size = 29390, upload-time = "2026-05-07T08:02:34.672Z" }, + { url = "https://files.pythonhosted.org/packages/5d/4f/37960d5255988b218c40c9b5a2b731013684294a50735d1dd1ab4894e531/google_cloud_core-2.6.1-py3-none-any.whl", hash = "sha256:2682a8a4474a32f56292fb4bca7fa7e4fb0b4af958f6abfe4bca8d195747fd45", size = 29393, upload-time = "2026-08-06T06:23:11.405Z" }, ] [[package]] name = "google-cloud-logging" -version = "3.16.0" +version = "3.16.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core", extra = ["grpc"] }, @@ -2991,9 +3148,9 @@ dependencies = [ { name = "proto-plus" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/ba/e749846f13c8d1c6c01eb6317e8b09abc130fe67b5d72081a48d1bf96971/google_cloud_logging-3.16.0.tar.gz", hash = "sha256:08a3076b8f0f724219d6f73b2a242ef69d51e8bce226133aebe41a25f23f5400", size = 293703, upload-time = "2026-06-03T15:28:23.862Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/65/d7dd485edea0ff3b403c680675042fd999dbe8ee6bc881d2248dfbc609ea/google_cloud_logging-3.16.2.tar.gz", hash = "sha256:d65044004d3a2ae6eced1f0118f0c44dc551872ddb837ba815f75d159ca148c8", size = 294046, upload-time = "2026-08-06T06:24:27.714Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/d5/91035dd77e0033dfb00d52b2bcad1e4f7408eb931981f86a1584301670a8/google_cloud_logging-3.16.0-py3-none-any.whl", hash = "sha256:9e5bfbdfe7b5315ece00e1703a2ea25fe42ca35e0b4750127b019f50d069b01b", size = 234188, upload-time = "2026-06-03T15:27:37.407Z" }, + { url = "https://files.pythonhosted.org/packages/88/2f/a5cd299307ab1fa8fa67be540cdea5a377947120bb6a072bfdb52928ad73/google_cloud_logging-3.16.2-py3-none-any.whl", hash = "sha256:797d4d50dd1c0fea6a851a911bbaa092e3690b45786fd8ea438ef762eeeb8f35", size = 233852, upload-time = "2026-08-06T06:23:20.089Z" }, ] [[package]] @@ -3014,7 +3171,7 @@ wheels = [ [[package]] name = "google-cloud-secret-manager" -version = "2.29.0" +version = "2.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core", extra = ["grpc"] }, @@ -3024,9 +3181,9 @@ dependencies = [ { name = "proto-plus" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d2/7c/5c88cdde9664f6c75fb68aa11e0af4309a92bef38dd38df0456ffb0f469b/google_cloud_secret_manager-2.29.0.tar.gz", hash = "sha256:ee64133af8fdb3780affb65ec6ccf10ab15a0113d8edeba388665f4be87ce1be", size = 278437, upload-time = "2026-06-03T16:13:43.149Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/4a/7acb616b316c91969f7abf5f3719cb61cc4a97af86411e683ddb11147aa1/google_cloud_secret_manager-2.30.0.tar.gz", hash = "sha256:26ec87737731b483f7f95c26a8c7ab79e22cb66317c95006e7f6985dbc43c8a2", size = 286034, upload-time = "2026-07-16T20:36:23.29Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/c2/fc3275bc42a522757cb5141d7dae51f048b93d2f5fe4574fcee5392cef03/google_cloud_secret_manager-2.29.0-py3-none-any.whl", hash = "sha256:21bac2d0adb0bb3c13c346d7223832f197c2266534528a1bf1402774e06395a3", size = 225042, upload-time = "2026-06-03T16:12:20.162Z" }, + { url = "https://files.pythonhosted.org/packages/18/8b/9347282b7f6828511d8cf927f3ab62b4b849aaa46aa12ae79e2f6da6cb0b/google_cloud_secret_manager-2.30.0-py3-none-any.whl", hash = "sha256:0f285e77d09a73700e3fca9abbc77f844a50276989bf76d64a76b6e2b871e396", size = 229181, upload-time = "2026-07-16T20:36:01.125Z" }, ] [[package]] @@ -3083,26 +3240,26 @@ wheels = [ [[package]] name = "google-resumable-media" -version = "2.10.0" +version = "2.10.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-crc32c" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/48/f8/1ca5781d6be9cb9f73f7d40f4958c4bd1226a60598e3e39e1d6aaf838c4b/google_resumable_media-2.10.0.tar.gz", hash = "sha256:e324bc9d0fdae4c52a08ae90456edc4e71ece858399e1217ac0eb3a51d6bc6ee", size = 2164570, upload-time = "2026-06-03T16:14:26.103Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/f5/f35505e6091614e285056a495488cb0a9c1a9dcc88a4a3c91bbc5fd4835b/google_resumable_media-2.10.1.tar.gz", hash = "sha256:224975032ddb73f7ed9e2f0f4cc08ed1b06874c52d48cc8533e3eb72980b21a0", size = 2164548, upload-time = "2026-08-06T06:24:50.489Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/d8/00c6854ac1512bb9eaf13bd3f8f28222f7674947fc510a4ff7616f2efc80/google_resumable_media-2.10.0-py3-none-any.whl", hash = "sha256:88152884bee37b2bf36a0ab81ad8c7fd12212c9803dd981d77c1b35b02d34e7c", size = 81533, upload-time = "2026-06-03T16:13:12.51Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ba/77ef49baf338c03a11deadac984e3161b3f2b4fa4bb5aab160e7ca0fd522/google_resumable_media-2.10.1-py3-none-any.whl", hash = "sha256:4e2cbc704207ddc09f23b1f18e8ef4a4ccbfe0f1768b370e5c969704adbd0a1c", size = 81533, upload-time = "2026-08-06T06:23:45.464Z" }, ] [[package]] name = "googleapis-common-protos" -version = "1.75.0" +version = "1.75.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b5/c8/f439cffde755cffa462bfbb156278fa6f9d09119719af9814b858fd4f81f/googleapis_common_protos-1.75.0.tar.gz", hash = "sha256:53a062ff3c32552fbd62c11fe23768b78e4ddf0494d5e5fd97d3f4689c75fbbd", size = 151035, upload-time = "2026-05-07T08:04:49.423Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/73/74bcab964c9a7a61f2bb71e8179b0f13e6fa98f7ce00fd168aab291e4a2e/googleapis_common_protos-1.75.1.tar.gz", hash = "sha256:d3042c6c5a2d4e67113104d6b6818b59b6bd92a197f2a91508e801fe815cf071", size = 150967, upload-time = "2026-08-06T06:24:51.972Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/c8/e2645aa8ed02fd4c7a2f59d68783b65b1f3cbdfe39a6308e156509d1fee8/googleapis_common_protos-1.75.0-py3-none-any.whl", hash = "sha256:961ed60399c457ceb0ee8f285a84c870aabc9c6a832b9d37bb281b5bebde43ed", size = 300631, upload-time = "2026-05-07T08:03:30.345Z" }, + { url = "https://files.pythonhosted.org/packages/9a/51/186c02b8549b69ccda44429cf6ff5081e4b61a602ddfe6a8020d1be31d1b/googleapis_common_protos-1.75.1-py3-none-any.whl", hash = "sha256:28a1934bcd33b9c9da66ac301a0a4227e3367f095a17d0375cb98f0a09d93b79", size = 300626, upload-time = "2026-08-06T06:23:46.696Z" }, ] [package.optional-dependencies] @@ -3112,91 +3269,91 @@ grpc = [ [[package]] name = "grpc-google-iam-v1" -version = "0.14.4" +version = "0.14.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "googleapis-common-protos", extra = ["grpc"] }, { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/44/4f/d098419ad0bfc06c9ce440575f05aa22d8973b6c276e86ac7890093d3c37/grpc_google_iam_v1-0.14.4.tar.gz", hash = "sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038", size = 23706, upload-time = "2026-04-01T01:57:49.813Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d2/d0/fa5bdd5f3f421bb68dc6dc162e9caaf942897ca41ce7255b524723c80f0b/grpc_google_iam_v1-0.14.5.tar.gz", hash = "sha256:07fd3a9fafb586588e771831fbfc8f6597050181d0c3b45e039d18b8fdc1aab5", size = 23736, upload-time = "2026-08-06T06:24:54.489Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/22/c2dd50c09bf679bd38173656cd4402d2511e563b33bc88f90009cf50613c/grpc_google_iam_v1-0.14.4-py3-none-any.whl", hash = "sha256:412facc320fcbd94034b4df3d557662051d4d8adfa86e0ddb4dca70a3f739964", size = 32675, upload-time = "2026-04-01T01:57:47.69Z" }, + { url = "https://files.pythonhosted.org/packages/84/ab/be3ad0d46cffe35fd1e7cc3f9947edd6cb3c552229de3be2742f15f7ea47/grpc_google_iam_v1-0.14.5-py3-none-any.whl", hash = "sha256:0f5e680b20aa0a9441e68c769da04d94d70fca4e43751a82d8abb8aa6a7181ca", size = 32674, upload-time = "2026-08-06T06:23:49.467Z" }, ] [[package]] name = "grpcio" -version = "1.81.1" +version = "1.83.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b0/b5/1ff353970a87eda4c98251e34d2dfd214abd4982dc89119c9252a2a482d2/grpcio-1.81.1.tar.gz", hash = "sha256:6fa10a767143a5e82e8eaab53918af0cd8909a57a27f8cb2288b80a613ac671b", size = 13026582, upload-time = "2026-06-11T12:46:51.673Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/d5/f2b159d8eec08be2a855ef698f5b6f7f9fdda022e4dd9e4f5d968affd678/grpcio-1.81.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:6f9a0c9c1cc15c112d1c053064fd032b64917062292c3d70aea280e02ae10b77", size = 6086868, upload-time = "2026-06-11T12:44:19.364Z" }, - { url = "https://files.pythonhosted.org/packages/80/41/9c95232b94b219ed8b14029d9cd000e0381cafba869c451dda60af84f4ba/grpcio-1.81.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:69ef28e54fc85397f91b8c19592b8ef3d81952080366914823bd8572a2958120", size = 12062291, upload-time = "2026-06-11T12:44:27.142Z" }, - { url = "https://files.pythonhosted.org/packages/83/8b/bd9284bdd665ddf877a3e8bc2930d1bcf6ebdbae7b0da5c783dc26bd6e33/grpcio-1.81.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:15641444eca4a29358107b3dceb74c1c6305c55c822fd199b458aaea4068a7fb", size = 6635242, upload-time = "2026-06-11T12:44:30.741Z" }, - { url = "https://files.pythonhosted.org/packages/60/24/78fa025517a925f1a17da71c4ef9d5f1c6f9fa65af22dfb523c5c6317a21/grpcio-1.81.1-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d4b2dddfc219f54f956ccd53cf76a1d338ffe68fc7f2849ec9c7feb9927ff692", size = 7332974, upload-time = "2026-06-11T12:44:33.72Z" }, - { url = "https://files.pythonhosted.org/packages/f7/11/402295b388dd35861007f8a26a37c2e2f284212d57bdf407c31f36043746/grpcio-1.81.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ca1cc11d82677b9662082e5478b7528e2b7db7beaa6bdff42bd62789d81be399", size = 6836597, upload-time = "2026-06-11T12:44:36.108Z" }, - { url = "https://files.pythonhosted.org/packages/4d/71/37b10fd4fd579ffade6e695c14e9df5e8cba9e2365b81c131da438b67c34/grpcio-1.81.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa2ba7d2ad6df4d80127cea65e5b8d5e2c3adbf153ff4804452836328aca7c54", size = 7440660, upload-time = "2026-06-11T12:44:38.664Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d5/40203f828abc83d458b634666df6df13778032f178c03845ad5a93682388/grpcio-1.81.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:592b5fee597faa91cce2dd294dd7d9a1c83d76c4dbf877e33ec1adb866b2fbed", size = 8443171, upload-time = "2026-06-11T12:44:41.678Z" }, - { url = "https://files.pythonhosted.org/packages/eb/2c/0ed82ea35b5ec595e10444940c1db8c0e0ef57aa46bc8797d5ff838a219e/grpcio-1.81.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62481553b1793a27e9b9c3cf9e5bd483ef045ca72462592074b46d42b0c4d9b9", size = 7868905, upload-time = "2026-06-11T12:44:44.854Z" }, - { url = "https://files.pythonhosted.org/packages/9e/1f/dcbdc1a68a07cc2b631c3098953794f17d75f93426a019240b90ce5423d6/grpcio-1.81.1-cp310-cp310-win32.whl", hash = "sha256:bb693b1e3d9a2f3fd228e2110daf4b5aeedb36761ca1e4282f74725f6d89f611", size = 4202215, upload-time = "2026-06-11T12:44:47.165Z" }, - { url = "https://files.pythonhosted.org/packages/75/a1/d7ab9f1f42efcb7d9e6111d38be6b367737a72ea2c534e1f55c81e1b6436/grpcio-1.81.1-cp310-cp310-win_amd64.whl", hash = "sha256:88268ca418cacea64cecb0d1d600d3c6b3a8038fcba02e1e205178c5b1f47661", size = 4936582, upload-time = "2026-06-11T12:44:49.479Z" }, - { url = "https://files.pythonhosted.org/packages/52/ea/1c2fa386b718ff493225e61cfc052ef400b4d6ffc54cbe261026432624b5/grpcio-1.81.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:d71d30f2d92f67d944631c523713934fee37292469e182ebcd2c1dd8a64ce53f", size = 6093112, upload-time = "2026-06-11T12:44:52.131Z" }, - { url = "https://files.pythonhosted.org/packages/2b/18/acf45fa8bd1bc5d7b0c2fd3dc4c209379fbd5bb396b440b68a83342226b7/grpcio-1.81.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b137f4bf3ada9dc44d411478decc6ff09a79ed30b306cd2abaa98408c3588137", size = 12074277, upload-time = "2026-06-11T12:44:55.354Z" }, - { url = "https://files.pythonhosted.org/packages/48/d7/ee86a60699b7db039f772a2c4a7e4facc7138984ff42c0130933a0063884/grpcio-1.81.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a3acb384427816dd5d470f47e62137b87f74da694faa8a50147012cf40df276a", size = 6640348, upload-time = "2026-06-11T12:44:59.223Z" }, - { url = "https://files.pythonhosted.org/packages/26/ee/d2de5e47378ffc207d476c230fea3be4d2601edbce9995f4fe45535d4896/grpcio-1.81.1-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f9a0ebbe45c29b5e5866593c12b78bd9035f0f0f0d4bc8361680cd580d99db49", size = 7331842, upload-time = "2026-06-11T12:45:02.001Z" }, - { url = "https://files.pythonhosted.org/packages/23/d6/abeda5c2b896a0b341584fe5ac411bbf72e197a9a374c355fb90965e08d2/grpcio-1.81.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a37165cc80b1a368384b383e63a4c38116a10467ae44c904d2d7468c4470ec2", size = 6842229, upload-time = "2026-06-11T12:45:04.76Z" }, - { url = "https://files.pythonhosted.org/packages/10/1c/1f0da7d590b4aeee006826ba568d0e419ca14b23e18f901a3da3e9fba613/grpcio-1.81.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6282caffb41ec326d4cb67ca9cf53b739d1b2f975a2acb498c7418e9f7d9a416", size = 7446096, upload-time = "2026-06-11T12:45:07.499Z" }, - { url = "https://files.pythonhosted.org/packages/6a/81/5c505d508f7c887aa7982d21443a4126597c80d34b0bcf40f9cec576d7f3/grpcio-1.81.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a35009284d0d3d5c2c9601c164a911b8b4331608d98a9a66d47d97bb2f522b70", size = 8445238, upload-time = "2026-06-11T12:45:10.243Z" }, - { url = "https://files.pythonhosted.org/packages/f7/b2/524847365122ee509ca17bcc4e092198b700e94af7bfd5bb5e6dd9f3ee66/grpcio-1.81.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1b22c80559854b789a01fd89e8929b3798a156c0829b5282a8939f33ad4115ad", size = 7873989, upload-time = "2026-06-11T12:45:13.102Z" }, - { url = "https://files.pythonhosted.org/packages/18/fa/07c037c50b006909d1d13a5848774f8aa7b242f70dc03a035c64eea0e6db/grpcio-1.81.1-cp311-cp311-win32.whl", hash = "sha256:428bec0161b48d8cf583c068591bc0016d0d9cfff52462b72b3884861ea768c5", size = 4202223, upload-time = "2026-06-11T12:45:16.166Z" }, - { url = "https://files.pythonhosted.org/packages/41/ed/6bff15376920942fac6b95b9802752b837437172c9e8fc2d3170546b89cc/grpcio-1.81.1-cp311-cp311-win_amd64.whl", hash = "sha256:30e825f6848d9f18bba350ed6c75c1b02a0b5184474a31db9a32b1fa66fd8c79", size = 4941303, upload-time = "2026-06-11T12:45:18.724Z" }, - { url = "https://files.pythonhosted.org/packages/85/07/9a979c81738863a738dc23d65177056e71fbb2db817740ed870b33434e7a/grpcio-1.81.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8b39472beafc0bdcafc4c8c73ad082ebfdb449d566897a61e7acb4fa88089115", size = 6053264, upload-time = "2026-06-11T12:45:21.017Z" }, - { url = "https://files.pythonhosted.org/packages/75/95/539706ca0d3bd40dbad583dc56fd883da941f37556b629132da5762781b9/grpcio-1.81.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:12b7524c88d4026d3dcb7b0ebe16b6714f3b4af402ddd0f0639ab064a00c87c3", size = 12052560, upload-time = "2026-06-11T12:45:23.652Z" }, - { url = "https://files.pythonhosted.org/packages/e0/44/f257b7e0bd69c93b06c6cb8ac8d1b901ccb42bedabd83c1a4c77a71f8810/grpcio-1.81.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1e123f9b37edb8375fd74130d1f69c944bbf0a7b06761ae7211154b8759e94d2", size = 6595983, upload-time = "2026-06-11T12:45:26.963Z" }, - { url = "https://files.pythonhosted.org/packages/b9/f3/19782aa04c960968bef8c5539329d8e3bbc3364e2e46d19eb5e5cc5e43b7/grpcio-1.81.1-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2c2e2ae6867c2966b8daccc836d54a13218e0007e9a490aeb81dd05be64d22d7", size = 7303455, upload-time = "2026-06-11T12:45:29.707Z" }, - { url = "https://files.pythonhosted.org/packages/eb/8c/dea020b6d91508cd84463917a63149ec196ee7db505d032ae43fcb3303b9/grpcio-1.81.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:766bc7c9a9c340342f4c864ccbda8e78111e4751f13b895812b9c148fb79e9d0", size = 6809167, upload-time = "2026-06-11T12:45:32.52Z" }, - { url = "https://files.pythonhosted.org/packages/1c/c7/3030dd940408083bd32cd95d634777a71605ade4887154d93e8a89244946/grpcio-1.81.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b259a04a737cb3496be0901328eb8b7552ed8df4865d8c8f1cf1bffcfc0776a3", size = 7412536, upload-time = "2026-06-11T12:45:35.403Z" }, - { url = "https://files.pythonhosted.org/packages/e0/dd/1172a9e42b168edcafefad6115346ef619a3fc02158bb170e66ced24bcdd/grpcio-1.81.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:85b10a45b8993d195c4f3ff57025b8d1e11834909ee475c403bfa60cb4caefaf", size = 8408276, upload-time = "2026-06-11T12:45:37.78Z" }, - { url = "https://files.pythonhosted.org/packages/25/7a/71437c7f3596e5246155c515852795a85a1a8d228190212432b13b97a95d/grpcio-1.81.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8ea1936c26b99999b27479853039a7f34713f56c49375ad52b38535ec93a796c", size = 7849660, upload-time = "2026-06-11T12:45:40.627Z" }, - { url = "https://files.pythonhosted.org/packages/65/40/7debc0da45d2efebafb82da75644be347497fe4ee250514b8cd3b86ae8bf/grpcio-1.81.1-cp312-cp312-win32.whl", hash = "sha256:a185a04039df6cae8648bc8ab6d6fde7bf94f7188ecf7828e76ac52eef1e41d6", size = 4185819, upload-time = "2026-06-11T12:45:43.027Z" }, - { url = "https://files.pythonhosted.org/packages/2e/b9/8fe3ba5ed462067774ebc1f9c7f26aa7ebcc280ddd476be107153de1339e/grpcio-1.81.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ad74f8bb1a18963914c5452d289422830b39459e8776ebbcd207be1fbfb1d94", size = 4930461, upload-time = "2026-06-11T12:45:45.775Z" }, - { url = "https://files.pythonhosted.org/packages/7a/42/dcc2e4b600538ef18327c0839d56b7d3c3812337c5d710df5877dbb39b1e/grpcio-1.81.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:b10e1ff4756ed27d5a29d7fc79cfce7ef1ff56ad20025b89bac7cf79e09abbbe", size = 6054466, upload-time = "2026-06-11T12:45:48.43Z" }, - { url = "https://files.pythonhosted.org/packages/7b/4a/a36e03210183a8a7d4c80c3936acee679f4bd77d5861f369db47b2cc5f05/grpcio-1.81.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:819edbdcb42ab8598b494bcf0222684bbb7a3c772bd1b1f0be7e029a6063c28e", size = 12048795, upload-time = "2026-06-11T12:45:54.011Z" }, - { url = "https://files.pythonhosted.org/packages/b0/d5/d68e30b29098f63beab6fe501100fe82674ff142b32c672532da86a99b3a/grpcio-1.81.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c5bf2dc311127d91230cc79b92188c082634a06cf66c5234db49a43b910183b0", size = 6599094, upload-time = "2026-06-11T12:45:57.799Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b3/e837954d279754f638a11cca5dcf6b24a005efb398984cefaf7735945a54/grpcio-1.81.1-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e8ca6a1fcdb2943c9cbc1804a1baf3acb6071d72a471591678ded84218006e14", size = 7307182, upload-time = "2026-06-11T12:46:00.568Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1e/b47957057e729adc6cdf519a47f8be2562b7140e280f1418443eb4022192/grpcio-1.81.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e64dd101d380a115cc5a0c7856788adb535f1a4e21fc543775602f8be95180ae", size = 6810962, upload-time = "2026-06-11T12:46:03.312Z" }, - { url = "https://files.pythonhosted.org/packages/40/26/569868e364e05b19ec8f969da53d230bcd89c962cd198f7c29943155c4d3/grpcio-1.81.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:98a07f9bf591e3a8919797bee1c53f026ba4acd587e5a4404c8e57c9ec36b2a5", size = 7415698, upload-time = "2026-06-11T12:46:06.005Z" }, - { url = "https://files.pythonhosted.org/packages/36/0c/5440a0582cb5653fc42a6e262eeb22700943313f8076f9dc927491b20a59/grpcio-1.81.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c261d74b1a945cf895a9d6eccd1685a8e837531beaab782da4d630a8d12deffb", size = 8407779, upload-time = "2026-06-11T12:46:08.84Z" }, - { url = "https://files.pythonhosted.org/packages/ff/aa/66fe9f39871d766987d869a03ee0842a026f499c7b1e62decb9e78a8088e/grpcio-1.81.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58ad1131c300d3c9b933802b3cc4dc69d380822935ba50b28703156ea826fbf7", size = 7844521, upload-time = "2026-06-11T12:46:12.171Z" }, - { url = "https://files.pythonhosted.org/packages/f0/9e/69bb7194861bcd28fb3193261d4f9c3831b4446993f002cf59068943e7ab/grpcio-1.81.1-cp313-cp313-win32.whl", hash = "sha256:78e29211f26da2fdd0e9c6d2b79f489476140cf7029b6a64808ade7ca4156a42", size = 4182786, upload-time = "2026-06-11T12:46:15.192Z" }, - { url = "https://files.pythonhosted.org/packages/0d/20/3da8bb0d637feccdc3e1e419bb511ce93651ce7d54164f95de22cc0b8b34/grpcio-1.81.1-cp313-cp313-win_amd64.whl", hash = "sha256:edb59506291b647a30884b1d51a599d605f40b20af4a7dc3d33786a47a31de60", size = 4928648, upload-time = "2026-06-11T12:46:17.823Z" }, - { url = "https://files.pythonhosted.org/packages/b6/58/19414622b1bf6981bc9c05a365bd548e71876c89000083b3af489251e9c0/grpcio-1.81.1-cp314-cp314-linux_armv7l.whl", hash = "sha256:506f48f2f9c29b143fca3dad7b0d518c188b6c9648c75a2ae6e2d9f2c13a060b", size = 6055336, upload-time = "2026-06-11T12:46:20.557Z" }, - { url = "https://files.pythonhosted.org/packages/32/f1/2ec88adb92b0eba970dd0e0e7dd086341daa3c75eba4f735f9e44bf684b0/grpcio-1.81.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d865db4a6318e1c1bea83292e0ed231090538fc4ca45425b0f0480eb338bbc6e", size = 12056279, upload-time = "2026-06-11T12:46:24.255Z" }, - { url = "https://files.pythonhosted.org/packages/41/36/e8c5f8c6ec71de73733695ebc809e98b178b534ec6d8eaa31a7ebab4ad4c/grpcio-1.81.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2aa72e3ce1770317ef534f63d397b55e130725f5149bd36077c3b539019db27", size = 6608225, upload-time = "2026-06-11T12:46:27.601Z" }, - { url = "https://files.pythonhosted.org/packages/30/22/96fc577a845ab093326d9ab1adb874bd4936c8cf98ac8ed2f3db13a0a2fb/grpcio-1.81.1-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0490c30c261eded63f3f354979f9dc4502a9fb944cccb60cd9dc85f5a7349854", size = 7306576, upload-time = "2026-06-11T12:46:30.514Z" }, - { url = "https://files.pythonhosted.org/packages/76/7b/61dab5d5969f28d97fb1009cead1df0a5cd987d3315e1b37f18a4449f8bc/grpcio-1.81.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:410482da976329fe5f4067270401b12cf2bd552ff8020f054ecfaddb5475f9d6", size = 6812165, upload-time = "2026-06-11T12:46:33.699Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/6e501929d4f5f96462fd82fd9f0f06e5f9612207582b862868d68757b27d/grpcio-1.81.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3657301562ac3cb8018d30d0d3ebfa39932239f7b5703422057ef14b69949f5", size = 7422962, upload-time = "2026-06-11T12:46:36.511Z" }, - { url = "https://files.pythonhosted.org/packages/2a/7e/f2157589e66daa78ebb3165942d05a08bdea93b9d11c2bc1e172aef89685/grpcio-1.81.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:24c8e57504c8f45b237e40b99262d181071e5099a07053695b75d97bb53053a0", size = 8408176, upload-time = "2026-06-11T12:46:39.803Z" }, - { url = "https://files.pythonhosted.org/packages/da/df/c6717fef716e00d235ffb96123baf6dce76d6004f6233fa767c502861460/grpcio-1.81.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b427c19380991a4eaab2f6144b64b99b412043314c6bf4ab544f97bb31ee4190", size = 7846681, upload-time = "2026-06-11T12:46:43.013Z" }, - { url = "https://files.pythonhosted.org/packages/36/84/3502e9f210a6a5c4438c8aca3f88edd2e04f6a27f3d41b26cf0a0024b096/grpcio-1.81.1-cp314-cp314-win32.whl", hash = "sha256:61233fe8951e5c85dff81c2458b6528624760166946b5b47ea150a589168411f", size = 4264615, upload-time = "2026-06-11T12:46:45.741Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/4af731ff7492c68a96e4c71bfd0f4590acde92b31c6fe4894e6465c10ff6/grpcio-1.81.1-cp314-cp314-win_amd64.whl", hash = "sha256:3768a5ff1b2125e6f552e561b6b2dca0e64982d8949689b4df145cf8b98d7821", size = 5070275, upload-time = "2026-06-11T12:46:48.486Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/0c/98/304898ac4e04e2d5e4e4c2eadc178b1f2a16d5f4bc2f91306c87d64680b9/grpcio-1.83.0.tar.gz", hash = "sha256:7674587248fbbb2ac6e4eecf83a8a0f3d91a928f941de571acfd3a2f007fbc24", size = 13428824, upload-time = "2026-07-23T15:20:37.759Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/fd/655c8a773d728bc3c93fb4713ae4bf79ffc75996f86fb78b2974c8e1dfbd/grpcio-1.83.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:fba099b716e73512d61b97f71ea3c31a72abb36904036e316bf4dd148ca8dcc8", size = 6334247, upload-time = "2026-07-23T15:18:53.099Z" }, + { url = "https://files.pythonhosted.org/packages/d4/9a/1ce5760d35a04a992006dd2f79afff2db548f93ee7426fa95c9f1fc90c61/grpcio-1.83.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:6755ed67cc3e454d51ae9f6e1915b80d3942fa4de956ef48dacd45ab7f40b727", size = 12168650, upload-time = "2026-07-23T15:18:56.348Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ab/bbcb5be0a1a6cb21f036e2afdd4f7a70147cfb7a7b42648a310d7c43acfc/grpcio-1.83.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5882c1a721b50ce0123ee5e839e1ab059ad72a7ade76cdf2d5bd833b56791acf", size = 6916899, upload-time = "2026-07-23T15:18:58.339Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d2/4c27977ecb3b3f9f363b93f570e001cb24ef264a9a907d7fd0f949ed59f0/grpcio-1.83.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4e3eedfc92b6b9f2960115e7e620cf0cbf80bb7849a51ce3820dc54dfd88b6b9", size = 7648761, upload-time = "2026-07-23T15:19:00.071Z" }, + { url = "https://files.pythonhosted.org/packages/23/49/0c823a7627ff2e69a61e4a53c4edf215272892fc2c47c6431f033d46f4cc/grpcio-1.83.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4fcaa7c45c45b4a89e2867d1f1785d9481a788399d915e341ed2eb49aeef9dd4", size = 7074920, upload-time = "2026-07-23T15:19:02.293Z" }, + { url = "https://files.pythonhosted.org/packages/3b/ce/963f01ff7c789a76909c9691b704112e02ca1e11c10405cd99c2bd7c40f1/grpcio-1.83.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6b6c666a1d5613ff360c9e90f44665e3a88b25a815209ddbc0917eec281931cb", size = 7598046, upload-time = "2026-07-23T15:19:03.921Z" }, + { url = "https://files.pythonhosted.org/packages/eb/de/1ce6bdefc847a7973040d10cebc8996c653a2a687c0a4da8d05dcab4e397/grpcio-1.83.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6be5c807b717be3dd649446f021301fd7907e376318675d2147823071034112a", size = 8634792, upload-time = "2026-07-23T15:19:05.633Z" }, + { url = "https://files.pythonhosted.org/packages/a5/8b/7fe6a73895e3bdd788101d1276e48e0d262ebb165afacec1ec4efebcd785/grpcio-1.83.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c834e86d8fd2f03d7e4db49a027f7c5b89c5b88eed305543a5295bd6fee61e40", size = 8000286, upload-time = "2026-07-23T15:19:07.739Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b0/9a779de2bcda8722501a056fad1bec3d1117977af0c080ab1fc0655fdf35/grpcio-1.83.0-cp310-cp310-win32.whl", hash = "sha256:35a5b1c192496b6c25956eebfa963468935612206fd2543ac3ce981e6a5e0f03", size = 4404616, upload-time = "2026-07-23T15:19:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f0/8e/ce9a23590cac33a6c24e6386cc0ffc55821cc13212acc822e98f00a67161/grpcio-1.83.0-cp310-cp310-win_amd64.whl", hash = "sha256:8f6c395e493d20c39b29392ca200e9aaeb78d0bc2f04db0c0a7da7ddc939aa57", size = 5162304, upload-time = "2026-07-23T15:19:11.467Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f6/3b781cd07a715ea5f5125ae264226e7fc4d87603d6d3955022cabfdc5da2/grpcio-1.83.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:8ff0b8767ddd62704e0d9571c1890af08d84a3a689ebba1807e62519d0b3277f", size = 6338720, upload-time = "2026-07-23T15:19:13.177Z" }, + { url = "https://files.pythonhosted.org/packages/21/cc/d14833d15d5984e366f1b027fa78bd038c9b028c66880bffb0f5a4d25ee2/grpcio-1.83.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:4772402f43517b4824980be4b3b2274a81eec0004a70009473c31b340d43e223", size = 12178773, upload-time = "2026-07-23T15:19:15.401Z" }, + { url = "https://files.pythonhosted.org/packages/6b/98/8acbb416544e7871132d8e42a07ed70c802d70e6a16c6009e505a34d32a4/grpcio-1.83.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f4cee5fc86e84a0cf7ad1574b454c3320e087c07f55b7df5dc0ac6a873fb90c0", size = 6921203, upload-time = "2026-07-23T15:19:17.824Z" }, + { url = "https://files.pythonhosted.org/packages/45/9c/0fdbfaf4fc54e5c88f6bce4008a065092fe7fbc4460eb5617ae8b20fd505/grpcio-1.83.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f5e822a7e7d03282f6ad225e710493c48b9057a353358344a5f7c42b2b37618d", size = 7648508, upload-time = "2026-07-23T15:19:19.685Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ea/107b9dbb2ed3ad14dd774fd3dde7d29ff9938a6c198654becb2c3a0e9a6a/grpcio-1.83.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5f410d7c2903eabb34789dfd6342eef04af1ad459943936b7e09a9f5bd417b9", size = 7079466, upload-time = "2026-07-23T15:19:21.478Z" }, + { url = "https://files.pythonhosted.org/packages/3b/06/9fa9941089e6fae83b060b6ce61c1e81053e52decae43197245f45e07d36/grpcio-1.83.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee94a4016fdf8699fb1fd8a38652475ff677f1c72074cee44deeeb9a7e95e745", size = 7605583, upload-time = "2026-07-23T15:19:23.74Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2f/f10fb56062dc2771c630827a82d9ad0ecd05cad572ea3b08d49f6631680a/grpcio-1.83.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c6444666317338e903093c7c756e6cc88eee59f798cb8dd41e87725bf54e1617", size = 8637810, upload-time = "2026-07-23T15:19:25.536Z" }, + { url = "https://files.pythonhosted.org/packages/99/55/f84927258f6a1b6ea6dea661fdc6de859b35e560c96f3012d15ccd39f85e/grpcio-1.83.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:aa074041231f03959cb097dd5517b0677b8ea49215bae01d5710a7b69dd59969", size = 8008021, upload-time = "2026-07-23T15:19:27.863Z" }, + { url = "https://files.pythonhosted.org/packages/c9/6b/cdf72161397ccd29d4ca2192f641524536c9cf54ad948c9dd0e0e01138fa/grpcio-1.83.0-cp311-cp311-win32.whl", hash = "sha256:cb056f6e171c42639a50460b2929c82241fda51f71cf3dcdd68090fe45095a45", size = 4404376, upload-time = "2026-07-23T15:19:30.137Z" }, + { url = "https://files.pythonhosted.org/packages/df/ed/e0ffeb4c848699c194dc9fb6a29ab29bcb2b6aac8c416bf18c51bfe8242c/grpcio-1.83.0-cp311-cp311-win_amd64.whl", hash = "sha256:7416952ca770477990257206276999056f8316d79196f2f25942393e58a20b49", size = 5164469, upload-time = "2026-07-23T15:19:31.941Z" }, + { url = "https://files.pythonhosted.org/packages/15/2b/51e32514a4e9b715375c99721aadff0f24164cc2049b8269eda4de82a814/grpcio-1.83.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:28f6c35ac8fcf10e4594f138e468f194360089dde40d126a7033e863fc479930", size = 6303167, upload-time = "2026-07-23T15:19:33.78Z" }, + { url = "https://files.pythonhosted.org/packages/39/33/b5b50fc2c6fbe350e04814047bb2d409feec7b36ef8b170254c050e06bc0/grpcio-1.83.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:33898e6a28e4ae598f1577cb1c4fec2a15c033d0ec52b9b45a09610dd045b9da", size = 12160538, upload-time = "2026-07-23T15:19:35.958Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5f/734e72e7b9f79bcf0b2c270b8d3bca0e4ebb97a27a50d06240b145f6d41e/grpcio-1.83.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6fb8a1dd0c6f0f931e69e9d0dc6d1c406ed2a44fa963414eafba07b7fb685d16", size = 6869310, upload-time = "2026-07-23T15:19:38.607Z" }, + { url = "https://files.pythonhosted.org/packages/a4/17/a1735f215b2a5cd43c38b79eac072ad197e61be9829905b6b29550abd0db/grpcio-1.83.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2b5e75c34842cd9c1b95285ca395c6a569664b81e3ffa6b714125922942abaaf", size = 7613472, upload-time = "2026-07-23T15:19:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/b2/78/c9e81f806ac704b6b145cb01628db398985b1f8dfdc10e23b55fb0902b3d/grpcio-1.83.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeb339838db07600481ef869507279b75326c75eac6d10f7afa62a0da1d2bcdd", size = 7040616, upload-time = "2026-07-23T15:19:42.349Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ba/94cd5af859876049d340480acbb61a959096c84b567f215534faa78d0424/grpcio-1.83.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f47d62808b4c0a97b78bff88a6d4ca283a2a492b9a04a87d814af95ca3b9c19c", size = 7570491, upload-time = "2026-07-23T15:19:44.357Z" }, + { url = "https://files.pythonhosted.org/packages/3e/15/108d30d5a5c964312ae8b9cb0e8cc5b3c1cc68d8f757cca52b3565534d26/grpcio-1.83.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62003babc444a606dcd1f009cd16391ce23669ae4ad6ec267a873da7937a69f5", size = 8605036, upload-time = "2026-07-23T15:19:46.454Z" }, + { url = "https://files.pythonhosted.org/packages/ea/23/3828ae13c3db8233d123ad612747665817b952d8a954f32390230b582336/grpcio-1.83.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1aa567f8c3f19850ffd5d2858c9a8ea7c80f0db6c01186b71eb31e923ec984f5", size = 7981587, upload-time = "2026-07-23T15:19:48.913Z" }, + { url = "https://files.pythonhosted.org/packages/17/5b/77af31228f55f55a2a5112bb0077ad0a1c4d23dbb0c2853a62475bbdcc14/grpcio-1.83.0-cp312-cp312-win32.whl", hash = "sha256:cb2906c61db4f9c64cc360054b5df70eeb81846228e9e56a4944bd415a63dadc", size = 4394004, upload-time = "2026-07-23T15:19:50.618Z" }, + { url = "https://files.pythonhosted.org/packages/c0/da/f706e39550e7a3732ce2b9c5926107a93d74a802775b19b642a6df27dc96/grpcio-1.83.0-cp312-cp312-win_amd64.whl", hash = "sha256:1c699bbb20f143c8f2bff219de578aa2dc1f919399d67dc702b038b986ee62df", size = 5158525, upload-time = "2026-07-23T15:19:52.246Z" }, + { url = "https://files.pythonhosted.org/packages/56/eb/135daaa713f32d33b8f99b4153b3f8dc3b2a124996ac15581bf9ebdad3c3/grpcio-1.83.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:6662f3b1e07cc7493d437351860dc867bddc6a93c83ecf33bbfdaf0c217ab2d0", size = 6304480, upload-time = "2026-07-23T15:19:53.962Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a1/121806ce69f23138dabe06aa595b0e5f1ae051a37e4c1954eed7d692c800/grpcio-1.83.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:74fe6f9e8a35c7dbf32255ee154d15e3e5338a81ed39173d079d594d2e544cd1", size = 12154419, upload-time = "2026-07-23T15:19:56.3Z" }, + { url = "https://files.pythonhosted.org/packages/b0/e8/d0389e09cd6b4c4d3089b92967ae4e3ffd64795bd349bf2f85cd6656d3da/grpcio-1.83.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10b3fa0475eb572c9a81a6fe37fa16a9c500c0c91cfc148cac15692b7e3c2867", size = 6873200, upload-time = "2026-07-23T15:19:58.701Z" }, + { url = "https://files.pythonhosted.org/packages/f8/51/f464c1d211fa50d5adbabe1b2e519948d99c13757052bfc9ea7afa28e284/grpcio-1.83.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:5f20a988480b0f28207f057f7f7ae1313393c3cef0adcfeae8248f9947eaf881", size = 7618811, upload-time = "2026-07-23T15:20:00.733Z" }, + { url = "https://files.pythonhosted.org/packages/e8/c0/539fe0832f2dd6500a28f5263071623fb34e8d4867aec632ccf81bd21156/grpcio-1.83.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bd82671b39065ba18cd536e9cd45b27ff649053f81ddd2c6a966d595067080f", size = 7042310, upload-time = "2026-07-23T15:20:02.675Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ca/ccf617d37ffa72567fa8e005ec7090c99da922799be2fb9847c8b21ca18c/grpcio-1.83.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc60215b5cb9fc8ca72942c498b551ac2305bd08f6ef8d4e3f0d21b64fbecd61", size = 7575412, upload-time = "2026-07-23T15:20:04.712Z" }, + { url = "https://files.pythonhosted.org/packages/eb/b9/fd8d5245f823a8e0fd35d90e20ea3aa4acd47f8d5318fa8df307df52dec6/grpcio-1.83.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f1c3e5689d4b90987b1d72022bcfe866a9a3dc66197484cf856d96b6150e7f45", size = 8604248, upload-time = "2026-07-23T15:20:06.77Z" }, + { url = "https://files.pythonhosted.org/packages/14/1e/f37632fc11db72dfa4bba86c3a43e54358e53030df111ecae5e91a733ad6/grpcio-1.83.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a21cb4eeeba124443f399be2e8b624943cde864dcbe588cb42e5c483a52a906c", size = 7977458, upload-time = "2026-07-23T15:20:09.109Z" }, + { url = "https://files.pythonhosted.org/packages/93/b6/d70b69ae5c0cfc341b9ba474980e4ed99cbf05c0e4a14e9eee8cb73db0a5/grpcio-1.83.0-cp313-cp313-win32.whl", hash = "sha256:8fe04f1050a59f875601eb55d42b4f66946fe89817f967e34db1462ccd07dadf", size = 4393993, upload-time = "2026-07-23T15:20:11.017Z" }, + { url = "https://files.pythonhosted.org/packages/0f/13/45d4cccb555cf4c476226979bf3d2fd0b0254216f7564c3a053e35117efc/grpcio-1.83.0-cp313-cp313-win_amd64.whl", hash = "sha256:6e01ecd9d8ef280abe1365138a4dc318f9a5287f4cb1b41d07816f796653f735", size = 5159650, upload-time = "2026-07-23T15:20:12.979Z" }, + { url = "https://files.pythonhosted.org/packages/9c/60/f2cca8147ea213d3e43ae9158d03ad04e020fdf32ff027253e1fe93f921d/grpcio-1.83.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:3f351629f6ae16ecc0ec3553e586a6763ffd9f6114044286d0cbec3e09241bfa", size = 6305607, upload-time = "2026-07-23T15:20:15.353Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ab/d3874931d123a95e83a3ebf8aa04537988fb62425cedb8bf3cefc5ad41b2/grpcio-1.83.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d05ff664100d429335b93c91b8b34ddf9e94a112205e7fa06dede309e44a4e4c", size = 12166617, upload-time = "2026-07-23T15:20:17.435Z" }, + { url = "https://files.pythonhosted.org/packages/92/ff/6f18f9426b69306f4e00a9add3b0ee2748da8aad53836ef80cab0d62d04f/grpcio-1.83.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7936f2a56cf04f6514705c0fedf400971de01b6aa1719327e4718f410a765e2b", size = 6880213, upload-time = "2026-07-23T15:20:19.98Z" }, + { url = "https://files.pythonhosted.org/packages/70/21/706d1147c6b93b98f179240c13991fbcc56880eba0c868abb1ad40d8a0a6/grpcio-1.83.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b0a0be840e51b6b7ee9df9269770faf77bdf4b771053c257c21d12bad607714c", size = 7618335, upload-time = "2026-07-23T15:20:22.161Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/1a8443c889115ec9e213a213e86bc93a71ee9088027e5befa09aaa0edd9d/grpcio-1.83.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:009667eaf3dcd5224c713589cdc98e7ca4ed0ff0b61132c6b276e930eb83a2df", size = 7043416, upload-time = "2026-07-23T15:20:24.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/c6/94e0fee5b12bc1da1370185b680988db6f739d19b42d9959db01a7ea50bf/grpcio-1.83.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bb669918fd88936b15599caff4160a77ab74bdeb25f2231f6e45b61282d6107b", size = 7583253, upload-time = "2026-07-23T15:20:26.313Z" }, + { url = "https://files.pythonhosted.org/packages/a0/97/de1ccb671fb85575bc5192faedf9ecdbdf5b390d2e6584dcf552bcbd370e/grpcio-1.83.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c19b454d3d3f28db81f2c7c4dbaee96e7f6fd149721733ffe79d6bc530f17404", size = 8605102, upload-time = "2026-07-23T15:20:28.437Z" }, + { url = "https://files.pythonhosted.org/packages/17/0f/0e0ec749a7034ffcbaa050e39779872950ead90c22e7e0116be3f28b2b46/grpcio-1.83.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:61007cd08640abc5c54547ee32505474c482cd733a53cb87551ea81faa6350af", size = 7979826, upload-time = "2026-07-23T15:20:31.182Z" }, + { url = "https://files.pythonhosted.org/packages/83/fa/c3fda157287f64bc65acee6c5aa90c41acf9e0d3a8e69a265eecff6d00a1/grpcio-1.83.0-cp314-cp314-win32.whl", hash = "sha256:32e11c37f5285b0c6fa3042c05fe06903696689749833fc64e67dec71b9bbe33", size = 4471765, upload-time = "2026-07-23T15:20:33.195Z" }, + { url = "https://files.pythonhosted.org/packages/a1/00/b1b26431c9d54eee11724fd6e5585473a2ed47fbc1fb95e5204906a642ce/grpcio-1.83.0-cp314-cp314-win_amd64.whl", hash = "sha256:2bb48cb5e6dd005ca12b89ce4b6ac0b48ff3112c747542ee7986ef611a8ca6d9", size = 5298932, upload-time = "2026-07-23T15:20:35.48Z" }, ] [[package]] name = "grpcio-status" -version = "1.81.1" +version = "1.83.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "googleapis-common-protos" }, { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/26/0aa9168c87882381fd810d140c279a2490ed6aee655f0515d6f56c5ca404/grpcio_status-1.81.1.tar.gz", hash = "sha256:9389a03e746017b10f0630c064289201458f3ce01f5d7ef4b0bebc1ef6cf82ad", size = 13923, upload-time = "2026-06-11T12:58:48.636Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/fd/848dd7e009de85f8ca59999d1cc618ff8ebf7ea5636d083a47455d212d24/grpcio_status-1.83.0.tar.gz", hash = "sha256:837219c6de9afdccb6f6f72b34bc71e151a2011ef04040e3faaca746a57e54ae", size = 13965, upload-time = "2026-07-23T15:24:26.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/5e/5abfec5f7e89d3b7993d57cfb025ca5f968a2c18656d7fcda2b6919440b9/grpcio_status-1.81.1-py3-none-any.whl", hash = "sha256:08072fa9995f4a95c647fc6f4f85e2411573d00087bcabdf30f260114338f232", size = 14638, upload-time = "2026-06-11T12:58:31.982Z" }, + { url = "https://files.pythonhosted.org/packages/d6/00/73204406228cf989bea6b0fd9fe4702fab49a8a152a0c6f90856dadb6ac7/grpcio_status-1.83.0-py3-none-any.whl", hash = "sha256:f6a838a7c5fb84ae98833ec0ef81ed438c26e11e54b2ddb8e92ad328c861de69", size = 14636, upload-time = "2026-07-23T15:23:49.044Z" }, ] [[package]] @@ -3225,11 +3382,11 @@ wheels = [ [[package]] name = "idna" -version = "3.18" +version = "3.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15", size = 215237, upload-time = "2026-08-18T05:14:24.27Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, + { url = "https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4", size = 68550, upload-time = "2026-08-18T05:14:22.343Z" }, ] [[package]] @@ -3306,14 +3463,14 @@ wheels = [ [[package]] name = "jaraco-functools" -version = "4.5.0" +version = "4.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/36/cf/ea4ef2920830dea3f5ab2ea4da6fb67724e6dca80ee2553788c3607243d0/jaraco_functools-4.5.0.tar.gz", hash = "sha256:3bb5665ea4a020cf78a7040e89154c77edadb3ca74f366479669c5999aa70b03", size = 20272, upload-time = "2026-05-15T21:34:10.025Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/1f/c23395957d41ccf27c4e535c3d334c4051e5395b3752057ba4cbaec35c56/jaraco_functools-4.6.0.tar.gz", hash = "sha256:880c577ec9720b3a052d5bc611fb9f2269b3d87902ef42440df443b88e443280", size = 20837, upload-time = "2026-07-14T01:28:02.544Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/9a/982e48afcffcd727a9144506720ffd4224b6b7e355c98641866f38b7c043/jaraco_functools-4.5.0-py3-none-any.whl", hash = "sha256:79ce39246eddbde4b3a03b77ea5f0f7878dc669b166a66cf3fa8e266aa3fa2f4", size = 10594, upload-time = "2026-05-15T21:34:08.595Z" }, + { url = "https://files.pythonhosted.org/packages/02/36/ecc85bc96c273dc8a11273ed4782272975e6338d4a3e9228621175edf0e3/jaraco_functools-4.6.0-py3-none-any.whl", hash = "sha256:99e3dc0060c5cbe8fcd1cdb36258e2a65ca40f1566b2033b12abb1bb44dd3c30", size = 11677, upload-time = "2026-07-14T01:28:01.59Z" }, ] [[package]] @@ -3432,22 +3589,47 @@ wheels = [ name = "keystoneauth1" version = "5.14.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ - { name = "iso8601" }, - { name = "os-service-types" }, - { name = "pbr" }, - { name = "requests" }, - { name = "stevedore" }, - { name = "typing-extensions" }, + { name = "iso8601", marker = "python_full_version < '3.11'" }, + { name = "os-service-types", version = "1.8.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pbr", marker = "python_full_version < '3.11'" }, + { name = "requests", marker = "python_full_version < '3.11'" }, + { name = "stevedore", version = "5.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/02/d9/a01a3898657626cbcca9fa0e8fa58facb4632e172bdac622d47950f7e12a/keystoneauth1-5.14.0.tar.gz", hash = "sha256:7b942084d3db27dd285c13253cdfee10b05be0436db1c01e15dc744902197a7f", size = 288739, upload-time = "2026-05-13T09:09:26.125Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/72/eb/698dc17e4beb315f83a47d47be128b8a63303dc8b7e7c31110410e10a68b/keystoneauth1-5.14.0-py3-none-any.whl", hash = "sha256:f8c503a95fdd83b5b72736657e4ffbb53d4b28b01763f23013f0294ed8a0e4b9", size = 343268, upload-time = "2026-05-13T09:09:24.573Z" }, ] +[[package]] +name = "keystoneauth1" +version = "5.15.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "iso8601", marker = "python_full_version >= '3.11'" }, + { name = "os-service-types", version = "1.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "requests", marker = "python_full_version >= '3.11'" }, + { name = "stevedore", version = "5.9.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/627b01cde69d0ece2fd552b8c7c34af06acf13a0a77d1829ff0b46a3b45f/keystoneauth1-5.15.0.tar.gz", hash = "sha256:ce2cacdfd028e65bd23ff403d6572ebfab3b006d6d2dde3aa85c263675a9fbb5", size = 288544, upload-time = "2026-07-03T16:21:31.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/f6/6552fed59449604d982ffe9fe202b82f0724d333319812d1f544a95d3a09/keystoneauth1-5.15.0-py3-none-any.whl", hash = "sha256:9e2a4cf45cc2e2164093157091bc073eda1f334f755e8fab9fd25420c6f6acef", size = 342364, upload-time = "2026-07-03T16:21:29.866Z" }, +] + [[package]] name = "kubernetes" -version = "36.0.2" +version = "36.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -3461,9 +3643,9 @@ dependencies = [ { name = "urllib3" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/57/8b538af5076bc3372949d76f70ba3449bdfe52f9e6488170fa5d4f7cbe70/kubernetes-36.0.2.tar.gz", hash = "sha256:03551fcb49cae1f708f63624041e37403545b7aaed10cbf54e2b01a37a5438e3", size = 2336738, upload-time = "2026-06-01T18:20:30.785Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/57/b07b96353f902aa1bdbe00e878e3a12a137977d03a962479785576aa8ec9/kubernetes-36.0.3.tar.gz", hash = "sha256:36993ed25ce59b789c9341473a228fcf268504a2fec7c2b2b1531d73072e5ce7", size = 2337528, upload-time = "2026-07-13T20:38:12.128Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/2c/5c160dbdef7123f8cc97fd8ece7e0198627a426a2a49614845e9086feb8d/kubernetes-36.0.2-py2.py3-none-any.whl", hash = "sha256:faf9b5241b58de0c4a5069f2a0ffc8ac06fece7215156cd3d3ba081a78a858b6", size = 4617568, upload-time = "2026-06-01T18:20:28.737Z" }, + { url = "https://files.pythonhosted.org/packages/5b/30/a96d47df739689ac0001ade0afefc16e3b477fc2fb426b568515fdc8afce/kubernetes-36.0.3-py2.py3-none-any.whl", hash = "sha256:8fde9241c4b298e6374a069dcf728359b4e72c2fb29489a975ba4e1c047cf10f", size = 4618066, upload-time = "2026-07-13T20:38:10.172Z" }, ] [[package]] @@ -3534,11 +3716,11 @@ wheels = [ [[package]] name = "markdown" -version = "3.10.2" +version = "3.10.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", hash = "sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950", size = 368805, upload-time = "2026-02-09T14:57:26.942Z" } +sdist = { url = "https://files.pythonhosted.org/packages/29/6f/da4c6aea59b3001f2e8c0ec7497475aadaf3b021c10cab5b2858f0f32b26/markdown-3.10.3.tar.gz", hash = "sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f", size = 372596, upload-time = "2026-07-30T19:05:29.005Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", hash = "sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36", size = 108180, upload-time = "2026-02-09T14:57:25.787Z" }, + { url = "https://files.pythonhosted.org/packages/64/69/4a5af2bc115a9a33fefe51709749de8262be3f9ba063d1753a837cdbc49c/markdown-3.10.3-py3-none-any.whl", hash = "sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea", size = 110757, upload-time = "2026-07-30T19:05:27.883Z" }, ] [[package]] @@ -4010,21 +4192,22 @@ wheels = [ [[package]] name = "oci" -version = "2.181.0" +version = "2.184.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "circuitbreaker" }, { name = "crc32c" }, { name = "cryptography" }, + { name = "pyjwt" }, { name = "pyopenssl" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/5b/e33df95b556869afc9d640839328b5d80909b92971be3d1ee19c0f1a7ab9/oci-2.181.0.tar.gz", hash = "sha256:8d52a4a65bf0d20bbd59dc3248ed3747b409b5061bcf18e90f2e52f6049fd154", size = 17498303, upload-time = "2026-06-29T23:14:44.777Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/91/147428da81ab96b41a3943ac984b9e4e0cda527b71c4e61b83f45c604eee/oci-2.184.2.tar.gz", hash = "sha256:71e16eabcd4e66e9956d0cd084060c54b1e030567012d074ac0ba38526b7e4ed", size = 18021615, upload-time = "2026-08-18T04:15:18.774Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/24/f846a7c9085b9f6166d098b01cef11e0326775614686cf2e6f31c7637113/oci-2.181.0-py3-none-any.whl", hash = "sha256:5a797cd916a88b7f80c3e610ec2752d21f4c95eb2151b2b0db060bd5c58460d6", size = 35765962, upload-time = "2026-06-29T23:14:37.213Z" }, + { url = "https://files.pythonhosted.org/packages/ee/6f/492f55aa51d208e7495eb6bd307a00f0561f9892b91f003106c2da4bbcdf/oci-2.184.2-py3-none-any.whl", hash = "sha256:5cd73d82493c7f5ba94039502927cf8d48d61ebb4d945ead4042513d3834a60f", size = 36631564, upload-time = "2026-08-18T04:15:11.143Z" }, ] [[package]] @@ -4073,10 +4256,12 @@ dependencies = [ { name = "iso8601" }, { name = "jmespath" }, { name = "jsonpatch" }, - { name = "keystoneauth1" }, + { name = "keystoneauth1", version = "5.14.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "keystoneauth1", version = "5.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "munch" }, { name = "netifaces" }, - { name = "os-service-types" }, + { name = "os-service-types", version = "1.8.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "os-service-types", version = "1.9.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pbr" }, { name = "pyyaml" }, { name = "requestsexceptions" }, @@ -4088,29 +4273,51 @@ wheels = [ [[package]] name = "opentelemetry-api" -version = "1.43.0" +version = "1.44.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/cc/e4c9584181f86494df0f6bdec1a4f3280c50db44704dc2a407e994fc87bb/opentelemetry_api-1.43.0.tar.gz", hash = "sha256:107d0d03857ea8fc7c5fcbbbd83f800c281f0d560553d61c1d675fccfd1761c1", size = 73476, upload-time = "2026-06-24T15:19:55.323Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/8b/aa9e2d8b8dfa7c946f7dec5d1f8f6ba8eca062f43509a06bdb5ce93d26c0/opentelemetry_api-1.44.0.tar.gz", hash = "sha256:67647e5e9566edcf421166fdf022b3537f818635daa852b289e34604dc6fb33a", size = 72406, upload-time = "2026-07-16T15:25:32.678Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/83/6dba32b85f31868400440dc7ad2ca1eab94cbbf3a7b0459ed39f8311a9e2/opentelemetry_api-1.43.0-py3-none-any.whl", hash = "sha256:20acf45e9b21851926835292e4045d290acade1edd2ff3de86d2f069687ba1fd", size = 61912, upload-time = "2026-06-24T15:19:35.434Z" }, + { url = "https://files.pythonhosted.org/packages/ca/6f/a04e900f465ff3221ccc395522503e2d10e79fa21f2723c8e177aae1e0d1/opentelemetry_api-1.44.0-py3-none-any.whl", hash = "sha256:94b98c893a91b88657eaac1e3ba89618cdb85be6918196705354f34728b2cdef", size = 60018, upload-time = "2026-07-16T15:25:11.657Z" }, ] [[package]] name = "os-service-types" version = "1.8.2" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ - { name = "pbr" }, - { name = "typing-extensions" }, + { name = "pbr", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/51/62/31e39aa8f2ac5bff0b061ce053f0610c9fe659e12aeca20bfb26d1665024/os_service_types-1.8.2.tar.gz", hash = "sha256:ab7648d7232849943196e1bb00a30e2e25e600fa3b57bb241d15b7f521b5b575", size = 27476, upload-time = "2025-11-21T13:55:47.726Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/29/26/0937af7b4383f1eba5bca789b8d191c0e09e59bb64962b18f4a14534ce41/os_service_types-1.8.2-py3-none-any.whl", hash = "sha256:f78890d71814deffabf0ed4358288ec2ced579bc4d0bb87a79ae806cbb4deb6e", size = 24876, upload-time = "2025-11-21T13:55:46.093Z" }, ] +[[package]] +name = "os-service-types" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +dependencies = [ + { name = "pbr", marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/ae/fe7ac23155ae0b4b9779e06e9c5bb4070f2315dc4ca886a88fa3230d344b/os_service_types-1.9.0.tar.gz", hash = "sha256:1f2e5fb71d1f6f4ff31d8992674f2368465bc2f25cd94018015c3ddbfc5c617f", size = 28087, upload-time = "2026-08-04T13:07:43.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/79/f8ae99ae9bb54cd63e7ab89251b2a4ff4ff07f02847403948b6a6f50f816/os_service_types-1.9.0-py3-none-any.whl", hash = "sha256:f268545c896434177bf55c43f7d5129e65210d5d456df3f00a1c9832a71c3a4b", size = 25282, upload-time = "2026-08-04T13:07:42.258Z" }, +] + [[package]] name = "packaging" version = "26.3" @@ -4167,11 +4374,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/d0/43/187e14a5e53a4541e [[package]] name = "platformdirs" -version = "4.10.0" +version = "4.11.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224, upload-time = "2026-05-28T03:32:53.587Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/d7/e7bfbc86e9f99ff7807e24de7703f032e9c9ba80bb355cf26e0e9bc5a75e/platformdirs-4.11.3.tar.gz", hash = "sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab", size = 33050, upload-time = "2026-08-13T22:43:27.52Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743, upload-time = "2026-05-28T03:32:52.175Z" }, + { url = "https://files.pythonhosted.org/packages/19/a9/c34aebedd3a4c9afe5101b1b8713710b3fec18087c8a36c35d2f909861bd/platformdirs-4.11.3-py3-none-any.whl", hash = "sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7", size = 23491, upload-time = "2026-08-13T22:43:26.121Z" }, ] [[package]] @@ -4185,14 +4392,11 @@ wheels = [ [[package]] name = "portalocker" -version = "3.2.0" +version = "4.2.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pywin32", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5e/77/65b857a69ed876e1951e88aaba60f5ce6120c33703f7cb61a3c894b8c1b6/portalocker-3.2.0.tar.gz", hash = "sha256:1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac", size = 95644, upload-time = "2025-06-14T13:20:40.03Z" } +sdist = { url = "https://files.pythonhosted.org/packages/66/92/d15473a60e4cb7bc450e10d3160d7d531d6fa8cb144e31395afd76cf4be2/portalocker-4.2.0.tar.gz", hash = "sha256:f4c5024903126159c4798e6aec6c32e30a0759db39bf795c0dbeb180a2e8c843", size = 259245, upload-time = "2026-08-22T00:22:15.62Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/a6/38c8e2f318bf67d338f4d629e93b0b4b9af331f455f0390ea8ce4a099b26/portalocker-3.2.0-py3-none-any.whl", hash = "sha256:3cdc5f565312224bc570c49337bd21428bba0ef363bbcf58b9ef4a9f11779968", size = 22424, upload-time = "2025-06-14T13:20:38.083Z" }, + { url = "https://files.pythonhosted.org/packages/32/49/abd8a4154c911cc6c247edb7195d14846b614314c58ae09cf710d7d56098/portalocker-4.2.0-py3-none-any.whl", hash = "sha256:b33a8ce7d9b74922123a6fe64c2d785c015e5e9049ce7f1db5bd44e288731460", size = 128016, upload-time = "2026-08-22T00:22:14.254Z" }, ] [[package]] @@ -4325,29 +4529,29 @@ wheels = [ [[package]] name = "proto-plus" -version = "1.28.0" +version = "1.28.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/56/e647b0c675392d2da368da7b6f158f7368b18542fd6f7d7400a2f39de000/proto_plus-1.28.0.tar.gz", hash = "sha256:38e5696342835b08fc116f30a25665b29531cda9d5d5643e9b81fc312385abd9", size = 57221, upload-time = "2026-05-07T08:04:50.811Z" } +sdist = { url = "https://files.pythonhosted.org/packages/26/6a/056256feb4bd000869aba5c16cf2aa911572ca2a2feb185f86e457b5171e/proto_plus-1.28.3.tar.gz", hash = "sha256:5f91b30dafa6bb38d432c5557a6ee1d35ffd40b4b1e0e3ca27260448560b91d9", size = 58051, upload-time = "2026-08-06T06:24:55.581Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/20/b122d4626976acb81132036d2ad1bb35a1a8775fceb837ec30964622516a/proto_plus-1.28.0-py3-none-any.whl", hash = "sha256:a630604310899e73c59ec302e5765c058d412b2f090b9c79c8822589f14955b8", size = 50410, upload-time = "2026-05-07T08:03:31.962Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/cfee3c50294f55a2f0f9575052dec2c2a48891ad4b1c2a133b05a87026cd/proto_plus-1.28.3-py3-none-any.whl", hash = "sha256:dc76880b8ee951cca002098574376cf71e055f9f16d9ba6570fb8a06f726d281", size = 50795, upload-time = "2026-08-06T06:23:50.653Z" }, ] [[package]] name = "protobuf" -version = "7.35.1" +version = "7.36.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/01/9ef0afd7999eb9badb3a768b4aedd78c86d4c65cfaf1958ab276199e76b4/protobuf-7.35.1.tar.gz", hash = "sha256:ce115a26fe0c39a2c29973d914d327e516a6455464489fe3cd1e51a1b354f81a", size = 458717, upload-time = "2026-06-11T21:55:40.257Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/e7/0553e21d25ca4d9f573135775348a372c3ec34a93a71d5f297c3bac38341/protobuf-7.36.0.tar.gz", hash = "sha256:e8e09cb0d794c6687926fa558a8a6e72aa10edb997d5ca61da0765f12a3e00ea", size = 510034, upload-time = "2026-08-20T16:34:01.071Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/03/8aeeb7458d22546bf64b5250ca1daeb5ff757d900e8e4a7476c6f0db843e/protobuf-7.35.1-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6", size = 433226, upload-time = "2026-06-11T21:55:31.719Z" }, - { url = "https://files.pythonhosted.org/packages/37/4b/dfb89eb0e652a1ff073c39a59fb5e3a83cfe9b57a2c83fa6d78270101767/protobuf-7.35.1-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799", size = 328847, upload-time = "2026-06-11T21:55:34.035Z" }, - { url = "https://files.pythonhosted.org/packages/0f/58/dc12f2cd484951524af6e3382c785869b9b3fb5e52ee95ae23add53ee8f9/protobuf-7.35.1-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:b73f9489a4b8b1c9cb1f8ed951c736392592edb24b9d6819f36d2e10b171d5b4", size = 344030, upload-time = "2026-06-11T21:55:34.941Z" }, - { url = "https://files.pythonhosted.org/packages/e4/be/5b3cfe508bfab6761414ff944e3366eb13be4fd71efcd69450f89ba39f43/protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4", size = 327130, upload-time = "2026-06-11T21:55:35.921Z" }, - { url = "https://files.pythonhosted.org/packages/d8/bc/6d6c7ba8709c85f8f2c390b2b118d6fb08a783676a572271851bf45a7d22/protobuf-7.35.1-cp310-abi3-win32.whl", hash = "sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30", size = 428945, upload-time = "2026-06-11T21:55:37.034Z" }, - { url = "https://files.pythonhosted.org/packages/0a/19/8d0cb6f20a1ef7b18f1c8986ad5783f22f84cce39c6ce9a6e645ea55192e/protobuf-7.35.1-cp310-abi3-win_amd64.whl", hash = "sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87", size = 439996, upload-time = "2026-06-11T21:55:38.123Z" }, - { url = "https://files.pythonhosted.org/packages/19/c7/5f7c636ec43e0c545e28d1f1db71990108306f7bdcb89f069ba97e428e7f/protobuf-7.35.1-py3-none-any.whl", hash = "sha256:4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9", size = 171659, upload-time = "2026-06-11T21:55:39.155Z" }, + { url = "https://files.pythonhosted.org/packages/8f/ae/58e3ca96cb2e118cc546b677359b3c6659f79a140935c08dec94c7998585/protobuf-7.36.0-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:9103532dffd80c6fab7e50c65a31007680a06eb57537d437bb1b35812c138a37", size = 453256, upload-time = "2026-08-20T16:33:53.945Z" }, + { url = "https://files.pythonhosted.org/packages/f0/15/5162230af4912697f0fe406f6800f80760945babcff0e2c2fe6c84ef2d5d/protobuf-7.36.0-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:bf94a5917c71058262de683669bc0a797a7669d3de71f0b36d058e3194f47b44", size = 341436, upload-time = "2026-08-20T16:33:55.134Z" }, + { url = "https://files.pythonhosted.org/packages/d7/09/1670b2bfc9a45e807e520c3e9be36524db9ccc7dc05ea17af7681cabdc61/protobuf-7.36.0-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:3297e60abdff301e5f74393d87f6cc59dacab5f024a89548a6e8de1d26576b16", size = 354440, upload-time = "2026-08-20T16:33:56.077Z" }, + { url = "https://files.pythonhosted.org/packages/c7/f8/bd5804695ba400e423c33fd4d9f58c28d86633d5ba1945c36ff3967d98cb/protobuf-7.36.0-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:70f5ec8eb0da81a44360c0dc0beac99a0d78071d21956a7076bae8bd2051841b", size = 340439, upload-time = "2026-08-20T16:33:56.992Z" }, + { url = "https://files.pythonhosted.org/packages/ef/9f/acd02338235a3e7d03168c4303478347b7624fc8189ff4e7f0d2654bbe86/protobuf-7.36.0-cp310-abi3-win32.whl", hash = "sha256:7326fd717bdc419162a735938d89d4032332bcc3408804012b24ff3a37086071", size = 440216, upload-time = "2026-08-20T16:33:57.99Z" }, + { url = "https://files.pythonhosted.org/packages/0e/4e/12cb93270967a2affff5b3f720694700d4d87712a67afd05c8cb3f6fa52c/protobuf-7.36.0-cp310-abi3-win_amd64.whl", hash = "sha256:1781cc1de61249b750848029bca452c0a8b7e990080316b9bbc2518b2117b488", size = 453731, upload-time = "2026-08-20T16:33:58.951Z" }, + { url = "https://files.pythonhosted.org/packages/01/c3/629999e78d46c1115c11886d51c6bd68c17ce4a944f1ea3e153a91316a33/protobuf-7.36.0-py3-none-any.whl", hash = "sha256:53374d53fc29a67f7dbbf0ade47d7526a0f0137bf0f9c90e48d8a60790ef748c", size = 177024, upload-time = "2026-08-20T16:34:00.053Z" }, ] [[package]] @@ -4380,11 +4584,11 @@ wheels = [ [[package]] name = "pyasn1" -version = "0.6.3" +version = "0.6.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/5f/6583902b6f79b399c9c40674ac384fd9cd77805f9e6205075f828ef11fb2/pyasn1-0.6.3.tar.gz", hash = "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", size = 148685, upload-time = "2026-03-17T01:06:53.382Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/9a/23310166d960def5897e91fe20e5b724601b02a22e84ba1f94232c0b7f67/pyasn1-0.6.4.tar.gz", hash = "sha256:9c447d8431c947fe4c8febc4ed9e760bc29011a5b01e5c74b67025bd9fb8ce81", size = 151262, upload-time = "2026-07-09T01:12:33.988Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl", hash = "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde", size = 83997, upload-time = "2026-03-17T01:06:52.036Z" }, + { url = "https://files.pythonhosted.org/packages/9a/3b/6163796d69c3977d1e4287bea4a6979161cbbdd170ebb430511e8e1999ce/pyasn1-0.6.4-py3-none-any.whl", hash = "sha256:deda9277cfd454080ec40b207fb6df82206a3a2688735233cdcd8d3d565f088b", size = 84410, upload-time = "2026-07-09T01:12:32.92Z" }, ] [[package]] @@ -4576,16 +4780,16 @@ wheels = [ [[package]] name = "pydantic-settings" -version = "2.14.2" +version = "2.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "python-dotenv" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/b5/8f48e906c3e0205276e8bd8cb7512217a87b2685304d64be27cad5b3019f/pydantic_settings-2.14.2.tar.gz", hash = "sha256:c19dd64b19097f1de80184f0cc7b0272a13ae6e170cbf240a3e27e381ed14a5f", size = 237700, upload-time = "2026-06-19T13:44:56.324Z" } +sdist = { url = "https://files.pythonhosted.org/packages/68/ca/31c57507b13119d7d3cfa1576dad2911a4861e3be07b579395f4e9d393f9/pydantic_settings-2.15.0.tar.gz", hash = "sha256:694b793e84f766ba76a90ebdefc01d0a9a045dab0382bee70393da93712ad117", size = 261253, upload-time = "2026-08-07T09:24:57.419Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/c1/6e422f34e569cf8e18df68d1939c81c099d2b61e4f7d9621c8a77560799c/pydantic_settings-2.14.2-py3-none-any.whl", hash = "sha256:a20c97b37910b6550d5ea50fbcc2d4187defe58cd57070b73863d069419c9440", size = 61715, upload-time = "2026-06-19T13:44:55.02Z" }, + { url = "https://files.pythonhosted.org/packages/30/a4/2bffa9f8e804325a09867f0e9d30795c80ea9f8d62560bd1b6ad6220eb2f/pydantic_settings-2.15.0-py3-none-any.whl", hash = "sha256:0ba092c291c94baceb5eff768aa0d56400a457585bc0175925a5a5510303da42", size = 69413, upload-time = "2026-08-07T09:24:55.839Z" }, ] [[package]] @@ -4640,7 +4844,7 @@ wheels = [ [[package]] name = "pygit2" -version = "1.19.3" +version = "1.20.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.14'", @@ -4651,72 +4855,82 @@ resolution-markers = [ dependencies = [ { name = "cffi", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/44/415aa93422b4bfc21a6448acb7e16280d5f33a9a3fae38a384e37b046ae4/pygit2-1.19.3.tar.gz", hash = "sha256:a543e6d4ebb43825564935758dc234e770016fed673b84370d46ae9580558831", size = 810489, upload-time = "2026-06-13T08:06:04.982Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/3a/36e8827f45d9daf79ea94cbc6148e6243df1fcabc7cac55cd152c5fa99a8/pygit2-1.19.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:59bca67a3f2af724659494bec9fed288b99242be13d76349d0170177512712fa", size = 5710933, upload-time = "2026-06-13T08:04:44.661Z" }, - { url = "https://files.pythonhosted.org/packages/38/77/9e87bbe723c50d6841740449c6e80a7aa63da01af59ca84b1169450dea7c/pygit2-1.19.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb2e65666356f072d774f935aa0858f68ea34644d7a1467ea4918470748a2722", size = 5699637, upload-time = "2026-06-13T08:04:46.804Z" }, - { url = "https://files.pythonhosted.org/packages/2c/89/d0ba3e7f3cea1ec7c359d0456fc2cc3d5010c2a8a5a26da5298284e32a1c/pygit2-1.19.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0424822de48cb466f54c45c4d73924be201fd8ad347ccf0545fe7e601f056ebb", size = 6035985, upload-time = "2026-06-13T08:04:48.46Z" }, - { url = "https://files.pythonhosted.org/packages/29/d0/63e37c75f8822b6d2cb0e1877a5e3de7e29a15e3ed2fe48c37b47164ff71/pygit2-1.19.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e6aeb43e12fde33ec981209da90f66076e956538e457e4a50ba1665f97e3b2ea", size = 4639470, upload-time = "2026-06-13T08:04:50.116Z" }, - { url = "https://files.pythonhosted.org/packages/52/30/23ad5ac73519086eab4953cd9999eb24d57625826fcd28de2e2b57a9bf62/pygit2-1.19.3-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eaf59b7f6435c276850d34392503b55e703392094ff4c87c3c0a4161b3d90133", size = 5795950, upload-time = "2026-06-13T08:04:51.696Z" }, - { url = "https://files.pythonhosted.org/packages/ec/1d/cad147ad317bc61e549784db8ee89391e868dd3da77174d57c6a960e4241/pygit2-1.19.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e536656457dd306d0ebae2ac442c2c8f8798ea2333095b85391bc3423f4ac1b3", size = 6041627, upload-time = "2026-06-13T08:04:53.232Z" }, - { url = "https://files.pythonhosted.org/packages/af/03/bcef734c7c46ab8702ce7f06f30f45716a7d8f97ec45fafdb20baef40473/pygit2-1.19.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:38d52f8d30bf969e3bfcab22cf5cdc4dc69590e06e8e948b1bb25cccb3bbbe3d", size = 5766485, upload-time = "2026-06-13T08:04:55.035Z" }, - { url = "https://files.pythonhosted.org/packages/42/b6/1f04fab2433f6ad10bd8820c1296f557d2fc9131abaff73d89783d8b85ac/pygit2-1.19.3-cp311-cp311-win32.whl", hash = "sha256:8b7a0a16372b245d065efb10a4ef5d61dc08794a69fa8ed6dd1ff918409b7d84", size = 944332, upload-time = "2026-06-13T08:04:56.358Z" }, - { url = "https://files.pythonhosted.org/packages/21/66/a88310e96bfbd47feea5359d2380d90326ec5de3a114772ae7e515f3653d/pygit2-1.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:2b8f748836ac00fd785373ef8f5c9be1ed509e357cb270cc3f5674c0ad44d44d", size = 1254403, upload-time = "2026-06-13T08:04:57.447Z" }, - { url = "https://files.pythonhosted.org/packages/97/ed/aa3a0a44c2d4419b1c01804ea1ff232bdbcaaf1a1a7f1f8274ff62d9534e/pygit2-1.19.3-cp311-cp311-win_arm64.whl", hash = "sha256:98f2241ef66ec97ab21a2a1a6851c1305929c7a9e9e3e94db5faeb5d2ed06aa2", size = 969498, upload-time = "2026-06-13T08:04:58.863Z" }, - { url = "https://files.pythonhosted.org/packages/a2/9c/9bc9a8d727b2ae8ae77306ecfb77a5dcf836da4997d4f7053c893f8e0d11/pygit2-1.19.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d696ee240cc8b84e747b04443d85768c859ef0b88abe4a3505dc0b8e2a953ca0", size = 5708797, upload-time = "2026-06-13T08:05:00.097Z" }, - { url = "https://files.pythonhosted.org/packages/63/7e/9099ea2f90791549185f8ac737a8b448e05cf3882cc79928a380be9bf38c/pygit2-1.19.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86318a704bef836067fa9ac06c56591738d548dcdf2ea24ec227257e3f8115f8", size = 5700295, upload-time = "2026-06-13T08:05:01.676Z" }, - { url = "https://files.pythonhosted.org/packages/39/84/e9610f041dc43699fca8af55050f9bf9fe0d340ab9902ab8e3fa67bece23/pygit2-1.19.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc3ddb3e5d16cf662d2d0faeb53259e31ae584cc990cd76df909beeb4a36736a", size = 6036822, upload-time = "2026-06-13T08:05:03.473Z" }, - { url = "https://files.pythonhosted.org/packages/64/bd/419ec17df3f1f1182de8c8fe800b698ff2a489cc50ec2d34990092bf3d61/pygit2-1.19.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73820fb34339fe3c52731d1c46c298a3239ee75b61bc3a2d9b45f8b8873acc47", size = 4638181, upload-time = "2026-06-13T08:05:05.145Z" }, - { url = "https://files.pythonhosted.org/packages/90/5f/aecca9c7f4ffdc1facc4b2402ea40073848e67c8c607a5f0698e1e8a61e4/pygit2-1.19.3-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20f6ad50608f51b053bf6c321ae2c31cc57f15e4131a4609261c44e29bdae7cb", size = 5799910, upload-time = "2026-06-13T08:05:06.48Z" }, - { url = "https://files.pythonhosted.org/packages/ea/2a/e131af7752f75f70e04f7f3ae724481d0e2db9c6c688a2081ffb5948657e/pygit2-1.19.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b2c63c7a371dbd5825e5fb7069b759c79aa5dec97806d49cb2c9f9a8a373209d", size = 6042766, upload-time = "2026-06-13T08:05:08.052Z" }, - { url = "https://files.pythonhosted.org/packages/6f/a5/978ee5233379b2aa725c290a7cc3baca9b141f4fc37d55d9a473631b529b/pygit2-1.19.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:977eb52cd4134ff60d3faa168327a03f8724278c38bfcd347d8e3a11041ee9cd", size = 5771434, upload-time = "2026-06-13T08:05:09.398Z" }, - { url = "https://files.pythonhosted.org/packages/26/33/7c506492fffe3e92d9e911fae43a4b4a3dee43682b71b7793d586c25acfc/pygit2-1.19.3-cp312-cp312-win32.whl", hash = "sha256:14a2734d793d2d937d3bfc9d35b280ec83fc97a91b1934b1013554d41e6d3d70", size = 945030, upload-time = "2026-06-13T08:05:11.187Z" }, - { url = "https://files.pythonhosted.org/packages/82/ff/57ad08d1e87ae6e4208f80923ce1a6ea8a03ea776376e39d64816637b168/pygit2-1.19.3-cp312-cp312-win_amd64.whl", hash = "sha256:a7caeaf46aaa8e51c512af9ac1377f388e4836c9d042e134bbc5e22519fbd1bf", size = 1254825, upload-time = "2026-06-13T08:05:12.315Z" }, - { url = "https://files.pythonhosted.org/packages/2d/cf/476c217a4ab3c9b4abf2506fb1135e54b19d205ce7ddecb1d961bf93a9dc/pygit2-1.19.3-cp312-cp312-win_arm64.whl", hash = "sha256:2aafa010e3ac227913f398c8a680bce419e396dfe651685fffb779ed1c109a00", size = 969650, upload-time = "2026-06-13T08:05:13.438Z" }, - { url = "https://files.pythonhosted.org/packages/7f/12/1e0f0fc54a24ddfdabb0da0bafb3237c82b5628a8c5258ba66fb8d39b5b2/pygit2-1.19.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9238bf7a8a953f4faedcbe90eb097b760a2709c7e7ab38edcf18dc2d0ce9dcff", size = 5708790, upload-time = "2026-06-13T08:05:14.755Z" }, - { url = "https://files.pythonhosted.org/packages/82/12/9093b7b81de7fe869f6ae51319a05b9f0a8b2567674e0d61fd54aacb833f/pygit2-1.19.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f999a4995504a6c14443de9481b7c6c54802663fe80c7504e1b946348f43786", size = 5700256, upload-time = "2026-06-13T08:05:16.363Z" }, - { url = "https://files.pythonhosted.org/packages/eb/07/a5133f79cf86e8a0cadf9f424cdd5b912ba47410c7254c0237b6e5290ddb/pygit2-1.19.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0918bc9b7597f243aa4b9c785912ae853e9aee4f572bcd5c9c591fcb703542f7", size = 6037556, upload-time = "2026-06-13T08:05:17.823Z" }, - { url = "https://files.pythonhosted.org/packages/0e/fc/3aa049d88eaa51f14f1fbfc0b70ac4c2362d3306dbeb8d1e5e3ca301e1dc/pygit2-1.19.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18403fee0171867be5fc1c1415bcd5d5a7fab51299bdd44bcf467c22a868fd22", size = 4638864, upload-time = "2026-06-13T08:05:19.325Z" }, - { url = "https://files.pythonhosted.org/packages/bf/b7/5e772367db14f800048fa2a0981abd45baae6dcd8b83453da6ac0f92cead/pygit2-1.19.3-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cacece712337029092a98cf1af8d244e92fa8b36e5a64d7e14212ff73ea821e8", size = 5801146, upload-time = "2026-06-13T08:05:20.748Z" }, - { url = "https://files.pythonhosted.org/packages/07/79/075b37b9a971cc7df9721add0e03cded83cab9e7d9736a80820357b2a972/pygit2-1.19.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:49d7c494bdaa5a8da366e4c4b7c822e52bd33bb6f22c67f8585b5396e91f8ac7", size = 6043951, upload-time = "2026-06-13T08:05:22.232Z" }, - { url = "https://files.pythonhosted.org/packages/94/76/72e13c487d013f21f97690f0662cb03533d91aad39e0c7c4c8cd3e4453d0/pygit2-1.19.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2bbe74fbe553c6f991512391822c27c9321e3a0b45cab872f45c8d458393eee3", size = 5772767, upload-time = "2026-06-13T08:05:23.487Z" }, - { url = "https://files.pythonhosted.org/packages/a1/24/5ba37f80fcb303bcf1a3813631e5b5dddfbac771cce7efc0b03428f4fa2e/pygit2-1.19.3-cp313-cp313-win32.whl", hash = "sha256:3ab184751ca7a92007dbd8ae4ae4ac3b7228ef60ae2d2e18129b44bbe5c0aa4c", size = 945026, upload-time = "2026-06-13T08:05:25.053Z" }, - { url = "https://files.pythonhosted.org/packages/ba/48/4ae19f2e4dc8ff2ddc2fd64de7fd1d26aeb2b453069d6c9ee251dd567983/pygit2-1.19.3-cp313-cp313-win_amd64.whl", hash = "sha256:522d9c6ab9206880dceaae5516720c0f0df706859d2ba97f49adcaeea2d661bd", size = 1254793, upload-time = "2026-06-13T08:05:26.174Z" }, - { url = "https://files.pythonhosted.org/packages/7a/7b/473ca9e35dfd82c758b700a6cf4ecc107b849674e91ab219383063ebb12f/pygit2-1.19.3-cp313-cp313-win_arm64.whl", hash = "sha256:c77d5a1334ca3f1432c83457e03be8759d8e9040e0d25c59c738f2318545654a", size = 969666, upload-time = "2026-06-13T08:05:27.351Z" }, - { url = "https://files.pythonhosted.org/packages/99/15/ec8a777b497853edab4e150c9ea46019b6c709b3c2b06fd06454a1aaa8c6/pygit2-1.19.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:214140f2201474e9d8e3889e5635e323aa90a58e6ae224a9de56be83d3e9b747", size = 5710849, upload-time = "2026-06-13T08:05:28.71Z" }, - { url = "https://files.pythonhosted.org/packages/fa/be/a8c449fba4c70239d6e9d0023b1fdd783c2dbb52872fef9c4de1652e930a/pygit2-1.19.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:46fc9fd234b2a38176625af6bfd2dbad99ab937379a980761c59a343bdff4910", size = 5700188, upload-time = "2026-06-13T08:05:30.466Z" }, - { url = "https://files.pythonhosted.org/packages/b3/19/8e92b4008324137878e9f9e130b4e349956d2a2b719521b8ce45aad6a0de/pygit2-1.19.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb9f46b561ee53f22cb479e7fdefd7b8ae478d12656436a48166c2ad81a3c021", size = 6039510, upload-time = "2026-06-13T08:05:31.892Z" }, - { url = "https://files.pythonhosted.org/packages/90/8f/baf3a0944f54acc27ceaa22b47ca52cd64c8bb1ec69473f80d3f4bafe54d/pygit2-1.19.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9f393932fadd8e74f26d7ebb58da649e7a188d9156b732dd6c9f0dfc273d4430", size = 4643029, upload-time = "2026-06-13T08:05:33.385Z" }, - { url = "https://files.pythonhosted.org/packages/69/1b/0b045e74fe01b29af28a5d54a9c89693db97e7e6cbd700f8086f4294e85e/pygit2-1.19.3-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9521a9b45de3affd82618e94f7e5116685e695e65fcbf67b2f1e44a086c0f4a", size = 5803099, upload-time = "2026-06-13T08:05:34.873Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/0d4eb93b7088316b9885b9c29b6a971009a20bf93aebd5762d3b809d72bf/pygit2-1.19.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:241f0fcd2aaf025e9fb5e1887eac5f244cb6b0a6e83dc27d673fa634ab0e0ee3", size = 6044603, upload-time = "2026-06-13T08:05:36.191Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8a/5a486a8aa9a1aa6a1ed5189b71b1b96e92bd164cc3e4d010e285032a2662/pygit2-1.19.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1729caee68cdf35c0cdb913de3850724438e4bdf480742da4f21a3e86d83662", size = 5773603, upload-time = "2026-06-13T08:05:37.605Z" }, - { url = "https://files.pythonhosted.org/packages/94/ff/e6a5da1fe3b104fc153160bfe56a85298a6c81b5411ee8de97e4039d3a2f/pygit2-1.19.3-cp314-cp314-win32.whl", hash = "sha256:2c300d234ef15e4c557a7e9ac880163606b364d0d4e20ddbf1204b4ee9f9b61c", size = 965699, upload-time = "2026-06-13T08:05:39.151Z" }, - { url = "https://files.pythonhosted.org/packages/bc/a1/a8f21afe574f22fde3d04fb102c4e75b5a1077fa1ea1ee3f7b072aa8f858/pygit2-1.19.3-cp314-cp314-win_amd64.whl", hash = "sha256:0ff9f187b01d6629c14ad069b100e147093b70279496984faa012783c5832b66", size = 1288277, upload-time = "2026-06-13T08:05:40.315Z" }, - { url = "https://files.pythonhosted.org/packages/95/65/f5268ac09c91f25e349a658cd9722b3528b1c4d6b18aab7472132e067912/pygit2-1.19.3-cp314-cp314-win_arm64.whl", hash = "sha256:cdfbf879ee0d468d7929eb26e35db7442b56a411af1d5b7d28e858cccf71598a", size = 997247, upload-time = "2026-06-13T08:05:41.629Z" }, - { url = "https://files.pythonhosted.org/packages/e9/98/9825e08b78a58bc99e979e322b8c776e6a4b49dcebf68471b650bf97e1ed/pygit2-1.19.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:79a3b565e20bbbbf21d29de1675a18e0e556545a2c738f38c0ac0435269f56bd", size = 5714170, upload-time = "2026-06-13T08:05:43.326Z" }, - { url = "https://files.pythonhosted.org/packages/82/00/8836f806512ac0a9e8613b2b446a0fe2578834c01c2234ca6d6f2abd6751/pygit2-1.19.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:828856512070cda223c19046b02af50135a5b0efa274a80fbf7c82d773f8e89f", size = 5703231, upload-time = "2026-06-13T08:05:44.997Z" }, - { url = "https://files.pythonhosted.org/packages/1f/9b/117fcbd26d30729e9f46889747823e51cb5597d191c100da298faa79bb90/pygit2-1.19.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eec2b1d50bf52d2139d3d478d6d5f5ee56103da4a6dbd786344e8a85254dd07b", size = 6097836, upload-time = "2026-06-13T08:05:46.269Z" }, - { url = "https://files.pythonhosted.org/packages/70/8c/c1fa28b4e3064ef0e06e49af3cbcbf50b62f36fab3f9832c15cd46d0a175/pygit2-1.19.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dbfa10f22670e7fef13bf249c32aebcafe23115790155d6b71efafb9aa7d4cba", size = 4697771, upload-time = "2026-06-13T08:05:47.629Z" }, - { url = "https://files.pythonhosted.org/packages/2b/c5/1d72a285fe794e2ce87ebe4b107c7cc713917e6e62b24264580b966740ea/pygit2-1.19.3-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d22c2940bde27f9ffe095aac87e7c8b8a9c787f91782c7463387d39a2592d04c", size = 5854885, upload-time = "2026-06-13T08:05:48.988Z" }, - { url = "https://files.pythonhosted.org/packages/60/ac/250da1cff67e38af607792ed98a49c64b5980d5332d5f26c1882f722cefe/pygit2-1.19.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0ed9f15b4b0b80191669fdf5b702b697ffbc245d24995befa80e46bef3aea25e", size = 6100802, upload-time = "2026-06-13T08:05:50.395Z" }, - { url = "https://files.pythonhosted.org/packages/33/fc/1208276e01868b7ec1eb4c108dedabee114e24809eecf08820f9a52c3435/pygit2-1.19.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:40f1253e042d0a5dfed16eec92b5b28a529c2873f4ee77ca60d1ea7b79a14600", size = 5824124, upload-time = "2026-06-13T08:05:51.787Z" }, - { url = "https://files.pythonhosted.org/packages/03/3a/04d44e2ff972a8a7846d48ae288f717a058331d6e056a652cafbcd7f6867/pygit2-1.19.3-cp314-cp314t-win32.whl", hash = "sha256:245d627a8ae3f35dafd9ce5b35538ddb5ba0c3fe6be8d2f9aa410f93a9184b83", size = 968784, upload-time = "2026-06-13T08:05:53.107Z" }, - { url = "https://files.pythonhosted.org/packages/40/89/d42e745838fa0d9072bf425adf5b590b521b7a196d3b92f40951af9e4514/pygit2-1.19.3-cp314-cp314t-win_amd64.whl", hash = "sha256:8d2e3044ac1b09ef9120deb1896a56423c6dd17eb5ac4012c3c49dd590ee4910", size = 1291338, upload-time = "2026-06-13T08:05:54.546Z" }, - { url = "https://files.pythonhosted.org/packages/cf/10/61513d337a9241e9ce54edfd8fc1d8f2b0f36cbfa37de227ded0ffdbdc96/pygit2-1.19.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ef2790c9ff7e7673d7262e9e059c5af86c09197037073fd004d22a63e4151291", size = 998330, upload-time = "2026-06-13T08:05:55.888Z" }, - { url = "https://files.pythonhosted.org/packages/fe/52/7645ca57a4987f202487baf86a1d8feaa8c4b45e9bed53415074f17cee94/pygit2-1.19.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a1fe33a036aa2172934cafbdd17e2a0f3a73477727fc147e94f881bfe3961c2", size = 5653015, upload-time = "2026-06-13T08:05:57.131Z" }, - { url = "https://files.pythonhosted.org/packages/e1/89/4be52d0e6e58c401b18d54603530fbf0f6988f63081f39b62fffca3cf54f/pygit2-1.19.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:09db53b92c546e621218fb82a97149dc7a155a8323a3dbce6b5048da70b0c00c", size = 5650631, upload-time = "2026-06-13T08:05:58.632Z" }, - { url = "https://files.pythonhosted.org/packages/ab/fb/bf14acbc711b40d1a1517c429d8c2a6b0cb6e8513bf1b25f13c79dbb04fa/pygit2-1.19.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c14d61de0c803188a0481d394a8ba61c7e1c38210a1e525097f18a0ad563009e", size = 5563807, upload-time = "2026-06-13T08:06:00.232Z" }, - { url = "https://files.pythonhosted.org/packages/45/b8/826cdd7f00bfcf52ae46c3ad405c8279c5431fb91b4171021366efec6a40/pygit2-1.19.3-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:806d1e22d3828ea6767fb025f355374d6dd562161a0312f995723ab15e1de42d", size = 5316588, upload-time = "2026-06-13T08:06:02.341Z" }, - { url = "https://files.pythonhosted.org/packages/62/47/9a5d33c552d52e554efe7a39b5022b5455709d75093089ac867750379df0/pygit2-1.19.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:5af3422728f61958b6a0faaf7de754ecae5bed689adc31d1b727da3c697a752b", size = 1224962, upload-time = "2026-06-13T08:06:03.897Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/f1/54/9273c78efd3d570091af585bdeb68a46089e80602dafe11989cca40c6d0f/pygit2-1.20.0.tar.gz", hash = "sha256:7253735629c22fff412a72c48c204b19c206fda9fcb01e51113d9689194cb1cf", size = 826041, upload-time = "2026-08-08T14:45:11.281Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/ba/3dec5c58bc307558d7e846e2367658913fd7f49813f9c9afef12b05e3983/pygit2-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:97a903fdd3e6e99d22bac87f0aaf439ccb9ad86bb4c9e15655188e97c0e53513", size = 5727580, upload-time = "2026-08-08T14:43:36.628Z" }, + { url = "https://files.pythonhosted.org/packages/37/17/657bc991833d80321f882291408f89a8677701c93c47f48023a95381345d/pygit2-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0bba0fd1568d9ba2948cdfe0680019cb0b8c1d58e54825856b6e31ebf13a1398", size = 5715849, upload-time = "2026-08-08T14:43:38.348Z" }, + { url = "https://files.pythonhosted.org/packages/74/b3/3b02bc8feeec5ddefcd8782a27478b86f30a306916e356c7b7164c5836ef/pygit2-1.20.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:12a837854f1e7fc2c141eb2ac193a316e26812ca04ad4ed977ed9be92e598d27", size = 6069889, upload-time = "2026-08-08T14:43:39.956Z" }, + { url = "https://files.pythonhosted.org/packages/0e/c8/145f9fa3a960cb1c4ef1f31dd6170c5e1cb870960ca238038213e0c515e3/pygit2-1.20.0-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d458c50de33f5d0f086122ecf87651aba4291a89d99d79ef46976ed9088cbd0b", size = 4667780, upload-time = "2026-08-08T14:43:41.528Z" }, + { url = "https://files.pythonhosted.org/packages/2a/18/ecbc0dcce05103dfc556f3b3c44d9fa4f5023ca32e977a5c152ce4de001a/pygit2-1.20.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45403d9f0c38df1ab2219d22e5e3fca6a7d40c27784a2a771a629a1c05a6a055", size = 5833427, upload-time = "2026-08-08T14:43:42.955Z" }, + { url = "https://files.pythonhosted.org/packages/45/1c/ac65749cdc2fa6efdc9f7d45e0b1cb1553df0155c9cf2921fe80161053db/pygit2-1.20.0-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e9b7f915c8a555f2300ec231652e91303b67654465f26669fb86a6c7b2d2dcc8", size = 5325995, upload-time = "2026-08-08T14:43:44.506Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8b/d92f8bbe1b90f703cc50ec12d4343c93f7e44656ef81ca0a2aae4b923ddf/pygit2-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2ec2ade07eb56515f8fa4864efafb472ffac1715431338c985039273852aee8e", size = 6199586, upload-time = "2026-08-08T14:43:45.921Z" }, + { url = "https://files.pythonhosted.org/packages/ed/7c/b5207badbc9dc61593280868a83949132eb17a4cd8a3503cf3d4173cfd0c/pygit2-1.20.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:db972efa0a0f3bd2f3f215cb5cbb3cca68b11fd638400167e0ec4c4d5726fb15", size = 4887211, upload-time = "2026-08-08T14:43:47.42Z" }, + { url = "https://files.pythonhosted.org/packages/12/a6/00f14abd34701bbf329e71e56e5fb70c2f0272d9ef572c9924f4b2fbed92/pygit2-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5d6cfc3684ac7ca944e7172f0518adcbc93c1d7711705c4b36ef70218fc721ce", size = 5931583, upload-time = "2026-08-08T14:43:48.97Z" }, + { url = "https://files.pythonhosted.org/packages/54/07/c0701027b77555930913592b5a265eef09f7260221d4c6348a629972f0e3/pygit2-1.20.0-cp311-cp311-win32.whl", hash = "sha256:8c9073e38f216e937cfc69d8d93e97a59c59f06dfa67c557134b10f8927503d2", size = 1019027, upload-time = "2026-08-08T14:43:50.315Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5a/09e66f51a5147929fe4a5653e9e9f3820e91998820fd15837ecfdd98e4fd/pygit2-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:c4800ad2643e0cb540f802973866b16480d45da2c8237a56c0b9405460ea97e6", size = 1332836, upload-time = "2026-08-08T14:43:51.372Z" }, + { url = "https://files.pythonhosted.org/packages/89/c0/7241ced2014b485f6de3eb692236f0db8f6d92d79cbdcbff972d0b78614a/pygit2-1.20.0-cp311-cp311-win_arm64.whl", hash = "sha256:83f1ccb0455e801b70dc13b4fec6dcc5ed0412ab7a38b986e0f559c9ed0bf7e2", size = 1043630, upload-time = "2026-08-08T14:43:52.8Z" }, + { url = "https://files.pythonhosted.org/packages/32/4a/20433a321dc495231f6c017db880dfb6e0d5436780a699ce5e6ac5c1fead/pygit2-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dec857dcd64cfb3f52d2e79faa53ff9fc34a6db2ed5d3f865bf5a7239177de56", size = 5725662, upload-time = "2026-08-08T14:43:54.133Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b7/add39585242cd7f24701e4899e6cff73cc8aa64dc9c945497071043f39cd/pygit2-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9374c6f8d8ee0ba01a58238416ed2b24d4c154a8823ebc6b638a7ee4a480415", size = 5716598, upload-time = "2026-08-08T14:43:56.171Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b8/6039aef21a18da62dd41c0457af47c6d84e24845b1cc938661ec56446a55/pygit2-1.20.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62bd32dcfc1982e1cb2218ca38c14c511caf970ec64ae2d39e6aa0d9d62dc4f0", size = 6070500, upload-time = "2026-08-08T14:43:57.701Z" }, + { url = "https://files.pythonhosted.org/packages/26/0b/8e9852340ddcaea2f4f28f4d4f6324254c75d845654aae61f67b7b2b084b/pygit2-1.20.0-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9a540410f9f893c5e68e221d1df21319fe5add04e45d51b2329ce0fa14516b7", size = 4667205, upload-time = "2026-08-08T14:43:59.178Z" }, + { url = "https://files.pythonhosted.org/packages/33/26/bd9b33dbd8535b4f667f7cac56a15740fa5039c8ceb735fda1cd0d2d3b65/pygit2-1.20.0-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b2be2e29283268a2842342c7d4e206e1d8326dfc71598743fa8ef61ef6d744d5", size = 5838298, upload-time = "2026-08-08T14:44:00.745Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ce/7a7c5007c3b1e7082503b23a51f1329f42525cda6531630623fb52ba8390/pygit2-1.20.0-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8119ef9b00587f243ee5462dfe5dc71aad600cf1b25b268bffa67065d3412439", size = 5327204, upload-time = "2026-08-08T14:44:02.11Z" }, + { url = "https://files.pythonhosted.org/packages/33/61/fa9b9c75c4a87d5877179c13ea26e958f2ea5bb6a42f5228615bf26e4010/pygit2-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7150878d113dee6291ca2d17876729b739e762d1585d90459aa61b34bd662de7", size = 6201154, upload-time = "2026-08-08T14:44:03.481Z" }, + { url = "https://files.pythonhosted.org/packages/8f/e2/3ba5a1d42e3334c93387eb4d01365762f735c25655e9907c23d58e110cef/pygit2-1.20.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a79cf9048797997cc3610726b7b2827d6459961208553b187522786ab5ffc0f2", size = 4886640, upload-time = "2026-08-08T14:44:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/23/6b/bba0edae78e97e220908c33a8bf1ef5418bc558e3c657ec0d29f18e77304/pygit2-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:97619aa269f31f2b94e83078b5c6df4e7a0cc9bdfe5b672378c10ed09d50c360", size = 5936908, upload-time = "2026-08-08T14:44:06.544Z" }, + { url = "https://files.pythonhosted.org/packages/09/9b/22149d9b5059ad47b21bf9c7791fc59ce2226aafb95dbfe0e6e7fa54af89/pygit2-1.20.0-cp312-cp312-win32.whl", hash = "sha256:d49d7bb4987fabece611f4f873bfe490e574f0bb5bb4fafe557d4d504efe3026", size = 1019713, upload-time = "2026-08-08T14:44:07.836Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/8c9fb460aa70e34681e26d1b314dc2ee6a7de556941d20d6fec3485d0377/pygit2-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:2c16126d27218e7b5d059e5072b15819261ec3ad515ff45ed611fa1687993c25", size = 1333225, upload-time = "2026-08-08T14:44:09.124Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a3/8ca3be722208fd764364feabe5c2a9186a96dcc2be73feb7f7bfce4dda5b/pygit2-1.20.0-cp312-cp312-win_arm64.whl", hash = "sha256:3f7b97f577d7d15d59fbef8e3f6f6943bdc5e315cbf6d4c0478984858e55b0ea", size = 1043775, upload-time = "2026-08-08T14:44:10.157Z" }, + { url = "https://files.pythonhosted.org/packages/f9/52/4247a6180b6a4100a7232404a97cad74a62f19942c405383f1d13c361168/pygit2-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9217790892f6c9faf38737a078ac36203bd082b226e0b0ba68d8930f4ba7737b", size = 5725672, upload-time = "2026-08-08T14:44:11.347Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ee/e28c2f0bc3d753158e93900bf0e236038b79f2d20a09be8952f1c4c1e692/pygit2-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c21715780541121c9784a7e4372c32b440b3ac67452b5364af738f5f4b82f8e1", size = 5716639, upload-time = "2026-08-08T14:44:13.068Z" }, + { url = "https://files.pythonhosted.org/packages/6f/76/ca1ac1f568e7a326a01b6b1e09960f4e09a7f1a06c6d93b0ffdb28b51dd3/pygit2-1.20.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23a1879065591b65b26f58048450629c2cdbdaa2a65328eee27d908614b963db", size = 6071276, upload-time = "2026-08-08T14:44:14.639Z" }, + { url = "https://files.pythonhosted.org/packages/af/88/5d56e8d5bbd75e3929afe177755bb7c28cf4e8bf1cb05eb3713769b3e75f/pygit2-1.20.0-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4e51e9a9a4aa15bd570d57c5febc0142b86a19c4f2b579e9a33d6c170189ff9b", size = 4667815, upload-time = "2026-08-08T14:44:16.291Z" }, + { url = "https://files.pythonhosted.org/packages/5c/84/8ed86da20b9d451b2be4a916f9ede203fbfdd6aa40c5e54ffadeeb4544af/pygit2-1.20.0-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c7fba542df37ef208dba315579df6ea62c841ed60101154e15e811480f3f5ae", size = 5839457, upload-time = "2026-08-08T14:44:17.708Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7c/c29b37d10614ee0787e3fdaa79664c8bb68f38587ad75f8f84122021f3c4/pygit2-1.20.0-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4600c5cf14895bd7a4ffac14932969c02b6fd7ce2a047b004f3397bdc040425c", size = 5327439, upload-time = "2026-08-08T14:44:19.089Z" }, + { url = "https://files.pythonhosted.org/packages/aa/04/f462bd2bf8acd34859418e72de805b92af7d216d37e5ddbfd09a01284dc9/pygit2-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229bbd20bde6a9fcceee732ca4bc30360d375b0db439e19c6b9a0e1d3bb4311e", size = 6202569, upload-time = "2026-08-08T14:44:20.579Z" }, + { url = "https://files.pythonhosted.org/packages/16/47/8805d05d6a1d1768f5ccfc2a87d7ea33c31ba99d7ab2762b838eccdda922/pygit2-1.20.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:223be35205f6dd4ed9fd35ae9feca59fb1a98913de090d8716c5830495e31901", size = 4888440, upload-time = "2026-08-08T14:44:21.93Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/8ef9d3c585d1d37acb236e2fc637905da931c9321dced6ce9ee3754a9145/pygit2-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:46b6bac662c55cfbdc137f131050317d56e508a4506ab2e8ac01518f33a29bcd", size = 5938354, upload-time = "2026-08-08T14:44:23.287Z" }, + { url = "https://files.pythonhosted.org/packages/68/63/97aff45f675521f1a0397e93e7b8f623b86ef79c70567ea8bbfc0bee6ccd/pygit2-1.20.0-cp313-cp313-win32.whl", hash = "sha256:a455a1d9714b49ba36fc45985d58debe3d6d07fbaa187cd217f79713ae1d1af7", size = 1019675, upload-time = "2026-08-08T14:44:25.099Z" }, + { url = "https://files.pythonhosted.org/packages/4b/68/428fab56d8df919bcd735aa9ef0ac9100ab47b9ed9d9aa4cd0a686da9b5d/pygit2-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:451bfe3ec1719419157f49423d1a13a90788df78d2e97fe53efd2c872dbdf8a1", size = 1333178, upload-time = "2026-08-08T14:44:26.254Z" }, + { url = "https://files.pythonhosted.org/packages/cb/f3/51e78c77badab4b73434749bc19ba1f406c191e0911da6a051b803c3445e/pygit2-1.20.0-cp313-cp313-win_arm64.whl", hash = "sha256:e9f715e5ddef14eb4ba344b1deca8a82a2015acb01f6aa0a79eaea122dfc9384", size = 1043747, upload-time = "2026-08-08T14:44:27.502Z" }, + { url = "https://files.pythonhosted.org/packages/95/99/c6b55c5f695b84921afdc4b52ac14191e4b8006e18220f09d32d63d15c1e/pygit2-1.20.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:79dece6a15fee4e0c1fc9231b3156327933adbdd6d21c2070e3c06c26add3d73", size = 5728008, upload-time = "2026-08-08T14:44:28.757Z" }, + { url = "https://files.pythonhosted.org/packages/ca/43/a6639265efc0ce9cdbf9943cac9ab03d74f26128882059495193c7d0652f/pygit2-1.20.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:15907f5b6e28dafd54062e41e9375cb4dc2f9cc37ffad58b0195dfeab58b3325", size = 5716504, upload-time = "2026-08-08T14:44:30.193Z" }, + { url = "https://files.pythonhosted.org/packages/66/04/6c9b77b553e55bfc104540969df57e08c10ca7d91e26c035a7d58f9a681d/pygit2-1.20.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68b4cc2a442b59202c038214aa93ea9db8bb222429552e545afe0a98a5ccb004", size = 6073519, upload-time = "2026-08-08T14:44:31.745Z" }, + { url = "https://files.pythonhosted.org/packages/41/c1/9507ccfaac42424d70b6acea6b03e2645e55d6cc57efbba458d718ed117e/pygit2-1.20.0-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e9c63594002feaa4b406dd3b133b4d40a1c53dd285f9bbf3156af89647f2ddf2", size = 4672126, upload-time = "2026-08-08T14:44:33.154Z" }, + { url = "https://files.pythonhosted.org/packages/49/0b/eea71c54f11e943a3c6493df26db59fc4fe859bf701bb366992ba241ca76/pygit2-1.20.0-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b99f40e2b3ea98e8ff905958db279d21e735d2fb5888818b359480f0883c2d", size = 5841077, upload-time = "2026-08-08T14:44:34.499Z" }, + { url = "https://files.pythonhosted.org/packages/85/a6/46786c212302b4bc10a26b64640a7419db17aed48e420b191a0a76abfb9c/pygit2-1.20.0-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cf93fd9dea38087f6642837bfeb6db722b661ea9dd90b604d06810063ff030e6", size = 5329043, upload-time = "2026-08-08T14:44:35.806Z" }, + { url = "https://files.pythonhosted.org/packages/65/4f/b0159fd6d4efd997ff5f3eb8b3340b7ac797b98f8c06f51aaac19c0b444d/pygit2-1.20.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:115580869b6c78bbf07b24f389c8a146c6f080e55121ada2506b3ca29710dead", size = 6203519, upload-time = "2026-08-08T14:44:37.722Z" }, + { url = "https://files.pythonhosted.org/packages/a5/10/797f5583a85b013a0f216ce3c88f6f5556f9fa4b6bcc5d1de297e6e21d6c/pygit2-1.20.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:37e0db3a58603531d6ceef3b36b0bab645a2a81b91c1b8e0e1111f34d67fa61d", size = 4889896, upload-time = "2026-08-08T14:44:39.097Z" }, + { url = "https://files.pythonhosted.org/packages/41/96/cb1e48a08bd7030dbb4455a1c3f940bcdfc2943e24bbac3cfe1150753652/pygit2-1.20.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93ed5d0c305c265b97337844b2cecc8075ff05f657475ffcefbe985de8b04134", size = 5939118, upload-time = "2026-08-08T14:44:40.445Z" }, + { url = "https://files.pythonhosted.org/packages/c6/e1/c7d2683de4c7fb59b7f6f3d2c6dea638fb72c8c45655e1639517c7c8a8d2/pygit2-1.20.0-cp314-cp314-win32.whl", hash = "sha256:c7ec615560faf3a4f868263df680954bf3deb74cefd24be63a2caad4ffadf6f9", size = 1044051, upload-time = "2026-08-08T14:44:41.801Z" }, + { url = "https://files.pythonhosted.org/packages/a4/52/2a903622fa9599fc0e0d68a7614513ba26248a89590042ee7752d58c0d35/pygit2-1.20.0-cp314-cp314-win_amd64.whl", hash = "sha256:4ae51387c4016966703f990fad2a1adf60f594239d8a0f5b308ec82921e3b582", size = 1368061, upload-time = "2026-08-08T14:44:43.145Z" }, + { url = "https://files.pythonhosted.org/packages/a4/bd/e05a00751c65745383fadddaea02d49d81a4bbff2d7d1d7a745c7763f67c/pygit2-1.20.0-cp314-cp314-win_arm64.whl", hash = "sha256:055057b36ce141ccc6ce600475c3f8ce0edadad45c78b480cdcb61da29f7ecf7", size = 1074468, upload-time = "2026-08-08T14:44:44.609Z" }, + { url = "https://files.pythonhosted.org/packages/13/a1/4ba9ac3ce81f02d2f089c3c878282767d06eb97716834432917aa676cd58/pygit2-1.20.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:00415a2aad3a4e1eeeb1da5c0d805e992971e849a1a7d9f604c8e0381dff70fa", size = 5731464, upload-time = "2026-08-08T14:44:45.997Z" }, + { url = "https://files.pythonhosted.org/packages/a3/87/231bdc55a8243c44e6cab4772b863842abba73752258d8adf93ca12d2d5a/pygit2-1.20.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4207f901c377410f3d85df259d32903af1523258150968a1add805f40daad8bc", size = 5719730, upload-time = "2026-08-08T14:44:47.525Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bc/8688683a38f3b250ccc80b64f4a157a9cfb61dd836989b78ba923379a410/pygit2-1.20.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4cf13d0b12fc1df25953a23c3112f4cb8abed1802b0479b317086f79f5d1511", size = 6134328, upload-time = "2026-08-08T14:44:48.924Z" }, + { url = "https://files.pythonhosted.org/packages/81/1a/6ecf1236d9ba766e97797735d6d584b3713dd1ef03628b39c87ad231b90e/pygit2-1.20.0-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d3b2db875ff92b288bb23cdb4bd398b045869e98c8dde55ba49d9abf264f19fc", size = 4730024, upload-time = "2026-08-08T14:44:50.259Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/304e83eb83da4b84d90168f003f9ae6761871f97285fe4352760abc098e6/pygit2-1.20.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fb2becd2cee9b610da613902aeca5426ac8c4a09e16344e1f75802f2ffe2bf3", size = 5893950, upload-time = "2026-08-08T14:44:51.797Z" }, + { url = "https://files.pythonhosted.org/packages/2e/11/e64b6414998dbcb336a5523e1e222e7656f5d679f7da7d797962fce57ede/pygit2-1.20.0-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cbbe502c735ee630be31be1c6e20f9ef35f980c492301c77969ce3d883242ffc", size = 5379546, upload-time = "2026-08-08T14:44:53.392Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ba/22ae0fe087d1eef7ab694882a3ab5e0c4cafac63ab2dc8e9c5716c5d4d3b/pygit2-1.20.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:254e0b61201c78b1cabe87d06d60891676311da07b5393a04e0ac813c130d583", size = 6261117, upload-time = "2026-08-08T14:44:55.394Z" }, + { url = "https://files.pythonhosted.org/packages/e0/20/71b6064e532b8071035f40a1c727040861eaecfe8b04ecfa0a998fcfb7c0/pygit2-1.20.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:7cb0607755a251ca5ab942f1f45796dddb03b8499770f8c97d8de5f3616233ee", size = 4938423, upload-time = "2026-08-08T14:44:57.237Z" }, + { url = "https://files.pythonhosted.org/packages/51/bb/3751758fd0a2e52881e3b760376f9a848483bbf80db01f13fcea556c293e/pygit2-1.20.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5c23e5405d6837760d3de58635492221067ee2d89c000c7b53e39e679b378ee1", size = 5990631, upload-time = "2026-08-08T14:44:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/50/19/dc0af298676f0dc1c1affedef0fdd49c3e831b71442c63f4047d3da81f4b/pygit2-1.20.0-cp314-cp314t-win32.whl", hash = "sha256:20dd3576c05cc94dd6ad6650d0a937593de6115bcbfeba37414dd57fa33c9b8a", size = 1047236, upload-time = "2026-08-08T14:45:00.101Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2f/cd193585ba738814cab54f6b99faa12e8449b5706b24d242d1c7dc785b0d/pygit2-1.20.0-cp314-cp314t-win_amd64.whl", hash = "sha256:82006722c4aacd4f5e4c93cd8914d1dd1521ec77a71c37f50ac58bc4f6b563f4", size = 1371325, upload-time = "2026-08-08T14:45:01.439Z" }, + { url = "https://files.pythonhosted.org/packages/ed/b8/c0e5ae3702f46a36fa3bd914853d52c534968e0417a2e5775f439a921317/pygit2-1.20.0-cp314-cp314t-win_arm64.whl", hash = "sha256:3831bf91550c487540f3e2d5cea211689b8e65b4589e812d3c335cb5500a5eae", size = 1075577, upload-time = "2026-08-08T14:45:02.598Z" }, + { url = "https://files.pythonhosted.org/packages/3f/9e/7388a45ad7a1ab0f2e68d43a1117b3dc0526fb383e0623da0ce402b15555/pygit2-1.20.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e6432cf4eb368366affb1bce4eaac750f03ee440defe5ee185557ba7e656909a", size = 5666736, upload-time = "2026-08-08T14:45:03.884Z" }, + { url = "https://files.pythonhosted.org/packages/68/15/865f9b69a98daf0d218dafc2946c074889cd5291e3cd7dba3fa2af2b11da/pygit2-1.20.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aff3a6312006e668ce35983ef3c8d3c27115a37ce9ceb6ce316422f25d44b01d", size = 5664511, upload-time = "2026-08-08T14:45:05.361Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a4/ed18018054b88e378918088943ddc87eace2794ed058e66ee003dbb5779d/pygit2-1.20.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8108f420748549807603e5463f46df123844a7b5c0123d990d1107f308a3171f", size = 5577852, upload-time = "2026-08-08T14:45:06.776Z" }, + { url = "https://files.pythonhosted.org/packages/63/d0/b769009606f3d3adb7eaed9cf889e40dc5c6b03be2896fc2c924c3a886bf/pygit2-1.20.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de6729361800d312f9062c53a218f141af8909bad44c4d0064995728a284e8ae", size = 5333941, upload-time = "2026-08-08T14:45:08.433Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e6/dc41a33491517159e72ed197e60b50f74fd4f22903308f89dad815993205/pygit2-1.20.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:e063d809e5ae8624a3c29a9743417670f2f57ab27fcf300f4e35575f9f30be79", size = 1300896, upload-time = "2026-08-08T14:45:09.999Z" }, ] [[package]] name = "pygments" -version = "2.20.0" +version = "2.21.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, ] [[package]] @@ -4738,15 +4952,15 @@ crypto = [ [[package]] name = "pyopenssl" -version = "26.3.0" +version = "26.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/b7/da07bae88f5a9506b4def6f2f4903cf4c3b8831e560dba8fa18ca08f758f/pyopenssl-26.3.0.tar.gz", hash = "sha256:589de7fae1c9ea670d18422ed00fc04da787bbde8e1454aea872aa57b49ad341", size = 182024, upload-time = "2026-06-12T20:28:07.458Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/e8/7325d258199b159eb2c03fe32107533e2832e70e63f4fb88a6aa00023201/pyopenssl-26.4.0.tar.gz", hash = "sha256:28dfcce0162b9211413e26dfbfdf1d24317fbeba18fc93c12400a1856b2a0bc7", size = 182046, upload-time = "2026-08-01T19:50:50.512Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/18/1dd71c9b43192ab83f1d531ad6002dc81108ac36c475f79fb7a295abe2f4/pyopenssl-26.3.0-py3-none-any.whl", hash = "sha256:46367f8f66b92271e6d218da9c87607e1ef5a0bc5c8dea5bb3db82f395c385a3", size = 56008, upload-time = "2026-06-12T20:28:05.999Z" }, + { url = "https://files.pythonhosted.org/packages/51/ad/2cf6d3fa2fae5c79e1ed9960c0d42badd0f94d81dd12b50604cdc839e648/pyopenssl-26.4.0-py3-none-any.whl", hash = "sha256:f0eb0cb2d581d3ad2b9c489468485e7f2ab6727d08401bcf9d824c3caddf3c1c", size = 56026, upload-time = "2026-08-01T19:50:48.94Z" }, ] [[package]] @@ -4801,16 +5015,16 @@ wheels = [ [[package]] name = "pytest-env" -version = "1.6.0" +version = "1.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "python-dotenv" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/69/4db1c30625af0621df8dbe73797b38b6d1b04e15d021dd5d26a6d297f78c/pytest_env-1.6.0.tar.gz", hash = "sha256:ac02d6fba16af54d61e311dd70a3c61024a4e966881ea844affc3c8f0bf207d3", size = 16163, upload-time = "2026-03-12T22:39:43.78Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/49/08ee056f9cc655e437abcf2ae399884844b623223476ae6a77244131db03/pytest_env-1.7.0.tar.gz", hash = "sha256:0c1dc1101fb8d3ab3611e8f8d657ba06c3c0c167fc85c90457e5b27f2508f43e", size = 16408, upload-time = "2026-07-21T13:09:21.834Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/16/ad52f56b96d851a2bcfdc1e754c3531341885bd7177a128c13ff2ca72ab4/pytest_env-1.6.0-py3-none-any.whl", hash = "sha256:1e7f8a62215e5885835daaed694de8657c908505b964ec8097a7ce77b403d9a3", size = 10400, upload-time = "2026-03-12T22:39:41.887Z" }, + { url = "https://files.pythonhosted.org/packages/3e/fc/9f2975c41d41bf5bd9a7d0fc03085ec20052b456b079df53828ae4a1b100/pytest_env-1.7.0-py3-none-any.whl", hash = "sha256:9ee0f1fe859d23fcdb533fe2909a404b3b133d02674a56df275bbe4df4eb104b", size = 10263, upload-time = "2026-07-21T13:09:20.677Z" }, ] [[package]] @@ -4881,11 +5095,11 @@ wheels = [ [[package]] name = "python-dotenv" -version = "1.2.2" +version = "1.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/53/ed9d74092561d4b01a2ef1349d52cdbc135e526c245f366b089cfca6de49/python_dotenv-1.2.3.tar.gz", hash = "sha256:a20a594dabeaa385725aa239d5244871c143ecb356add8a20fcf23773a6c3a35", size = 58945, upload-time = "2026-08-16T16:54:54.067Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, + { url = "https://files.pythonhosted.org/packages/0d/17/c5c6b53ddc18f297992099b3d9ec16c855c0ccc83263a21fe4d1c625ec6c/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9", size = 22780, upload-time = "2026-08-16T16:54:52.473Z" }, ] [[package]] @@ -4950,11 +5164,11 @@ wheels = [ [[package]] name = "pytz" -version = "2026.2" +version = "2026.3.post1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/48/fb042503b6ca6cd271261dc559fd6432f7d8c713153e9ec5c591af4dfc1c/pytz-2026.3.post1.tar.gz", hash = "sha256:2211d3fcf9a797d3405cac96ac7f61d80e6a644f72a3309607282fe8a2010c5d", size = 319745, upload-time = "2026-07-25T15:12:07.385Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7b/39c34ca613b0b198cb866466651b26b045e2009864c5183c979a3b83f383/pytz-2026.3.post1-py2.py3-none-any.whl", hash = "sha256:dd95840dd199baea12d9cc096a1d452caa6596a1c1e4b5f3dbd1541855d5e815", size = 508283, upload-time = "2026-07-25T15:12:05.782Z" }, ] [[package]] @@ -5162,16 +5376,16 @@ wheels = [ [[package]] name = "responses" -version = "0.26.1" +version = "0.26.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, { name = "requests" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/58/1fb6de3503428196df78638f991ec8095274f1ee9723e272ee4d9ff0092b/responses-0.26.1.tar.gz", hash = "sha256:2eb3218553cc8f79b57d257bac23af5e1bf381f5b9390b1767816f0843e01dc2", size = 83088, upload-time = "2026-05-21T19:56:39.747Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/1a/4af3e6d659394b809838490b144e4ab8d7ed3b9fecc7ca78f5d2f79b1a3d/responses-0.26.2.tar.gz", hash = "sha256:9c9259b46a8349197edebf43cfa68a87e1a2802ef503ff8b2fecbabc0b45afd8", size = 84030, upload-time = "2026-07-03T16:44:50.325Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/31/6a620b4427d546b9e7cca8b3b8c5f0559d9cef2bb9eedcda7f73c1473c19/responses-0.26.1-py3-none-any.whl", hash = "sha256:8aacc4586eb08fb2208ef64a9eb4258d9b0c6e6f4260845f2f018ab847495345", size = 35502, upload-time = "2026-05-21T19:56:38.046Z" }, + { url = "https://files.pythonhosted.org/packages/7c/28/693e1d9ebf72baa062ded80d837a035b86ce75eda5a269379e9e2b1008a8/responses-0.26.2-py3-none-any.whl", hash = "sha256:6fdfeabd58e5ec473b98dfe02e6d46d3173bd8dd573eff2ccccf1a05a5135364", size = 35609, upload-time = "2026-07-03T16:44:49.1Z" }, ] [[package]] @@ -5473,39 +5687,39 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.20" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" }, - { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" }, - { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" }, - { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" }, - { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" }, - { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" }, - { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" }, - { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" }, - { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" }, - { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" }, - { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" }, - { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" }, - { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" }, - { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" }, - { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, +version = "0.16.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/8f/d8074b1f25e003164087a8bfe79a0f1a3945135764dbb6aaab04103dcaf9/ruff-0.16.4.tar.gz", hash = "sha256:13171aa9d9af2240ee3504e639de73122c67e74036de5ba2e1d01422cd17e3dc", size = 4899731, upload-time = "2026-08-20T17:43:59.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/80/779895ef584e089d22f2c6df0d0e99a65ec2df0805f1fffd439415b8c1f0/ruff-0.16.4-py3-none-linux_armv6l.whl", hash = "sha256:df4075f71ddac40b9934af60c3ec8a53047dd5a5fdc43224e6e4e8e9a27cb6f7", size = 10006909, upload-time = "2026-08-20T17:43:16.888Z" }, + { url = "https://files.pythonhosted.org/packages/a9/e6/f553199b5e8927a05cb5c422d921fd0656b29ab976e91c44802107c6b0da/ruff-0.16.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0c95538517af68004306b0fb3214ff2f2af67a65092aee77cd9eb86db6656604", size = 10240201, upload-time = "2026-08-20T17:43:19.337Z" }, + { url = "https://files.pythonhosted.org/packages/1c/70/4a6dc4bb34da4dee35e30f09bbd1bfbdd26f33b62fb9b8df31f08a199cd2/ruff-0.16.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:963f83df8e69e575b64d67dd447ebbc917db41a14bf38d4593a4183e7aaa8255", size = 9835122, upload-time = "2026-08-20T17:43:21.708Z" }, + { url = "https://files.pythonhosted.org/packages/24/12/c6e22d686372c15bcb7af99831f1a1be96df696491babf4f24e4f942c527/ruff-0.16.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32a5057c7ff3f6e6480a48fccfb3a412a690f48a3d03ac5cf08177d6c2da3ade", size = 9977162, upload-time = "2026-08-20T17:43:24.236Z" }, + { url = "https://files.pythonhosted.org/packages/46/49/72b10ec912f5ab5854992eaf7aa7cd36729b6937d9dc4e0fb41b3bf428ec/ruff-0.16.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3dce8d9b0c57c265b91885a66a567d8ea1372e8eb4e250fa8e5e3f579e99cff", size = 9829789, upload-time = "2026-08-20T17:43:26.966Z" }, + { url = "https://files.pythonhosted.org/packages/fa/80/0f30e32e7f6ee26edc39075502db9d368d788a44a79b55f763eb4ab03796/ruff-0.16.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7dc651db49283c69f8e72c834eec4fe5573e4c646856aebece0ce385dceb2a80", size = 10527949, upload-time = "2026-08-20T17:43:29.384Z" }, + { url = "https://files.pythonhosted.org/packages/52/3d/86e8ad3542169e56cac3859a343afdb9df2ad54d35a59ce1e67baee83421/ruff-0.16.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3817b87dbcabc92f13b05019257c5b89b5b4d51b5fb20f56fb5235ceb723cd07", size = 11333695, upload-time = "2026-08-20T17:43:31.872Z" }, + { url = "https://files.pythonhosted.org/packages/d0/16/481c29b380c20a0054a8261066665e1b3488e23636c49d0a43e75975b9bb/ruff-0.16.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9fce1499134b2c8c68e5166f95705a5812062bb93aacc5f9873bb1a27084bc7", size = 10727741, upload-time = "2026-08-20T17:43:34.596Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b6/56bc0b8cf45b54b28b3a5e6381c8945d51b5b18adf659454c32295209a31/ruff-0.16.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2d812e482f5a7e02eee26cd73d2a37ebbdf47d795ea63ba1b89110ae93e9fb3", size = 10286522, upload-time = "2026-08-20T17:43:37.288Z" }, + { url = "https://files.pythonhosted.org/packages/e8/8b/b345b4fb110f2fbe2bd31eabd271e5e8b3b7e4ee6c0e02f2dc6be78db000/ruff-0.16.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:6baaf984aa7976edf93d3b627fe2d1d22ee94bbca05fa6f90fc76d73924e3454", size = 10584182, upload-time = "2026-08-20T17:43:39.984Z" }, + { url = "https://files.pythonhosted.org/packages/29/e5/827b34041c35f58774a9681a4213994c164fc987800f4dddabcf451da0bf/ruff-0.16.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:bdfcf0b28662eb890372d50f92c283bb94e67e7635ed93c7fd533970acff7b2b", size = 10134195, upload-time = "2026-08-20T17:43:42.351Z" }, + { url = "https://files.pythonhosted.org/packages/0f/10/d0bffcdd6729b87afc82ba0ef377173356a7dc8e972f5179968cf2fdf98c/ruff-0.16.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b66b02cb9b04f537643cadf5768e5f98dc461890d530cb67113d71c8c76e605d", size = 9825821, upload-time = "2026-08-20T17:43:44.532Z" }, + { url = "https://files.pythonhosted.org/packages/f5/32/0db2a863b796ca62d83e92a07a3ccf00921b14db02059347576a2fda3d4b/ruff-0.16.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8528bf9a4b291a60bf02ea453511e8ce6215bd2b982ee80405b66b008b6c30a0", size = 10267658, upload-time = "2026-08-20T17:43:46.989Z" }, + { url = "https://files.pythonhosted.org/packages/b2/a0/fbdeb59e48c6261f523e56c8f12e9c08fbe693786595cc7e3959207a9232/ruff-0.16.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:fbd85d2875fdd67e833213a651f613bbf25303abf6aa822a5121f4531195678d", size = 10697071, upload-time = "2026-08-20T17:43:49.891Z" }, + { url = "https://files.pythonhosted.org/packages/aa/28/0c6dd865859c6d17bc8ccc34cb72b0e02d6c7eb25e8a1e22b5bea681e2c0/ruff-0.16.4-py3-none-win32.whl", hash = "sha256:312769988007aaeb8e189b443ccdd03c0e6374489e053467be6d96518ebff76e", size = 10021687, upload-time = "2026-08-20T17:43:52.281Z" }, + { url = "https://files.pythonhosted.org/packages/a3/03/e724450f621698117f9aa6dd241c94d0274ae96781378dc86745ae29f0e7/ruff-0.16.4-py3-none-win_amd64.whl", hash = "sha256:05d9d27a18c4bcbefada602480ec9e01e0bc949d432e0ced5df77edac195919c", size = 10567657, upload-time = "2026-08-20T17:43:54.78Z" }, + { url = "https://files.pythonhosted.org/packages/0e/fe/da8b9e1347696bb22120b77280ec5ce25d500ca5cb39d5ad6e5c18de19c1/ruff-0.16.4-py3-none-win_arm64.whl", hash = "sha256:a3a61621c9b6f6a89573e938a080e648f1695baa3f58570a3a707bc51ff65a21", size = 10451579, upload-time = "2026-08-20T17:43:57.135Z" }, ] [[package]] name = "s3transfer" -version = "0.19.0" +version = "0.19.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/94/dcdaeb1713cab9c84def276cfac7388b17c7d9855bbcfe88d77e4dbafd44/s3transfer-0.19.0.tar.gz", hash = "sha256:ce436931687addc4c1712d52d40b32f53e88315723f107ffa20ba82b05a0f685", size = 165171, upload-time = "2026-06-16T19:44:51.599Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/43/35e4d8aa320bffe8287fe8f65f578fa2d2db0a64212f0e710dce58267854/s3transfer-0.19.2.tar.gz", hash = "sha256:ba0309fd86be3c27dbf78cdd813c13c5e1df16e5874b99d2535ebbdfb9892993", size = 165592, upload-time = "2026-07-22T19:30:44.432Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/5f/4c174edad94f82de888ac00a5ddd8d07b35609b6c94f0bdf4d74af57703e/s3transfer-0.19.0-py3-none-any.whl", hash = "sha256:777cc2415536f1debadb5c2ef7779275d0fc0fe0e042411cdd6caebeb2685262", size = 90101, upload-time = "2026-06-16T19:44:50.439Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e7/5c595c75e9f41a44f30e526eda465ea0b4eec93470e074e4a111b253f13a/s3transfer-0.19.2-py3-none-any.whl", hash = "sha256:d8168eccca828cbb2cd573675333f3bddd254313a9c42494b84c76b539e8ba25", size = 90216, upload-time = "2026-07-22T19:30:43.251Z" }, ] [[package]] @@ -5537,11 +5751,11 @@ wheels = [ [[package]] name = "setuptools" -version = "82.0.1" +version = "84.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316, upload-time = "2026-03-09T12:47:17.221Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449, upload-time = "2026-08-08T18:27:58.365Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223, upload-time = "2026-03-09T12:47:15.026Z" }, + { url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216, upload-time = "2026-08-08T18:27:56.719Z" }, ] [[package]] @@ -5573,11 +5787,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.4" +version = "2.9.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/47/2c/0a5f6f8ee0d5589e48c7640213ed5175d52cf540a06725b628cc1a45d6ce/soupsieve-2.8.4.tar.gz", hash = "sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e", size = 121110, upload-time = "2026-05-24T13:55:57.154Z" } +sdist = { url = "https://files.pythonhosted.org/packages/69/99/a6ca3beb3ccacb41fb3321d8a60e5566f9e6467601ef8eba6a17e1b89778/soupsieve-2.9.2.tar.gz", hash = "sha256:4a55d8cf158a9c2e587fa4922f1bbb91d68ac829e2d6f25403a85747c71daf74", size = 122445, upload-time = "2026-08-07T00:57:24.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/f5/0c41cb68dcae6b7de4fac4188a3a9589e21fb31df21ea3a2e888db95e6c9/soupsieve-2.8.4-py3-none-any.whl", hash = "sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65", size = 37304, upload-time = "2026-05-24T13:55:55.406Z" }, + { url = "https://files.pythonhosted.org/packages/eb/dc/ad025c1ee131eba60c69f4dd5779b18fcf1e6b21a343e2162a84d5d133c7/soupsieve-2.9.2-py3-none-any.whl", hash = "sha256:8089a26fd974ca7a1f30276d3d8492ab266ab15af581642dfe8aa162e0c1c823", size = 37370, upload-time = "2026-08-07T00:57:23.524Z" }, ] [[package]] @@ -5704,11 +5918,29 @@ wheels = [ name = "stevedore" version = "5.8.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] sdist = { url = "https://files.pythonhosted.org/packages/e9/88/35e4d27d9177d7df76d060e0a18f69c6c5794c96960c94042e20a12c8ba2/stevedore-5.8.0.tar.gz", hash = "sha256:b49867b32ca3016e94100e68dbf26e72aa7b8708d0a3f73c08aeb220370ac715", size = 514710, upload-time = "2026-05-18T09:15:27.731Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f5/ac/19f9941c74add59d17694930ec8105d5eddeee4ce56dd8632b765ca16d6c/stevedore-5.8.0-py3-none-any.whl", hash = "sha256:88eede9e66ca80e34085b9174e2327da2c61ac91f24f70e41c3ad76e4bb4872b", size = 54553, upload-time = "2026-05-18T09:15:25.82Z" }, ] +[[package]] +name = "stevedore" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version == '3.12.*'", + "python_full_version == '3.11.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/db/a1/3b8ed9c1fc3aa6eebb57732d924ddaa0500ecc3b638d0454816320994383/stevedore-5.9.1.tar.gz", hash = "sha256:e97a2667923efda926e8713fde6a73616df68210a3cbc6f02b48967b676fd8bf", size = 518111, upload-time = "2026-08-20T15:25:14.754Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/97/bba6e7ec2f5498b9dcb7b1b6400086b80ae5a8ebaff4b25e8c8add75f439/stevedore-5.9.1-py3-none-any.whl", hash = "sha256:5c8ff3a9f336cc1a06ac0f597bc79d11a2f950bfd32e290ca56b5a301fafafbf", size = 54931, upload-time = "2026-08-20T15:25:13.602Z" }, +] + [[package]] name = "tabulate" version = "0.10.0" @@ -5720,14 +5952,14 @@ wheels = [ [[package]] name = "tencentcloud-sdk-python" -version = "3.1.124" +version = "3.1.162" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/32/9ade25ae78acd1267fb0e1c353e531595b02493f751abed4ac0ce65f7574/tencentcloud_sdk_python-3.1.124.tar.gz", hash = "sha256:534d3723b5814efcaa5de599c421f6c0bb96a29c869ec465e408a3062d26e307", size = 15369308, upload-time = "2026-06-30T14:19:00.111Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/85/4de2797df7d6ed6cf1c50b267a5e28ed5b5101a9fa9e03b986b667c3489f/tencentcloud_sdk_python-3.1.162.tar.gz", hash = "sha256:479ba1c9aee234f8b23a7bfa3f6ecb81664f980e9de68a96a58040defc463909", size = 16500383, upload-time = "2026-08-21T08:30:55.931Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/ee/32d9bf7cb2fc233093d12107d2f3df28870a90cd99848e9f37db35ad3e9f/tencentcloud_sdk_python-3.1.124-py2.py3-none-any.whl", hash = "sha256:c60c6d19a29482c91a3be463d1795893128bfa6f4436550b7d3222b448de4d28", size = 16273816, upload-time = "2026-06-30T14:18:47.495Z" }, + { url = "https://files.pythonhosted.org/packages/c8/8c/88cd87f9eac191f5ecaa6b99841028fe50ecebee76a8912a59ebfdc72956/tencentcloud_sdk_python-3.1.162-py2.py3-none-any.whl", hash = "sha256:37bcca6e91d73ac95f85996b3e4940eea12c01d2e4cb016318974242f919f539", size = 17423436, upload-time = "2026-08-21T08:30:38.284Z" }, ] [[package]] @@ -5850,41 +6082,41 @@ wheels = [ [[package]] name = "types-six" -version = "1.17.0.20260518" +version = "1.17.0.20260724" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/14/ec/31f3a70f3b4f7dbbf28025a5b2ed0b3a3eb237c01bc3357e45547c04defd/types_six-1.17.0.20260518.tar.gz", hash = "sha256:b0196d5188bd589bc5ab92901edc1a4ff3c5fd4b0dc19d074a5f1f8213e5213a", size = 15787, upload-time = "2026-05-18T06:04:07.387Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/0a/1fb3a4b570f654475a2eadb8c14cc213c25bec5ba25b51364189dcb0b753/types_six-1.17.0.20260724.tar.gz", hash = "sha256:d7abfa82d40eb7dfbb6356c5b1abb4ddc87e0854515a213512e6be98c5d6bc02", size = 15900, upload-time = "2026-07-24T04:58:28.187Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/2e/0e64ff848fa3d3ee1563ee3e6b3f9f226c25e5ce17020fb0be1f832a7e32/types_six-1.17.0.20260518-py3-none-any.whl", hash = "sha256:2ed782cafcef9614e51292ae39bae93e42ff7b20c1c0a00c6be35e1c0e493a70", size = 19940, upload-time = "2026-05-18T06:04:06.565Z" }, + { url = "https://files.pythonhosted.org/packages/f7/b5/e955d46780884ab065dd2dca5a4c240585d0ea4c851e978d669e06b71abb/types_six-1.17.0.20260724-py3-none-any.whl", hash = "sha256:5076f03667e21f77b45c029c0aba0a4f5f0f0472c27fc102c8ec7bb68206ecf4", size = 19937, upload-time = "2026-07-24T04:58:27.335Z" }, ] [[package]] name = "typing-extensions" -version = "4.15.0" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.2" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, ] [[package]] name = "tzdata" -version = "2026.2" +version = "2026.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ff/5a28bdfd8c3ebec42564ac7d0e54ca3db65044a9314a97f9564fa7a1e926/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415", size = 198674, upload-time = "2026-07-10T08:50:37.887Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, + { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, ] [[package]] @@ -5919,15 +6151,15 @@ wheels = [ [[package]] name = "vcrpy" -version = "8.2.1" +version = "8.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/db/08183b845b0040bb877dad2bd7e4e0976fc232bb3476d7ee369c6c4f8b5a/vcrpy-8.2.1.tar.gz", hash = "sha256:d73a6e4eb6dae8148e659764b7a00e68cc51ba29ba9e6a85e1f0790ad96b97df", size = 90511, upload-time = "2026-06-16T13:20:52.906Z" } +sdist = { url = "https://files.pythonhosted.org/packages/39/d5/8a1f8eb603e2d35fbb0ecd1e309d0c5c18a0ecfc8c0a8f04088bbc8f833b/vcrpy-8.3.0.tar.gz", hash = "sha256:46d64e77e8d95e5c76c7d9a94ff05d8b38b2ae4e1d4869eb0235024b6fcb5212", size = 96117, upload-time = "2026-07-04T14:27:01.608Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/7c/0e812ab83f5289404c674f3461ba783250b967d34b5ab034d361236ec042/vcrpy-8.2.1-py3-none-any.whl", hash = "sha256:7ce58c9e2792b246f79d6f4b3e9660676cc6f853be17e1547305b4437ab1ff85", size = 44925, upload-time = "2026-06-16T13:20:51.734Z" }, + { url = "https://files.pythonhosted.org/packages/34/77/cb4219be91508399cbcb6143bad89462cfb16f6c638458f454a5d46ac95a/vcrpy-8.3.0-py3-none-any.whl", hash = "sha256:bd66e6143746778157f00e2a922527a8d96b2fdc350be8988a45a29c843815b9", size = 46530, upload-time = "2026-07-04T14:27:00.546Z" }, ] [[package]] @@ -5965,88 +6197,88 @@ wheels = [ [[package]] name = "wrapt" -version = "2.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/a4/282c8e64300a59fc834518a54bf0afabb4ff9218b5fa76958b450459a844/wrapt-2.2.2.tar.gz", hash = "sha256:0788e321027c999bf221b667bd4a54aaefd1a36283749a860ac3eb77daed0302", size = 129068, upload-time = "2026-06-20T23:49:44.49Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/8b/59781d0fe7b0adfbea37f600857de4be68921e454aeecf1a11bda35cdccc/wrapt-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:055e6fcfaa28e58c6a8c247d48b92be9d56f818b7068aa4f22b15b3343a09931", size = 80556, upload-time = "2026-06-20T23:47:28.473Z" }, - { url = "https://files.pythonhosted.org/packages/94/dc/66c61aca927230c9cf97a3cb005c803971a1076ff9f7d61085d035c20085/wrapt-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8374eb6b1a58809211e84ff835a182bb17ab2807a5bfef23204c8cff38178a00", size = 81648, upload-time = "2026-06-20T23:47:30.504Z" }, - { url = "https://files.pythonhosted.org/packages/23/1b/545eee1c18f3af4cf140bb5822b6ef81ebe569df0a63ac109973103a30a5/wrapt-2.2.2-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:656593bb3f5529f03d27af4136c4d7b11990e470bcbc6fefa5ef218695bece55", size = 152956, upload-time = "2026-06-20T23:47:31.867Z" }, - { url = "https://files.pythonhosted.org/packages/44/a7/6f42a3d03e44dc612a5dcff324e7366075a7857f0be2d49a8cb8a68279b8/wrapt-2.2.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfb00cb7bb22099e2f64b7340fb96113639aa7260c0972af3797ace2297b936c", size = 154771, upload-time = "2026-06-20T23:47:33.352Z" }, - { url = "https://files.pythonhosted.org/packages/bf/55/4d76175aaa97523c38f1d28f79d18ab41a1b116814158a818bc0eba00571/wrapt-2.2.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e7f10ee0bd53673bfd52b67cbce83336fe6cad90d2377b03baf66491d2bbfb91", size = 149460, upload-time = "2026-06-20T23:47:34.712Z" }, - { url = "https://files.pythonhosted.org/packages/84/9b/12e23264d8f4735e8483262f95c5a6b03c3665fd2a84bdf99a45b6a2f4ec/wrapt-2.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4402f57c5f0d0579599858ffbdd9bf4e3f0972f51096f2bd6cc7dab6b76ee49e", size = 153648, upload-time = "2026-06-20T23:47:36.092Z" }, - { url = "https://files.pythonhosted.org/packages/d6/a3/bcd5ec37289dcd85ecd4d15395a6a6063d60bc45ff94a9d77814e1e54d64/wrapt-2.2.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:3a4eb7964ff4643d333c84f880bcf554652b2a1050aebc54ae696327f61acfaf", size = 148502, upload-time = "2026-06-20T23:47:37.623Z" }, - { url = "https://files.pythonhosted.org/packages/f2/be/716d708f607fa70f8a6eb47dff8ee945d5278dfc89ffeeff33039d052e63/wrapt-2.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e542b7c5af91e2123a8aabf19894319d5ec4268d2a9ffd2f239386133fc47746", size = 152238, upload-time = "2026-06-20T23:47:39.118Z" }, - { url = "https://files.pythonhosted.org/packages/b5/c0/1a48e7e54501274f5d906f18372221b13183b0afbb5b8bb4c7ca0392c0b4/wrapt-2.2.2-cp310-cp310-win32.whl", hash = "sha256:6e7e45b43d3c774d244fe7264378f5a3f0f383bc55a54a9866434e524540110f", size = 77278, upload-time = "2026-06-20T23:47:40.476Z" }, - { url = "https://files.pythonhosted.org/packages/b0/82/9cd69a1af288fbdedf01a10e3c8a0b6890b08c7f3f96d36a213699dbcd94/wrapt-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:955f1d6e72a352e478de8d8b503abe301c5e139a141b62eb0923bd694995025f", size = 80131, upload-time = "2026-06-20T23:47:41.785Z" }, - { url = "https://files.pythonhosted.org/packages/7f/73/8db7e27daef37ae70a53ea62bef7fe80cc51a8b5e9e9181a8be6eb9a999c/wrapt-2.2.2-cp310-cp310-win_arm64.whl", hash = "sha256:b89d8d73c82db2bb7e6090b3afd7973f980d24e905cc34394eab60b884b3bf67", size = 79615, upload-time = "2026-06-20T23:47:43.109Z" }, - { url = "https://files.pythonhosted.org/packages/27/15/0c2d55168707465abfc41f33c0b23d792a5fa9b65c26983606940900a120/wrapt-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f1a2ff355ece6a111ca7a20dc86df6659c9205d3fcee674ca34f2a2854fd4e73", size = 80782, upload-time = "2026-06-20T23:47:44.367Z" }, - { url = "https://files.pythonhosted.org/packages/7d/b5/5c0b093eb48f8a062ef6267d3cb36e9bb1b88440181f6545a383c60efdf8/wrapt-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:55b9a899e6fff5444f229d30aa6e9ac92d2216d9d60f33c771b5d76a760d5f8e", size = 81678, upload-time = "2026-06-20T23:47:45.857Z" }, - { url = "https://files.pythonhosted.org/packages/34/f3/de70937472dd3e8a4e6811192f9c6075efdffd4a2cd9b4596bf160f89668/wrapt-2.2.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a2d78c363f97d8bd718ee40432c66395685e9e98528ccaa423c3355d1715a26d", size = 159671, upload-time = "2026-06-20T23:47:47.345Z" }, - { url = "https://files.pythonhosted.org/packages/a5/ec/40aed2330e7f02ecf74386ffcfef9ccb7108c6a430f15b6a252b663b1bed/wrapt-2.2.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d619e1eed9bd4f6ed9f24cd61971aa086fa86505289628d464bcf8a2c2e3f328", size = 160785, upload-time = "2026-06-20T23:47:48.759Z" }, - { url = "https://files.pythonhosted.org/packages/45/04/aa5309beed5344b00220ae6b3b24055852192656194c27947bee1736306a/wrapt-2.2.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:518b0c5e323511ec56a38894802ddd5e1222626484e68efe63f201854ad788e5", size = 153699, upload-time = "2026-06-20T23:47:50.177Z" }, - { url = "https://files.pythonhosted.org/packages/01/df/2def7e99d1fe87eea413f95f671924cdddcb08823b1ffd212748dfa6d062/wrapt-2.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4bccea5cdecffa9dd70e343741f0e41e0a16619313d04b72f78bb525162ebcd0", size = 159695, upload-time = "2026-06-20T23:47:51.602Z" }, - { url = "https://files.pythonhosted.org/packages/c7/f6/a906d01a2ce12157bad2404957b3e2140da354b8a70b2fa48bbf282871c0/wrapt-2.2.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:209112cafd963710a05d199aae431d79a28bc76eb8e6d1bbbb8ad24340722cae", size = 152813, upload-time = "2026-06-20T23:47:53.03Z" }, - { url = "https://files.pythonhosted.org/packages/02/49/bc0086292d239575b4c08f4cf8a4079fa58abbad58ec23abf84833a283ed/wrapt-2.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5a5290e4bf2f332fc29ce72ffb9a2fff678aaac047e2e9f5f7165cd7792e099", size = 158809, upload-time = "2026-06-20T23:47:54.391Z" }, - { url = "https://files.pythonhosted.org/packages/55/83/8fbd034de1f3e907edaa18786d5dd8f6932874edee0826c7cecb5cab03a1/wrapt-2.2.2-cp311-cp311-win32.whl", hash = "sha256:5499236ad1dc116012e2a5dd943f3f31af12fce452128e2bbcbd55a7d3d4d14c", size = 77414, upload-time = "2026-06-20T23:47:55.882Z" }, - { url = "https://files.pythonhosted.org/packages/7e/9c/23695baa331c6de4e874c3d78b8e0bed92e1d2a274e665b29858f6841672/wrapt-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8636809939152be6ae20a6cef0fed9fe60f411b47847d0426a826884b469e971", size = 80368, upload-time = "2026-06-20T23:47:57.237Z" }, - { url = "https://files.pythonhosted.org/packages/08/49/40cefc342bf89b234a4490d741290fce781774b831aefb39c25471da96c9/wrapt-2.2.2-cp311-cp311-win_arm64.whl", hash = "sha256:5d0a142f7af07caeb5e5da87493162a7b8efa19ba919e550a746f7446e13fb30", size = 79489, upload-time = "2026-06-20T23:47:58.56Z" }, - { url = "https://files.pythonhosted.org/packages/2a/85/180b40628b23772692a0c76e8030114e1c0ae068470ed531919f0a5f2a4a/wrapt-2.2.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8417fd3c674d3c8023d080292d29301531a12daf8bd938dd419710dd2f464f2b", size = 81484, upload-time = "2026-06-20T23:47:59.924Z" }, - { url = "https://files.pythonhosted.org/packages/94/f2/21c90f2a16689702e2aaff45795b11018dff2c9b1242bac10d225483f676/wrapt-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e7070c7472582e31af3dfc2622b2381a0df7435110a9388ed8db5ffbce67efb", size = 82151, upload-time = "2026-06-20T23:48:01.303Z" }, - { url = "https://files.pythonhosted.org/packages/5f/b3/7e6e9fcf4fe7e1b69a49fe6cc5a44e8224bab6283c5233c97e132f14908e/wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2e096c9d39a59b35b63c9aacfbbbec2088ff51ff1fc31051acc60a07f42f273a", size = 169828, upload-time = "2026-06-20T23:48:02.719Z" }, - { url = "https://files.pythonhosted.org/packages/0b/43/894f132d857ed5a9904d937baf368badcbe5ea9e436e2f1930fe21c9f1f0/wrapt-2.2.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d1a6050405bf334be33bf66296f113563622972a34900ae6fa60fd283a1a900", size = 171544, upload-time = "2026-06-20T23:48:04.266Z" }, - { url = "https://files.pythonhosted.org/packages/29/de/3c833e03725b477e9ea34028224dd21a48781830101e4e036f77e8b6b102/wrapt-2.2.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:10adb01371408c6de504a6658b9886480f1a4919a83752748a387a504a21df79", size = 160663, upload-time = "2026-06-20T23:48:05.708Z" }, - { url = "https://files.pythonhosted.org/packages/33/be/27edce350b24e3054d9d047f65f16d4c4d4c1f3f31c4278a1f8a95c723c8/wrapt-2.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3442eee2a5798f9b451f1b2cd7518ce8b7e28a2a364696c414460a0e295c012a", size = 169387, upload-time = "2026-06-20T23:48:07.243Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c4/9fd9679af8bf38e146652c7f47b6b352c3e5795b4ad1c0b7f94e15ac2aa7/wrapt-2.2.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:6c99012a22f735a85eed7c4b86a3e99c30fdd57d9e115b2b45f796264b58d0bf", size = 158849, upload-time = "2026-06-20T23:48:08.91Z" }, - { url = "https://files.pythonhosted.org/packages/bc/c2/aa6c0c2206803068c6859dabe01f8c84c43744da93d4c67b8946d21655ee/wrapt-2.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3b686cfc008776a3952d6213cb296ed7f45d782a8453936406faa89eac0835ab", size = 168147, upload-time = "2026-06-20T23:48:10.374Z" }, - { url = "https://files.pythonhosted.org/packages/42/63/3eb25da41049d20ae18fcab2dd8b056e02387c4bfa626cbdfb7c3b872e4f/wrapt-2.2.2-cp312-cp312-win32.whl", hash = "sha256:ef2cce266b5b0b07e19fa82e59673b81142b7a3607c8ed1254113d048ed668da", size = 77734, upload-time = "2026-06-20T23:48:11.769Z" }, - { url = "https://files.pythonhosted.org/packages/da/09/0390e008a305360948fa9ce69507d041ac12cb2ee5d28e34467e2ee79391/wrapt-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:abf8c20a2d72ee69e16328b3c91342c446e723bfe48bfcc4dded3b9722ac027f", size = 80585, upload-time = "2026-06-20T23:48:13.117Z" }, - { url = "https://files.pythonhosted.org/packages/d3/b3/84c445c66969f2d3457276b183a48c91097d59bbef9af6c075366b0f8c36/wrapt-2.2.2-cp312-cp312-win_arm64.whl", hash = "sha256:c6c64c5d02578bc4c4bca4f0aef1504de933c1d5b4ac2710b9131111459506c8", size = 79553, upload-time = "2026-06-20T23:48:14.5Z" }, - { url = "https://files.pythonhosted.org/packages/43/fc/f32f4b22c6511173c11d9e541ab4e7d8467a0f1b3455acaf784115d31ff8/wrapt-2.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9e8b648270c613720a202d9a45ebabc33261b22c3a839b115ac5bce8c0bb0d69", size = 81296, upload-time = "2026-06-20T23:48:15.881Z" }, - { url = "https://files.pythonhosted.org/packages/72/06/4d117d5d77a9344776c0248b24dae3d3dd2f58e5f765fa08cf887072e719/wrapt-2.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6fb7e94e8fe3e4c3067bb1653a91cce7c5e83acc119fdd41501b1bf74654617", size = 81841, upload-time = "2026-06-20T23:48:17.262Z" }, - { url = "https://files.pythonhosted.org/packages/15/ff/63ad96f98eb58a742b1a20d80f21da88924405910149950b912368150468/wrapt-2.2.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb18fc51e813df0d9c98049e3bf2298a5495a648602040e21fa3c7329371159e", size = 167882, upload-time = "2026-06-20T23:48:18.764Z" }, - { url = "https://files.pythonhosted.org/packages/20/1f/8bb62d8933df7acf3247194e6e9fc68edf9d2fa203252c89c94b319dd472/wrapt-2.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94b00b00f806eb3ef2abe9049ed45994a81ee9284884d96e6b8314927c6cea3d", size = 167411, upload-time = "2026-06-20T23:48:20.315Z" }, - { url = "https://files.pythonhosted.org/packages/17/09/8789dcb09ee1de715727db7521aabbb68ffa68dfade3a49468440cfced49/wrapt-2.2.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:62415fd095bc590b842b6d092f2b5d9ccbaeb7e0b28535c03dcea2718b48636b", size = 158607, upload-time = "2026-06-20T23:48:21.728Z" }, - { url = "https://files.pythonhosted.org/packages/9c/20/66e02562d53ee67d841f175e38e3c993c2d78a3e104c576cad61c028b43c/wrapt-2.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a41e758d80dc0ab8c210f641ac892009d356cf1f955d97db544c8dd317b4d14c", size = 166367, upload-time = "2026-06-20T23:48:23.177Z" }, - { url = "https://files.pythonhosted.org/packages/bd/a3/832ac4e41222fb263b3042d42c2f08d305db7d0f0c9b1d3a271a9eede8f6/wrapt-2.2.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b84cd4058001c9727b0e9980b7a9e66325b5ca748b1b578e822cade1bc6b304f", size = 157176, upload-time = "2026-06-20T23:48:24.711Z" }, - { url = "https://files.pythonhosted.org/packages/b7/01/1bd5e4d2df9c0178989ac8da9186543465388588ee2ef153e2591accebef/wrapt-2.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26fc73a1b15e0946d2942b9a4426d162b51676338327dc067ccd8d2d76385f94", size = 167025, upload-time = "2026-06-20T23:48:26.118Z" }, - { url = "https://files.pythonhosted.org/packages/1c/69/583ed25291ab53e1ec117135fb1c33425e2f46d2bc8f29c17f7a94cf4274/wrapt-2.2.2-cp313-cp313-win32.whl", hash = "sha256:3c4095803491f6ef72128914c28ec05bbad9758433bb35f6715a3e9c8e46fb2d", size = 77605, upload-time = "2026-06-20T23:48:27.643Z" }, - { url = "https://files.pythonhosted.org/packages/29/68/e69fc6d06e1523c68e0d00f95c9aed1158ce9908ee41603f7f2eae3d5db6/wrapt-2.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:2cb07f414fab25dbe6b5c7398e1491423a5c81a6209533639969a6c928d474a4", size = 80508, upload-time = "2026-06-20T23:48:29.013Z" }, - { url = "https://files.pythonhosted.org/packages/55/21/fe7a393d9e5dc0923bed8f5d857e9dcff210f1fa0888c02cc8f3ffaa55aa/wrapt-2.2.2-cp313-cp313-win_arm64.whl", hash = "sha256:1fc7691f070220215cccb2a20836b9adbaecb8ff22ad47abe63de5f110994fac", size = 79565, upload-time = "2026-06-20T23:48:30.429Z" }, - { url = "https://files.pythonhosted.org/packages/b6/e5/c120d13bf5091164f68c3c1657e84f16f57e71d978421b626393ac5bd7eb/wrapt-2.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ec8f83949028366531383603139403cac7a826e4011955813cdd640017845ce5", size = 83264, upload-time = "2026-06-20T23:48:31.807Z" }, - { url = "https://files.pythonhosted.org/packages/d3/b0/d4a1eb97e0e286625bdf21bc7f702637f9607787ffbbdb5ec14d50c79dbf/wrapt-2.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4b481fb0c40d9fd90a5809911208da700987d373a20a4709dc9e3944af7a6bec", size = 83791, upload-time = "2026-06-20T23:48:33.482Z" }, - { url = "https://files.pythonhosted.org/packages/18/1e/f060df47755e87b57684cee7bfc1362b204df55fac96ffebc0631b697b79/wrapt-2.2.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0065a3b657cec06813b4241d2462ccec287f6863103d7445b725fb3a889736f9", size = 203399, upload-time = "2026-06-20T23:48:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/c4/de/2316a757a1abb6453700b79d83e532146dcef2611348282d4d8889792161/wrapt-2.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30f7424af5c5c345b7f26490e097f74a2ef45b3d08b664dc33571aee3bd3b56c", size = 210461, upload-time = "2026-06-20T23:48:36.569Z" }, - { url = "https://files.pythonhosted.org/packages/ed/29/d1160785ae18ca2495a6d82a21154103d74f656c9fd457fb35f6b11b965a/wrapt-2.2.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:07fdcb012821859168641acf68afad61ef9783cf37100af85f152550e9677194", size = 195313, upload-time = "2026-06-20T23:48:38.175Z" }, - { url = "https://files.pythonhosted.org/packages/f5/2d/7caa9598ae61a9cf0989cc501739cbeeb7d650ab3193cca1407b9af0c6ab/wrapt-2.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f90038ab58fafb584801ca62d72384d7d5225d93c76f7b773c22fae545bd8066", size = 206116, upload-time = "2026-06-20T23:48:39.804Z" }, - { url = "https://files.pythonhosted.org/packages/ac/02/281ea1088b8650d865f311b35cf86fd21df89128e2909714f1161e01c9d0/wrapt-2.2.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:c5d7825491bfa2d08b97e9557768987952c7b9ae687d06c3320b40a37ccb7f20", size = 192668, upload-time = "2026-06-20T23:48:41.346Z" }, - { url = "https://files.pythonhosted.org/packages/be/7d/976e2d5b4b5c5babda40974edd54d0a5585cb60132ed86b46f4b80239b16/wrapt-2.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0ad520e6daa9bbf136f14de735474dbec7dcc0891f718e1d274ce8dc92e645af", size = 198891, upload-time = "2026-06-20T23:48:43.056Z" }, - { url = "https://files.pythonhosted.org/packages/59/b7/e47651797c097f75a37e2ce86dcf04048ff576f3a674f7c558df7b5e9622/wrapt-2.2.2-cp313-cp313t-win32.whl", hash = "sha256:25904acb9475f46c24fe0423dbc8fda8cc5fbc282ab3dc6e72e919748c53f4e9", size = 78537, upload-time = "2026-06-20T23:48:44.509Z" }, - { url = "https://files.pythonhosted.org/packages/d1/6f/9fa5d59fb06d890defb5a8f727ce6a14d2932c8760153f96956628559fee/wrapt-2.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:305d4c247d61c4115794a169141823c62f719525ddb90b23aa332741c77d2c28", size = 82005, upload-time = "2026-06-20T23:48:46.391Z" }, - { url = "https://files.pythonhosted.org/packages/15/80/4c7bd9873d1f9f7d138d93556b500469dbe24f42710b877519c2b9eb380d/wrapt-2.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:c20279cd1a29800815d7b2d6338b60a6c6e78263f9d6e62e0eda251ba9cae2d0", size = 80762, upload-time = "2026-06-20T23:48:47.964Z" }, - { url = "https://files.pythonhosted.org/packages/24/05/7fd9c3f83b2c74cbfc572a0b88aa37431e04bd8aed70d2c0efd3464206de/wrapt-2.2.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0e64826f920c42d9d9f87e8cc09ffae66c51ede12d59061a5a426deb9aa71745", size = 81341, upload-time = "2026-06-20T23:48:49.39Z" }, - { url = "https://files.pythonhosted.org/packages/4b/68/1bfa43100dd90d4ef74a05897b86275cf57e1313ca14aae2545bc9f872c9/wrapt-2.2.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:dcaa5e1451bd8751d7bd1568dfa3321c78092a52a7ecb5d1a0f18a5791e1fd00", size = 81921, upload-time = "2026-06-20T23:48:50.986Z" }, - { url = "https://files.pythonhosted.org/packages/74/eb/df7b7f0b631dbbc750f39be27d8b55f65777d8ac86da80e12be41a644c4b/wrapt-2.2.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0abfd648dac9ac9c5b3aa9b523d27f1789046640b58dcd5652a720ddb325e1fc", size = 167713, upload-time = "2026-06-20T23:48:52.598Z" }, - { url = "https://files.pythonhosted.org/packages/4d/9a/d1bd36f6d088c8e652a9383cabbd49af30b8c576302a7eccddbab6963e3f/wrapt-2.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4bfd8d1eb438153eff8b8cfe87f032ba65731e1ce06138b5090f745a33f6f95", size = 166779, upload-time = "2026-06-20T23:48:54.33Z" }, - { url = "https://files.pythonhosted.org/packages/4c/ae/24ffacd4187fac2740a1972093929e836dea092d42c87d728cd98fee11a6/wrapt-2.2.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c427c9d06d859848a69f0d928fe28b5c33a941b2265d10a0e1f15cd244f1ee33", size = 158407, upload-time = "2026-06-20T23:48:55.944Z" }, - { url = "https://files.pythonhosted.org/packages/a3/ed/974427668249a356051e8d67d47fa54ef6c777f0fcf3bae9d292c047d4b6/wrapt-2.2.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4250b43d1a129d947e083c4dc6baf333c9bb34edd26f912d5b0457841fc858ab", size = 166594, upload-time = "2026-06-20T23:48:57.617Z" }, - { url = "https://files.pythonhosted.org/packages/fb/5f/e1d7c6e4523f78db2fbd7826babd0348da1d5e0834c4f918b9ab5757dfae/wrapt-2.2.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:173e5bb5ca350a6e0abab60b7ec7cdd7992a814cb14b4de670a28f067f105663", size = 157068, upload-time = "2026-06-20T23:48:59.171Z" }, - { url = "https://files.pythonhosted.org/packages/1e/c1/7ebd1027f00700c0b0233b20aceef2b4784294ed64971424c4a78e069e34/wrapt-2.2.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:aa14b01804bce36c6d63d7b6a4f55df390f29f8648cc13a1f40b166f4d54680d", size = 166470, upload-time = "2026-06-20T23:49:00.737Z" }, - { url = "https://files.pythonhosted.org/packages/99/eb/974e471a6a978b8180186b8a9dc5ae3361ce269a967190b709b8ce17abfb/wrapt-2.2.2-cp314-cp314-win32.whl", hash = "sha256:58f9f8d637c9a6e245c6ef5b109b67ec187d2faed23d1405656b51d96e0a5b56", size = 78062, upload-time = "2026-06-20T23:49:02.327Z" }, - { url = "https://files.pythonhosted.org/packages/49/ec/e1281156cdc7a66693838ad7a0865ad641c74abd337a957d668b575aaffb/wrapt-2.2.2-cp314-cp314-win_amd64.whl", hash = "sha256:385cb1866f20479e83299af585375bfa0a4b0c6c9907a981483ea782ea8ae406", size = 80832, upload-time = "2026-06-20T23:49:03.837Z" }, - { url = "https://files.pythonhosted.org/packages/45/7d/1b6b5ddd94005a2dac97a4490c9838f3154977850d633abcb65b30089437/wrapt-2.2.2-cp314-cp314-win_arm64.whl", hash = "sha256:8ffbeaea6771a6eba6e6eeb09767864995726bc8240bb54baf88a9bb1db34d5c", size = 80029, upload-time = "2026-06-20T23:49:05.237Z" }, - { url = "https://files.pythonhosted.org/packages/b0/33/9ebcf8aafe91c601127cbd93708c16aa8f688f34a10bf004046803ecdc4f/wrapt-2.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:09f811d43f6f33ec7515f0be76b159569f4057ab54d3e079c3204dddb90afa2a", size = 83357, upload-time = "2026-06-20T23:49:06.632Z" }, - { url = "https://files.pythonhosted.org/packages/39/38/ec45b635153327b52e52732a0ea980e5f00b7efba65f9e018828f1e69daa/wrapt-2.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a795d3c06e5fbf9ea2f13196180b77aeab1b4685917256ee0d014cc163d90063", size = 83794, upload-time = "2026-06-20T23:49:08.098Z" }, - { url = "https://files.pythonhosted.org/packages/4e/ea/1a89e6d3b7a83c3affe5c09cde77792c947e63e4bc85ad84cd5bb9abb0d8/wrapt-2.2.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:45c2f2768e790c9f8db90f239ef23a2af8e7570f25a35619ef902df4a738447f", size = 203362, upload-time = "2026-06-20T23:49:09.811Z" }, - { url = "https://files.pythonhosted.org/packages/19/d8/3b58763d9863b5a73771c0d97110f9595d248db454009e07e1535ee905a4/wrapt-2.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbf00ee0cb55ec24e2b0995a71942b85b21a066db8f3f46e1dbfdb9433ffba81", size = 210449, upload-time = "2026-06-20T23:49:11.521Z" }, - { url = "https://files.pythonhosted.org/packages/2d/6f/17fd9e053103d8be148d20d5d7505facc72d5fe1f9127973904ceaed79cf/wrapt-2.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2252f77663651b89255895f58cc6ac08fcb206d4371813e5af61bb62d4f7689c", size = 195349, upload-time = "2026-06-20T23:49:13.346Z" }, - { url = "https://files.pythonhosted.org/packages/ef/04/d0d1ccaaa12cb7dccf28a23f0279a608ba498f71e81d949d5ed54bcfd5c1/wrapt-2.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2cd7181ab1c31192ff5219269830744b5a62020b3a6d433588c4f1c95b8f8bff", size = 206099, upload-time = "2026-06-20T23:49:15.051Z" }, - { url = "https://files.pythonhosted.org/packages/44/b3/e8aa07b619890a2aa6cde1931b1887abb08820721b564a5f80b7ca3f3aa0/wrapt-2.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6fe35fd51b74867d8b80174c277bd6bbf6a73e443f908129dc531c4b688a20d5", size = 192728, upload-time = "2026-06-20T23:49:16.854Z" }, - { url = "https://files.pythonhosted.org/packages/b7/f0/1819fb50f0d3c9bd758d8a83b56f1b470dee8b5b8eac8702b7c137cea9d4/wrapt-2.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:11d95fc2fbad3163596c39d440e6f21ca9fccece74b56e30a37ac2fca786a07c", size = 198842, upload-time = "2026-06-20T23:49:18.504Z" }, - { url = "https://files.pythonhosted.org/packages/67/7c/e88313f16a99930b899ef970d91c281544a470749a359decad994483bbda/wrapt-2.2.2-cp314-cp314t-win32.whl", hash = "sha256:d8a15813215f33fa83667bfc978b300e35669ea8bb424e970a1426bcb7bc6cca", size = 79059, upload-time = "2026-06-20T23:49:20.107Z" }, - { url = "https://files.pythonhosted.org/packages/a0/4f/ac12fda57a55068a094ec42851fb0a40e8489d8941863d517452de62e507/wrapt-2.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:d09db0f7e8357060d3c38fc22a018aba683a796bf184360fd1a58f6fc180dc77", size = 82462, upload-time = "2026-06-20T23:49:21.631Z" }, - { url = "https://files.pythonhosted.org/packages/48/a7/df732dac86d9b2027c56bd163dbc883e037b16c3469614752e148d219c61/wrapt-2.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:f32fe639c39561ccc187bcae17e9271be0eb45f1c2952510d2f29b33ab577347", size = 81182, upload-time = "2026-06-20T23:49:23.199Z" }, - { url = "https://files.pythonhosted.org/packages/6e/d2/6317eb6d4554855bbf12d61857774af34747bf88a42c19bf306de67e2fa3/wrapt-2.2.2-py3-none-any.whl", hash = "sha256:5bad217350f19ce99ca5b5e71d406765ea86fe541628426772b657375ee1c048", size = 61460, upload-time = "2026-06-20T23:49:42.966Z" }, +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2b/b0/c1f5a970721f06b85c0cd5142e0ff8fe067708abd779b0c4f4be7d61d09f/wrapt-2.3.0.tar.gz", hash = "sha256:681a2d0eefd721998f90642762b8e75c2159ec531b20ad5e437245ea7b06a107", size = 131509, upload-time = "2026-07-28T06:06:14.895Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/31/5822ce37ca8820c2ed35a498c67c8b37960b9cee2ba437fd32849d0a234c/wrapt-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0bb2797048db0956348cb3058c33bc4184614f13231389cfbccc16a5d32780a7", size = 81191, upload-time = "2026-07-28T06:04:04.858Z" }, + { url = "https://files.pythonhosted.org/packages/7a/5a/3c6117938be98754578ab83f5a40d7d0ea2cd2c487dc5cd6027ee7228229/wrapt-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce9f398f868d2b3b27aa2ea4de79645ef9077aeeac8dfc2814b0d542c6a2b87f", size = 82255, upload-time = "2026-07-28T06:04:07.151Z" }, + { url = "https://files.pythonhosted.org/packages/a5/0f/94ae724c5087eb6054c0d63febd7094947dcf302fe058e2e0488102a872b/wrapt-2.3.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ad71df7a04dd3497e9302e81f4a7c91bd401ea0e15a9df9029527900f94bee43", size = 155228, upload-time = "2026-07-28T06:04:08.272Z" }, + { url = "https://files.pythonhosted.org/packages/6c/21/1f780bba935dcf697c0c59de9be3a559bbb8e31a53ca3f25422023738432/wrapt-2.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc82c2ccc8e234c844f5303d9f2984b346dcdd53e94823ce8420d2c75b4b9023", size = 157073, upload-time = "2026-07-28T06:04:09.459Z" }, + { url = "https://files.pythonhosted.org/packages/73/31/6c7799d7b6431fcd7e1b83245fb45258a2d2c3a2187fbaecb83572a72d7a/wrapt-2.3.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a6e19531ae33c508cea7d84a7edfda01fa86e51b8d1a93a77712c55e6e469152", size = 151594, upload-time = "2026-07-28T06:04:10.784Z" }, + { url = "https://files.pythonhosted.org/packages/ce/17/42d670dbfafd49076c6eb2b7d67633d7e1c968e39bfb11a135acb6fac67b/wrapt-2.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df4ce31150bcd5d9f36f816aac3010ab4f4bf8672ac1d3b0ac7d539ec61c7c02", size = 156069, upload-time = "2026-07-28T06:04:12.316Z" }, + { url = "https://files.pythonhosted.org/packages/1f/d6/c66b4ba4eda49257c84d5c2df26118280f09ca7905aee20d0064db778d13/wrapt-2.3.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:e2e692bc0d63f881cf7006730a56bd4e0c2fab5dc318466942805d692b166276", size = 150930, upload-time = "2026-07-28T06:04:13.482Z" }, + { url = "https://files.pythonhosted.org/packages/c0/f2/1a3b949c0322fb27396eafd1044328c1cb0400e0b32105d75a3cd03096e7/wrapt-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c8388ba7faf5dbf9ee106bb70d66f257629b1bd98091123e19e8a4553a319199", size = 154525, upload-time = "2026-07-28T06:04:14.698Z" }, + { url = "https://files.pythonhosted.org/packages/12/65/147563a3dfa6e830c857b93b530ebd8c0cd9d540e5914aec8f9b12880c02/wrapt-2.3.0-cp310-cp310-win32.whl", hash = "sha256:e045ff75d7d94900fc32896ed93c45ce2d2cac28c9dead582ff9a5a49d446e35", size = 77879, upload-time = "2026-07-28T06:04:16.102Z" }, + { url = "https://files.pythonhosted.org/packages/c4/eb/921405b4dc55d4f8be4c700ef120539fdd75d5fdb50d83bd257171ee18e0/wrapt-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4fc96b159af0a3e0faa72475a69d66292bea72a5bed1e1aca1bffbddc3cb2b0", size = 80733, upload-time = "2026-07-28T06:04:17.43Z" }, + { url = "https://files.pythonhosted.org/packages/b6/13/75947450c5bb57795fa86384721cd52c5c4deb0879022f309501a8a85d44/wrapt-2.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:1236fa25173ca964c97422470482e9011b9e3c7ed0d75798b40b3da3b0e0e760", size = 80199, upload-time = "2026-07-28T06:04:18.761Z" }, + { url = "https://files.pythonhosted.org/packages/00/b8/9182e4c618a847be0baccb68e4602b070d0fa22c782cf058f4bc66b32709/wrapt-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ab559e1b2551d23d54db2a0001c6d73bad022a254639561c5f6c382a9d6c2fe", size = 81427, upload-time = "2026-07-28T06:04:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/84/ca/613cefd9c5977366b1587e61c0b428176d382e6d75b454084c5e58503042/wrapt-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bff9a671bc00709cab5a7f745c592b5671873449db0ee2a569af994f16b29a4d", size = 82360, upload-time = "2026-07-28T06:04:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/71/71/4cd2151a236f44a6e2dd4ed8011838d7ba0be3d656c8bafdfc65a2ed1917/wrapt-2.3.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fc648a335d7e01adb3640b25f02fd0ea05886cf04d0af7f4ee902bc7b5e466e8", size = 161700, upload-time = "2026-07-28T06:04:22.723Z" }, + { url = "https://files.pythonhosted.org/packages/49/2c/bc508fee75eb2919ed69769800b09968e4aab16897f909a23f39c81e323f/wrapt-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0077f3d65541925fa83002f967b22ad6550d24813ac64cb905f717194128d9c", size = 162922, upload-time = "2026-07-28T06:04:24.177Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e5/04f34d38e66d857dfc2fc4088d60e70c0e422467822defa49b2b4a26e17b/wrapt-2.3.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9790ea25190a4e0fe4cdf4eeb868e9d75f8a024a70a5b6bf9c348a3a2b72e731", size = 156125, upload-time = "2026-07-28T06:04:25.58Z" }, + { url = "https://files.pythonhosted.org/packages/23/41/c35940ea1c423f129ebe4361db853bc80d4def6326242e1206fa15bf94f4/wrapt-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:816877aa749253149f9ecfd2635d4d948ecfa338e1a0311d187b1acb1bb8a3eb", size = 162039, upload-time = "2026-07-28T06:04:27.154Z" }, + { url = "https://files.pythonhosted.org/packages/0e/60/9bda34c3d7d182aa703fe35339ae0ed4c4dad5e5c587f93890143e1f87fb/wrapt-2.3.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3d1c2c1b808600d2ea808e6360910a60ed5f409a4011655e10f9164ba0a414a6", size = 155110, upload-time = "2026-07-28T06:04:28.497Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ba/60bfd9b1a751f4fcb2d603668fc272d651ccdd339a56acf8c40ad21a0293/wrapt-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5ba1e5e08ddc46130e9682b2c249f2d1dd39bda9106ed4bd401b7519f18f41bd", size = 161089, upload-time = "2026-07-28T06:04:29.959Z" }, + { url = "https://files.pythonhosted.org/packages/0f/32/2bd358c6f4f1305c813479d1e9ba746bebdd794f4a20107ab2b3ee0cbd45/wrapt-2.3.0-cp311-cp311-win32.whl", hash = "sha256:45c9279b373d15649dfa2c2077cb3408ea1a6d3125afbdab9d6b809a66f68e14", size = 78030, upload-time = "2026-07-28T06:04:31.241Z" }, + { url = "https://files.pythonhosted.org/packages/4a/62/ecc969b13b141fef89b888c9760821cb01a86ac8fc953911592c8e1e1522/wrapt-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:195b1842b4122fb54e3cd3dd5b2b4aa49302a5a61da901df0481f5c97aedde84", size = 80944, upload-time = "2026-07-28T06:04:32.655Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3d/9278ada8a2b3f24372b630361e84e9a7de7abc3784634860c26d1c37785a/wrapt-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:6db604ef0c67bdb2042ecdfd7b7f037cf09733557ca42360d1018285634f7b98", size = 80074, upload-time = "2026-07-28T06:04:33.811Z" }, + { url = "https://files.pythonhosted.org/packages/5b/4a/d17a0fad1bf1c5f2c887ff71fef75654141b0880bff71d157d955b5bec3a/wrapt-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0a45ffae742ce91a16e11cb6c7cd71e7f9994f3cbd283b962ab093f5c6dcf525", size = 82139, upload-time = "2026-07-28T06:04:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/6e/55/51b92daaf6defb57f4dc56bdcce985400f75c6984a03ca5e78ccac717028/wrapt-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69e477046f2237ef0bc6547544ee73008dc764ca26eff44f09e976d221b34d5d", size = 82723, upload-time = "2026-07-28T06:04:36.502Z" }, + { url = "https://files.pythonhosted.org/packages/28/7f/cfd9bc4b1f5e424eeea83d0493e43f3b1b02707ce8e50c47945873982bd5/wrapt-2.3.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d221a6e6ddd302b8397433184e96b59f259f50024b854db1c411a881586b6b8", size = 172381, upload-time = "2026-07-28T06:04:37.674Z" }, + { url = "https://files.pythonhosted.org/packages/cb/89/ff7814f6eb6856b479946117d1138a2fbb46cdb6b1f379db359056c69743/wrapt-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:392158c9a7f2ab1b8699418bfc0fe6f83548788c418b27d7bf2019ad3405cebb", size = 174120, upload-time = "2026-07-28T06:04:38.987Z" }, + { url = "https://files.pythonhosted.org/packages/12/1e/8eded8615d39e3ce81f626937a3a87b280a2a86239a2bf14a4b4bb345034/wrapt-2.3.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e5301c35cf75655eb33498f2bd6ae8703ca19940e3167dc9cdf740c712a39c60", size = 163035, upload-time = "2026-07-28T06:04:40.361Z" }, + { url = "https://files.pythonhosted.org/packages/35/ea/a0af2d9da62897af2a055484920de05dade30d2ba2c0d65cbdea875d3d8b/wrapt-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:418f54bb09d1762db02c7009b4051149893af3153a87f92d70356703c11eea02", size = 171887, upload-time = "2026-07-28T06:04:41.614Z" }, + { url = "https://files.pythonhosted.org/packages/7e/dd/63cd4c864c65ef4906df64bd2d378f4a62b54f28063f282dfb3bf93caead/wrapt-2.3.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1598becd30f8f2777d18564064eb4f4dbe1ab0e05a8f09786d0ef505ac782bf3", size = 161113, upload-time = "2026-07-28T06:04:42.864Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ee/82f1fc9e431b5c2c5a6d201aa865dbeae3984c311c6d11a185f0c8367cf6/wrapt-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3da470536bf9645143323dd41b32db55c6f4304ad382094c1a1da8a92061e10d", size = 170530, upload-time = "2026-07-28T06:04:44.212Z" }, + { url = "https://files.pythonhosted.org/packages/37/a5/5dc590e863a419930d988f8b7ca3e75a6befcfb10b6003b3a152f3d5f732/wrapt-2.3.0-cp312-cp312-win32.whl", hash = "sha256:fb8e2e6704a1e0b1b989546c69e2688371ef4a07fa5f61bde3eb6211186f5ac1", size = 78323, upload-time = "2026-07-28T06:04:45.484Z" }, + { url = "https://files.pythonhosted.org/packages/51/f9/4a6925a07951df56394f7e6ebe14f69f1c5ef9d87aa63e0839acf15aa63a/wrapt-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:cdc021cb0b62471d6aac7f2bd92f3b4658073775f9ee7fcd325c511129e7bcc8", size = 81180, upload-time = "2026-07-28T06:04:47.021Z" }, + { url = "https://files.pythonhosted.org/packages/a8/4f/8b5de0395b2a72216751d41c9861df6facaeb611b619d8810ed2b3b23eb2/wrapt-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:67bfe2485f50368c3fcd2275fc1fd100e350d601e0058921a7c82678a465aeab", size = 80155, upload-time = "2026-07-28T06:04:48.373Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6e/0f88a072483e76b881e3fdcd6b6ffb4a5791002514fe541e72b1b73c859a/wrapt-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0d3fb71e65b001adfc42684522eeccd9c21d8ba679945abc993439567b66e59f", size = 81960, upload-time = "2026-07-28T06:04:49.622Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ff/b7e2776e7c294075eb712cc9ef573d1b818f393006d09787262b8fc871c4/wrapt-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:51a7a4181c1295774812271fbcd7c909df372bc25579d4ed9eb875caaf0ae86f", size = 82435, upload-time = "2026-07-28T06:04:50.9Z" }, + { url = "https://files.pythonhosted.org/packages/d8/90/343bb5d0f1f9669bc252a6073f085b4abf862511bd5c9c9eaec754341f1d/wrapt-2.3.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9045917809c63fdf7abe3a2ceaed3d670b8ee4500ddd9291192d30aeb34467c5", size = 170350, upload-time = "2026-07-28T06:04:52.187Z" }, + { url = "https://files.pythonhosted.org/packages/59/f8/13b79a392930bd0dd6b86cbfbfe1c40944110456e1dc6d809e5c46ece904/wrapt-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:54ca1d5573f69b5fe1d74f1f65799c68015e82f685efec9fd8cfa40a094c44d0", size = 170022, upload-time = "2026-07-28T06:04:53.599Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fc/4f1b6918f5290db959d6e0c07f77385d87cede29c39c9cf8f145e9c82954/wrapt-2.3.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:242b60c21e30866e6a2fa606c612b47c553fa60c0eaeeeb7797fb842ac0ce609", size = 161043, upload-time = "2026-07-28T06:04:54.936Z" }, + { url = "https://files.pythonhosted.org/packages/01/e1/45d3cf74414780bdff6d0380467e003f6eb0f028b6c9403db868dbc7209c/wrapt-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3f3d7ec0a51fbfe00d3aef047641ff2c58b25565b4717fc1f90e050be01cba8", size = 168576, upload-time = "2026-07-28T06:04:56.261Z" }, + { url = "https://files.pythonhosted.org/packages/f3/73/2fa58dd97f191c997755e2c6d569a68f0c433db4e4b36099bdd7227b6cac/wrapt-2.3.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:261f53870cd4fb2bf38f9f972c56c728fd224cb7c65721307de59d9e7e6741ae", size = 159140, upload-time = "2026-07-28T06:04:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/29/a8/08a56e2000a8816d449dcbad8c8b081697acbbd490821ceca0f9d8e8d20c/wrapt-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8159ec0b0cb7608175eb150de94c19e34f4d47ac655f5ca9baf45df6b688ffd3", size = 169263, upload-time = "2026-07-28T06:04:59.161Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d4/354e1725e35a73b2af4fa70a3e024c7a5d1bf1802dfb862dcb668aae0253/wrapt-2.3.0-cp313-cp313-win32.whl", hash = "sha256:10461884b3014fbfc8eb7d09a93c5f246363e6711d9d881f95eb8c27fdef049f", size = 78241, upload-time = "2026-07-28T06:05:00.507Z" }, + { url = "https://files.pythonhosted.org/packages/6c/7e/34c87fa2174848dfee820322aaa318bab08913998ccecc8d2f57b4ad4639/wrapt-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:ac870cc97b73bb00ac353329e9559a4bebc47c4c86792ed9b23b58c15b6ad838", size = 81113, upload-time = "2026-07-28T06:05:01.839Z" }, + { url = "https://files.pythonhosted.org/packages/11/86/fcc9a530579e008c9478bb565a6cdfbfd33536660f069c8b91a6607c5050/wrapt-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:a65e8db2b4e90c2e7ade931086351c98ef420bf7a94ee08c95ac8a3cbbc43579", size = 80182, upload-time = "2026-07-28T06:05:03.152Z" }, + { url = "https://files.pythonhosted.org/packages/96/50/3864848b95b28ef73e17551fc8dccbff2628a834f52cf26a57f9c419fb83/wrapt-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:fd1f2f557dd3491fe75905e578f4db967393d40d1a8f468edc4d40ac7f2d5944", size = 83921, upload-time = "2026-07-28T06:05:04.476Z" }, + { url = "https://files.pythonhosted.org/packages/3b/4c/3d1921a60c3e8c71c540ff136e6a47a1fbccf7f671e818394889f7871d9c/wrapt-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9f5d2aec29dfc76c37e23897dee92766a3fd4f3bff3ae7fc9c6b4bf37d8c1360", size = 84412, upload-time = "2026-07-28T06:05:05.921Z" }, + { url = "https://files.pythonhosted.org/packages/fa/1a/4a796ff7adb26ada6d4b758c94d47a38320b085e7099afc088efbbcdb006/wrapt-2.3.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:646d20d413ffcd1b0a2f700076e2d0252d872dcb7754860a73e45a59ea883614", size = 207168, upload-time = "2026-07-28T06:05:07.256Z" }, + { url = "https://files.pythonhosted.org/packages/1d/3e/d7777776806c579b761bac2f91721dda9f04c7a1b380213c5935cc750ae6/wrapt-2.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:379f670f45b7bb8993edd9f6fc36c6cc65edb81cffa0b504be34acb0303fff0a", size = 214351, upload-time = "2026-07-28T06:05:08.945Z" }, + { url = "https://files.pythonhosted.org/packages/63/27/2d64d394df7bf181955b3bb562bf33c4492fb4be113f53071106d43ad8b5/wrapt-2.3.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6208f302f110295d64b22a7ac96500c791bf492dce4366e622e4912b077c9687", size = 199020, upload-time = "2026-07-28T06:05:10.418Z" }, + { url = "https://files.pythonhosted.org/packages/3e/3d/fb31d3db7d9834d265fb1a27a2adf0ddf51557c67458c97b22439ad6ae3d/wrapt-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ed635a9ca4f3a5a2b900c10c69e823373bc00ebc114b459383596d3487da3570", size = 209969, upload-time = "2026-07-28T06:05:11.983Z" }, + { url = "https://files.pythonhosted.org/packages/1f/d1/8724b5da582e62070dc9bf4d8bf1972f317297eefd7ba1f2b5c6393ccf6c/wrapt-2.3.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:e3b9eaa742ae7a0aaaaad4ca4b69469d757af2d6e6663ef1dadc47adec0aeb41", size = 196324, upload-time = "2026-07-28T06:05:13.557Z" }, + { url = "https://files.pythonhosted.org/packages/0d/5c/3d9ef411149543016ee6bcf3af707f787cebd946527452b94bf122e9b7b4/wrapt-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0f7284f88f4833705132d06d3b425a43095c2cbd07c58166aac3ab646ba12a4", size = 202610, upload-time = "2026-07-28T06:05:15.048Z" }, + { url = "https://files.pythonhosted.org/packages/13/9b/4fc042ceb757866dd4a5fc057b3b736f2b360d3703ce9f830d83dc9226e0/wrapt-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:7ebb274aba688b043429eb1500ff8a76ce0cb8ac0812ca3e301f06247b8722b3", size = 79178, upload-time = "2026-07-28T06:05:16.469Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ff/b94878f8eed809ca042685276bcea9f24e8c2ca7c9653bb80bbb920a68a5/wrapt-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:c4bded758ad6f03b965830944a2f0bc5b2eb3767fe5a7310134315d1a6610e98", size = 82634, upload-time = "2026-07-28T06:05:18.026Z" }, + { url = "https://files.pythonhosted.org/packages/80/fb/663e1de5332a71685a729754312d327d4cada767c36e1c5a2db4c8de49e6/wrapt-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:d2cc64539da63e39ffb9c7ede849b6e8ddaaf7b3876b5cfb04efd85a5f3f4eb6", size = 81387, upload-time = "2026-07-28T06:05:19.417Z" }, + { url = "https://files.pythonhosted.org/packages/58/10/b073beaea89bc0d3670a75ff51139430a54b6af7ba7796507730634536dd/wrapt-2.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ea52a0d0f08c584943d5764be0e84efa912c8da23c23e1e285ff2f5641c18fcc", size = 81978, upload-time = "2026-07-28T06:05:21.133Z" }, + { url = "https://files.pythonhosted.org/packages/b3/31/0916d9cebf848ed3f1a0c1888faee421747df77331e4db2bc527a9a85988/wrapt-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd85b0aa88efdb189d6ae2f35f4526943a8f091c38599c9c31478241c819e6a1", size = 82518, upload-time = "2026-07-28T06:05:22.562Z" }, + { url = "https://files.pythonhosted.org/packages/f5/73/31c1bf0f3384062751c2094dadb314916d70aa9b6bfd26d994b4a7b393fa/wrapt-2.3.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:141ed6211286a9660d8d6702de598b43f0934b4f0eda16393f100a80f501d945", size = 170187, upload-time = "2026-07-28T06:05:23.904Z" }, + { url = "https://files.pythonhosted.org/packages/ed/25/fce087d54b79b8905f3c3c9dd5f454bbd8d8acb80b960c4a6aee5b4659b3/wrapt-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e49885a62ec4ee854d1b9e6371fda6afd219917225752abf729a3f36d4df9a5", size = 169288, upload-time = "2026-07-28T06:05:25.378Z" }, + { url = "https://files.pythonhosted.org/packages/c7/30/0d09e6dddc6b7a7230ac77f50254b5980ab4fcd22976f72f8cc8a0404458/wrapt-2.3.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d6159c9b2fefec02314e1332dbbbfaf960e369dfd26bcf7f8b258b5732065b3", size = 160932, upload-time = "2026-07-28T06:05:27.022Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ca/0913af0d2ec0c43865d32d615f518fea66c13c5c930e489e9b0de248e9a8/wrapt-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:24da48596326ef8e448cfa837b454f638713d3531262375f00e5a9681682fc07", size = 169017, upload-time = "2026-07-28T06:05:28.501Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f2/3d1e47ea81b822210f5df1bf942fd90780a75c055243d569b664529dea88/wrapt-2.3.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:cd3a2edf0427013736b8127955cec62608c56e53ea47e82812ea32059cda407f", size = 159065, upload-time = "2026-07-28T06:05:30.01Z" }, + { url = "https://files.pythonhosted.org/packages/43/a5/ef2066ced8e5fca204e2b361e9708e36555b40949c583d997ea3b590817d/wrapt-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4fa0df3bff4e7ce45759f33fd39335fe2f60477bb9ecf7b8aa41e7d07ee36a23", size = 168821, upload-time = "2026-07-28T06:05:31.649Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e1/016104650d4e572fa91506eb396b3dd8efbccc9284fdc1c9479c3d21db28/wrapt-2.3.0-cp314-cp314-win32.whl", hash = "sha256:2935d5454b3f179a29b12cf390ee47246740ba2c3a7545b1b46ba31a5f2a4a0b", size = 78700, upload-time = "2026-07-28T06:05:33.391Z" }, + { url = "https://files.pythonhosted.org/packages/3d/97/6fdc20a9f2ca304748b3f0819cbf377d55260562777bf0b615431bc3c181/wrapt-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:cc2cea812e5cb179a796b766747e7d3b21088760d8deb95676d482b8c8e6fa7d", size = 81422, upload-time = "2026-07-28T06:05:34.774Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a4/9cbd53bf05746bea2c392af39cb052427a8ec95cbd494d930733d8f44681/wrapt-2.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:22cc5c0a717bd4da87018ae0bffd4c19c6fb679d3ff357216ba566ab26c76cab", size = 80639, upload-time = "2026-07-28T06:05:36.228Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/6c5e4a0f66ea0d2b2dd267e8dd05a0014eea56840b3c8595d40b0a5d1f91/wrapt-2.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a6b5984cd65dd639546f0eb4b8eacf1c31cb2fe9fb5c27bffe240987cdb2cf84", size = 84030, upload-time = "2026-07-28T06:05:37.714Z" }, + { url = "https://files.pythonhosted.org/packages/6a/eb/a1aedf03283bc9cbf8a1783995ddc54e3c5a86878f19002d2c428494f4c5/wrapt-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c88abcf53daef80e01a75c7530e727fa6e2c1888fe83e3dcdba4c96216a1f5c7", size = 84419, upload-time = "2026-07-28T06:05:39.131Z" }, + { url = "https://files.pythonhosted.org/packages/63/61/50d511c0dc5105563849e86daa3e16ac7feef699f79fb05af45ea70107d5/wrapt-2.3.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:85de890ff968196e92dd1ae73a9fb8970495e7650a457b1c9ef0ac3dd550bce2", size = 207171, upload-time = "2026-07-28T06:05:40.69Z" }, + { url = "https://files.pythonhosted.org/packages/3f/59/9b538cf7795217e810699d16bc88b96a830d9b5c403eb2ec2db6b5f2ae81/wrapt-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50f416b74d092bb9f41b424e90dd457f365f7ba4b11de62a23679769a21bd85c", size = 214329, upload-time = "2026-07-28T06:05:42.287Z" }, + { url = "https://files.pythonhosted.org/packages/b3/28/9935d62b1499e5c8b3d191e99ba4eb31ca237a0b699142011a837e9dc7ea/wrapt-2.3.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:39febbee6d77301d31da6996b152ce52452da7c7ef72aba10c2fa976dff9c295", size = 199079, upload-time = "2026-07-28T06:05:43.958Z" }, + { url = "https://files.pythonhosted.org/packages/2b/01/4446b80fa2ffa47a3449b250d004ba1c1937f07f64a179608fec735df866/wrapt-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:93513bec052c6cd987f9f580c3df068c8bc4ebae6543736be3ca7ec5959cafcd", size = 209992, upload-time = "2026-07-28T06:05:45.677Z" }, + { url = "https://files.pythonhosted.org/packages/d4/07/56f26c9f9979586a021e8148747004aba4498f49458c90b0502969b904e1/wrapt-2.3.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:729126e667da34d251b8ebf8a45ef0c5ddadc21542b3d6e1abf4259ece6508df", size = 196334, upload-time = "2026-07-28T06:05:47.608Z" }, + { url = "https://files.pythonhosted.org/packages/8b/41/6d7bcc895b0f28b2250e10908f060687b9165429dcd7f22ddb3d4c031b74/wrapt-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:626b69db2021aa01671ec7bbc9740e558522bd44c18cf2ce69bf3d666a014109", size = 202644, upload-time = "2026-07-28T06:05:49.183Z" }, + { url = "https://files.pythonhosted.org/packages/cd/25/7860927edba06b758b8852a6f02e832be715563c67a6795d94350bc81099/wrapt-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:629d73378082c00a8173031f9fb30a3ac6abbc894a5bfdfae71fabc60642d501", size = 79685, upload-time = "2026-07-28T06:05:50.976Z" }, + { url = "https://files.pythonhosted.org/packages/c4/0f/270bafe92fde3b069a39bc01e39ee79340895b335640df861d43d2a51885/wrapt-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:42869085687f0aefd57c0f636c3f9354f8ffb321a8ba9cb52d19beb796e561c5", size = 83104, upload-time = "2026-07-28T06:05:52.405Z" }, + { url = "https://files.pythonhosted.org/packages/55/b3/af176d79a8515a8a720eccdad9a96f6e31a30abf2865430c8c42adf2fd13/wrapt-2.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b1e5aa486e269b00ed35e64771c7d0ab8096cfd2643405ca8cd60ebedc099a51", size = 81774, upload-time = "2026-07-28T06:05:53.902Z" }, + { url = "https://files.pythonhosted.org/packages/00/39/3daf9f47be208606586de4568ba6713db53ebc8fd7a575aea1fe57983b69/wrapt-2.3.0-py3-none-any.whl", hash = "sha256:d8c7ed08477429752b8c44991f40ad7838b18332a160698740a6bfbc10d998a2", size = 61866, upload-time = "2026-07-28T06:06:12.9Z" }, ] [[package]] @@ -6060,118 +6292,118 @@ wheels = [ [[package]] name = "yarl" -version = "1.24.2" +version = "1.24.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/79/12/1e8f37460ea0f7eb59c221fdaf0ed75e7ac43e97f8093b9c6f411df50a78/yarl-1.24.2.tar.gz", hash = "sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8", size = 210798, upload-time = "2026-05-19T21:31:05.599Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/df/f1c7a3de0831cd83194f1a85c5bb431b13f81e6b45079314c86d1c4ef3f2/yarl-1.24.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12", size = 129057, upload-time = "2026-05-19T21:27:47.564Z" }, - { url = "https://files.pythonhosted.org/packages/48/41/7daafb32dd7562bf45b1ce56562e7e1a9146f6479b6456873eb8a3413c40/yarl-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0", size = 91545, upload-time = "2026-05-19T21:27:50.089Z" }, - { url = "https://files.pythonhosted.org/packages/a8/8f/7b3ec212f1ea0683f55f978e3246bc313c38818664edfc97a9f349a4901e/yarl-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75", size = 91380, upload-time = "2026-05-19T21:27:51.953Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1b/8bafab7db23b0567ae9db749099b329d91e3b82bc6028b2050ba583e116c/yarl-1.24.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727", size = 105957, upload-time = "2026-05-19T21:27:53.98Z" }, - { url = "https://files.pythonhosted.org/packages/7f/77/21030c2f8d21d21559719beafc772ada2014be933418ed1eaed9cc800e42/yarl-1.24.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413", size = 97242, upload-time = "2026-05-19T21:27:55.981Z" }, - { url = "https://files.pythonhosted.org/packages/50/d8/f9ea63d1b6aa910a866e089d871fff6cbd49caab29b86b35221a62dfa0d5/yarl-1.24.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9", size = 114719, upload-time = "2026-05-19T21:27:58.037Z" }, - { url = "https://files.pythonhosted.org/packages/e9/a3/04e0ee98ac58a249ea7ed75223f5f901ba81a834f0b4921b58e5cec11757/yarl-1.24.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2", size = 112140, upload-time = "2026-05-19T21:27:59.618Z" }, - { url = "https://files.pythonhosted.org/packages/02/ad/0b9cc9f38a7324a7eb1d80f834eaa5283d17e9271bbda3186e598dddaeac/yarl-1.24.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90", size = 106721, upload-time = "2026-05-19T21:28:02.586Z" }, - { url = "https://files.pythonhosted.org/packages/65/e7/a52478ebfc66ec989e085c6ae038b9f1bfa4190baa193b133b669c709e2f/yarl-1.24.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643", size = 106478, upload-time = "2026-05-19T21:28:04.523Z" }, - { url = "https://files.pythonhosted.org/packages/04/d8/5508530fea8472542de00013ae280765fc938ee196fc4030c43a498afb36/yarl-1.24.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac", size = 105423, upload-time = "2026-05-19T21:28:06.515Z" }, - { url = "https://files.pythonhosted.org/packages/84/f1/ece28505e9628e8b756e11bb4f28864a17cc33b6b44db4d2aaf0622bf630/yarl-1.24.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f", size = 99878, upload-time = "2026-05-19T21:28:08.637Z" }, - { url = "https://files.pythonhosted.org/packages/3f/52/fb5d34529b46dd84013afcfb30b8d2bc2832ed03d412736f577d604fa393/yarl-1.24.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36", size = 114025, upload-time = "2026-05-19T21:28:10.64Z" }, - { url = "https://files.pythonhosted.org/packages/43/f0/ff9d31aaab024f7a251c0ed308a98ae29bf9f7dc344e78f28b1322431ca2/yarl-1.24.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a", size = 105613, upload-time = "2026-05-19T21:28:12.784Z" }, - { url = "https://files.pythonhosted.org/packages/31/7d/3296fb3f3ecd52bf9ae6c16b0895c1cda7e9170a2083861552b683f70264/yarl-1.24.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53", size = 111665, upload-time = "2026-05-19T21:28:14.393Z" }, - { url = "https://files.pythonhosted.org/packages/1a/74/77aa6ddaca4fbf42e45e675a465c43956dd40702281049975a2aa04eae59/yarl-1.24.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342", size = 106914, upload-time = "2026-05-19T21:28:15.893Z" }, - { url = "https://files.pythonhosted.org/packages/d8/02/7611f22cd1d4ed7373eb7f9ee21fde1046edba2e7c0e514880d760352f48/yarl-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4", size = 92658, upload-time = "2026-05-19T21:28:17.471Z" }, - { url = "https://files.pythonhosted.org/packages/91/00/671d0add79938127292839ae44506ce2f7fe8909c72d5a931864f128fd0b/yarl-1.24.2-cp310-cp310-win_arm64.whl", hash = "sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39", size = 87887, upload-time = "2026-05-19T21:28:19.021Z" }, - { url = "https://files.pythonhosted.org/packages/c5/c5/1ce244152ff2839645e7cae92f90e7bafcb2c52bea7ff586ac714f14f5df/yarl-1.24.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1", size = 128971, upload-time = "2026-05-19T21:28:20.543Z" }, - { url = "https://files.pythonhosted.org/packages/87/5a/00f36967203ed89cb3acd2c8ed526cc3fed9418eb70ce128160a911c8499/yarl-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c", size = 91507, upload-time = "2026-05-19T21:28:22.556Z" }, - { url = "https://files.pythonhosted.org/packages/31/d0/1fb0c1cd27288f39f6974da4318c32768d72c9890984541fdf1e2e32a51d/yarl-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d", size = 91343, upload-time = "2026-05-19T21:28:24.092Z" }, - { url = "https://files.pythonhosted.org/packages/03/ce/d4a646508bed2f8dec6435b40166fe9308dd191262033d3f307b2bbcaecd/yarl-1.24.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae", size = 105704, upload-time = "2026-05-19T21:28:25.872Z" }, - { url = "https://files.pythonhosted.org/packages/4b/07/b3278e82d8bc41485bcf6d856cd0433262593de615b1d3dc43bd3f5bead4/yarl-1.24.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a", size = 97281, upload-time = "2026-05-19T21:28:27.352Z" }, - { url = "https://files.pythonhosted.org/packages/17/5b/4cee6e7c92e487bebe7afc797da0aa54a248ab4e776a68fe369ec29665a5/yarl-1.24.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e", size = 114020, upload-time = "2026-05-19T21:28:29.458Z" }, - { url = "https://files.pythonhosted.org/packages/5c/82/111076571545a7d4f9cca3fbd5c6f40615af58642be09f12328f48022468/yarl-1.24.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50", size = 111450, upload-time = "2026-05-19T21:28:31.262Z" }, - { url = "https://files.pythonhosted.org/packages/b6/ec/08f671f69a444d704aeecebf92af659b67b97a869942411d0a578b08c334/yarl-1.24.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003", size = 106384, upload-time = "2026-05-19T21:28:32.856Z" }, - { url = "https://files.pythonhosted.org/packages/e5/86/ce41e7a7a199340b2330d52b60f25c4074b6636dd0e60b1a80d31a9db042/yarl-1.24.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f", size = 106153, upload-time = "2026-05-19T21:28:35.222Z" }, - { url = "https://files.pythonhosted.org/packages/c4/5d/31be8a729531ab3e55ac3e7e5c800be8c89ea98947f418b2f6ea259fb6ee/yarl-1.24.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f", size = 105322, upload-time = "2026-05-19T21:28:36.642Z" }, - { url = "https://files.pythonhosted.org/packages/47/9b/b57afb22b386ae87ac9940f09878b98d8c333f89113e6fc96fcf4ca9eb64/yarl-1.24.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294", size = 99057, upload-time = "2026-05-19T21:28:38.386Z" }, - { url = "https://files.pythonhosted.org/packages/a3/4f/06348c27c8389256c313e8a57d796808fc0264c915dd5e7cfd3c0e314dc7/yarl-1.24.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2", size = 113502, upload-time = "2026-05-19T21:28:40.091Z" }, - { url = "https://files.pythonhosted.org/packages/5f/1c/284f307b298e4a17b7943b07d9d7ecc4151537f8d137ba51f3bb6c31ca20/yarl-1.24.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c", size = 105253, upload-time = "2026-05-19T21:28:41.987Z" }, - { url = "https://files.pythonhosted.org/packages/c8/bf/0de123bec8619e45c80cbded9085f61b5b4a9eddb8abe6d25d28ee1ec866/yarl-1.24.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b", size = 111345, upload-time = "2026-05-19T21:28:43.93Z" }, - { url = "https://files.pythonhosted.org/packages/90/af/0248eb065e51129d2a9b2436cd1b5c772c19a6b04e5b6a186955671e3319/yarl-1.24.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5", size = 106558, upload-time = "2026-05-19T21:28:45.806Z" }, - { url = "https://files.pythonhosted.org/packages/21/3c/f960d7a65ef97d8ba9b424fb5128796a4bc710fc6df2ddbbd7dfdc3bbd20/yarl-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45", size = 92808, upload-time = "2026-05-19T21:28:48.465Z" }, - { url = "https://files.pythonhosted.org/packages/03/1a/49fb03750e4de4d2284cd5b885a383133c34eef45bd59631b2bb8b7e81e8/yarl-1.24.2-cp311-cp311-win_arm64.whl", hash = "sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122", size = 87610, upload-time = "2026-05-19T21:28:50.07Z" }, - { url = "https://files.pythonhosted.org/packages/f0/da/866bcb01076ba49d2b42b309867bed3826421f1c479655eb7a607b44f20b/yarl-1.24.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8", size = 129957, upload-time = "2026-05-19T21:28:51.695Z" }, - { url = "https://files.pythonhosted.org/packages/bf/1d/fcefb70922ea2268a8971d8e5874d9a8218644200fb8465f1dcad55e6851/yarl-1.24.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2", size = 92164, upload-time = "2026-05-19T21:28:53.242Z" }, - { url = "https://files.pythonhosted.org/packages/29/b6/170e2b8d4e3bc30e6bfdcca53556537f5bf595e938632dfcb059311f3ff6/yarl-1.24.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d", size = 91688, upload-time = "2026-05-19T21:28:54.865Z" }, - { url = "https://files.pythonhosted.org/packages/fe/a5/c9f655d5553ea0b99fdac9d6a99ad3f9b3e73b8e5758bb46f58c9831f74c/yarl-1.24.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035", size = 102902, upload-time = "2026-05-19T21:28:56.963Z" }, - { url = "https://files.pythonhosted.org/packages/5d/bc/6b9664d815d79af4ee553337f9d606c56bbf269186ada9172de45f1b5f60/yarl-1.24.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576", size = 97931, upload-time = "2026-05-19T21:28:58.56Z" }, - { url = "https://files.pythonhosted.org/packages/98/ec/32ba48acae30fecd60928f5791188b80a9d6ee3840507ffda29fecd37b71/yarl-1.24.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8", size = 111030, upload-time = "2026-05-19T21:29:00.148Z" }, - { url = "https://files.pythonhosted.org/packages/82/5a/6f4cd081e5f4934d2ae3a8ef4abe3afacc010d26f0035ee91b35cd7d7c37/yarl-1.24.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7", size = 110392, upload-time = "2026-05-19T21:29:02.155Z" }, - { url = "https://files.pythonhosted.org/packages/7a/da/323a01c349bd5fb01bb6652e314d9bb218cee630a736bdb810ad50e4013f/yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c", size = 105612, upload-time = "2026-05-19T21:29:04.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/80/264ab684f181e1a876389374519ff05d10248725535ae2ac4e8ac4e563d6/yarl-1.24.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d", size = 104487, upload-time = "2026-05-19T21:29:06.491Z" }, - { url = "https://files.pythonhosted.org/packages/41/07/efabe5df87e96d7ad5959760b888344be48cd6884db127b407c6b5503adc/yarl-1.24.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db", size = 102333, upload-time = "2026-05-19T21:29:08.267Z" }, - { url = "https://files.pythonhosted.org/packages/44/0c/bcf7c42603e1009295f586d8890f2ba032c8b53310e815adf0a202c73d9f/yarl-1.24.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712", size = 99025, upload-time = "2026-05-19T21:29:10.682Z" }, - { url = "https://files.pythonhosted.org/packages/4f/82/84482ab1a57a0f21a08afe6a7004c61d741f8f2ecc3b05c321577c612164/yarl-1.24.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996", size = 110507, upload-time = "2026-05-19T21:29:12.954Z" }, - { url = "https://files.pythonhosted.org/packages/c4/8d/a546ba1dfe1b0f290e05fef145cd07614c0f15df1a707195e512d1e39d1d/yarl-1.24.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b", size = 103719, upload-time = "2026-05-19T21:29:14.893Z" }, - { url = "https://files.pythonhosted.org/packages/1a/b6/267f2a09213138473adfce6b8a6e17791d7fee70bd4d9003218e4dec58b0/yarl-1.24.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c", size = 110438, upload-time = "2026-05-19T21:29:16.485Z" }, - { url = "https://files.pythonhosted.org/packages/48/2d/1c8d89c7c5f9cad9fb2902445d94e2ab1d7aa35de029afbb8ae95c42d00f/yarl-1.24.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1", size = 105719, upload-time = "2026-05-19T21:29:18.367Z" }, - { url = "https://files.pythonhosted.org/packages/a7/25/722e3b93bd687009afb2d59a35e13d30ddd8f80571445bb0c4e4ce26ec66/yarl-1.24.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad", size = 92901, upload-time = "2026-05-19T21:29:20.014Z" }, - { url = "https://files.pythonhosted.org/packages/39/47/4486ccfb674c04854a1ef8aa77868b6a6f765feaf69633409d7ca4f02cb8/yarl-1.24.2-cp312-cp312-win_arm64.whl", hash = "sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30", size = 87229, upload-time = "2026-05-19T21:29:22.1Z" }, - { url = "https://files.pythonhosted.org/packages/82/62/fcf0ce677f17e5c471c06311dd25964be38a4c586993632910d2e75278bc/yarl-1.24.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536", size = 128978, upload-time = "2026-05-19T21:29:23.83Z" }, - { url = "https://files.pythonhosted.org/packages/d3/58/8e63299bb71ed61a834121d9d3fe6c9fcf2a6a5d09754ff4f20f2d20baf5/yarl-1.24.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607", size = 91733, upload-time = "2026-05-19T21:29:25.375Z" }, - { url = "https://files.pythonhosted.org/packages/c1/24/16748d5dab6daec8b0ed81ccec639a1cded0f18dcc62a4f696b4fe366c37/yarl-1.24.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1", size = 91113, upload-time = "2026-05-19T21:29:26.928Z" }, - { url = "https://files.pythonhosted.org/packages/1b/66/b63fff7b71211e866624b21432d5943cbb633eb0c2872d9ee3070648f22c/yarl-1.24.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986", size = 103899, upload-time = "2026-05-19T21:29:28.842Z" }, - { url = "https://files.pythonhosted.org/packages/9d/ac/ba1974b8533909636f7733fe86cf677e3619527c3c2fa913e0ea89c48757/yarl-1.24.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488", size = 97862, upload-time = "2026-05-19T21:29:31.086Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a5/123ac993b5c2ba6f554a140305620cb8f150fa543711bbc49be3ec0a65a4/yarl-1.24.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b", size = 111060, upload-time = "2026-05-19T21:29:32.657Z" }, - { url = "https://files.pythonhosted.org/packages/23/37/c472d3af3509688392134a88a825276770a187f1daa4de3f6dc0a327a751/yarl-1.24.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592", size = 110613, upload-time = "2026-05-19T21:29:34.379Z" }, - { url = "https://files.pythonhosted.org/packages/df/88/09c28dad91e662ccfaa1b78f1c57badde74fc9d0b23e74aef644750ecd73/yarl-1.24.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617", size = 107012, upload-time = "2026-05-19T21:29:36.216Z" }, - { url = "https://files.pythonhosted.org/packages/07/ab/9d4f69d571a94f4d112fa7e2e007200f5a54d319f58c82ac7b7baa61f5c6/yarl-1.24.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92", size = 105887, upload-time = "2026-05-19T21:29:38.746Z" }, - { url = "https://files.pythonhosted.org/packages/8e/9a/000b2b66c0d772a499fc531d21dab92dfeb73b640a12eed6ba89f49bb2d0/yarl-1.24.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a", size = 103620, upload-time = "2026-05-19T21:29:40.368Z" }, - { url = "https://files.pythonhosted.org/packages/41/7c/7c1050f73450fbdaa3f0c72017059f00ce5e13366692f3dba25275a1083d/yarl-1.24.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44", size = 100599, upload-time = "2026-05-19T21:29:42.66Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b1/29e5756b3926705f5f6089bd5b9f50a56eaac550da6e260bf713ead44d04/yarl-1.24.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a", size = 110604, upload-time = "2026-05-19T21:29:44.632Z" }, - { url = "https://files.pythonhosted.org/packages/a3/4b/8415bc96e9b150cde942fbac9a8182985e58f40ce5c54c34ed015407d3ee/yarl-1.24.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf", size = 105161, upload-time = "2026-05-19T21:29:46.755Z" }, - { url = "https://files.pythonhosted.org/packages/8b/d4/cde059abfa229553b7298a2eadde2752e723d50aeedaef86ce59da2718ee/yarl-1.24.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056", size = 110619, upload-time = "2026-05-19T21:29:48.972Z" }, - { url = "https://files.pythonhosted.org/packages/e7/2c/d6a6c9a61549f7b6c7e6dc6937d195bcf069582b47b7200dcd0e7b256acf/yarl-1.24.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992", size = 107362, upload-time = "2026-05-19T21:29:51Z" }, - { url = "https://files.pythonhosted.org/packages/92/dd/3ae5fe417e9d1c353a548553326eb9935e76b6b727161563b424cc296df3/yarl-1.24.2-cp313-cp313-win_amd64.whl", hash = "sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656", size = 92667, upload-time = "2026-05-19T21:29:52.743Z" }, - { url = "https://files.pythonhosted.org/packages/10/cc/a7beb239f78f27fca1b053c8e8595e4179c02e62249b4687ec218c370c50/yarl-1.24.2-cp313-cp313-win_arm64.whl", hash = "sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461", size = 87069, upload-time = "2026-05-19T21:29:54.442Z" }, - { url = "https://files.pythonhosted.org/packages/40/0e/e08087695fc12789263821c5dc0f8dc52b5b17efd0887cacf419f8a43ba3/yarl-1.24.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2", size = 129670, upload-time = "2026-05-19T21:29:56.631Z" }, - { url = "https://files.pythonhosted.org/packages/3a/98/ab4b5ed1b1b5cd973c8a3eb994c3a6aefb6ce6d399e21bb5f0316c33815c/yarl-1.24.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630", size = 91916, upload-time = "2026-05-19T21:29:58.645Z" }, - { url = "https://files.pythonhosted.org/packages/ba/b1/5297bb6a7df4782f7605bffc43b31f5044070935fbbcaa6c705a07e6ac65/yarl-1.24.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8", size = 91625, upload-time = "2026-05-19T21:30:00.412Z" }, - { url = "https://files.pythonhosted.org/packages/02/a7/45baabfff76829264e623b185cff0c340d7e11bf3e1cd9ea37e7d17934bd/yarl-1.24.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14", size = 104574, upload-time = "2026-05-19T21:30:02.544Z" }, - { url = "https://files.pythonhosted.org/packages/f3/40/3a5ab144d3d650ca37d4f4b57e56169be8af3ca34c448793e064b30baaed/yarl-1.24.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535", size = 97534, upload-time = "2026-05-19T21:30:04.319Z" }, - { url = "https://files.pythonhosted.org/packages/9c/b5/5658fef3681fb5776b4513b052bec750009f47b3a592251c705d75375798/yarl-1.24.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14", size = 111481, upload-time = "2026-05-19T21:30:05.988Z" }, - { url = "https://files.pythonhosted.org/packages/4c/06/fdcd7dde037f00866dce123ed4ba23dba94beb56fc4cf561668d27be37f2/yarl-1.24.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3", size = 111529, upload-time = "2026-05-19T21:30:07.738Z" }, - { url = "https://files.pythonhosted.org/packages/c2/53/d81269aaafccea0d33396c03035de997b743f11e648e6e27a0df99c72980/yarl-1.24.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208", size = 107338, upload-time = "2026-05-19T21:30:09.713Z" }, - { url = "https://files.pythonhosted.org/packages/ae/04/23049463f729bd899df203a7960505a75333edd499cda8aa1d5a82b64df5/yarl-1.24.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50", size = 106147, upload-time = "2026-05-19T21:30:11.365Z" }, - { url = "https://files.pythonhosted.org/packages/14/18/04a4b5830b43ed5e4c5015b40e9f6241ad91487d71611061b4e111d6ac80/yarl-1.24.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd", size = 104272, upload-time = "2026-05-19T21:30:12.978Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f7/8cffdf319aee7a7c1dbd07b61d91c3e3fda460c7a93b5f93e445f3806c4c/yarl-1.24.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67", size = 99962, upload-time = "2026-05-19T21:30:15.001Z" }, - { url = "https://files.pythonhosted.org/packages/d7/39/b3cce3b7dbef64ac700ad4cea156a207d01bede0f507587616c364b5468e/yarl-1.24.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1", size = 111063, upload-time = "2026-05-19T21:30:16.683Z" }, - { url = "https://files.pythonhosted.org/packages/a1/ea/100818505e7ebf165c7242ff17fdf7d9fee79e27234aeca871c1082920d7/yarl-1.24.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1", size = 105438, upload-time = "2026-05-19T21:30:18.769Z" }, - { url = "https://files.pythonhosted.org/packages/8f/d2/e075a0b32aa6625087de9e653087df0759fed5de4a435fef594181102a77/yarl-1.24.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b", size = 111458, upload-time = "2026-05-19T21:30:21.024Z" }, - { url = "https://files.pythonhosted.org/packages/e6/5c/ceea7ba98b65c8eb8d947fdc52f9bedfcd43c6a57c9e3c90c17be8f324a3/yarl-1.24.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8", size = 107589, upload-time = "2026-05-19T21:30:23.412Z" }, - { url = "https://files.pythonhosted.org/packages/fa/d9/5582d57e2b2db9b85eb6663a22efdd78e08805f3f5389566e9fcad254d1b/yarl-1.24.2-cp314-cp314-win_amd64.whl", hash = "sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0", size = 94424, upload-time = "2026-05-19T21:30:25.425Z" }, - { url = "https://files.pythonhosted.org/packages/92/10/7dc07a0e22806a9280f42a57361395506e800c64e22737cd7b0886feab42/yarl-1.24.2-cp314-cp314-win_arm64.whl", hash = "sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57", size = 88690, upload-time = "2026-05-19T21:30:27.623Z" }, - { url = "https://files.pythonhosted.org/packages/9e/13/d5b8e2c8667db955bcb3de233f18798fefe7edf1d7429c2c9d4f9c401114/yarl-1.24.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b", size = 136248, upload-time = "2026-05-19T21:30:29.297Z" }, - { url = "https://files.pythonhosted.org/packages/de/46/a4a97c05c9c9b8fd266bb2a0df12992c7fbd02391eb9640583411b6dab32/yarl-1.24.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761", size = 95084, upload-time = "2026-05-19T21:30:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/95/b2/845cf2074a015e6fe0d0808cf1a2d9e868386c4220d657ebd8302b199043/yarl-1.24.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8", size = 95272, upload-time = "2026-05-19T21:30:33.062Z" }, - { url = "https://files.pythonhosted.org/packages/fe/16/e69d4aa244aef45235ddfebc0e04036a6829842bc5a6a795aedc6c998d23/yarl-1.24.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed", size = 101497, upload-time = "2026-05-19T21:30:34.842Z" }, - { url = "https://files.pythonhosted.org/packages/15/94/c07107715d621076863ee88b3ddf183fa5e9d4aba5769623c9979828410a/yarl-1.24.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543", size = 94002, upload-time = "2026-05-19T21:30:37.724Z" }, - { url = "https://files.pythonhosted.org/packages/a9/35/fc1bbdd895b5e4010b8fdd037f7ed3aa289d3863e08231b30231ca9a0815/yarl-1.24.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0", size = 106524, upload-time = "2026-05-19T21:30:40.196Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f2/32b66d0a4ba47c296cf86d03e2c67bff58399fe6d6d84d5205c04c66cc6d/yarl-1.24.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024", size = 106165, upload-time = "2026-05-19T21:30:41.888Z" }, - { url = "https://files.pythonhosted.org/packages/95/47/37cb5ff50c5e825d4d38e81bb04d1b7e96bf960f7ab89f9850b162f3f114/yarl-1.24.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf", size = 103010, upload-time = "2026-05-19T21:30:43.985Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/4597912315096f7bb359e46e13bf8b60994fcbb2db29b804c0902ef4eff5/yarl-1.24.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc", size = 101128, upload-time = "2026-05-19T21:30:46.291Z" }, - { url = "https://files.pythonhosted.org/packages/b9/d5/c8e86e120521e646013d02a8e3b8884392e28494be8f392366e50d208efc/yarl-1.24.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb", size = 101382, upload-time = "2026-05-19T21:30:48.085Z" }, - { url = "https://files.pythonhosted.org/packages/fa/98/70b229236118f89dbeb739b76f10225bbf53b5497725502594c9a01d699a/yarl-1.24.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420", size = 95964, upload-time = "2026-05-19T21:30:49.785Z" }, - { url = "https://files.pythonhosted.org/packages/87/f8/56c386981e3c8648d279fdef2397ffec577e8320fd5649745e34d54faeb7/yarl-1.24.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f", size = 106204, upload-time = "2026-05-19T21:30:51.862Z" }, - { url = "https://files.pythonhosted.org/packages/1a/1e/765afe97811ca35933e2a7de70ac57b1997ea2e4ee895719ee7a231fb7e5/yarl-1.24.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa", size = 101510, upload-time = "2026-05-19T21:30:53.62Z" }, - { url = "https://files.pythonhosted.org/packages/ee/78/393913f4b9039e1edd09ae8a9bbb9d539be909a8abf6d8a2084585bed4b7/yarl-1.24.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe", size = 105584, upload-time = "2026-05-19T21:30:55.962Z" }, - { url = "https://files.pythonhosted.org/packages/78/87/deb17b7049bbe74ea11a713b86f8f27800cc1c8648b0b797243ebb4830ba/yarl-1.24.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd", size = 103410, upload-time = "2026-05-19T21:30:57.962Z" }, - { url = "https://files.pythonhosted.org/packages/8f/be/f9f7594e23b5b93affff0318e4593c1920331bcaefda326cabcad94296a1/yarl-1.24.2-cp314-cp314t-win_amd64.whl", hash = "sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215", size = 102980, upload-time = "2026-05-19T21:30:59.735Z" }, - { url = "https://files.pythonhosted.org/packages/65/a4/ba80dccd3593ff1f01051a818694d07b58cb8232677ee9a22a5a1f93a9fc/yarl-1.24.2-cp314-cp314t-win_arm64.whl", hash = "sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d", size = 91219, upload-time = "2026-05-19T21:31:01.934Z" }, - { url = "https://files.pythonhosted.org/packages/fd/4d/4b880086bd0d3e034d25647be1d830afc3e3f610e98c4ab3490af6b1b6d5/yarl-1.24.2-py3-none-any.whl", hash = "sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9", size = 53576, upload-time = "2026-05-19T21:31:03.909Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/31/33/ebe9e3d1f86c7a0b51094c0a146392045ca1631d2664889539dec8088a33/yarl-1.24.5.tar.gz", hash = "sha256:e81b83143bee16329c23db3c1b2d82b29892fcbcb849186d2f6e98a5abe9a57f", size = 228679, upload-time = "2026-07-20T02:07:45.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ac/cacdda1f0a90441297210bc34cf7e4ac1b7318c8030ebd83bdf6fe82f1db/yarl-1.24.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88f50c94e21a0a7f14042c015b0eba1881af78562e7bf007e0033e624da59750", size = 135466, upload-time = "2026-07-20T02:04:21.695Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a5/1b2ceace0230e40c52ab1b263148059a43a6303219b996affc68f8381836/yarl-1.24.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6efbccc3d7f75d5b03105172a8dc86d82ba4da86817952529dd93185f4a88be2", size = 97291, upload-time = "2026-07-20T02:04:24.045Z" }, + { url = "https://files.pythonhosted.org/packages/59/1d/340d1a0db7bbce1f291afc044255ebf4ebbce2b25ab1b3f7d3d069080f5d/yarl-1.24.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0ebfaffe1a16cb72141c8e09f18cc76856dbe58639f393a4f2b26e474b96b871", size = 97154, upload-time = "2026-07-20T02:04:25.761Z" }, + { url = "https://files.pythonhosted.org/packages/05/41/25596a33c2fb5098dca8dc3773b04221db64ded0b7f8f09885647d864610/yarl-1.24.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ac73abdc7ab75610f95a8fd994c6457e87752b02a63987e188f937a1fc180f0", size = 109196, upload-time = "2026-07-20T02:04:27.543Z" }, + { url = "https://files.pythonhosted.org/packages/f2/df/dd9f2fb8a5c6054fbefd1538d2b9b1127e612d2ee64b307a070173b57afd/yarl-1.24.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4d97a951a81039050e45f04e96689b58b8243fa5e62aa14fe67cb6075300885e", size = 102556, upload-time = "2026-07-20T02:04:29.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/57/4754b9d2c8945880290ecba0864e8b0441e117bba70534fe819e3645e174/yarl-1.24.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe7b7bb170daccbba19ad33012d2b15f1e7942296fd4d45fc1b79013da8cc0f2", size = 117965, upload-time = "2026-07-20T02:04:30.845Z" }, + { url = "https://files.pythonhosted.org/packages/74/b5/6a9ece27d2043c3386f902dd078ab35d29ef5126b3206ebffb673283a7cb/yarl-1.24.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:89a1bbb58e0e3f7a283653d854b1e95d65e5cfd4af224dac5f02629ec1a3e621", size = 116266, upload-time = "2026-07-20T02:04:32.573Z" }, + { url = "https://files.pythonhosted.org/packages/9e/bc/a6653249f6ee59ec85dcfec008d9cbc16586dad613963bb17a91b2b993a5/yarl-1.24.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fa5e51397466ea7e98de493fa2ff1b8193cfef8a7b0f9b4842f92d342df0dba", size = 110758, upload-time = "2026-07-20T02:04:34.235Z" }, + { url = "https://files.pythonhosted.org/packages/65/7e/c5a12fb8208df7b981bc82256e7831ce428eeaf893f7bbe6179c57bb9252/yarl-1.24.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4103b77b8a8225e413107d2349b65eb3c1c52627b5cc5c3c4c1c6a798b218950", size = 110120, upload-time = "2026-07-20T02:04:35.85Z" }, + { url = "https://files.pythonhosted.org/packages/04/6c/1b659b964626694667b3ec01bf4bcff564b73ae7c48ea1fbfe588b78b461/yarl-1.24.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f9f3e9c8a9ecffa57bef8fb4fa19e5fa4d2d8307cf6bac5b1fca5e5860f4ba00", size = 108834, upload-time = "2026-07-20T02:04:37.67Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/bf48f55c2104e40c15b7b13fad0a5756a11552a55f01c90bc90a66ab81c3/yarl-1.24.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c0ebc836c47a6477e182169c6a476fc691d12b518894bf7dd2572f0d59f1c7ed", size = 103442, upload-time = "2026-07-20T02:04:39.576Z" }, + { url = "https://files.pythonhosted.org/packages/37/ac/84b273ac133ecdce598fc1f4140a08a1bf2044048bff8106371d207d105f/yarl-1.24.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:96d30286dd02679e32a39aa8f0b7498fc847fcda46cfc09df5513e82ce252440", size = 117413, upload-time = "2026-07-20T02:04:41.549Z" }, + { url = "https://files.pythonhosted.org/packages/a4/55/9307e03977d3b290dfa42e5d2bae7b6140808fd1786fbe70cd9d3bee53c5/yarl-1.24.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:fd8c81f346b58f45818d09ea11db69a8d5fd34a224b79871f6d44f12cd7977b1", size = 109498, upload-time = "2026-07-20T02:04:43.468Z" }, + { url = "https://files.pythonhosted.org/packages/fc/be/791a6f314cb4c989c19f8e3a10271f1e469c077143915e52474d80f26b4b/yarl-1.24.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5c55256dee8f4b27bfbf636c8363383c7c8db7890c7cba5217d7bd5f5f21dab6", size = 116062, upload-time = "2026-07-20T02:04:45.319Z" }, + { url = "https://files.pythonhosted.org/packages/19/1a/ddd3807b86055010e2f99aa89b3c640effdb65696766c20597f696f48a1c/yarl-1.24.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f4d8cf085a4c6a40fb97ea0f46938a8df43c85d31f9d45e2a8867ea9293790d", size = 110941, upload-time = "2026-07-20T02:04:47.054Z" }, + { url = "https://files.pythonhosted.org/packages/6d/03/f34271bba042d2187508bf62aea20a14129efb5a1acfc6a2efe7544630b4/yarl-1.24.5-cp310-cp310-win_amd64.whl", hash = "sha256:240cbec09667c1fed4c6cd0060b9ec57332427d7441289a2ed8875dc9fb2b224", size = 97534, upload-time = "2026-07-20T02:04:48.774Z" }, + { url = "https://files.pythonhosted.org/packages/e4/02/ecc8dc31b9f355731e700f8402b8075d2ea1737dbc4baf4abf0f0fc64288/yarl-1.24.5-cp310-cp310-win_arm64.whl", hash = "sha256:8a6987eaad834cb32dd57d9d582225f0054a5d1af706ccfbbdba735af4927e13", size = 93603, upload-time = "2026-07-20T02:04:50.686Z" }, + { url = "https://files.pythonhosted.org/packages/fe/db/3cb5df059756a45761cc3dee8fd25ec82b83a6585ea3542b969fda850f99/yarl-1.24.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c1fe720934a16ea8e7146175cba2126f87f54912c8c5435e7f7c7a51ef808d3", size = 135043, upload-time = "2026-07-20T02:04:52.39Z" }, + { url = "https://files.pythonhosted.org/packages/44/f8/767d6bd5a03db63bc467df2fb56d6fafeae9667d74aea92cd6af399f828b/yarl-1.24.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c687ed078e145f5fd53a14854beff320e1d2ab76df03e2009c98f39a0f68f39a", size = 96942, upload-time = "2026-07-20T02:04:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/ce/97/10b939c44d7b28d1dbc389cfc7012306d1ea8dba01eaef44b39fffaee52a/yarl-1.24.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:709f1efed56c4a145793c046cd4939f9959bcd818979a787b77d8e09c57a0840", size = 97046, upload-time = "2026-07-20T02:04:56.638Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7a/b410dbe39b6255c55fb2a2bcee96eb844d0789235ddc381a889a90dc72d6/yarl-1.24.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:874019bd513008b009f58657134e5d0c5e030b3559bd0553976837adf52fe966", size = 110512, upload-time = "2026-07-20T02:04:58.955Z" }, + { url = "https://files.pythonhosted.org/packages/83/c7/da591971f78a5617e1f21f5699858ebccd836fe181a6493788ffc91ba69b/yarl-1.24.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4582acf7ef76482f6f511ebaf1946dae7f2e85ec4728b81a678c01df63bd723", size = 102454, upload-time = "2026-07-20T02:05:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8e/73b0ed4de47289a78a96045d76d1cfe5e41848bf0da59ce25b2ec87ee05d/yarl-1.24.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2cabe6546e41dabe439999a23fcb5246e0c3b595b4315b96ef755252be90caeb", size = 117617, upload-time = "2026-07-20T02:05:02.325Z" }, + { url = "https://files.pythonhosted.org/packages/cf/14/b744747bc4f57a8d55bd744df463457524583e1e9f7538b5ace0346ab92e/yarl-1.24.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:17f57620f5475b3c69109376cc87e42a7af5db13c9398e4292772a706ff10780", size = 116135, upload-time = "2026-07-20T02:05:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/66/ca/95aa4d0e5b7ea4f20e4d577c42d001ed9df207569fdb063cc5ed4ebb496b/yarl-1.24.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:570fec8fbd22b032733625f03f10b7ff023bc399213db15e72a7acaef28c2f4e", size = 111935, upload-time = "2026-07-20T02:05:05.738Z" }, + { url = "https://files.pythonhosted.org/packages/72/0d/d2ad8d6b147832d177a4e720ba1962fe686eb0913b74503b3eca094b8bba/yarl-1.24.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5fede79c6f73ff2c3ef822864cb1ada23196e62756df53bc6231d351a49516a2", size = 110010, upload-time = "2026-07-20T02:05:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/50/18/eb335e4120903903f4865041355ae46256a2406eb2865bc24827f4f27b61/yarl-1.24.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ccf9aca873b767977c73df497a85dbedee4ee086ae9ae49dc461333b9b79f58", size = 110058, upload-time = "2026-07-20T02:05:09.246Z" }, + { url = "https://files.pythonhosted.org/packages/44/70/97353add32c62ad6f206d948ac5a5ee84398225e534dc6ed6433d1b335b6/yarl-1.24.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ad5d8201d310b031e6cd839d9bac2d4e5a01533ce5d3d5b50b7de1ef3af1de61", size = 103308, upload-time = "2026-07-20T02:05:11.31Z" }, + { url = "https://files.pythonhosted.org/packages/68/39/5e7398d4b6f6b3c9062823ebc60802df5b272e3fe9e788f9734c6ee46c85/yarl-1.24.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:841f0852f48fefea3b12c9dfec00704dfa3aef5215d0e3ce564bb3d7cd8d57c6", size = 116898, upload-time = "2026-07-20T02:05:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/09e52f2239e8b96357eccca05915382e4ba5405ebfb623b6036040d99654/yarl-1.24.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9baafc71b04f8f4bb0703b21d6fc9f0c30b346c636a532ff16ec8491a5ea4b1f", size = 109400, upload-time = "2026-07-20T02:05:14.821Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6a/e94133d4c2d1a14d2384310bf3e79d9cf32c9d1eae1c6f034fb80d098fa1/yarl-1.24.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d897129df1a22b12aeed2c2c98df0785a2e8e6e0bde87b389491d0025c187077", size = 115934, upload-time = "2026-07-20T02:05:17.78Z" }, + { url = "https://files.pythonhosted.org/packages/4e/3c/34955ed967b976fc38edcbb6d538dee79dbda4cb7fc7f72a0907a7c78e0f/yarl-1.24.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd625535328fd9882374356269227670189adfcc6a2d90284f323c05862eecbd", size = 112178, upload-time = "2026-07-20T02:05:19.675Z" }, + { url = "https://files.pythonhosted.org/packages/f5/46/d7bd3a8859d47dcfaffd7127af7076032a7da278a9a02e17b5f37bfb6712/yarl-1.24.5-cp311-cp311-win_amd64.whl", hash = "sha256:f4239bbec5a3577ddb49e4b50aeb32d8e5792098262ae2f63723f916a29b1a25", size = 97544, upload-time = "2026-07-20T02:05:21.523Z" }, + { url = "https://files.pythonhosted.org/packages/01/69/c1bfd21e32c638974ea2c542a0b8c53ef1fa9eff336020f5d014f9503ff2/yarl-1.24.5-cp311-cp311-win_arm64.whl", hash = "sha256:3ac6aff147deb9c09461b2d4bbdf6256831198f5d8a23f5d37138213090b6d8a", size = 93359, upload-time = "2026-07-20T02:05:23.493Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/71d051c850b5af41d168c679d9eb67eb7c55283ac4ee131673edf134bc4e/yarl-1.24.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d693396e5aea78db03decd60aec9ece16c9b40ba00a587f089615ff4e718a81d", size = 136035, upload-time = "2026-07-20T02:05:25.489Z" }, + { url = "https://files.pythonhosted.org/packages/03/4d/8ad27f9a1b7e69313cca5d695b925b48efe51208d3490e0844bae97cabc0/yarl-1.24.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3363fcc96e665878946ad7a106b9a13eac0541766a690ef287c0232ac768b6ec", size = 97642, upload-time = "2026-07-20T02:05:27.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b4/05b4131c407006cd1e410e9c6539f16a0945724677e5364447313c15ea3e/yarl-1.24.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9d399bdcfb4a0f659b9b3788bbc89babe63d9a6a65aacdf4d4e7065ff2e6316c", size = 97323, upload-time = "2026-07-20T02:05:29.441Z" }, + { url = "https://files.pythonhosted.org/packages/20/16/e618c875c73e0e39611f20a581b3d5e8d59b8857bf001bee3263044c6deb/yarl-1.24.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90333fd89b43c0d08ac85f3f1447593fc2c66de18c3d6378d7125ea118dc7a54", size = 107741, upload-time = "2026-07-20T02:05:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c4defeaf3ed33fcb346aacf9c6e971a8d4e2bde04a0310e79abb208e7965/yarl-1.24.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:665b0a2c463cc9423dd647e0bfd9f4ccc9b50f768c55304d5e9f80b177c1de12", size = 103570, upload-time = "2026-07-20T02:05:33.303Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e7/0e0e0de5865ebd5914537ef486f36c727a59865c3ac0cf5ff1b32aececbf/yarl-1.24.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e006d3a974c4ee19512e5f058abedb6eef36a5e553c14812bdeba1758d812e6d", size = 115815, upload-time = "2026-07-20T02:05:35.292Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/ca56b700cb170aba25a3893b75355b213935657dc5714d2383354a270e62/yarl-1.24.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7d42c531243450ef0d4d9c172e7ed6ef052640f195629065041b5add4e058d1", size = 116025, upload-time = "2026-07-20T02:05:37.503Z" }, + { url = "https://files.pythonhosted.org/packages/d6/d0/d56c859b8222116f5d68459199f48359e0bf121b6f65a69bf329b3602ba0/yarl-1.24.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f08c7513ecef5aad65687bfdf6bc601ae9fccd04a42904501f8f7141abad9eb9", size = 109835, upload-time = "2026-07-20T02:05:39.506Z" }, + { url = "https://files.pythonhosted.org/packages/70/a2/3a35557e4d1a79425040eba202ccaf08bdc8717680fc77e2498a1ad2e0a5/yarl-1.24.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c95b17fe34ed802f17e205112e6e10db92275c34fee290aa9bdc55a9c724027", size = 108884, upload-time = "2026-07-20T02:05:41.584Z" }, + { url = "https://files.pythonhosted.org/packages/e4/35/ef4c26356b7913c68983bac2d72a4212b3347af551cb8d250b99b5ed7b7f/yarl-1.24.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56b149b22de33b23b0c6077ab9518c6dcb538ad462e1830e68d06591ccf6e38b", size = 107308, upload-time = "2026-07-20T02:05:43.697Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/ff0dc66c2ccf3e0153ab97ff61eabab4400e6a5264af427ab30cd69f1857/yarl-1.24.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8fe66b8f300da93798025a785a5b90b42f3810dc2b72283ff84a41aaaebc293", size = 103646, upload-time = "2026-07-20T02:05:45.895Z" }, + { url = "https://files.pythonhosted.org/packages/74/f0/33b9271c7f881766359d58266fa0811d2e5210ed860e28da7dc6d7786344/yarl-1.24.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:377fe3732edbaf78ee74efdf2c9f49f6e99f20e7f9d2649fda3eb4badd77d76e", size = 115305, upload-time = "2026-07-20T02:05:47.832Z" }, + { url = "https://files.pythonhosted.org/packages/ef/65/fd79fb1868c4a80db8661091de525bf430f63c3bea1b20e8b6a84fc7d359/yarl-1.24.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e8ffa78582120024f476a611d7befc123cee59e47e8309d470cf667d806e613b", size = 108404, upload-time = "2026-07-20T02:05:49.604Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ba/dbabe6b262f17a816c70cfc09558dbf03ece3ec76684d02f911a3d3a189c/yarl-1.24.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:daba5e594f06114e37db186efd2dd916609071e59daca901a0a2e71f02b142ce", size = 115940, upload-time = "2026-07-20T02:05:51.741Z" }, + { url = "https://files.pythonhosted.org/packages/a5/43/fab2d1dad9d340a268cdde63756a123d069723efff6a372d123fa74a9517/yarl-1.24.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:65be18ec59496c13908f02a2472751d9ef840b4f3fb5726f129306bf6a2a7bba", size = 110006, upload-time = "2026-07-20T02:05:53.554Z" }, + { url = "https://files.pythonhosted.org/packages/c4/27/41eb51bbd1b8d89546b83897cfb0164f1e109304fd408dbb151b639eec0f/yarl-1.24.5-cp312-cp312-win_amd64.whl", hash = "sha256:a929d878fec099030c292803b31e5d5540a7b6a31e6a3cc76cb4685fc2a2f51b", size = 97618, upload-time = "2026-07-20T02:05:55.57Z" }, + { url = "https://files.pythonhosted.org/packages/3c/25/b2553764b3d65db711d8f45416351ec4f420847558eb669edcbcaadf5780/yarl-1.24.5-cp312-cp312-win_arm64.whl", hash = "sha256:7ce27823052e2013b597e0c738b13e7e36b8ccb9400df8959417b052ab0fd92c", size = 93018, upload-time = "2026-07-20T02:05:57.554Z" }, + { url = "https://files.pythonhosted.org/packages/e1/63/64ef361967cc983573149dc1515d531db5da8a4c92d22bb833d59e01b313/yarl-1.24.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:79af890482fc94648e8cde4c68620378f7fef60932710fa17a66abc039244da2", size = 135075, upload-time = "2026-07-20T02:05:59.671Z" }, + { url = "https://files.pythonhosted.org/packages/bb/89/55920fd853ce43e608adbc3962456f0d649d6bb15250dc2988321da0fe1c/yarl-1.24.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46c2f213e23a04b93a392942d782eb9e413e6ef6bf7c8c53884e599a5c174dcb", size = 97225, upload-time = "2026-07-20T02:06:01.769Z" }, + { url = "https://files.pythonhosted.org/packages/15/f0/7688d3f2cfff7590df2af38ec46d969f4281a4dddb08a9ad2eafbcdddf98/yarl-1.24.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92ab3e11448f2ff7bf53c5a26eff0edc086898ec8b21fb154b85839ce1d88075", size = 96751, upload-time = "2026-07-20T02:06:03.676Z" }, + { url = "https://files.pythonhosted.org/packages/05/1a/a851a0f94aaaf379dd4f901bfc80f634280bec51eb260b47363e2a4cd62e/yarl-1.24.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ebb0ec7f17803063d5aeb982f3b1bd2b2f4e4fae6751226cbd6ba1fcfe9e63ff", size = 107960, upload-time = "2026-07-20T02:06:05.699Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a8/faea066c12f9c77ca0de90641f1655f9dd7b412477bf28c76d692f3aecff/yarl-1.24.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:82632daed195dcc8ea664e8556dc9bdbd671960fb3776bd92806ce05792c2448", size = 103500, upload-time = "2026-07-20T02:06:07.556Z" }, + { url = "https://files.pythonhosted.org/packages/fb/9c/1e67084c2a6e2f2db0e3be798328cb3be42c0119b621d25461479a224d21/yarl-1.24.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:53e549287ef628fecba270045c9701b0c564563a9b0577d24a4ec75b8ab8040f", size = 115780, upload-time = "2026-07-20T02:06:09.599Z" }, + { url = "https://files.pythonhosted.org/packages/58/86/1f94664e147474337e3359f52012cf3d02f825f694317b178bfba1078c62/yarl-1.24.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fcd3b77e2f17bbe4ca56ec7bcb07992647d19d0b9c05d84886dcd6f9eb810afd", size = 115308, upload-time = "2026-07-20T02:06:11.352Z" }, + { url = "https://files.pythonhosted.org/packages/0a/43/8e55ae7538ba5f28ccb3c845c6dd4549cf7016d5992e5326512519107cdd/yarl-1.24.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d46b86567dd4e248c6c159fcbcdcce01e0a5c8a7cd2334a0fff759d0fa075b16", size = 110574, upload-time = "2026-07-20T02:06:13.129Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ba/a889ec8765cedcf2ac44dcb02d6a21e4861399b243b263c5f2dde27ee740/yarl-1.24.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f72c74aa99359e27a2ee8d6613fefa28b5f76a983c083074dfc2aaa4ab46213", size = 109914, upload-time = "2026-07-20T02:06:15.243Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c3/e45f821af67b791c2dbbe4a9f4137a1d33f8d386654a05a0c3f47bdfa25d/yarl-1.24.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3f45789ce415a7ec0820dc4f82925f9b5f7732070be1dec1f5f23ec381435a24", size = 107712, upload-time = "2026-07-20T02:06:17.443Z" }, + { url = "https://files.pythonhosted.org/packages/02/00/2ab0f42c9857fcb490bfaa6647b14540b53d241ab209f23220b958cc5832/yarl-1.24.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6e73e7fe93f17a7b191f52ec9da9dd8c06a8fe735a1ecbd13b97d1c723bff385", size = 104251, upload-time = "2026-07-20T02:06:19.259Z" }, + { url = "https://files.pythonhosted.org/packages/7a/70/709d9a286e98af2c7fd8e4e6cada658b5c0e30d87dd7e2a63c2fb5767217/yarl-1.24.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4a36f9becdd4c5c52a20c3e9484128b070b1dcfc8944c006f3a528295a359a9c", size = 115319, upload-time = "2026-07-20T02:06:21.207Z" }, + { url = "https://files.pythonhosted.org/packages/5c/6c/3eaa515142991fe84cfc483ff986492211f1978f90161ccefdbec919d09b/yarl-1.24.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:7bcbe0fcf850eae67b6b01749815a4f7161c560a844c769ad7b48fcd99f791c4", size = 109163, upload-time = "2026-07-20T02:06:23.006Z" }, + { url = "https://files.pythonhosted.org/packages/bb/64/711dafce66c323a3144d470547a71c5384c57623308ac8bb5e4b903ac148/yarl-1.24.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:24e861e9630e0daddcb9191fb187f60f034e17a4426f8101279f0c475cd74144", size = 115435, upload-time = "2026-07-20T02:06:24.923Z" }, + { url = "https://files.pythonhosted.org/packages/cf/f3/9b9d0e6d84bea851eb1ba99e4bdc755b86fd813e49ec86dfe42f26befdef/yarl-1.24.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9335a099ad87287c37fe5d1a982ff392fa5efe5d14b40a730b1ec1d6a41382b4", size = 110691, upload-time = "2026-07-20T02:06:26.973Z" }, + { url = "https://files.pythonhosted.org/packages/86/e4/62a06b7e87c4246ac76b7c2da136f972eb4a3a1fc94abb07e7022d6fdb0a/yarl-1.24.5-cp313-cp313-win_amd64.whl", hash = "sha256:2dbe06fc16bc91502bca713704022182e5729861ae00277c3a23354b40929740", size = 97454, upload-time = "2026-07-20T02:06:29.163Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/5fc8025b318ab10db413b61056bd0d95c557a70e8df4210c7511f866329c/yarl-1.24.5-cp313-cp313-win_arm64.whl", hash = "sha256:6b8536851f9f65e7f00c7a1d49ba7f2be0ffe2c11555367fc9f50d9f842410a1", size = 92813, upload-time = "2026-07-20T02:06:31.113Z" }, + { url = "https://files.pythonhosted.org/packages/a9/08/5f3085fef9564217074db9dd8573de1795bc82cde61a7ad10b6a7234a569/yarl-1.24.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:2729fcfc4f6a596fb0c50f32090400aa9367774ac296a00387e65098c0befa76", size = 135680, upload-time = "2026-07-20T02:06:33.273Z" }, + { url = "https://files.pythonhosted.org/packages/98/35/ba9436e579bd48a8801f2021d842d9ab4994c26e4c7dd3a4c1f1bcb57a9e/yarl-1.24.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ff330d3c30db4eb6b01d79e29d2d0b407a7ecad39cfd9ec993ece57396a2ec0d", size = 97395, upload-time = "2026-07-20T02:06:35.259Z" }, + { url = "https://files.pythonhosted.org/packages/18/a9/a07f76f3c44e02b25cc743af5ef93eef27f7013eadca770451b6a6ccb5db/yarl-1.24.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e42d75862735da90e7fc5a7b23db0c976f737113a54b3c9777a9b665e9cbff75", size = 97223, upload-time = "2026-07-20T02:06:37.216Z" }, + { url = "https://files.pythonhosted.org/packages/77/f7/a9a1d6fa7dd9e388f95b30f6ad3ec4e285f6c8f61f44ce16070c3fcfe414/yarl-1.24.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3732e66413163e72508da9eff9ce9d2846fde51fae45d3605393d3e6cd303e9", size = 108777, upload-time = "2026-07-20T02:06:39.292Z" }, + { url = "https://files.pythonhosted.org/packages/2f/44/e0b86c302471fabd6f02808ecf2ac52b8412b624787849d4bf2cdb466f6f/yarl-1.24.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b8ee53be440a0cffc991a27be3057e0530122548dbe7c0892df08822fce5ede", size = 103119, upload-time = "2026-07-20T02:06:41.456Z" }, + { url = "https://files.pythonhosted.org/packages/d1/16/9c16d180bf8faaf223225eb50e1245870ff1ae0e302a27153988e65c51fd/yarl-1.24.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:af3aefa655adb5869491fa907e652290386800ae99cc50095cba71e2c6aefdca", size = 116471, upload-time = "2026-07-20T02:06:43.696Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8d/b219b9df28a02ce95cfbdd41d2f7caa5669d0ff979c1c9975697145e33c5/yarl-1.24.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2120b96872df4a117cde97d270bac96aea7cc52205d305cf4611df694a487027", size = 115974, upload-time = "2026-07-20T02:06:45.874Z" }, + { url = "https://files.pythonhosted.org/packages/9b/e8/f20557aca240d88e69850ad1ee91756821d094bb1310565c04d25c6682a2/yarl-1.24.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:66410eb6345d467151934b49bfa70fb32f5b35a6140baa40ad97d6436abea2e9", size = 110830, upload-time = "2026-07-20T02:06:47.852Z" }, + { url = "https://files.pythonhosted.org/packages/db/18/199b85109a53eeca64ee19c9cca228287e8e4ab0cc1a09b28f530e65cce0/yarl-1.24.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4af7b7e1be0a69bee8210735fe6dcfc38879adfac6d62e789d53ba432d1ffa41", size = 110054, upload-time = "2026-07-20T02:06:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2f/ed28147f8cd7f48c49367c90713b30a555284b6105a6a56f3a05568da795/yarl-1.24.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa139875ff98ab97da323cfadfaff08900d1ad42f1b5087b0b812a55c5a06373", size = 108312, upload-time = "2026-07-20T02:06:51.835Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c5/55e16ae0a5c227cea8df1c6871ba57d614a34243146c05729caf2a1bd9c5/yarl-1.24.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:0055afc45e864b92729ac7600e2d102c17bef060647e74bca75fa84d66b9ff36", size = 103662, upload-time = "2026-07-20T02:06:54.061Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ea/dbd7c2caec459c9a426f18b02688ecbfb58620d0f6a3422d24769fbaf8ab/yarl-1.24.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f0e466ed7511fe9d459a819edbc6c2585c0b6eabde9fa8a8947552468a7a6ef0", size = 116090, upload-time = "2026-07-20T02:06:56.015Z" }, + { url = "https://files.pythonhosted.org/packages/06/84/39ce4ce3059e07fece5fbdbee8c4053406af9aca911ce9fa5f8548aab6af/yarl-1.24.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f141474e85b7e54998ec5180530a7cda99ab29e282fa50e0756d89981a9b43c5", size = 109523, upload-time = "2026-07-20T02:06:57.926Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8b/71ff44137b405c64a7788075669c24010019f57a7464b78c3a6cbee539d9/yarl-1.24.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:e2935f8c39e3b03e83519292d78f075189978f3f4adc15a78144c7c8e2a1cba5", size = 116084, upload-time = "2026-07-20T02:06:59.868Z" }, + { url = "https://files.pythonhosted.org/packages/62/c0/423078fdd4042e1862c11f0ffd977a0ffa393783c12bee94685923bc189e/yarl-1.24.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9d1216a7f6f77836617dba35687c5b78a4170afc3c3f18fc788f785ba26565c4", size = 111006, upload-time = "2026-07-20T02:07:01.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/52/6daa2ee9d95e5c98b8128f8df91eb692eb423ab274b8cf08db52152fad26/yarl-1.24.5-cp314-cp314-win_amd64.whl", hash = "sha256:5ba4f78df2bcc19f764a4b26a8a4f5049c110090ad5825993aacb052bf8003ad", size = 99215, upload-time = "2026-07-20T02:07:03.852Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0e/464a847d7359e0da75dd9fc5c1d1aa35d0159ea31e5f8e66a3c1c29ff3d0/yarl-1.24.5-cp314-cp314-win_arm64.whl", hash = "sha256:9e4e16c73d717c5cf27626c524d0a2e261ad20e46932b2670f64ad5dde23e26f", size = 94566, upload-time = "2026-07-20T02:07:06.074Z" }, + { url = "https://files.pythonhosted.org/packages/e2/55/e03acc4446772660bc335e86e41ef31e4d0d838fd641531a11a5ee33b493/yarl-1.24.5-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e1ae548a9d901adca07899a4147a7c826bbcc06239d3ce9a59f57886a28a4c88", size = 142533, upload-time = "2026-07-20T02:07:08.284Z" }, + { url = "https://files.pythonhosted.org/packages/ae/71/4acd3a1fc7cf14345cdb302665ecd2097f62c365b4f14ca17d4f37775cf9/yarl-1.24.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ff405d91509d88e8d44129cd87b18d70acd1f0c1aeabd7bc3c46792b1fe2acba", size = 100776, upload-time = "2026-07-20T02:07:10.197Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/cfb76b7fe99686db264bff829779a539d923e7564ffd7ef18da6c54c3774/yarl-1.24.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:47e98aab9d8d82ff682e7b0b5dded33bf138a32b817fcf7fa3b27b2d7c412928", size = 100913, upload-time = "2026-07-20T02:07:12.357Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3f/7116e782992abbd4fb6948488aec72078895e929a23078290739e8396fce/yarl-1.24.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0a658a6d3fafee5c6f63c58f3e785c8c43c93fbc02bf9f2b6663f8185e0971f", size = 106507, upload-time = "2026-07-20T02:07:14.173Z" }, + { url = "https://files.pythonhosted.org/packages/33/90/d4d2d73ee78229cc889872eb8e085d8f5c6f51abdb178409fd9b23cf74fd/yarl-1.24.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4377407001ca3c057773f44d8ddd6358fa5f691407c1ba92210bd3cf8d9e4c95", size = 99219, upload-time = "2026-07-20T02:07:16.019Z" }, + { url = "https://files.pythonhosted.org/packages/3e/fa/a6df1a9bccd644eec00abee0dff4277416222cec435330fd1f2858523ec1/yarl-1.24.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7c0494a31a1ac5461a226e7947a9c9b78c44e1dc7185164fa7e9651557a5d9bc", size = 111804, upload-time = "2026-07-20T02:07:18.141Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9e/7b2a1f4bcc20e9447156dd2b1c4d01f70d9df0759025ee7d09a84ffae134/yarl-1.24.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a7cff474ab7cd149765bb784cf6d78b32e18e20473fb7bda860bce98ab58e9da", size = 110943, upload-time = "2026-07-20T02:07:20.06Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/22c92affb0f9b623ca753d27d968b5625b868f12c6378d049d55ae247643/yarl-1.24.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbb833ccacdb5519eff9b8b71ee618cc2801c878e77e288775d77c3a2ced858a", size = 108251, upload-time = "2026-07-20T02:07:22.217Z" }, + { url = "https://files.pythonhosted.org/packages/45/44/5769b96298c1e195fb412997b6090af2a84105cf59c17613558a2d011d1f/yarl-1.24.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:82f75e05912e84b7a0fe57075d9c59de3cb352b928330f2eb69b2e1f54c3e1f0", size = 106025, upload-time = "2026-07-20T02:07:24.083Z" }, + { url = "https://files.pythonhosted.org/packages/4c/40/009e8e791fd9762c0e1567e69248acb4f49064597e1680874c16dd8bb798/yarl-1.24.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:16a2f5010280020e90f5330257e6944bc33e73593b136cc5a241e6c1dc292498", size = 106573, upload-time = "2026-07-20T02:07:26.248Z" }, + { url = "https://files.pythonhosted.org/packages/20/c6/b7480578f8a0a80946f36ad6df547ecec704f9ba69d2de60f8aa6f1c1cbf/yarl-1.24.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ffcd54362564dc1a30fb74d8b8a6e5a6b11ebd5e27266adc3b7427a21a6c9104", size = 100751, upload-time = "2026-07-20T02:07:28.098Z" }, + { url = "https://files.pythonhosted.org/packages/d4/27/4476f3360b91a48c5cf125e91f59a3bd35299d84a431a258d57f5977bb11/yarl-1.24.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0465ec8cedc2349b97a6b595ace64084a50c6e839eca40aa0626f38b8350e331", size = 111643, upload-time = "2026-07-20T02:07:30.88Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/5cdd3e5ee944e8af31e52f6cd3d3af5fd7b937e036ccbbba2c9ffebede95/yarl-1.24.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4db9aecb141cb7a5447171b57aa1ed3a8fee06af40b992ffc31206c0b0121550", size = 106312, upload-time = "2026-07-20T02:07:33.06Z" }, + { url = "https://files.pythonhosted.org/packages/18/86/f406b0c2a6f99575de2da671ef47aa06f89a5be83a27a46971c3b86cecdb/yarl-1.24.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f540c013589084679a6c7fac07096b10159737918174f5dfc5e11bf5bca4dfe6", size = 110379, upload-time = "2026-07-20T02:07:35.155Z" }, + { url = "https://files.pythonhosted.org/packages/f0/6c/9f3adfbd3b30b4fa0f7ccb3a83eba2c1152d3fff554d535e640ba0f7ba2b/yarl-1.24.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a61834fb15d81322d872eaafd333838ae7c9cea84067f232656f75965933d047", size = 108497, upload-time = "2026-07-20T02:07:37.35Z" }, + { url = "https://files.pythonhosted.org/packages/dd/37/91eb2e5ca883a529c1b390348a74cd9fc0512171727f547ce70bfe02be5c/yarl-1.24.5-cp314-cp314t-win_amd64.whl", hash = "sha256:5c88e5815a49d289e599f3513aa7fde0bc2092ff188f99c940f007f90f53d104", size = 102450, upload-time = "2026-07-20T02:07:39.578Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f4/ed5c402ac8fde4403ed3366c2716bfddc8a6677ebd59f3d62772cc7fe468/yarl-1.24.5-cp314-cp314t-win_arm64.whl", hash = "sha256:cf139c02f5f23ef6532040a30ff662c00a318c952334f211046b8e60b7f17688", size = 97222, upload-time = "2026-07-20T02:07:41.55Z" }, + { url = "https://files.pythonhosted.org/packages/61/02/962c1cbfc401a30c1d034dc67ff395f64b52302c6d62de556c1fca99acc0/yarl-1.24.5-py3-none-any.whl", hash = "sha256:a33700d13d9b7d84fd10947b09ff69fb9a792e519c8cb9764a3ca70baa6c23a7", size = 58612, upload-time = "2026-07-20T02:07:43.461Z" }, ] [[package]]