From 7281ac957b62bd2a7d0f28e99af681c052ec7c49 Mon Sep 17 00:00:00 2001 From: Rex P Date: Wed, 28 Aug 2024 11:33:44 +1000 Subject: [PATCH 01/13] Fix API typing and add generated stubs --- gcp/api/osv_service_v1_pb2.py | 14 +- gcp/api/osv_service_v1_pb2.pyi | 368 ++++++++++++++++++++ gcp/api/osv_service_v1_pb2_grpc.py | 98 +----- gcp/api/poetry.lock | 60 +++- gcp/api/pyproject.toml | 1 + gcp/api/v1/README.md | 1 + gcp/api/v1/api_descriptor.pb | Bin 112887 -> 112909 bytes osv/build_protos.sh | 2 +- osv/models.py | 4 +- osv/vulnerability_pb2.py | 2 +- osv/vulnerability_pb2.pyi | 520 +++++++++++++++++++++++++++++ poetry.lock | 158 +++++---- pyproject.toml | 1 + 13 files changed, 1057 insertions(+), 172 deletions(-) create mode 100644 gcp/api/osv_service_v1_pb2.pyi create mode 100644 osv/vulnerability_pb2.pyi diff --git a/gcp/api/osv_service_v1_pb2.py b/gcp/api/osv_service_v1_pb2.py index b8d6466bc11..6dc55ecc8b8 100644 --- a/gcp/api/osv_service_v1_pb2.py +++ b/gcp/api/osv_service_v1_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: osv_service_v1.proto -# Protobuf Python Version: 5.26.1 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -21,15 +21,15 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'osv_service_v1_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - DESCRIPTOR._loaded_options = None - _globals['_OSV'].methods_by_name['GetVulnById']._loaded_options = None +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_OSV'].methods_by_name['GetVulnById']._options = None _globals['_OSV'].methods_by_name['GetVulnById']._serialized_options = b'\202\323\344\223\002\020\022\016/v1/vulns/{id}' - _globals['_OSV'].methods_by_name['QueryAffected']._loaded_options = None + _globals['_OSV'].methods_by_name['QueryAffected']._options = None _globals['_OSV'].methods_by_name['QueryAffected']._serialized_options = b'\202\323\344\223\002\022\"\t/v1/query:\005query' - _globals['_OSV'].methods_by_name['QueryAffectedBatch']._loaded_options = None + _globals['_OSV'].methods_by_name['QueryAffectedBatch']._options = None _globals['_OSV'].methods_by_name['QueryAffectedBatch']._serialized_options = b'\202\323\344\223\002\027\"\016/v1/querybatch:\005query' - _globals['_OSV'].methods_by_name['DetermineVersion']._loaded_options = None + _globals['_OSV'].methods_by_name['DetermineVersion']._options = None _globals['_OSV'].methods_by_name['DetermineVersion']._serialized_options = b'\202\323\344\223\002)\" /v1experimental/determineversion:\005query' _globals['_VULNERABILITYLIST']._serialized_start=87 _globals['_VULNERABILITYLIST']._serialized_end=166 diff --git a/gcp/api/osv_service_v1_pb2.pyi b/gcp/api/osv_service_v1_pb2.pyi new file mode 100644 index 00000000000..fcaa5899dc5 --- /dev/null +++ b/gcp/api/osv_service_v1_pb2.pyi @@ -0,0 +1,368 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2021 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import osv.vulnerability_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class VulnerabilityList(google.protobuf.message.Message): + """A list of Vulnerability entries.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VULNS_FIELD_NUMBER: builtins.int + NEXT_PAGE_TOKEN_FIELD_NUMBER: builtins.int + next_page_token: builtins.str + @property + def vulns(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[osv.vulnerability_pb2.Vulnerability]: ... + def __init__( + self, + *, + vulns: collections.abc.Iterable[osv.vulnerability_pb2.Vulnerability] | None = ..., + next_page_token: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["next_page_token", b"next_page_token", "vulns", b"vulns"]) -> None: ... + +global___VulnerabilityList = VulnerabilityList + +@typing.final +class BatchVulnerabilityList(google.protobuf.message.Message): + """Batched lists of Vulnerability entries.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESULTS_FIELD_NUMBER: builtins.int + @property + def results(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___VulnerabilityList]: ... + def __init__( + self, + *, + results: collections.abc.Iterable[global___VulnerabilityList] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["results", b"results"]) -> None: ... + +global___BatchVulnerabilityList = BatchVulnerabilityList + +@typing.final +class Query(google.protobuf.message.Message): + """Query format.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + COMMIT_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + PACKAGE_FIELD_NUMBER: builtins.int + PAGE_TOKEN_FIELD_NUMBER: builtins.int + commit: builtins.str + """The commit hash to query for. If specified, `version` should not be set.""" + version: builtins.str + """The version string to query for. A fuzzy match is done against upstream + versions. If specified, `commit` should not be set. + """ + page_token: builtins.str + @property + def package(self) -> osv.vulnerability_pb2.Package: + """The package to query against. When a `commit` hash is given, this is + optional. + """ + + def __init__( + self, + *, + commit: builtins.str = ..., + version: builtins.str = ..., + package: osv.vulnerability_pb2.Package | None = ..., + page_token: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["commit", b"commit", "package", b"package", "param", b"param", "version", b"version"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["commit", b"commit", "package", b"package", "page_token", b"page_token", "param", b"param", "version", b"version"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["param", b"param"]) -> typing.Literal["commit", "version"] | None: ... + +global___Query = Query + +@typing.final +class BatchQuery(google.protobuf.message.Message): + """Batch query format.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + QUERIES_FIELD_NUMBER: builtins.int + @property + def queries(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Query]: + """The queries that form this batch query.""" + + def __init__( + self, + *, + queries: collections.abc.Iterable[global___Query] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["queries", b"queries"]) -> None: ... + +global___BatchQuery = BatchQuery + +@typing.final +class GetVulnByIdParameters(google.protobuf.message.Message): + """Parameters for GetBugById.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + id: builtins.str + def __init__( + self, + *, + id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["id", b"id"]) -> None: ... + +global___GetVulnByIdParameters = GetVulnByIdParameters + +@typing.final +class QueryAffectedParameters(google.protobuf.message.Message): + """Parameters for QueryAffected.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + QUERY_FIELD_NUMBER: builtins.int + @property + def query(self) -> global___Query: ... + def __init__( + self, + *, + query: global___Query | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["query", b"query"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["query", b"query"]) -> None: ... + +global___QueryAffectedParameters = QueryAffectedParameters + +@typing.final +class QueryAffectedBatchParameters(google.protobuf.message.Message): + """Parameters for QueryAffectedBatch.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + QUERY_FIELD_NUMBER: builtins.int + @property + def query(self) -> global___BatchQuery: ... + def __init__( + self, + *, + query: global___BatchQuery | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["query", b"query"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["query", b"query"]) -> None: ... + +global___QueryAffectedBatchParameters = QueryAffectedBatchParameters + +@typing.final +class DetermineVersionParameters(google.protobuf.message.Message): + """Parameters for DetermineVersion.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + QUERY_FIELD_NUMBER: builtins.int + @property + def query(self) -> global___VersionQuery: ... + def __init__( + self, + *, + query: global___VersionQuery | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["query", b"query"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["query", b"query"]) -> None: ... + +global___DetermineVersionParameters = DetermineVersionParameters + +@typing.final +class VersionQuery(google.protobuf.message.Message): + """The version query.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + FILE_HASHES_FIELD_NUMBER: builtins.int + name: builtins.str + """The name of the dependency. Can be empty.""" + @property + def file_hashes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FileHash]: ... + def __init__( + self, + *, + name: builtins.str = ..., + file_hashes: collections.abc.Iterable[global___FileHash] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["file_hashes", b"file_hashes", "name", b"name"]) -> None: ... + +global___VersionQuery = VersionQuery + +@typing.final +class FileHash(google.protobuf.message.Message): + """Information about the files in the repository + to identify the version. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _HashType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _HashTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[FileHash._HashType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + MD5: FileHash._HashType.ValueType # 0 + + class HashType(_HashType, metaclass=_HashTypeEnumTypeWrapper): ... + MD5: FileHash.HashType.ValueType # 0 + + FILE_PATH_FIELD_NUMBER: builtins.int + HASH_TYPE_FIELD_NUMBER: builtins.int + HASH_FIELD_NUMBER: builtins.int + file_path: builtins.str + """The file path inside the repository, relative to the repository root.""" + hash_type: global___FileHash.HashType.ValueType + hash: builtins.bytes + def __init__( + self, + *, + file_path: builtins.str = ..., + hash_type: global___FileHash.HashType.ValueType = ..., + hash: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["file_path", b"file_path", "hash", b"hash", "hash_type", b"hash_type"]) -> None: ... + +global___FileHash = FileHash + +@typing.final +class VersionMatchList(google.protobuf.message.Message): + """Result of DetmineVersion.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MATCHES_FIELD_NUMBER: builtins.int + @property + def matches(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___VersionMatch]: ... + def __init__( + self, + *, + matches: collections.abc.Iterable[global___VersionMatch] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["matches", b"matches"]) -> None: ... + +global___VersionMatchList = VersionMatchList + +@typing.final +class VersionMatch(google.protobuf.message.Message): + """Match information for the provided VersionQuery.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCORE_FIELD_NUMBER: builtins.int + REPO_INFO_FIELD_NUMBER: builtins.int + OSV_IDENTIFIER_FIELD_NUMBER: builtins.int + CPE23_FIELD_NUMBER: builtins.int + MINIMUM_FILE_MATCHES_FIELD_NUMBER: builtins.int + ESTIMATED_DIFF_FILES_FIELD_NUMBER: builtins.int + score: builtins.float + """Score in the interval (0.0, 1.0] with 1.0 being a perfect match.""" + cpe23: builtins.str + """CPE 2.3.""" + minimum_file_matches: builtins.int + """Definite number of files that have matched.""" + estimated_diff_files: builtins.int + """Estimated number of files that are different.""" + @property + def repo_info(self) -> global___VersionRepositoryInformation: + """Information about the upstream repository.""" + + @property + def osv_identifier(self) -> osv.vulnerability_pb2.Package: + """The OSV identifier.""" + + def __init__( + self, + *, + score: builtins.float = ..., + repo_info: global___VersionRepositoryInformation | None = ..., + osv_identifier: osv.vulnerability_pb2.Package | None = ..., + cpe23: builtins.str = ..., + minimum_file_matches: builtins.int = ..., + estimated_diff_files: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["osv_identifier", b"osv_identifier", "repo_info", b"repo_info"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["cpe23", b"cpe23", "estimated_diff_files", b"estimated_diff_files", "minimum_file_matches", b"minimum_file_matches", "osv_identifier", b"osv_identifier", "repo_info", b"repo_info", "score", b"score"]) -> None: ... + +global___VersionMatch = VersionMatch + +@typing.final +class VersionRepositoryInformation(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _RepoType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RepoTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[VersionRepositoryInformation._RepoType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSPECIFIED: VersionRepositoryInformation._RepoType.ValueType # 0 + GIT: VersionRepositoryInformation._RepoType.ValueType # 1 + + class RepoType(_RepoType, metaclass=_RepoTypeEnumTypeWrapper): ... + UNSPECIFIED: VersionRepositoryInformation.RepoType.ValueType # 0 + GIT: VersionRepositoryInformation.RepoType.ValueType # 1 + + TYPE_FIELD_NUMBER: builtins.int + ADDRESS_FIELD_NUMBER: builtins.int + TAG_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + COMMIT_FIELD_NUMBER: builtins.int + type: global___VersionRepositoryInformation.RepoType.ValueType + address: builtins.str + """Source address of the repository.""" + tag: builtins.str + """Commit tag""" + version: builtins.str + """Parsed version from commit tag""" + commit: builtins.str + """Commit hash hex.""" + def __init__( + self, + *, + type: global___VersionRepositoryInformation.RepoType.ValueType = ..., + address: builtins.str = ..., + tag: builtins.str = ..., + version: builtins.str = ..., + commit: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "commit", b"commit", "tag", b"tag", "type", b"type", "version", b"version"]) -> None: ... + +global___VersionRepositoryInformation = VersionRepositoryInformation diff --git a/gcp/api/osv_service_v1_pb2_grpc.py b/gcp/api/osv_service_v1_pb2_grpc.py index 6df3c17b669..d2d89a68ab3 100644 --- a/gcp/api/osv_service_v1_pb2_grpc.py +++ b/gcp/api/osv_service_v1_pb2_grpc.py @@ -1,35 +1,10 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc -import warnings from osv import vulnerability_pb2 as osv_dot_vulnerability__pb2 import osv_service_v1_pb2 as osv__service__v1__pb2 -GRPC_GENERATED_VERSION = '1.64.1' -GRPC_VERSION = grpc.__version__ -EXPECTED_ERROR_RELEASE = '1.65.0' -SCHEDULED_RELEASE_DATE = 'June 25, 2024' -_version_not_supported = False - -try: - from grpc._utilities import first_version_is_lower - _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) -except ImportError: - _version_not_supported = True - -if _version_not_supported: - warnings.warn( - f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in osv_service_v1_pb2_grpc.py depends on' - + f' grpcio>={GRPC_GENERATED_VERSION}.' - + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' - + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' - + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' - + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', - RuntimeWarning - ) - class OSVStub(object): """Open source vulnerability database. @@ -45,22 +20,22 @@ def __init__(self, channel): '/osv.v1.OSV/GetVulnById', request_serializer=osv__service__v1__pb2.GetVulnByIdParameters.SerializeToString, response_deserializer=osv_dot_vulnerability__pb2.Vulnerability.FromString, - _registered_method=True) + ) self.QueryAffected = channel.unary_unary( '/osv.v1.OSV/QueryAffected', request_serializer=osv__service__v1__pb2.QueryAffectedParameters.SerializeToString, response_deserializer=osv__service__v1__pb2.VulnerabilityList.FromString, - _registered_method=True) + ) self.QueryAffectedBatch = channel.unary_unary( '/osv.v1.OSV/QueryAffectedBatch', request_serializer=osv__service__v1__pb2.QueryAffectedBatchParameters.SerializeToString, response_deserializer=osv__service__v1__pb2.BatchVulnerabilityList.FromString, - _registered_method=True) + ) self.DetermineVersion = channel.unary_unary( '/osv.v1.OSV/DetermineVersion', request_serializer=osv__service__v1__pb2.DetermineVersionParameters.SerializeToString, response_deserializer=osv__service__v1__pb2.VersionMatchList.FromString, - _registered_method=True) + ) class OSVServicer(object): @@ -125,7 +100,6 @@ def add_OSVServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'osv.v1.OSV', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) - server.add_registered_method_handlers('osv.v1.OSV', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -144,21 +118,11 @@ def GetVulnById(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/osv.v1.OSV/GetVulnById', + return grpc.experimental.unary_unary(request, target, '/osv.v1.OSV/GetVulnById', osv__service__v1__pb2.GetVulnByIdParameters.SerializeToString, osv_dot_vulnerability__pb2.Vulnerability.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def QueryAffected(request, @@ -171,21 +135,11 @@ def QueryAffected(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/osv.v1.OSV/QueryAffected', + return grpc.experimental.unary_unary(request, target, '/osv.v1.OSV/QueryAffected', osv__service__v1__pb2.QueryAffectedParameters.SerializeToString, osv__service__v1__pb2.VulnerabilityList.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def QueryAffectedBatch(request, @@ -198,21 +152,11 @@ def QueryAffectedBatch(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/osv.v1.OSV/QueryAffectedBatch', + return grpc.experimental.unary_unary(request, target, '/osv.v1.OSV/QueryAffectedBatch', osv__service__v1__pb2.QueryAffectedBatchParameters.SerializeToString, osv__service__v1__pb2.BatchVulnerabilityList.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod def DetermineVersion(request, @@ -225,18 +169,8 @@ def DetermineVersion(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary( - request, - target, - '/osv.v1.OSV/DetermineVersion', + return grpc.experimental.unary_unary(request, target, '/osv.v1.OSV/DetermineVersion', osv__service__v1__pb2.DetermineVersionParameters.SerializeToString, osv__service__v1__pb2.VersionMatchList.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - _registered_method=True) + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/gcp/api/poetry.lock b/gcp/api/poetry.lock index f0426ac345c..d24e0e6b0ca 100644 --- a/gcp/api/poetry.lock +++ b/gcp/api/poetry.lock @@ -567,13 +567,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.63.2" +version = "1.64.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.63.2.tar.gz", hash = "sha256:27c5abdffc4911f28101e635de1533fb4cfd2c37fbaa9174587c799fac90aa87"}, - {file = "googleapis_common_protos-1.63.2-py2.py3-none-any.whl", hash = "sha256:27a2499c7e8aff199665b22741997e485eccc8645aa9176c7c988e6fae507945"}, + {file = "googleapis_common_protos-1.64.0-py2.py3-none-any.whl", hash = "sha256:d1bfc569f70ed2e96ccf06ead265c2cf42b5abfc817cda392e3835f3b67b5c59"}, + {file = "googleapis_common_protos-1.64.0.tar.gz", hash = "sha256:7d77ca6b7c0c38eb6b1bab3b4c9973acf57ce4f2a6d3a4136acba10bcbfb3025"}, ] [package.dependencies] @@ -767,13 +767,13 @@ setuptools = "*" [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -855,6 +855,21 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mypy-protobuf" +version = "3.6.0" +description = "Generate mypy stub files from protobuf specs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c"}, + {file = "mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c"}, +] + +[package.dependencies] +protobuf = ">=4.25.3" +types-protobuf = ">=4.24" + [[package]] name = "opentelemetry-api" version = "1.26.0" @@ -1097,13 +1112,13 @@ files = [ [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -1411,6 +1426,17 @@ files = [ {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] +[[package]] +name = "types-protobuf" +version = "5.27.0.20240626" +description = "Typing stubs for protobuf" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-protobuf-5.27.0.20240626.tar.gz", hash = "sha256:683ba14043bade6785e3f937a7498f243b37881a91ac8d81b9202ecf8b191e9c"}, + {file = "types_protobuf-5.27.0.20240626-py3-none-any.whl", hash = "sha256:688e8f7e8d9295db26bc560df01fb731b27a25b77cbe4c1ce945647f7024f5c1"}, +] + [[package]] name = "urllib3" version = "2.2.2" @@ -1525,20 +1551,24 @@ tomli = ">=2.0.1" [[package]] name = "zipp" -version = "3.20.0" +version = "3.20.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, - {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, + {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, + {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "2dea5fe7400aa9db9feb6f339a4087294c0decbeaccd846149a85e77c08ba012" +content-hash = "74a0163916a08c628d2235cade3093cc2e28e0383029c1ce87f4267a7e09736c" diff --git a/gcp/api/pyproject.toml b/gcp/api/pyproject.toml index b7ebcda05f4..1cd031714e1 100644 --- a/gcp/api/pyproject.toml +++ b/gcp/api/pyproject.toml @@ -18,6 +18,7 @@ osv = { path = "../../", develop = true } [tool.poetry.dev-dependencies] grpcio-tools = "*" +mypy-protobuf = "^3.6.0" yapf = "*" pylint = "*" diff --git a/gcp/api/v1/README.md b/gcp/api/v1/README.md index e5833e94b19..4a7394751be 100644 --- a/gcp/api/v1/README.md +++ b/gcp/api/v1/README.md @@ -20,6 +20,7 @@ python3 -m grpc_tools.protoc \ --go_out=../../../tools/indexer-api-caller/ \ --go_opt=Mosv/vulnerability.proto=github.com/google/osv/proto \ --go_opt=Mosv_service_v1.proto=github.com/google/osv/api/proto \ + --mypy_out=../ \ osv_service_v1.proto ``` diff --git a/gcp/api/v1/api_descriptor.pb b/gcp/api/v1/api_descriptor.pb index 8a0c1e373a8f5466c98459e7b4d3cfe4197a1641..1e13230c65328b29a01d635556e43a5147febfb6 100644 GIT binary patch delta 20519 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 O$6FfzvVvXR{r>?Hp!W~} delta 20564 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 L*Zw?@HEZ*~egw*3 diff --git a/osv/build_protos.sh b/osv/build_protos.sh index 84ef28f14d8..8343d03b07c 100755 --- a/osv/build_protos.sh +++ b/osv/build_protos.sh @@ -15,4 +15,4 @@ cd ../ -python -m grpc_tools.protoc --python_out=. --proto_path=. osv/vulnerability.proto +python -m grpc_tools.protoc --python_out=. --mypy_out=. --proto_path=. osv/vulnerability.proto diff --git a/osv/models.py b/osv/models.py index 400b31ee46c..d3625e9b607 100644 --- a/osv/models.py +++ b/osv/models.py @@ -20,7 +20,7 @@ import os from urllib.parse import urlparse -from typing import List +from typing import List, Self from google.cloud import ndb from google.protobuf import json_format @@ -335,7 +335,7 @@ def repo_url(self): return None @classmethod - def get_by_id(cls, vuln_id, *args, **kwargs): + def get_by_id(cls, vuln_id, *args, **kwargs) -> Self: """Overridden get_by_id to handle OSV allocated IDs.""" result = cls.query(cls.db_id == vuln_id).get() if result: diff --git a/osv/vulnerability_pb2.py b/osv/vulnerability_pb2.py index cfd062cc9ac..9916ad35fe8 100644 --- a/osv/vulnerability_pb2.py +++ b/osv/vulnerability_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: osv/vulnerability.proto -# Protobuf Python Version: 4.25.0 +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool diff --git a/osv/vulnerability_pb2.pyi b/osv/vulnerability_pb2.pyi new file mode 100644 index 00000000000..e5faa50861a --- /dev/null +++ b/osv/vulnerability_pb2.pyi @@ -0,0 +1,520 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2021 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import google.protobuf.struct_pb2 +import google.protobuf.timestamp_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class Commit(google.protobuf.message.Message): + """Commit reference. + + In some rare cases, this may refer to a small range of commits rather than an + exact commit (to accomodate for automated systems). In such cases, the + semantics are as follows: + + - If this is referring to a commit which introduces a vulnerability, then + *any* commits in the range is assumed to cause the vulnerability. + + - If this is referring to a commit which fixes a vulnerability, then *all* + commits in the range is assumed to cause the vulnerability. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _RepoType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _RepoTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Commit._RepoType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSPECIFIED: Commit._RepoType.ValueType # 0 + GIT: Commit._RepoType.ValueType # 1 + + class RepoType(_RepoType, metaclass=_RepoTypeEnumTypeWrapper): + """The repository type.""" + + UNSPECIFIED: Commit.RepoType.ValueType # 0 + GIT: Commit.RepoType.ValueType # 1 + + REPO_TYPE_FIELD_NUMBER: builtins.int + REPO_URL_FIELD_NUMBER: builtins.int + COMMIT_FIELD_NUMBER: builtins.int + repo_type: global___Commit.RepoType.ValueType + """Required. The type of the repo.""" + repo_url: builtins.str + """Required. The publicly accessible URL of the repo that can be directly + passed to clone commands. + """ + commit: builtins.str + """Required. The commit identifier (e.g. git SHA). In some cases where the + exact commit fails to be determined by automation, this may be a small + range in the form "A:B" which means the commit range from A (exclusive) to + B (inclusive). + """ + def __init__( + self, + *, + repo_type: global___Commit.RepoType.ValueType = ..., + repo_url: builtins.str = ..., + commit: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["commit", b"commit", "repo_type", b"repo_type", "repo_url", b"repo_url"]) -> None: ... + +global___Commit = Commit + +@typing.final +class Package(google.protobuf.message.Message): + """Package information and version.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + ECOSYSTEM_FIELD_NUMBER: builtins.int + PURL_FIELD_NUMBER: builtins.int + name: builtins.str + """Required. Name of the package. Should match the name used in the package + ecosystem (e.g. the npm package name). For C/C++ projects integrated in + OSS-Fuzz, this is the name used for the integration. + """ + ecosystem: builtins.str + """Required. The ecosystem for this package. + For the complete list of valid ecosystem names, see + . + """ + purl: builtins.str + """Optional. The package URL for this package.""" + def __init__( + self, + *, + name: builtins.str = ..., + ecosystem: builtins.str = ..., + purl: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ecosystem", b"ecosystem", "name", b"name", "purl", b"purl"]) -> None: ... + +global___Package = Package + +@typing.final +class Event(google.protobuf.message.Message): + """Version events.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + INTRODUCED_FIELD_NUMBER: builtins.int + FIXED_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + LAST_AFFECTED_FIELD_NUMBER: builtins.int + introduced: builtins.str + """The earliest version/commit where this vulnerability + was introduced in. + """ + fixed: builtins.str + """The version/commit that this vulnerability was fixed in.""" + limit: builtins.str + """The limit to apply to the range.""" + last_affected: builtins.str + """The last affected version.""" + def __init__( + self, + *, + introduced: builtins.str = ..., + fixed: builtins.str = ..., + limit: builtins.str = ..., + last_affected: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["fixed", b"fixed", "introduced", b"introduced", "last_affected", b"last_affected", "limit", b"limit"]) -> None: ... + +global___Event = Event + +@typing.final +class Range(google.protobuf.message.Message): + """Affected ranges.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Range._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSPECIFIED: Range._Type.ValueType # 0 + GIT: Range._Type.ValueType # 1 + SEMVER: Range._Type.ValueType # 2 + ECOSYSTEM: Range._Type.ValueType # 3 + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): + """Type of the version information.""" + + UNSPECIFIED: Range.Type.ValueType # 0 + GIT: Range.Type.ValueType # 1 + SEMVER: Range.Type.ValueType # 2 + ECOSYSTEM: Range.Type.ValueType # 3 + + TYPE_FIELD_NUMBER: builtins.int + REPO_FIELD_NUMBER: builtins.int + EVENTS_FIELD_NUMBER: builtins.int + type: global___Range.Type.ValueType + """Required. The type of version information.""" + repo: builtins.str + """Required if type is GIT. The publicly accessible URL of the repo that can + be directly passed to clone commands. + """ + @property + def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Event]: + """Required. Version event information.""" + + def __init__( + self, + *, + type: global___Range.Type.ValueType = ..., + repo: builtins.str = ..., + events: collections.abc.Iterable[global___Event] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["events", b"events", "repo", b"repo", "type", b"type"]) -> None: ... + +global___Range = Range + +@typing.final +class Affected(google.protobuf.message.Message): + """Affected versions and commits.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PACKAGE_FIELD_NUMBER: builtins.int + RANGES_FIELD_NUMBER: builtins.int + VERSIONS_FIELD_NUMBER: builtins.int + ECOSYSTEM_SPECIFIC_FIELD_NUMBER: builtins.int + DATABASE_SPECIFIC_FIELD_NUMBER: builtins.int + SEVERITY_FIELD_NUMBER: builtins.int + @property + def package(self) -> global___Package: + """Optional. Package information.""" + + @property + def ranges(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Range]: + """Required. Range information.""" + + @property + def versions(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Optional. List of affected versions.""" + + @property + def ecosystem_specific(self) -> google.protobuf.struct_pb2.Struct: + """Optional. JSON object holding additional information about the + vulnerability as defined by the ecosystem for which the record applies. + """ + + @property + def database_specific(self) -> google.protobuf.struct_pb2.Struct: + """Optional. JSON object holding additional information about the + vulnerability as defined by the database for which the record applies. + """ + + @property + def severity(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Severity]: + """Optional. Severity of the vulnerability for this package.""" + + def __init__( + self, + *, + package: global___Package | None = ..., + ranges: collections.abc.Iterable[global___Range] | None = ..., + versions: collections.abc.Iterable[builtins.str] | None = ..., + ecosystem_specific: google.protobuf.struct_pb2.Struct | None = ..., + database_specific: google.protobuf.struct_pb2.Struct | None = ..., + severity: collections.abc.Iterable[global___Severity] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["database_specific", b"database_specific", "ecosystem_specific", b"ecosystem_specific", "package", b"package"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["database_specific", b"database_specific", "ecosystem_specific", b"ecosystem_specific", "package", b"package", "ranges", b"ranges", "severity", b"severity", "versions", b"versions"]) -> None: ... + +global___Affected = Affected + +@typing.final +class Severity(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Severity._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSPECIFIED: Severity._Type.ValueType # 0 + CVSS_V3: Severity._Type.ValueType # 1 + CVSS_V2: Severity._Type.ValueType # 2 + CVSS_V4: Severity._Type.ValueType # 3 + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): + """Type of the severity.""" + + UNSPECIFIED: Severity.Type.ValueType # 0 + CVSS_V3: Severity.Type.ValueType # 1 + CVSS_V2: Severity.Type.ValueType # 2 + CVSS_V4: Severity.Type.ValueType # 3 + + TYPE_FIELD_NUMBER: builtins.int + SCORE_FIELD_NUMBER: builtins.int + type: global___Severity.Type.ValueType + """The type of this severity entry.""" + score: builtins.str + """The quantitative score.""" + def __init__( + self, + *, + type: global___Severity.Type.ValueType = ..., + score: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["score", b"score", "type", b"type"]) -> None: ... + +global___Severity = Severity + +@typing.final +class Credit(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Credit._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSPECIFIED: Credit._Type.ValueType # 0 + OTHER: Credit._Type.ValueType # 1 + FINDER: Credit._Type.ValueType # 2 + REPORTER: Credit._Type.ValueType # 3 + ANALYST: Credit._Type.ValueType # 4 + COORDINATOR: Credit._Type.ValueType # 5 + REMEDIATION_DEVELOPER: Credit._Type.ValueType # 6 + REMEDIATION_REVIEWER: Credit._Type.ValueType # 7 + REMEDIATION_VERIFIER: Credit._Type.ValueType # 8 + TOOL: Credit._Type.ValueType # 9 + SPONSOR: Credit._Type.ValueType # 10 + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): ... + UNSPECIFIED: Credit.Type.ValueType # 0 + OTHER: Credit.Type.ValueType # 1 + FINDER: Credit.Type.ValueType # 2 + REPORTER: Credit.Type.ValueType # 3 + ANALYST: Credit.Type.ValueType # 4 + COORDINATOR: Credit.Type.ValueType # 5 + REMEDIATION_DEVELOPER: Credit.Type.ValueType # 6 + REMEDIATION_REVIEWER: Credit.Type.ValueType # 7 + REMEDIATION_VERIFIER: Credit.Type.ValueType # 8 + TOOL: Credit.Type.ValueType # 9 + SPONSOR: Credit.Type.ValueType # 10 + + NAME_FIELD_NUMBER: builtins.int + CONTACT_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + name: builtins.str + """The name to give credit to.""" + type: global___Credit.Type.ValueType + """Optional. The type or role of the individual or entity being credited.""" + @property + def contact(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Contact methods (URLs).""" + + def __init__( + self, + *, + name: builtins.str = ..., + contact: collections.abc.Iterable[builtins.str] | None = ..., + type: global___Credit.Type.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["contact", b"contact", "name", b"name", "type", b"type"]) -> None: ... + +global___Credit = Credit + +@typing.final +class Reference(google.protobuf.message.Message): + """Reference URL.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Reference._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + NONE: Reference._Type.ValueType # 0 + """Next ID = 11.""" + ADVISORY: Reference._Type.ValueType # 2 + ARTICLE: Reference._Type.ValueType # 6 + DETECTION: Reference._Type.ValueType # 9 + DISCUSSION: Reference._Type.ValueType # 8 + EVIDENCE: Reference._Type.ValueType # 7 + FIX: Reference._Type.ValueType # 4 + INTRODUCED: Reference._Type.ValueType # 10 + PACKAGE: Reference._Type.ValueType # 5 + REPORT: Reference._Type.ValueType # 3 + WEB: Reference._Type.ValueType # 1 + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): ... + NONE: Reference.Type.ValueType # 0 + """Next ID = 11.""" + ADVISORY: Reference.Type.ValueType # 2 + ARTICLE: Reference.Type.ValueType # 6 + DETECTION: Reference.Type.ValueType # 9 + DISCUSSION: Reference.Type.ValueType # 8 + EVIDENCE: Reference.Type.ValueType # 7 + FIX: Reference.Type.ValueType # 4 + INTRODUCED: Reference.Type.ValueType # 10 + PACKAGE: Reference.Type.ValueType # 5 + REPORT: Reference.Type.ValueType # 3 + WEB: Reference.Type.ValueType # 1 + + TYPE_FIELD_NUMBER: builtins.int + URL_FIELD_NUMBER: builtins.int + type: global___Reference.Type.ValueType + """Required. The type of the reference.""" + url: builtins.str + """Required. The URL.""" + def __init__( + self, + *, + type: global___Reference.Type.ValueType = ..., + url: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["type", b"type", "url", b"url"]) -> None: ... + +global___Reference = Reference + +@typing.final +class Vulnerability(google.protobuf.message.Message): + """A vulnerability entry. + The protobuf representation is *NOT* stable and only used for implementing + the JSON based API. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCHEMA_VERSION_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + PUBLISHED_FIELD_NUMBER: builtins.int + MODIFIED_FIELD_NUMBER: builtins.int + WITHDRAWN_FIELD_NUMBER: builtins.int + ALIASES_FIELD_NUMBER: builtins.int + RELATED_FIELD_NUMBER: builtins.int + SUMMARY_FIELD_NUMBER: builtins.int + DETAILS_FIELD_NUMBER: builtins.int + AFFECTED_FIELD_NUMBER: builtins.int + REFERENCES_FIELD_NUMBER: builtins.int + DATABASE_SPECIFIC_FIELD_NUMBER: builtins.int + SEVERITY_FIELD_NUMBER: builtins.int + CREDITS_FIELD_NUMBER: builtins.int + schema_version: builtins.str + """The OSV schema version.""" + id: builtins.str + """The `id` field is a unique identifier for the vulnerability entry. It is a + string of the format `-`, where `DB` names the database and + `ENTRYID` is in the format used by the database. For example: + “OSV-2020-111”, “CVE-2021-3114”, or “GHSA-vp9c-fpxx-744v”. + """ + summary: builtins.str + """Required. One line human readable summary for the vulnerability. It is + recommended to keep this under 120 characters. + """ + details: builtins.str + """Required. Any additional human readable details for the vulnerability.""" + @property + def published(self) -> google.protobuf.timestamp_pb2.Timestamp: + """The RFC3339 timestamp indicating when this entry was published.""" + + @property + def modified(self) -> google.protobuf.timestamp_pb2.Timestamp: + """The RFC3339 timestamp indicating when this entry was last modified.""" + + @property + def withdrawn(self) -> google.protobuf.timestamp_pb2.Timestamp: + """Optional. The RFC3339 timestamp indicating when this entry is considered to + be withdrawn. + """ + + @property + def aliases(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Optional. IDs for the same vulnerability in other databases.""" + + @property + def related(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Optional. List of IDs of closely related vulnerabilities, such as the same + problem in alternate ecosystems. + """ + + @property + def affected(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Affected]: + """Required. Affected commit ranges and versions.""" + + @property + def references(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Reference]: + """Optional. URLs to more information/advisories (including the + scheme e.g "https://"). + """ + + @property + def database_specific(self) -> google.protobuf.struct_pb2.Struct: + """Optional. JSON object holding additional information about the + vulnerability as defined by the database for which the record applies. + """ + + @property + def severity(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Severity]: + """Optional. Severity of the vulnerability.""" + + @property + def credits(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Credit]: + """Optional. Credits for the vulnerability.""" + + def __init__( + self, + *, + schema_version: builtins.str = ..., + id: builtins.str = ..., + published: google.protobuf.timestamp_pb2.Timestamp | None = ..., + modified: google.protobuf.timestamp_pb2.Timestamp | None = ..., + withdrawn: google.protobuf.timestamp_pb2.Timestamp | None = ..., + aliases: collections.abc.Iterable[builtins.str] | None = ..., + related: collections.abc.Iterable[builtins.str] | None = ..., + summary: builtins.str = ..., + details: builtins.str = ..., + affected: collections.abc.Iterable[global___Affected] | None = ..., + references: collections.abc.Iterable[global___Reference] | None = ..., + database_specific: google.protobuf.struct_pb2.Struct | None = ..., + severity: collections.abc.Iterable[global___Severity] | None = ..., + credits: collections.abc.Iterable[global___Credit] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["database_specific", b"database_specific", "modified", b"modified", "published", b"published", "withdrawn", b"withdrawn"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["affected", b"affected", "aliases", b"aliases", "credits", b"credits", "database_specific", b"database_specific", "details", b"details", "id", b"id", "modified", b"modified", "published", b"published", "references", b"references", "related", b"related", "schema_version", b"schema_version", "severity", b"severity", "summary", b"summary", "withdrawn", b"withdrawn"]) -> None: ... + +global___Vulnerability = Vulnerability diff --git a/poetry.lock b/poetry.lock index 075b79e9ca0..554c442fc0e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "astroid" @@ -567,13 +567,13 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] [[package]] name = "googleapis-common-protos" -version = "1.63.2" +version = "1.64.0" description = "Common protobufs used in Google APIs" optional = false python-versions = ">=3.7" files = [ - {file = "googleapis-common-protos-1.63.2.tar.gz", hash = "sha256:27c5abdffc4911f28101e635de1533fb4cfd2c37fbaa9174587c799fac90aa87"}, - {file = "googleapis_common_protos-1.63.2-py2.py3-none-any.whl", hash = "sha256:27a2499c7e8aff199665b22741997e485eccc8645aa9176c7c988e6fae507945"}, + {file = "googleapis_common_protos-1.64.0-py2.py3-none-any.whl", hash = "sha256:d1bfc569f70ed2e96ccf06ead265c2cf42b5abfc817cda392e3835f3b67b5c59"}, + {file = "googleapis_common_protos-1.64.0.tar.gz", hash = "sha256:7d77ca6b7c0c38eb6b1bab3b4c9973acf57ce4f2a6d3a4136acba10bcbfb3025"}, ] [package.dependencies] @@ -601,61 +601,61 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [[package]] name = "grpcio" -version = "1.65.5" +version = "1.66.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.65.5-cp310-cp310-linux_armv7l.whl", hash = "sha256:b67d450f1e008fedcd81e097a3a400a711d8be1a8b20f852a7b8a73fead50fe3"}, - {file = "grpcio-1.65.5-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a70a20eed87bba647a38bedd93b3ce7db64b3f0e8e0952315237f7f5ca97b02d"}, - {file = "grpcio-1.65.5-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f79c87c114bf37adf408026b9e2e333fe9ff31dfc9648f6f80776c513145c813"}, - {file = "grpcio-1.65.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17f9fa2d947dbfaca01b3ab2c62eefa8240131fdc67b924eb42ce6032e3e5c1"}, - {file = "grpcio-1.65.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32d60e18ff7c34fe3f6db3d35ad5c6dc99f5b43ff3982cb26fad4174462d10b1"}, - {file = "grpcio-1.65.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fe6505376f5b00bb008e4e1418152e3ad3d954b629da286c7913ff3cfc0ff740"}, - {file = "grpcio-1.65.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33158e56c6378063923c417e9fbdb28660b6e0e2835af42e67f5a7793f587af7"}, - {file = "grpcio-1.65.5-cp310-cp310-win32.whl", hash = "sha256:1cbc208edb9acf1cc339396a1a36b83796939be52f34e591c90292045b579fbf"}, - {file = "grpcio-1.65.5-cp310-cp310-win_amd64.whl", hash = "sha256:bc74f3f745c37e2c5685c9d2a2d5a94de00f286963f5213f763ae137bf4f2358"}, - {file = "grpcio-1.65.5-cp311-cp311-linux_armv7l.whl", hash = "sha256:3207ae60d07e5282c134b6e02f9271a2cb523c6d7a346c6315211fe2bf8d61ed"}, - {file = "grpcio-1.65.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a2f80510f99f82d4eb825849c486df703f50652cea21c189eacc2b84f2bde764"}, - {file = "grpcio-1.65.5-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a80e9a5e3f93c54f5eb82a3825ea1fc4965b2fa0026db2abfecb139a5c4ecdf1"}, - {file = "grpcio-1.65.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b2944390a496567de9e70418f3742b477d85d8ca065afa90432edc91b4bb8ad"}, - {file = "grpcio-1.65.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3655139d7be213c32c79ef6fb2367cae28e56ef68e39b1961c43214b457f257"}, - {file = "grpcio-1.65.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05f02d68fc720e085f061b704ee653b181e6d5abfe315daef085719728d3d1fd"}, - {file = "grpcio-1.65.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1c4caafe71aef4dabf53274bbf4affd6df651e9f80beedd6b8e08ff438ed3260"}, - {file = "grpcio-1.65.5-cp311-cp311-win32.whl", hash = "sha256:84c901cdec16a092099f251ef3360d15e29ef59772150fa261d94573612539b5"}, - {file = "grpcio-1.65.5-cp311-cp311-win_amd64.whl", hash = "sha256:11f8b16121768c1cb99d7dcb84e01510e60e6a206bf9123e134118802486f035"}, - {file = "grpcio-1.65.5-cp312-cp312-linux_armv7l.whl", hash = "sha256:ee6ed64a27588a2c94e8fa84fe8f3b5c89427d4d69c37690903d428ec61ca7e4"}, - {file = "grpcio-1.65.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:76991b7a6fb98630a3328839755181ce7c1aa2b1842aa085fd4198f0e5198960"}, - {file = "grpcio-1.65.5-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:89c00a18801b1ed9cc441e29b521c354725d4af38c127981f2c950c796a09b6e"}, - {file = "grpcio-1.65.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:078038e150a897e5e402ed3d57f1d31ebf604cbed80f595bd281b5da40762a92"}, - {file = "grpcio-1.65.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97962720489ef31b5ad8a916e22bc31bba3664e063fb9f6702dce056d4aa61b"}, - {file = "grpcio-1.65.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b8270b15b99781461b244f5c81d5c2bc9696ab9189fb5ff86c841417fb3b39fe"}, - {file = "grpcio-1.65.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8e5c4c15ac3fe1eb68e46bc51e66ad29be887479f231f8237cf8416058bf0cc1"}, - {file = "grpcio-1.65.5-cp312-cp312-win32.whl", hash = "sha256:f5b5970341359341d0e4c789da7568264b2a89cd976c05ea476036852b5950cd"}, - {file = "grpcio-1.65.5-cp312-cp312-win_amd64.whl", hash = "sha256:238a625f391a1b9f5f069bdc5930f4fd71b74426bea52196fc7b83f51fa97d34"}, - {file = "grpcio-1.65.5-cp38-cp38-linux_armv7l.whl", hash = "sha256:6c4e62bcf297a1568f627f39576dbfc27f1e5338a691c6dd5dd6b3979da51d1c"}, - {file = "grpcio-1.65.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d7df567b67d16d4177835a68d3f767bbcbad04da9dfb52cbd19171f430c898bd"}, - {file = "grpcio-1.65.5-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:b7ca419f1462390851eec395b2089aad1e49546b52d4e2c972ceb76da69b10f8"}, - {file = "grpcio-1.65.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa36dd8496d3af0d40165252a669fa4f6fd2db4b4026b9a9411cbf060b9d6a15"}, - {file = "grpcio-1.65.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a101696f9ece90a0829988ff72f1b1ea2358f3df035bdf6d675dd8b60c2c0894"}, - {file = "grpcio-1.65.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2a6d8169812932feac514b420daffae8ab8e36f90f3122b94ae767e633296b17"}, - {file = "grpcio-1.65.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:47d0aaaab82823f0aa6adea5184350b46e2252e13a42a942db84da5b733f2e05"}, - {file = "grpcio-1.65.5-cp38-cp38-win32.whl", hash = "sha256:85ae8f8517d5bcc21fb07dbf791e94ed84cc28f84c903cdc2bd7eaeb437c8f45"}, - {file = "grpcio-1.65.5-cp38-cp38-win_amd64.whl", hash = "sha256:770bd4bd721961f6dd8049bc27338564ba8739913f77c0f381a9815e465ff965"}, - {file = "grpcio-1.65.5-cp39-cp39-linux_armv7l.whl", hash = "sha256:ab5ec837d8cee8dbce9ef6386125f119b231e4333cc6b6d57b6c5c7c82a72331"}, - {file = "grpcio-1.65.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cabd706183ee08d8026a015af5819a0b3a8959bdc9d1f6fdacd1810f09200f2a"}, - {file = "grpcio-1.65.5-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:ec71fc5b39821ad7d80db7473c8f8c2910f3382f0ddadfbcfc2c6c437107eb67"}, - {file = "grpcio-1.65.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a9e35bcb045e39d7cac30464c285389b9a816ac2067e4884ad2c02e709ef8e"}, - {file = "grpcio-1.65.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d750e9330eb14236ca11b78d0c494eed13d6a95eb55472298f0e547c165ee324"}, - {file = "grpcio-1.65.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2b91ce647b6307f25650872454a4d02a2801f26a475f90d0b91ed8110baae589"}, - {file = "grpcio-1.65.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8da58ff80bc4556cf29bc03f5fff1f03b8387d6aaa7b852af9eb65b2cf833be4"}, - {file = "grpcio-1.65.5-cp39-cp39-win32.whl", hash = "sha256:7a412959aa5f08c5ac04aa7b7c3c041f5e4298cadd4fcc2acff195b56d185ebc"}, - {file = "grpcio-1.65.5-cp39-cp39-win_amd64.whl", hash = "sha256:55714ea852396ec9568f45f487639945ab674de83c12bea19d5ddbc3ae41ada3"}, - {file = "grpcio-1.65.5.tar.gz", hash = "sha256:ec6f219fb5d677a522b0deaf43cea6697b16f338cb68d009e30930c4aa0d2209"}, + {file = "grpcio-1.66.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:ad7256f224437b2c29c2bef98ddd3130454c5b1ab1f0471fc11794cefd4dbd3d"}, + {file = "grpcio-1.66.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:5f4b3357e59dfba9140a51597287297bc638710d6a163f99ee14efc19967a821"}, + {file = "grpcio-1.66.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:e8d20308eeae15b3e182f47876f05acbdec1eebd9473a9814a44e46ec4a84c04"}, + {file = "grpcio-1.66.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1eb03524d0f55b965d6c86aa44e5db9e5eaa15f9ed3b164621e652e5b927f4b8"}, + {file = "grpcio-1.66.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37514b68a42e9cf24536345d3cf9e580ffd29117c158b4eeea34625200256067"}, + {file = "grpcio-1.66.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:516fdbc8e156db71a004bc431a6303bca24cfde186babe96dde7bd01e8f0cc70"}, + {file = "grpcio-1.66.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d0439a970d65327de21c299ea0e0c2ad0987cdaf18ba5066621dea5f427f922b"}, + {file = "grpcio-1.66.0-cp310-cp310-win32.whl", hash = "sha256:5f93fc84b72bbc7b84a42f3ca9dc055fa00d2303d9803be011ebf7a10a4eb833"}, + {file = "grpcio-1.66.0-cp310-cp310-win_amd64.whl", hash = "sha256:8fc5c710ddd51b5a0dc36ef1b6663430aa620e0ce029b87b150dafd313b978c3"}, + {file = "grpcio-1.66.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:dd614370e939f9fceeeb2915111a0795271b4c11dfb5fc0f58449bee40c726a5"}, + {file = "grpcio-1.66.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:245b08f9b3c645a6a623f3ed4fa43dcfcd6ad701eb9c32511c1bb7380e8c3d23"}, + {file = "grpcio-1.66.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:aaf30c75cbaf30e561ca45f21eb1f729f0fab3f15c592c1074795ed43e3ff96f"}, + {file = "grpcio-1.66.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49234580a073ce7ac490112f6c67c874cbcb27804c4525978cdb21ba7f3f193c"}, + {file = "grpcio-1.66.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de9e20a0acb709dcfa15a622c91f584f12c9739a79c47999f73435d2b3cc8a3b"}, + {file = "grpcio-1.66.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc008c6afa1e7c8df99bd9154abc4f0470d26b7730ca2521122e99e771baa8c7"}, + {file = "grpcio-1.66.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:50cea8ce2552865b87e3dffbb85eb21e6b98d928621600c0feda2f02449cd837"}, + {file = "grpcio-1.66.0-cp311-cp311-win32.whl", hash = "sha256:508411df1f2b7cfa05d4d7dbf3d576fe4f949cd61c03f3a6f0378c84e3d7b963"}, + {file = "grpcio-1.66.0-cp311-cp311-win_amd64.whl", hash = "sha256:6d586a95c05c82a5354be48bb4537e1accaf2472d8eb7e9086d844cbff934482"}, + {file = "grpcio-1.66.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:5ea27f4ce8c0daccfdd2c7961e6ba404b6599f47c948415c4cca5728739107a3"}, + {file = "grpcio-1.66.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:296a45ea835e12a1cc35ab0c57e455346c272af7b0d178e29c67742167262b4c"}, + {file = "grpcio-1.66.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:e36fa838ac1d6c87198ca149cbfcc92e1af06bb8c8cd852622f8e58f33ea3324"}, + {file = "grpcio-1.66.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:684a4c07883cbd4ac864f0d08d927267404f5f0c76f31c85f9bbe05f2daae2f2"}, + {file = "grpcio-1.66.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3084e590e857ba7585ae91078e4c9b6ef55aaf1dc343ce26400ba59a146eada"}, + {file = "grpcio-1.66.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:526d4f6ca19f31b25606d5c470ecba55c0b22707b524e4de8987919e8920437d"}, + {file = "grpcio-1.66.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:423ae18637cd99ddcf2e5a6851c61828c49e9b9d022d0442d979b4f230109787"}, + {file = "grpcio-1.66.0-cp312-cp312-win32.whl", hash = "sha256:7bc9d823e05d63a87511fb456dcc48dc0fced86c282bf60229675e7ee7aac1a1"}, + {file = "grpcio-1.66.0-cp312-cp312-win_amd64.whl", hash = "sha256:230cdd696751e7eb1395718cd308234749daa217bb8d128f00357dc4df102558"}, + {file = "grpcio-1.66.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:0f3010bf46b2a01c9e40644cb9ed91b4b8435e5c500a275da5f9f62580e31e80"}, + {file = "grpcio-1.66.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ba18cfdc09312eb2eea6fa0ce5d2eec3cf345ea78f6528b2eaed6432105e0bd0"}, + {file = "grpcio-1.66.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:53d4c6706b49e358a2a33345dbe9b6b3bb047cecd7e8c07ba383bd09349bfef8"}, + {file = "grpcio-1.66.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:643d8d9632a688ae69661e924b862e23c83a3575b24e52917ec5bcc59543d212"}, + {file = "grpcio-1.66.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba60ae3b465b3e85080ae3bfbc36fd0305ae495ab16fcf8022fc7d7a23aac846"}, + {file = "grpcio-1.66.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9d5251578767fe44602688c851c2373b5513048ac84c21a0fe946590a8e7933d"}, + {file = "grpcio-1.66.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5e8140b39f10d7be2263afa2838112de29374c5c740eb0afd99146cb5bdbd990"}, + {file = "grpcio-1.66.0-cp38-cp38-win32.whl", hash = "sha256:5b15ef1b296c4e78f15f64fc65bf8081f8774480ffcac45642f69d9d753d9c6b"}, + {file = "grpcio-1.66.0-cp38-cp38-win_amd64.whl", hash = "sha256:c072f90a1f0409f827ae86266984cba65e89c5831a0726b9fc7f4b5fb940b853"}, + {file = "grpcio-1.66.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:a639d3866bfb5a678b5c0b92cd7ab543033ed8988854290fd86145e71731fd4c"}, + {file = "grpcio-1.66.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ed35bf7da3fb3b1949e32bdf47a8b5ffe0aed11722d948933bd068531cd4682"}, + {file = "grpcio-1.66.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:1c5466222470cb7fbc9cc898af1d48eefd297cb2e2f59af6d4a851c862fa90ac"}, + {file = "grpcio-1.66.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:921b8f7f25d5300d7c6837a1e0639ef145fbdbfb728e0a5db2dbccc9fc0fd891"}, + {file = "grpcio-1.66.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3f6feb0dc8456d025e566709f7dd02885add99bedaac50229013069242a1bfd"}, + {file = "grpcio-1.66.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748452dbd5a047475d5413bdef08b0b9ceb2c0c0e249d4ee905a5fb82c6328dc"}, + {file = "grpcio-1.66.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:832945e64176520520317b50d64ec7d79924429528d5747669b52d0bf2c7bd78"}, + {file = "grpcio-1.66.0-cp39-cp39-win32.whl", hash = "sha256:8096a922eb91bc97c839f675c3efa1257c6ef181ae1b25d3fb97f2cae4c57c01"}, + {file = "grpcio-1.66.0-cp39-cp39-win_amd64.whl", hash = "sha256:375b58892301a5fc6ca7d7ff689c9dc9d00895f5d560604ace9f4f0573013c63"}, + {file = "grpcio-1.66.0.tar.gz", hash = "sha256:c1ea4c528e7db6660718e4165fd1b5ac24b79a70c870a7bc0b7bdb9babab7c1e"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.65.5)"] +protobuf = ["grpcio-tools (>=1.66.0)"] [[package]] name = "grpcio-status" @@ -737,13 +737,13 @@ setuptools = "*" [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -825,6 +825,21 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mypy-protobuf" +version = "3.6.0" +description = "Generate mypy stub files from protobuf specs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c"}, + {file = "mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c"}, +] + +[package.dependencies] +protobuf = ">=4.25.3" +types-protobuf = ">=4.24" + [[package]] name = "opentelemetry-api" version = "1.16.0" @@ -1024,13 +1039,13 @@ files = [ [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -1338,6 +1353,17 @@ files = [ {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] +[[package]] +name = "types-protobuf" +version = "5.27.0.20240626" +description = "Typing stubs for protobuf" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-protobuf-5.27.0.20240626.tar.gz", hash = "sha256:683ba14043bade6785e3f937a7498f243b37881a91ac8d81b9202ecf8b191e9c"}, + {file = "types_protobuf-5.27.0.20240626-py3-none-any.whl", hash = "sha256:688e8f7e8d9295db26bc560df01fb731b27a25b77cbe4c1ce945647f7024f5c1"}, +] + [[package]] name = "urllib3" version = "2.2.2" @@ -1452,20 +1478,24 @@ tomli = ">=2.0.1" [[package]] name = "zipp" -version = "3.20.0" +version = "3.20.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"}, - {file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"}, + {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, + {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "75de6400ddef55dacce3925c9f8d88b739b4100c80747279091a0d59174c4796" +content-hash = "4a08ff8078fad3a261e8e9e3be2f49aa7a3099d627dfcc5fdad40a5b48e89f11" diff --git a/pyproject.toml b/pyproject.toml index 8277ecf9fd2..6d45d41fb92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ requests = "^2.32" yapf = "*" pylint = "*" grpcio-tools = "*" +mypy-protobuf = "^3.6.0" [build-system] requires = ["poetry-core"] From 1b46f4a8fa4a99a87f0367bd28c71fd10bf78e56 Mon Sep 17 00:00:00 2001 From: Rex P Date: Wed, 28 Aug 2024 11:34:12 +1000 Subject: [PATCH 02/13] Add models stub typing --- osv/ecosystems/helper_base.py | 3 +- osv/models.py | 6 +- osv/models.pyi | 371 ++++++++++++++++++++++++++++++++++ osv/semver_index.py | 4 +- 4 files changed, 378 insertions(+), 6 deletions(-) create mode 100644 osv/models.pyi diff --git a/osv/ecosystems/helper_base.py b/osv/ecosystems/helper_base.py index 248971e8184..408e146a5b4 100644 --- a/osv/ecosystems/helper_base.py +++ b/osv/ecosystems/helper_base.py @@ -15,6 +15,7 @@ from abc import ABC, abstractmethod import bisect +from typing import Any import requests from urllib.parse import quote @@ -57,7 +58,7 @@ def next_version(self, package, version): return None @abstractmethod - def sort_key(self, version): + def sort_key(self, version: str) -> Any: """Sort key.""" def sort_versions(self, versions): diff --git a/osv/models.py b/osv/models.py index d3625e9b607..7f1915e5313 100644 --- a/osv/models.py +++ b/osv/models.py @@ -889,7 +889,7 @@ def get_source_repository(source_name): return SourceRepository.get_by_id(source_name) -def sorted_events(ecosystem, range_type, events): +def sorted_events(ecosystem, range_type, events) -> list[AffectedEvent]: """Sort events.""" if range_type == 'GIT': # No need to sort. @@ -921,14 +921,14 @@ def sorted_events(ecosystem, range_type, events): @ndb.tasklet -def get_aliases_async(bug_id): +def get_aliases_async(bug_id) -> ndb.Future: """Gets aliases asynchronously.""" alias_group = yield AliasGroup.query(AliasGroup.bug_ids == bug_id).get_async() return alias_group @ndb.tasklet -def get_related_async(bug_id): +def get_related_async(bug_id) -> ndb.Future: """Gets related bugs asynchronously.""" related_bugs = yield Bug.query(Bug.related == bug_id).fetch_async() related_bug_ids = [bug.db_id for bug in related_bugs] diff --git a/osv/models.pyi b/osv/models.pyi new file mode 100644 index 00000000000..8c7368d2006 --- /dev/null +++ b/osv/models.pyi @@ -0,0 +1,371 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Datastore types.""" + +import enum +import re +import os +from datetime import datetime + +from typing import List, Self + +from google.cloud import ndb + + +class ndbModel(ndb.Model): + key: ndb.Key + + +class IDCounter(ndbModel): + next_id: str + + +class AffectedCommits(ndbModel): + # The main bug ID. + bug_id: str + # The commit hash. + commits: list[bytes] + # Whether or not the bug is public. + public: bool + # The page for this batch of commits. + page: int + + +class RegressResult(ndbModel): + """Regression results.""" + # The commit hash. + commit: str + # Vulnerability summary. + summary: str + # Vulnerability details. + details: str + # Error (if any). + error: str + # OSS-Fuzz issue ID. + issue_id: str + # Project for the bug. + project: str + # Package ecosystem for the project. + ecosystem: str + # Repo URL. + repo_url: str + # Severity of the bug. + severity: str + # Reference URLs. + reference_urls: list[str] + # Source timestamp. + timestamp: datetime + + +class FixResult(ndbModel): + """Fix results.""" + # The commit hash. + commit: str + # Vulnerability summary. + summary: str + # Vulnerability details. + details: str + # Error (if any). + error: str + # OSS-Fuzz issue ID. + issue_id: str + # Project for the bug. + project: str + # Package ecosystem for the project. + ecosystem: str + # Repo URL. + repo_url: str + # Severity of the bug. + severity: str + # Reference URLs. + reference_urls: list[str] + # Source timestamp. + timestamp: datetime + + +class AffectedEvent(ndbModel): + """Affected event.""" + type: str + value: str + + +class AffectedRange2(ndbModel): + """Affected range.""" + # Type of range. + type: str + # Repo URL. + repo_url: str + # Events. + events: list[AffectedEvent] + + +class SourceOfTruth(enum.IntEnum): + """Source of truth.""" + NONE = 0 + # Internal to OSV (e.g. private OSS-Fuzz bugs). + INTERNAL = 1 + # Vulnerabilities that are available in a public repo. + SOURCE_REPO = 2 + + +class Package(ndbModel): + """Package.""" + ecosystem: str + name: str + purl: str + + +class Severity(ndbModel): + """Severity.""" + type: str + score: str + + +class AffectedPackage(ndbModel): + """Affected packages.""" + # The affected package identifier. + package: Package + # The list of affected ranges. + ranges: list[AffectedRange2] + # The list of explicit affected versions. + versions: list[str] + # Database specific metadata. + database_specific: dict + # Ecosystem specific metadata. + ecosystem_specific: dict + # Severity of the bug. + severities: list[Severity] + + +class Credit(ndbModel): + """Credits.""" + name: str + contact: list[str] + type: str + + +class Bug(ndbModel): + """Bug entity.""" + OSV_ID_PREFIX = 'OSV-' + # Very large fake version to use when there is no fix available. + _NOT_FIXED_SEMVER = '999999.999999.999999' + + # Display ID as used by the source database. The full qualified database that + # OSV tracks this as may be different. + db_id: str + # Other IDs this bug is known as. + aliases: list[str] + # Related IDs. + related: list[str] + # Status of the bug. + status: int + # Timestamp when Bug was allocated. + timestamp: datetime + # When the entry was last edited. + last_modified: datetime + # Last modified field of the original imported file + import_last_modified: datetime + # When the entry was withdrawn. + withdrawn: datetime + # The source identifier. + # For OSS-Fuzz, this oss-fuzz:. + # For others this is :. + source_id: str + # The main fixed commit (from bisection). + fixed: str + # The main regressing commit (from bisection). + regressed: str + # List of affected versions. + affected: list[str] + # List of normalized versions indexed for fuzzy matching. + affected_fuzzy: list[str] + # OSS-Fuzz issue ID. + issue_id: str + # Package URL for this package. + purl: list[str] + # Project/package name for the bug. + project: list[str] + # Package ecosystem for the project. + ecosystem: list[str] + # Summary for the bug. + summary: str + # Vulnerability details. + details: str + # Severity of the bug. + severities: list[Severity] + # Credits for the bug. + credits: list[Credit] + # Whether or not the bug is public (OSS-Fuzz only). + public: bool + # Reference URL types (dict of url -> type). + reference_url_types: dict + # Search indices (auto-populated) + search_indices: list[str] + # Whether or not the bug has any affected versions (auto-populated). + has_affected: bool + # Source of truth for this Bug. + source_of_truth: SourceOfTruth + # Whether the bug is fixed (indexed for querying). + is_fixed: bool + # Database specific. + database_specific: dict + # Normalized SEMVER fixed indexes for querying. + semver_fixed_indexes: list[str] + # Affected packages and versions. + affected_packages: list[AffectedPackage] + # The source of this Bug. + source: str + + +class RepoIndex(ndbModel): + """RepoIndex entry""" + # The dependency name + name: str + # The base cpe without the version + base_cpe: str + # The repository commit + commit: bytes + # The source address + repo_addr: str + # The scanned file extensions + file_exts: list[str] + # The hash algorithm used + file_hash_type: str + # The repository type + repo_type: str + # A bitmap of which buckets are empty + empty_bucket_bitmap: bytes + # Number of files in this repo + file_count: int + # Tag name of the source + tag: str + + +class FileResult(ndbModel): + """FileResult entry containing the path and hash""" + # The hash value of the file + hash: bytes + # The file path + path: str + + +class RepoIndexBucket(ndbModel): + """RepoIndexResult entries containing the actual hash values""" + # The file results per file + node_hash: bytes + # number of files this hash represents + files_contained: int + + +class SourceRepositoryType(enum.IntEnum): + """SourceRepository type.""" + GIT = 0 + BUCKET = 1 + REST_ENDPOINT = 2 + + +class SourceRepository(ndbModel): + """Source repository.""" + # The SourceRepositoryType of the repository. + type: int + # The name of the source. + name: str + # The repo URL for the source for SourceRepositoryType.GIT. + repo_url: str + # The username to use for SSH auth for SourceRepositoryType.GIT. + repo_username: str + # Optional branch for repo for SourceRepositoryType.GIT. + repo_branch: str + # The API endpoint for SourceRepositoryType.REST_ENDPOINT. + rest_api_url: str + # Bucket name for SourceRepositoryType.BUCKET. + bucket: str + # Vulnerability data not under this path is ignored by the importer. + directory_path: str + # Last synced hash for SourceRepositoryType.GIT. + last_synced_hash: str + # Last date recurring updates were requested. + last_update_date: datetime + # Patterns of files to exclude (regex). + ignore_patterns: list[str] + # Whether this repository is editable. + editable: bool + # Default extension. + extension: str + # Key path within each file to store the vulnerability. + key_path: str + # If true, don't analyze any Git ranges. + ignore_git: bool + # Whether to detect cherypicks or not (slow for large repos). + detect_cherrypicks: bool + # Whether to populate "affected[].versions" from Git ranges. + versions_from_repo: bool + # Ignore last import time once (SourceRepositoryType.BUCKET). + ignore_last_import_time: bool + # HTTP link prefix to individual OSV source records. + link: str + # HTTP link prefix to individual vulnerability records for humans. + human_link: str + # DB prefix, if the database allocates its own. + # https://ossf.github.io/osv-schema/#id-modified-fields + db_prefix: list[str] + + def ignore_file(self, file_path): + """Return whether or not we should be ignoring a file.""" + if not self.ignore_patterns: + return False + + file_name = os.path.basename(file_path) + for pattern in self.ignore_patterns: + if re.match(pattern, file_name): + return True + + return False + + def _pre_put_hook(self): # pylint: disable=arguments-differ + """Pre-put hook for validation.""" + if self.type == SourceRepositoryType.BUCKET and self.editable: + raise ValueError('BUCKET SourceRepository cannot be editable.') + + +class AliasGroup(ndbModel): + """Alias group.""" + bug_ids: list[str] + last_modified: datetime + + +class AliasAllowListEntry(ndbModel): + """Alias group allow list entry.""" + bug_id: str + + +class AliasDenyListEntry(ndbModel): + """Alias group deny list entry.""" + bug_id: str + + +def get_source_repository(source_name): + ... + + +def sorted_events(ecosystem, range_type, events) -> list[AffectedEvent]: + ... + + +def get_aliases_async(bug_id) -> ndb.Future: + ... + + +def get_related_async(bug_id) -> ndb.Future: + ... diff --git a/osv/semver_index.py b/osv/semver_index.py index 369962995d8..b8a4f5040ba 100644 --- a/osv/semver_index.py +++ b/osv/semver_index.py @@ -80,7 +80,7 @@ def _coerce_suffix(suffix): return pre + build + match.group(3) -def coerce(version): +def coerce(version: str): """Coerce a potentially invalid semver into valid semver.""" version = _strip_leading_v(version) version_pattern = re.compile(r'^(\d+)(\.\d+)?(\.\d+)?(.*)$') @@ -99,7 +99,7 @@ def is_valid(version): return semver.Version.is_valid(_strip_leading_v(version)) -def parse(version): +def parse(version: str): """Parse a SemVer.""" return semver.Version.parse(coerce(version)) From 4d0fca31fcb7c857148d2e300a2a33ff5f03c563 Mon Sep 17 00:00:00 2001 From: Rex P Date: Wed, 28 Aug 2024 15:02:29 +1000 Subject: [PATCH 03/13] Move model helper functions out of models --- osv/__init__.py | 1 + osv/model_helpers.py | 80 ++++++++++++++++++++++++++++++++++++++++++++ osv/models.pyi | 16 --------- 3 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 osv/model_helpers.py diff --git a/osv/__init__.py b/osv/__init__.py index e836fede8e4..45e00d7e271 100644 --- a/osv/__init__.py +++ b/osv/__init__.py @@ -18,4 +18,5 @@ from .repos import * from .sources import * from .models import * +from .model_helpers import * from .ecosystems import * diff --git a/osv/model_helpers.py b/osv/model_helpers.py new file mode 100644 index 00000000000..ff652434546 --- /dev/null +++ b/osv/model_helpers.py @@ -0,0 +1,80 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Datastore types.""" + +import datetime + +from typing import List, Self + +from google.cloud import ndb + +# pylint: disable=relative-beyond-top-level +from .models import AliasGroup, AffectedEvent, SourceRepository, Bug +from . import ecosystems + + +def utcnow(): + """For mocking.""" + return datetime.datetime.utcnow() + + +def get_source_repository(source_name: str) -> SourceRepository: + """Get source repository.""" + return SourceRepository.get_by_id(source_name) # type: ignore + + +def sorted_events(ecosystem, range_type, events) -> list[AffectedEvent]: + """Sort events.""" + if range_type == 'GIT': + # No need to sort. + return events + + if range_type == 'SEMVER': + ecosystem_helper = ecosystems.SemverEcosystem() + else: + ecosystem_helper = ecosystems.get(ecosystem) + + if ecosystem_helper is None or not ecosystem_helper.supports_ordering: + raise ValueError('Unsupported ecosystem ' + ecosystem) + + # Remove any magic '0' values. + sorted_copy = [] + zero_event = None + for event in events: + if event.value == '0': + zero_event = event + continue + + sorted_copy.append(event) + + sorted_copy.sort(key=lambda e: ecosystem_helper.sort_key(e.value)) + if zero_event: + sorted_copy.insert(0, zero_event) + + return sorted_copy + + +@ndb.tasklet +def get_aliases_async(bug_id) -> ndb.Future: + """Gets aliases asynchronously.""" + alias_group = yield AliasGroup.query(AliasGroup.bug_ids == bug_id).get_async() + return alias_group + + +@ndb.tasklet +def get_related_async(bug_id) -> ndb.Future: + """Gets related bugs asynchronously.""" + related_bugs = yield Bug.query(Bug.related == bug_id).fetch_async() + related_bug_ids = [bug.db_id for bug in related_bugs] + return related_bug_ids diff --git a/osv/models.pyi b/osv/models.pyi index 8c7368d2006..e8e503dc1e3 100644 --- a/osv/models.pyi +++ b/osv/models.pyi @@ -353,19 +353,3 @@ class AliasAllowListEntry(ndbModel): class AliasDenyListEntry(ndbModel): """Alias group deny list entry.""" bug_id: str - - -def get_source_repository(source_name): - ... - - -def sorted_events(ecosystem, range_type, events) -> list[AffectedEvent]: - ... - - -def get_aliases_async(bug_id) -> ndb.Future: - ... - - -def get_related_async(bug_id) -> ndb.Future: - ... From 6103e935d58903462bfaec93b99f66ddd271de0a Mon Sep 17 00:00:00 2001 From: Rex P Date: Wed, 28 Aug 2024 15:07:15 +1000 Subject: [PATCH 04/13] Add missing functions back to models.pyi --- osv/models.pyi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osv/models.pyi b/osv/models.pyi index e8e503dc1e3..4a7fa6bdde4 100644 --- a/osv/models.pyi +++ b/osv/models.pyi @@ -21,6 +21,7 @@ from datetime import datetime from typing import List, Self from google.cloud import ndb +from . import vulnerability_pb2 class ndbModel(ndb.Model): @@ -227,6 +228,19 @@ class Bug(ndbModel): # The source of this Bug. source: str + def update_from_vulnerability(self, + vulnerability: vulnerability_pb2.Vulnerability): + ... + + def to_vulnerability(self, + include_source=False, + include_alias=True) -> vulnerability_pb2.Vulnerability: + ... + + @ndb.tasklet + def to_vulnerability_async(self, include_source=False): + ... + class RepoIndex(ndbModel): """RepoIndex entry""" From 0c0b0044efb216ddbb4477abd41ab0224ffc99f9 Mon Sep 17 00:00:00 2001 From: Rex P Date: Thu, 29 Aug 2024 10:51:13 +1000 Subject: [PATCH 05/13] General typing improvements on server.py --- gcp/api/server.py | 115 ++++++++++++++++++++++++------------------- osv/model_helpers.py | 4 +- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/gcp/api/server.py b/gcp/api/server.py index 30418f905d7..5840a16025c 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -25,6 +25,7 @@ import os import threading import time +import concurrent.futures from typing import Callable, List from collections import defaultdict @@ -44,6 +45,7 @@ from osv import ecosystems from osv import semver_index from osv import purl_helpers +from osv import vulnerability_pb2 from osv.logs import setup_gcp_logging from gcp.api import osv_service_v1_pb2 from gcp.api import osv_service_v1_pb2_grpc @@ -154,7 +156,7 @@ class OSVServicer(osv_service_v1_pb2_grpc.OSVServicer, @trace_filter.log_trace def GetVulnById(self, request, context: grpc.ServicerContext): """Return a `Vulnerability` object for a given OSV ID.""" - bug: osv.Bug = osv.Bug.get_by_id(request.id) + bug: osv.Bug | None = osv.Bug.get_by_id(request.id) # type: ignore if not bug or bug.status == osv.BugStatus.UNPROCESSED: context.abort(grpc.StatusCode.NOT_FOUND, 'Bug not found.') return None @@ -207,7 +209,8 @@ def QueryAffected(self, request, context: grpc.ServicerContext): total_responses=ResponsesCount(0)) try: - results, next_page_token = do_query(request.query, query_context).result() + results, next_page_token = do_query( + request.query, query_context).result() # type: ignore except InvalidArgument: # Currently cannot think of any other way # this can be raised other than invalid cursor @@ -490,7 +493,7 @@ def should_skip_bucket(path: str) -> bool: def process_buckets( - file_results: List[osv.FileResult]) -> List[osv.RepoIndexBucket]: + file_results: List[osv.FileResult]) -> list[osv.RepoIndexBucket]: """ Create buckets in the same process as indexer to generate the same bucket hashes @@ -504,18 +507,19 @@ def process_buckets( buckets[int.from_bytes(fr.hash[:2], byteorder='big') % _BUCKET_SIZE].append( fr.hash) - results: list[osv.RepoIndexBucket] = [None] * _BUCKET_SIZE - for bucket_idx, bucket in enumerate(buckets): + results: list[osv.RepoIndexBucket] = [] + for bucket in buckets: bucket.sort() hasher = hashlib.md5() for v in bucket: hasher.update(v) - results[bucket_idx] = osv.RepoIndexBucket( - node_hash=hasher.digest(), - files_contained=len(bucket), - ) + results.append( + osv.RepoIndexBucket( + node_hash=hasher.digest(), + files_contained=len(bucket), + )) return results @@ -535,7 +539,8 @@ def build_determine_version_result( # Only interested in our maximum number of results bucket_match_items = bucket_match_items[:min( _MAX_DETERMINE_VER_RESULTS_TO_RETURN, len(bucket_match_items))] - idx_futures = ndb.get_multi_async([b[0] for b in bucket_match_items]) + idx_futures = ndb.get_multi_async([b[0] for b in bucket_match_items + ]) # type: ignore output = [] # Apply bitwise NOT to the user bitmap @@ -661,7 +666,7 @@ def determine_version(version_query: osv_service_v1_pb2.VersionQuery, continue for index_bucket in result: - parent_key = index_bucket.key.parent() + parent_key = index_bucket.key.parent() # type: ignore file_match_count[parent_key] += index_bucket.files_contained bucket_match_count[parent_key] += 1 @@ -677,7 +682,7 @@ def determine_version(version_query: osv_service_v1_pb2.VersionQuery, @ndb.tasklet -def do_query(query, +def do_query(query: osv_service_v1_pb2.Query, context: QueryContext, include_details=True) -> tuple[list, str | None]: """Do a query.""" @@ -727,6 +732,7 @@ def to_response(b): # Retrieve it asynchronously later. return bug_to_response(b, include_details) + bugs: list[vulnerability_pb2.Vulnerability] if query.WhichOneof('param') == 'commit': try: commit_bytes = codecs.decode(query.commit, 'hex') @@ -759,7 +765,7 @@ def to_response(b): else: context.service_context.abort(grpc.StatusCode.INVALID_ARGUMENT, 'Invalid query.') - return None + raise ValueError # Asynchronously retrieve computed aliases and related ids here # to prevent significant query time increase for packages with @@ -772,7 +778,7 @@ def to_response(b): related.append(osv.get_related_async(bug.id)) for i, alias in enumerate(aliases): - alias_group = yield alias + alias_group: osv.AliasGroup = yield alias if not alias_group: continue alias_ids = sorted(list(set(alias_group.bug_ids) - {bugs[i].id})) @@ -782,7 +788,7 @@ def to_response(b): bugs[i].modified.FromDatetime(modified_time) for i, related_ids in enumerate(related): - related_bug_ids = yield related_ids + related_bug_ids: list[str] = yield related_ids bugs[i].related[:] = sorted( list(set(related_bug_ids + list(bugs[i].related)))) @@ -814,7 +820,8 @@ def bug_to_response(bug, include_details=True, include_alias=False): @ndb.tasklet def _get_bugs(bug_ids, to_response=bug_to_response): """Get bugs from bug ids.""" - bugs = ndb.get_multi_async([ndb.Key(osv.Bug, bug_id) for bug_id in bug_ids]) + bugs = ndb.get_multi_async([ndb.Key(osv.Bug, bug_id) for bug_id in bug_ids + ]) # type: ignore responses = [] for future_bug in bugs: @@ -837,9 +844,11 @@ def _datastore_normalized_purl(purl: PackageURL): @ndb.tasklet -def query_by_commit(context: QueryContext, - commit: bytes, - to_response: Callable = bug_to_response) -> list: +def query_by_commit( + context: QueryContext, + commit: bytes, + to_response: Callable = bug_to_response +) -> list[vulnerability_pb2.Vulnerability]: """ Perform a query by commit. @@ -913,7 +922,8 @@ def _clean_purl(purl: PackageURL): # No qualifiers, and our PURLs never have versions, so just match name return purl_query.name == purl_db.name - if purl_db.qualifiers: + if (purl_db.qualifiers and isinstance(purl_db.qualifiers, dict) and + isinstance(purl_query.qualifiers, dict)): # A arch of 'source' matches all other architectures if purl_db.qualifiers['arch'] == 'source': purl_db.qualifiers['arch'] = purl_query.qualifiers['arch'] @@ -921,13 +931,14 @@ def _clean_purl(purl: PackageURL): return purl_query == purl_db -def _is_semver_affected(affected_packages, package_name, ecosystem, - purl: PackageURL | None, version): +def _is_semver_affected(affected_packages: list[osv.AffectedPackage], + package_name: str | None, ecosystem: str | None, + purl: PackageURL | None, version_str: str): """Returns whether or not the given version is within an affected SEMVER range. """ - version = semver_index.parse(version) + version = semver_index.parse(version_str) affected = False for affected_package in affected_packages: @@ -1004,7 +1015,7 @@ def _is_version_affected(affected_packages, @ndb.tasklet def _query_by_semver(context: QueryContext, query: ndb.Query, package_name: str | None, ecosystem: str | None, - purl: PackageURL | None, version: str): + purl: PackageURL | None, version: str) -> list[osv.Bug]: """ Perform a query by semver version. @@ -1026,8 +1037,8 @@ def _query_by_semver(context: QueryContext, query: ndb.Query, return [] results = [] - query = query.filter( - osv.Bug.semver_fixed_indexes > semver_index.normalize(version)) + query = query.filter(osv.Bug.semver_fixed_indexes + > semver_index.normalize(version)) # type: ignore context.query_counter += 1 if context.should_skip_query(): @@ -1057,7 +1068,7 @@ def _query_by_generic_version( ecosystem: str | None, purl: PackageURL | None, version: str, -): +) -> list[osv.Bug]: """ Query by generic version. @@ -1103,13 +1114,13 @@ def _query_by_generic_version( def query_by_generic_helper(context: QueryContext, base_query: ndb.Query, package_name: str | None, ecosystem: str | None, purl: PackageURL | None, version: str, - is_normalized): + is_normalized: bool) -> list[osv.Bug]: """ Helper function for query_by_generic. This function can be called multiple times. """ query: ndb.Query = base_query.filter(osv.Bug.affected_fuzzy == version) - results = [] + results: list[osv.Bug] = [] context.query_counter += 1 if context.should_skip_query(): return [] @@ -1120,7 +1131,7 @@ def query_by_generic_helper(context: QueryContext, base_query: ndb.Query, if context.should_break_page(len(results)): context.save_cursor_at_page_break(it) break - bug = it.next() + bug: osv.Bug = it.next() # type: ignore if _is_version_affected( bug.affected_packages, package_name, @@ -1134,12 +1145,14 @@ def query_by_generic_helper(context: QueryContext, base_query: ndb.Query, @ndb.tasklet -def query_by_version(context: QueryContext, - package_name: str | None, - ecosystem: str | None, - purl: PackageURL | None, - version: str, - to_response: Callable = bug_to_response): +def query_by_version( + context: QueryContext, + package_name: str | None, + ecosystem: str | None, + purl: PackageURL | None, + version: str, + to_response: Callable = bug_to_response +) -> list[vulnerability_pb2.Vulnerability]: """ Query by (fuzzy) version. @@ -1175,13 +1188,16 @@ def query_by_version(context: QueryContext, else: return [] + ecosystem_info = None if ecosystem: query = query.filter(osv.Bug.ecosystem == ecosystem) + ecosystem_info = ecosystems.get(ecosystem) if purl: purl_ecosystem = purl_helpers.purl_to_ecosystem(purl.type) if purl_ecosystem: ecosystem = purl_ecosystem + ecosystem_info = ecosystems.get(ecosystem) ecosystem_info = ecosystems.get(ecosystem) is_semver = ecosystem_info and ecosystem_info.is_semver @@ -1234,7 +1250,7 @@ def query_by_version(context: QueryContext, @ndb.tasklet def _query_by_comparing_versions(context: QueryContext, query: ndb.Query, - ecosystem: str, version: str) -> list: + ecosystem: str, version: str) -> list[osv.Bug]: """ Query by comparing versions. @@ -1248,7 +1264,7 @@ def _query_by_comparing_versions(context: QueryContext, query: ndb.Query, Returns: list of osv.Bugs """ - bugs = [] + bugs: list[osv.Bug] = [] context.query_counter += 1 if context.should_skip_query(): @@ -1264,17 +1280,17 @@ def _query_by_comparing_versions(context: QueryContext, query: ndb.Query, context.save_cursor_at_page_break(it) break - bug: osv.Bug = it.next() - for affected_package in bug.affected_packages: + # next() will never return None as we check for has next above. + bug: osv.Bug = it.next() # type: ignore + for affected_package in bug.affected_packages: # type: ignore affected_package: osv.AffectedPackage - package = affected_package.package - package: osv.Package + package: osv.Package = affected_package.package # type: ignore # If the queried ecosystem has no release specified (e.g., "Debian"), # compare against packages in all releases (e.g., "Debian:X"). # Otherwise, only compare within # the specified release (e.g., "Debian:11"). - package_ecosystem = package.ecosystem + package_ecosystem: str = package.ecosystem # type: ignore if not has_release: # Extracts ecosystem name for broader comparison (e.g., "Debian") package_ecosystem = package_ecosystem.split(':')[0] @@ -1293,9 +1309,10 @@ def _query_by_comparing_versions(context: QueryContext, query: ndb.Query, @ndb.tasklet -def query_by_package(context: QueryContext, package_name: str | None, - ecosystem: str | None, purl: PackageURL | None, - to_response: Callable) -> list: +def query_by_package( + context: QueryContext, package_name: str | None, ecosystem: str | None, + purl: PackageURL | None, + to_response: Callable) -> list[vulnerability_pb2.Vulnerability]: """ Query by package. @@ -1343,7 +1360,7 @@ def query_by_package(context: QueryContext, package_name: str | None, context.save_cursor_at_page_break(it) break - bug: osv.Bug = it.next() + bug: osv.Bug = it.next() # type: ignore if purl: affected = False @@ -1467,9 +1484,7 @@ def main(): args = parser.parse_args() port = args.port if not port: - port = os.environ.get('PORT') - if not port: - port = 8000 + port = int(os.environ.get('PORT', '8000')) serve(port, args.local) diff --git a/osv/model_helpers.py b/osv/model_helpers.py index ff652434546..e9aaae08cd6 100644 --- a/osv/model_helpers.py +++ b/osv/model_helpers.py @@ -66,14 +66,14 @@ def sorted_events(ecosystem, range_type, events) -> list[AffectedEvent]: @ndb.tasklet -def get_aliases_async(bug_id) -> ndb.Future: +def get_aliases_async(bug_id: str) -> ndb.Future: """Gets aliases asynchronously.""" alias_group = yield AliasGroup.query(AliasGroup.bug_ids == bug_id).get_async() return alias_group @ndb.tasklet -def get_related_async(bug_id) -> ndb.Future: +def get_related_async(bug_id: str) -> ndb.Future: """Gets related bugs asynchronously.""" related_bugs = yield Bug.query(Bug.related == bug_id).fetch_async() related_bug_ids = [bug.db_id for bug in related_bugs] From 047f7c7edd97c5dcb1cb27ec6fa81a8400b9c57f Mon Sep 17 00:00:00 2001 From: Rex P Date: Thu, 29 Aug 2024 14:34:59 +1000 Subject: [PATCH 06/13] Remove models.pyi stub file, add type hint directly to the main file --- osv/models.py | 240 ++++++++++++++++---------------- osv/models.pyi | 369 ------------------------------------------------- pyproject.toml | 5 + 3 files changed, 127 insertions(+), 487 deletions(-) delete mode 100644 osv/models.pyi diff --git a/osv/models.py b/osv/models.py index 7f1915e5313..3680bda8681 100644 --- a/osv/models.py +++ b/osv/models.py @@ -13,7 +13,7 @@ # limitations under the License. """Datastore types.""" -import datetime +from datetime import datetime, UTC import enum import logging import re @@ -65,7 +65,7 @@ def _check_valid_event_type(prop, value): def utcnow(): """For mocking.""" - return datetime.datetime.utcnow() + return datetime.now(UTC) def _get_purl_indexes(affected_packages): @@ -110,7 +110,7 @@ def _maybe_strip_repo_prefixes(versions: List[str], class IDCounter(ndb.Model): """Counter for ID allocations.""" # Next ID to allocate. - next_id = ndb.IntegerProperty() + next_id: int = ndb.IntegerProperty() class AffectedCommits(ndb.Model): @@ -118,81 +118,82 @@ class AffectedCommits(ndb.Model): MAX_COMMITS_PER_ENTITY = 10000 # The main bug ID. - bug_id = ndb.StringProperty() + bug_id: str = ndb.StringProperty() # The commit hash. - commits = ndb.BlobProperty(repeated=True, indexed=True) + commits: list[bytes] = ndb.BlobProperty(repeated=True, indexed=True) # Whether or not the bug is public. - public = ndb.BooleanProperty() + public: bool = ndb.BooleanProperty() # The page for this batch of commits. - page = ndb.IntegerProperty(indexed=False) + page: int = ndb.IntegerProperty(indexed=False) class RegressResult(ndb.Model): """Regression results.""" # The commit hash. - commit = ndb.StringProperty(default='') + commit: str = ndb.StringProperty(default='') # Vulnerability summary. - summary = ndb.TextProperty() + summary: str = ndb.TextProperty() # Vulnerability details. - details = ndb.TextProperty() + details: str = ndb.TextProperty() # Error (if any). - error = ndb.StringProperty() + error: str = ndb.StringProperty() # OSS-Fuzz issue ID. - issue_id = ndb.StringProperty() + issue_id: str = ndb.StringProperty() # Project for the bug. - project = ndb.StringProperty() + project: str = ndb.StringProperty() # Package ecosystem for the project. - ecosystem = ndb.StringProperty() + ecosystem: str = ndb.StringProperty() # Repo URL. - repo_url = ndb.StringProperty() + repo_url: str = ndb.StringProperty() # Severity of the bug. - severity = ndb.StringProperty(validator=_check_valid_severity) + severity: str = ndb.StringProperty(validator=_check_valid_severity) # Reference URLs. - reference_urls = ndb.StringProperty(repeated=True) + reference_urls: list[str] = ndb.StringProperty(repeated=True) # Source timestamp. - timestamp = ndb.DateTimeProperty() + timestamp: datetime = ndb.DateTimeProperty() class FixResult(ndb.Model): """Fix results.""" # The commit hash. - commit = ndb.StringProperty(default='') + commit: str = ndb.StringProperty(default='') # Vulnerability summary. - summary = ndb.TextProperty() + summary: str = ndb.TextProperty() # Vulnerability details. - details = ndb.TextProperty() + details: str = ndb.TextProperty() # Error (if any). - error = ndb.StringProperty() + error: str = ndb.StringProperty() # OSS-Fuzz issue ID. - issue_id = ndb.StringProperty() + issue_id: str = ndb.StringProperty() # Project for the bug. - project = ndb.StringProperty() + project: str = ndb.StringProperty() # Package ecosystem for the project. - ecosystem = ndb.StringProperty() + ecosystem: str = ndb.StringProperty() # Repo URL. - repo_url = ndb.StringProperty() + repo_url: str = ndb.StringProperty() # Severity of the bug. - severity = ndb.StringProperty(validator=_check_valid_severity) + severity: str = ndb.StringProperty(validator=_check_valid_severity) # Reference URLs. - reference_urls = ndb.StringProperty(repeated=True) + reference_urls: list[str] = ndb.StringProperty(repeated=True) # Source timestamp. - timestamp = ndb.DateTimeProperty() + timestamp: datetime = ndb.DateTimeProperty() class AffectedEvent(ndb.Model): """Affected event.""" - type = ndb.StringProperty(validator=_check_valid_event_type) - value = ndb.StringProperty() + type: str = ndb.StringProperty(validator=_check_valid_event_type) + value: str = ndb.StringProperty() class AffectedRange2(ndb.Model): """Affected range.""" # Type of range. - type = ndb.StringProperty(validator=_check_valid_range_type) + type: str = ndb.StringProperty(validator=_check_valid_range_type) # Repo URL. - repo_url = ndb.StringProperty() + repo_url: str = ndb.StringProperty() # Events. - events = ndb.LocalStructuredProperty(AffectedEvent, repeated=True) + events: list[AffectedEvent] = ndb.LocalStructuredProperty( + AffectedEvent, repeated=True) class SourceOfTruth(enum.IntEnum): @@ -206,38 +207,40 @@ class SourceOfTruth(enum.IntEnum): class Package(ndb.Model): """Package.""" - ecosystem = ndb.StringProperty() - name = ndb.StringProperty() - purl = ndb.StringProperty() + ecosystem: str = ndb.StringProperty() + name: str = ndb.StringProperty() + purl: str = ndb.StringProperty() class Severity(ndb.Model): """Severity.""" - type = ndb.StringProperty() - score = ndb.StringProperty() + type: str = ndb.StringProperty() + score: str = ndb.StringProperty() class AffectedPackage(ndb.Model): """Affected packages.""" # The affected package identifier. - package = ndb.StructuredProperty(Package) + package: Package = ndb.StructuredProperty(Package) # The list of affected ranges. - ranges = ndb.LocalStructuredProperty(AffectedRange2, repeated=True) + ranges: list[AffectedRange2] = ndb.LocalStructuredProperty( + AffectedRange2, repeated=True) # The list of explicit affected versions. - versions = ndb.TextProperty(repeated=True) + versions: list[str] = ndb.TextProperty(repeated=True) # Database specific metadata. - database_specific = ndb.JsonProperty() + database_specific: dict = ndb.JsonProperty() # Ecosystem specific metadata. - ecosystem_specific = ndb.JsonProperty() + ecosystem_specific: dict = ndb.JsonProperty() # Severity of the bug. - severities = ndb.LocalStructuredProperty(Severity, repeated=True) + severities: list[Severity] = ndb.LocalStructuredProperty( + Severity, repeated=True) class Credit(ndb.Model): """Credits.""" - name = ndb.StringProperty() - contact = ndb.StringProperty(repeated=True) - type = ndb.StringProperty() + name: str = ndb.StringProperty() + contact: list[str] = ndb.StringProperty(repeated=True) + type: str = ndb.StringProperty() class Bug(ndb.Model): @@ -248,70 +251,71 @@ class Bug(ndb.Model): # Display ID as used by the source database. The full qualified database that # OSV tracks this as may be different. - db_id = ndb.StringProperty() + db_id: str = ndb.StringProperty() # Other IDs this bug is known as. - aliases = ndb.StringProperty(repeated=True) + aliases: list[str] = ndb.StringProperty(repeated=True) # Related IDs. - related = ndb.StringProperty(repeated=True) + related: list[str] = ndb.StringProperty(repeated=True) # Status of the bug. - status = ndb.IntegerProperty() + status: int = ndb.IntegerProperty() # Timestamp when Bug was allocated. - timestamp = ndb.DateTimeProperty() + timestamp: datetime = ndb.DateTimeProperty() # When the entry was last edited. - last_modified = ndb.DateTimeProperty() + last_modified: datetime = ndb.DateTimeProperty() # Last modified field of the original imported file - import_last_modified = ndb.DateTimeProperty() + import_last_modified: datetime = ndb.DateTimeProperty() # When the entry was withdrawn. - withdrawn = ndb.DateTimeProperty() + withdrawn: datetime = ndb.DateTimeProperty() # The source identifier. # For OSS-Fuzz, this oss-fuzz:. # For others this is :. - source_id = ndb.StringProperty() + source_id: str = ndb.StringProperty() # The main fixed commit (from bisection). - fixed = ndb.StringProperty(default='') + fixed: str = ndb.StringProperty(default='') # The main regressing commit (from bisection). - regressed = ndb.StringProperty(default='') + regressed: str = ndb.StringProperty(default='') # List of affected versions. - affected = ndb.TextProperty(repeated=True) + affected: list[str] = ndb.TextProperty(repeated=True) # List of normalized versions indexed for fuzzy matching. - affected_fuzzy = ndb.StringProperty(repeated=True) + affected_fuzzy: list[str] = ndb.StringProperty(repeated=True) # OSS-Fuzz issue ID. - issue_id = ndb.StringProperty() + issue_id: str = ndb.StringProperty() # Package URL for this package. - purl = ndb.StringProperty(repeated=True) + purl: list[str] = ndb.StringProperty(repeated=True) # Project/package name for the bug. - project = ndb.StringProperty(repeated=True) + project: list[str] = ndb.StringProperty(repeated=True) # Package ecosystem for the project. - ecosystem = ndb.StringProperty(repeated=True) + ecosystem: list[str] = ndb.StringProperty(repeated=True) # Summary for the bug. - summary = ndb.TextProperty() + summary: str = ndb.TextProperty() # Vulnerability details. - details = ndb.TextProperty() + details: str = ndb.TextProperty() # Severity of the bug. - severities = ndb.LocalStructuredProperty(Severity, repeated=True) + severities: list[Severity] = ndb.LocalStructuredProperty( + Severity, repeated=True) # Credits for the bug. - credits = ndb.LocalStructuredProperty(Credit, repeated=True) + credits: list[Credit] = ndb.LocalStructuredProperty(Credit, repeated=True) # Whether or not the bug is public (OSS-Fuzz only). - public = ndb.BooleanProperty() + public: bool = ndb.BooleanProperty() # Reference URL types (dict of url -> type). - reference_url_types = ndb.JsonProperty() + reference_url_types: dict = ndb.JsonProperty() # Search indices (auto-populated) - search_indices = ndb.StringProperty(repeated=True) + search_indices: list[str] = ndb.StringProperty(repeated=True) # Whether or not the bug has any affected versions (auto-populated). - has_affected = ndb.BooleanProperty() + has_affected: bool = ndb.BooleanProperty() # Source of truth for this Bug. - source_of_truth = ndb.IntegerProperty(default=SourceOfTruth.INTERNAL) + source_of_truth: SourceOfTruth = ndb.IntegerProperty(default=SourceOfTruth.INTERNAL) # Whether the bug is fixed (indexed for querying). - is_fixed = ndb.BooleanProperty() + is_fixed: bool = ndb.BooleanProperty() # Database specific. - database_specific = ndb.JsonProperty() + database_specific: dict = ndb.JsonProperty() # Normalized SEMVER fixed indexes for querying. - semver_fixed_indexes = ndb.StringProperty(repeated=True) + semver_fixed_indexes: list[str] = ndb.StringProperty(repeated=True) # Affected packages and versions. - affected_packages = ndb.LocalStructuredProperty( + affected_packages: list[AffectedPackage] = ndb.LocalStructuredProperty( AffectedPackage, repeated=True) # The source of this Bug. - source = ndb.StringProperty() + source: str = ndb.StringProperty() def id(self): """Get the bug ID.""" @@ -760,41 +764,41 @@ def to_vulnerability_async(self, include_source=False): class RepoIndex(ndb.Model): """RepoIndex entry""" # The dependency name - name = ndb.StringProperty() + name: str = ndb.StringProperty() # The base cpe without the version - base_cpe = ndb.StringProperty() + base_cpe: str = ndb.StringProperty() # The repository commit - commit = ndb.BlobProperty() + commit: bytes = ndb.BlobProperty() # The source address - repo_addr = ndb.StringProperty() + repo_addr: str = ndb.StringProperty() # The scanned file extensions - file_exts = ndb.StringProperty(repeated=True) + file_exts: list[str] = ndb.StringProperty(repeated=True) # The hash algorithm used - file_hash_type = ndb.StringProperty() + file_hash_type: str = ndb.StringProperty() # The repository type - repo_type = ndb.StringProperty() + repo_type: str = ndb.StringProperty() # A bitmap of which buckets are empty - empty_bucket_bitmap = ndb.BlobProperty() + empty_bucket_bitmap: bytes = ndb.BlobProperty() # Number of files in this repo - file_count = ndb.IntegerProperty() + file_count: int = ndb.IntegerProperty() # Tag name of the source - tag = ndb.StringProperty() + tag: str = ndb.StringProperty() class FileResult(ndb.Model): """FileResult entry containing the path and hash""" # The hash value of the file - hash = ndb.BlobProperty(indexed=True) + hash: bytes = ndb.BlobProperty(indexed=True) # The file path - path = ndb.TextProperty() + path: str = ndb.TextProperty() class RepoIndexBucket(ndb.Model): """RepoIndexResult entries containing the actual hash values""" # The file results per file - node_hash = ndb.BlobProperty(indexed=True) + node_hash: bytes = ndb.BlobProperty(indexed=True) # number of files this hash represents - files_contained = ndb.IntegerProperty() + files_contained: int = ndb.IntegerProperty() class SourceRepositoryType(enum.IntEnum): @@ -807,48 +811,48 @@ class SourceRepositoryType(enum.IntEnum): class SourceRepository(ndb.Model): """Source repository.""" # The SourceRepositoryType of the repository. - type = ndb.IntegerProperty() + type: int = ndb.IntegerProperty() # The name of the source. - name = ndb.StringProperty() + name: str = ndb.StringProperty() # The repo URL for the source for SourceRepositoryType.GIT. - repo_url = ndb.StringProperty() + repo_url: str = ndb.StringProperty() # The username to use for SSH auth for SourceRepositoryType.GIT. - repo_username = ndb.StringProperty() + repo_username: str = ndb.StringProperty() # Optional branch for repo for SourceRepositoryType.GIT. - repo_branch = ndb.StringProperty() + repo_branch: str = ndb.StringProperty() # The API endpoint for SourceRepositoryType.REST_ENDPOINT. - rest_api_url = ndb.StringProperty() + rest_api_url: str = ndb.StringProperty() # Bucket name for SourceRepositoryType.BUCKET. - bucket = ndb.StringProperty() + bucket: str = ndb.StringProperty() # Vulnerability data not under this path is ignored by the importer. - directory_path = ndb.StringProperty() + directory_path: str = ndb.StringProperty() # Last synced hash for SourceRepositoryType.GIT. - last_synced_hash = ndb.StringProperty() + last_synced_hash: str = ndb.StringProperty() # Last date recurring updates were requested. - last_update_date = ndb.DateTimeProperty() + last_update_date: datetime = ndb.DateTimeProperty() # Patterns of files to exclude (regex). - ignore_patterns = ndb.StringProperty(repeated=True) + ignore_patterns: list[str] = ndb.StringProperty(repeated=True) # Whether this repository is editable. - editable = ndb.BooleanProperty(default=False) + editable: bool = ndb.BooleanProperty(default=False) # Default extension. - extension = ndb.StringProperty(default='.yaml') + extension: str = ndb.StringProperty(default='.yaml') # Key path within each file to store the vulnerability. - key_path = ndb.StringProperty() + key_path: str = ndb.StringProperty() # If true, don't analyze any Git ranges. - ignore_git = ndb.BooleanProperty(default=False) + ignore_git: bool = ndb.BooleanProperty(default=False) # Whether to detect cherypicks or not (slow for large repos). - detect_cherrypicks = ndb.BooleanProperty(default=True) + detect_cherrypicks: bool = ndb.BooleanProperty(default=True) # Whether to populate "affected[].versions" from Git ranges. - versions_from_repo = ndb.BooleanProperty(default=True) + versions_from_repo: bool = ndb.BooleanProperty(default=True) # Ignore last import time once (SourceRepositoryType.BUCKET). - ignore_last_import_time = ndb.BooleanProperty(default=False) + ignore_last_import_time: bool = ndb.BooleanProperty(default=False) # HTTP link prefix to individual OSV source records. - link = ndb.StringProperty() + link: str = ndb.StringProperty() # HTTP link prefix to individual vulnerability records for humans. - human_link = ndb.StringProperty() + human_link: str = ndb.StringProperty() # DB prefix, if the database allocates its own. # https://ossf.github.io/osv-schema/#id-modified-fields - db_prefix = ndb.StringProperty(repeated=True) + db_prefix: list[str] = ndb.StringProperty(repeated=True) def ignore_file(self, file_path): """Return whether or not we should be ignoring a file.""" @@ -870,18 +874,18 @@ def _pre_put_hook(self): # pylint: disable=arguments-differ class AliasGroup(ndb.Model): """Alias group.""" - bug_ids = ndb.StringProperty(repeated=True) - last_modified = ndb.DateTimeProperty() + bug_ids: list[str] = ndb.StringProperty(repeated=True) + last_modified: datetime = ndb.DateTimeProperty() class AliasAllowListEntry(ndb.Model): """Alias group allow list entry.""" - bug_id = ndb.StringProperty() + bug_id: str = ndb.StringProperty() class AliasDenyListEntry(ndb.Model): """Alias group deny list entry.""" - bug_id = ndb.StringProperty() + bug_id: str = ndb.StringProperty() def get_source_repository(source_name): diff --git a/osv/models.pyi b/osv/models.pyi deleted file mode 100644 index 4a7fa6bdde4..00000000000 --- a/osv/models.pyi +++ /dev/null @@ -1,369 +0,0 @@ -# Copyright 2021 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Datastore types.""" - -import enum -import re -import os -from datetime import datetime - -from typing import List, Self - -from google.cloud import ndb -from . import vulnerability_pb2 - - -class ndbModel(ndb.Model): - key: ndb.Key - - -class IDCounter(ndbModel): - next_id: str - - -class AffectedCommits(ndbModel): - # The main bug ID. - bug_id: str - # The commit hash. - commits: list[bytes] - # Whether or not the bug is public. - public: bool - # The page for this batch of commits. - page: int - - -class RegressResult(ndbModel): - """Regression results.""" - # The commit hash. - commit: str - # Vulnerability summary. - summary: str - # Vulnerability details. - details: str - # Error (if any). - error: str - # OSS-Fuzz issue ID. - issue_id: str - # Project for the bug. - project: str - # Package ecosystem for the project. - ecosystem: str - # Repo URL. - repo_url: str - # Severity of the bug. - severity: str - # Reference URLs. - reference_urls: list[str] - # Source timestamp. - timestamp: datetime - - -class FixResult(ndbModel): - """Fix results.""" - # The commit hash. - commit: str - # Vulnerability summary. - summary: str - # Vulnerability details. - details: str - # Error (if any). - error: str - # OSS-Fuzz issue ID. - issue_id: str - # Project for the bug. - project: str - # Package ecosystem for the project. - ecosystem: str - # Repo URL. - repo_url: str - # Severity of the bug. - severity: str - # Reference URLs. - reference_urls: list[str] - # Source timestamp. - timestamp: datetime - - -class AffectedEvent(ndbModel): - """Affected event.""" - type: str - value: str - - -class AffectedRange2(ndbModel): - """Affected range.""" - # Type of range. - type: str - # Repo URL. - repo_url: str - # Events. - events: list[AffectedEvent] - - -class SourceOfTruth(enum.IntEnum): - """Source of truth.""" - NONE = 0 - # Internal to OSV (e.g. private OSS-Fuzz bugs). - INTERNAL = 1 - # Vulnerabilities that are available in a public repo. - SOURCE_REPO = 2 - - -class Package(ndbModel): - """Package.""" - ecosystem: str - name: str - purl: str - - -class Severity(ndbModel): - """Severity.""" - type: str - score: str - - -class AffectedPackage(ndbModel): - """Affected packages.""" - # The affected package identifier. - package: Package - # The list of affected ranges. - ranges: list[AffectedRange2] - # The list of explicit affected versions. - versions: list[str] - # Database specific metadata. - database_specific: dict - # Ecosystem specific metadata. - ecosystem_specific: dict - # Severity of the bug. - severities: list[Severity] - - -class Credit(ndbModel): - """Credits.""" - name: str - contact: list[str] - type: str - - -class Bug(ndbModel): - """Bug entity.""" - OSV_ID_PREFIX = 'OSV-' - # Very large fake version to use when there is no fix available. - _NOT_FIXED_SEMVER = '999999.999999.999999' - - # Display ID as used by the source database. The full qualified database that - # OSV tracks this as may be different. - db_id: str - # Other IDs this bug is known as. - aliases: list[str] - # Related IDs. - related: list[str] - # Status of the bug. - status: int - # Timestamp when Bug was allocated. - timestamp: datetime - # When the entry was last edited. - last_modified: datetime - # Last modified field of the original imported file - import_last_modified: datetime - # When the entry was withdrawn. - withdrawn: datetime - # The source identifier. - # For OSS-Fuzz, this oss-fuzz:. - # For others this is :. - source_id: str - # The main fixed commit (from bisection). - fixed: str - # The main regressing commit (from bisection). - regressed: str - # List of affected versions. - affected: list[str] - # List of normalized versions indexed for fuzzy matching. - affected_fuzzy: list[str] - # OSS-Fuzz issue ID. - issue_id: str - # Package URL for this package. - purl: list[str] - # Project/package name for the bug. - project: list[str] - # Package ecosystem for the project. - ecosystem: list[str] - # Summary for the bug. - summary: str - # Vulnerability details. - details: str - # Severity of the bug. - severities: list[Severity] - # Credits for the bug. - credits: list[Credit] - # Whether or not the bug is public (OSS-Fuzz only). - public: bool - # Reference URL types (dict of url -> type). - reference_url_types: dict - # Search indices (auto-populated) - search_indices: list[str] - # Whether or not the bug has any affected versions (auto-populated). - has_affected: bool - # Source of truth for this Bug. - source_of_truth: SourceOfTruth - # Whether the bug is fixed (indexed for querying). - is_fixed: bool - # Database specific. - database_specific: dict - # Normalized SEMVER fixed indexes for querying. - semver_fixed_indexes: list[str] - # Affected packages and versions. - affected_packages: list[AffectedPackage] - # The source of this Bug. - source: str - - def update_from_vulnerability(self, - vulnerability: vulnerability_pb2.Vulnerability): - ... - - def to_vulnerability(self, - include_source=False, - include_alias=True) -> vulnerability_pb2.Vulnerability: - ... - - @ndb.tasklet - def to_vulnerability_async(self, include_source=False): - ... - - -class RepoIndex(ndbModel): - """RepoIndex entry""" - # The dependency name - name: str - # The base cpe without the version - base_cpe: str - # The repository commit - commit: bytes - # The source address - repo_addr: str - # The scanned file extensions - file_exts: list[str] - # The hash algorithm used - file_hash_type: str - # The repository type - repo_type: str - # A bitmap of which buckets are empty - empty_bucket_bitmap: bytes - # Number of files in this repo - file_count: int - # Tag name of the source - tag: str - - -class FileResult(ndbModel): - """FileResult entry containing the path and hash""" - # The hash value of the file - hash: bytes - # The file path - path: str - - -class RepoIndexBucket(ndbModel): - """RepoIndexResult entries containing the actual hash values""" - # The file results per file - node_hash: bytes - # number of files this hash represents - files_contained: int - - -class SourceRepositoryType(enum.IntEnum): - """SourceRepository type.""" - GIT = 0 - BUCKET = 1 - REST_ENDPOINT = 2 - - -class SourceRepository(ndbModel): - """Source repository.""" - # The SourceRepositoryType of the repository. - type: int - # The name of the source. - name: str - # The repo URL for the source for SourceRepositoryType.GIT. - repo_url: str - # The username to use for SSH auth for SourceRepositoryType.GIT. - repo_username: str - # Optional branch for repo for SourceRepositoryType.GIT. - repo_branch: str - # The API endpoint for SourceRepositoryType.REST_ENDPOINT. - rest_api_url: str - # Bucket name for SourceRepositoryType.BUCKET. - bucket: str - # Vulnerability data not under this path is ignored by the importer. - directory_path: str - # Last synced hash for SourceRepositoryType.GIT. - last_synced_hash: str - # Last date recurring updates were requested. - last_update_date: datetime - # Patterns of files to exclude (regex). - ignore_patterns: list[str] - # Whether this repository is editable. - editable: bool - # Default extension. - extension: str - # Key path within each file to store the vulnerability. - key_path: str - # If true, don't analyze any Git ranges. - ignore_git: bool - # Whether to detect cherypicks or not (slow for large repos). - detect_cherrypicks: bool - # Whether to populate "affected[].versions" from Git ranges. - versions_from_repo: bool - # Ignore last import time once (SourceRepositoryType.BUCKET). - ignore_last_import_time: bool - # HTTP link prefix to individual OSV source records. - link: str - # HTTP link prefix to individual vulnerability records for humans. - human_link: str - # DB prefix, if the database allocates its own. - # https://ossf.github.io/osv-schema/#id-modified-fields - db_prefix: list[str] - - def ignore_file(self, file_path): - """Return whether or not we should be ignoring a file.""" - if not self.ignore_patterns: - return False - - file_name = os.path.basename(file_path) - for pattern in self.ignore_patterns: - if re.match(pattern, file_name): - return True - - return False - - def _pre_put_hook(self): # pylint: disable=arguments-differ - """Pre-put hook for validation.""" - if self.type == SourceRepositoryType.BUCKET and self.editable: - raise ValueError('BUCKET SourceRepository cannot be editable.') - - -class AliasGroup(ndbModel): - """Alias group.""" - bug_ids: list[str] - last_modified: datetime - - -class AliasAllowListEntry(ndbModel): - """Alias group allow list entry.""" - bug_id: str - - -class AliasDenyListEntry(ndbModel): - """Alias group deny list entry.""" - bug_id: str diff --git a/pyproject.toml b/pyproject.toml index 6d45d41fb92..e59f4293018 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,11 @@ pylint = "*" grpcio-tools = "*" mypy-protobuf = "^3.6.0" +[tool.pyright] +executionEnvironments = [ + { root = "osv/models.py", reportAssignmentType = "none" }, +] + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" From 7d1539d10f03a7127e0a500664e7a98240e2773a Mon Sep 17 00:00:00 2001 From: Rex P Date: Thu, 29 Aug 2024 14:50:55 +1000 Subject: [PATCH 07/13] Formatting and gitignore --- osv/models.py | 3 ++- tools/api-performance-test/.gitignore | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 tools/api-performance-test/.gitignore diff --git a/osv/models.py b/osv/models.py index 3680bda8681..fe597f114a0 100644 --- a/osv/models.py +++ b/osv/models.py @@ -304,7 +304,8 @@ class Bug(ndb.Model): # Whether or not the bug has any affected versions (auto-populated). has_affected: bool = ndb.BooleanProperty() # Source of truth for this Bug. - source_of_truth: SourceOfTruth = ndb.IntegerProperty(default=SourceOfTruth.INTERNAL) + source_of_truth: SourceOfTruth = ndb.IntegerProperty( + default=SourceOfTruth.INTERNAL) # Whether the bug is fixed (indexed for querying). is_fixed: bool = ndb.BooleanProperty() # Database specific. diff --git a/tools/api-performance-test/.gitignore b/tools/api-performance-test/.gitignore new file mode 100644 index 00000000000..a58010f74b5 --- /dev/null +++ b/tools/api-performance-test/.gitignore @@ -0,0 +1 @@ +all_bugs From 9cf9be12d3747155f30f07a79276d9ede4b3cf51 Mon Sep 17 00:00:00 2001 From: Rex P Date: Thu, 29 Aug 2024 15:45:20 +1000 Subject: [PATCH 08/13] Remove unneeded type --- osv/model_helpers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/osv/model_helpers.py b/osv/model_helpers.py index e9aaae08cd6..a802c384755 100644 --- a/osv/model_helpers.py +++ b/osv/model_helpers.py @@ -15,8 +15,6 @@ import datetime -from typing import List, Self - from google.cloud import ndb # pylint: disable=relative-beyond-top-level From f63cff46975173f73bf77245532e04e49da04a55 Mon Sep 17 00:00:00 2001 From: Rex P Date: Thu, 29 Aug 2024 16:02:16 +1000 Subject: [PATCH 09/13] Apprently the deprecation alternative is not correct? --- osv/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osv/models.py b/osv/models.py index fe597f114a0..135590c1ee7 100644 --- a/osv/models.py +++ b/osv/models.py @@ -65,7 +65,9 @@ def _check_valid_event_type(prop, value): def utcnow(): """For mocking.""" - return datetime.now(UTC) + # The alternative mentioned in the deprecation notice + # does not behave in the same way? Tests fail. + return datetime.utcnow() def _get_purl_indexes(affected_packages): From 4fe2a66667d77f7012a6c9fd5c20b8c9ea17989c Mon Sep 17 00:00:00 2001 From: Rex P Date: Thu, 29 Aug 2024 16:04:52 +1000 Subject: [PATCH 10/13] Eventually the tests will pass --- osv/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osv/models.py b/osv/models.py index 135590c1ee7..b651cdf5ac3 100644 --- a/osv/models.py +++ b/osv/models.py @@ -13,7 +13,7 @@ # limitations under the License. """Datastore types.""" -from datetime import datetime, UTC +from datetime import datetime import enum import logging import re From 04424e41dba035f91d1f087617c9816b31fa3792 Mon Sep 17 00:00:00 2001 From: Rex P Date: Tue, 3 Sep 2024 14:01:18 +1000 Subject: [PATCH 11/13] Add type for callable, remove unnecessary List import. --- gcp/api/server.py | 31 +++++++++++++++++++++---------- osv/models.py | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/gcp/api/server.py b/gcp/api/server.py index d00357ff0b4..a4b8ad1b753 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -15,7 +15,6 @@ import argparse import codecs -import concurrent from dataclasses import dataclass from datetime import datetime, timedelta import math @@ -26,7 +25,7 @@ import threading import time import concurrent.futures -from typing import Callable, List +from typing import Callable from collections import defaultdict @@ -96,6 +95,13 @@ # Prefix for the _TAG_PREFIX = "refs/tags/" +# ---- +# Type Aliases: + +ToResponseCallable = Callable[[osv.Bug], vulnerability_pb2.Vulnerability] + +# ---- + _ndb_client = ndb.Client() @@ -156,7 +162,7 @@ class OSVServicer(osv_service_v1_pb2_grpc.OSVServicer, @trace_filter.log_trace def GetVulnById(self, request, context: grpc.ServicerContext): """Return a `Vulnerability` object for a given OSV ID.""" - bug: osv.Bug | None = osv.Bug.get_by_id(request.id) # type: ignore + bug = osv.Bug.get_by_id(request.id) if not bug or bug.status == osv.BugStatus.UNPROCESSED: context.abort(grpc.StatusCode.NOT_FOUND, 'Bug not found.') return None @@ -493,7 +499,7 @@ def should_skip_bucket(path: str) -> bool: def process_buckets( - file_results: List[osv.FileResult]) -> list[osv.RepoIndexBucket]: + file_results: list[osv.FileResult]) -> list[osv.RepoIndexBucket]: """ Create buckets in the same process as indexer to generate the same bucket hashes @@ -727,7 +733,7 @@ def do_query(query: osv_service_v1_pb2.Query, 'version specified in params and purl query', ) - def to_response(b): + def to_response(b: osv.Bug): # Skip retrieving aliases from to_vulnerability(). # Retrieve it asynchronously later. return bug_to_response(b, include_details) @@ -808,7 +814,9 @@ def to_response(b): return bugs, next_page_token_str -def bug_to_response(bug, include_details=True, include_alias=False): +def bug_to_response(bug: osv.Bug, + include_details=True, + include_alias=False) -> vulnerability_pb2.Vulnerability: """Convert a Bug entity to a response object.""" if include_details: return bug.to_vulnerability( @@ -818,7 +826,10 @@ def bug_to_response(bug, include_details=True, include_alias=False): @ndb.tasklet -def _get_bugs(bug_ids, to_response=bug_to_response): +def _get_bugs( + bug_ids: list[str], + to_response: ToResponseCallable = bug_to_response +) -> list[vulnerability_pb2.Vulnerability]: """Get bugs from bug ids.""" bugs = ndb.get_multi_async([ndb.Key(osv.Bug, bug_id) for bug_id in bug_ids ]) # type: ignore @@ -847,7 +858,7 @@ def _datastore_normalized_purl(purl: PackageURL): def query_by_commit( context: QueryContext, commit: bytes, - to_response: Callable = bug_to_response + to_response: ToResponseCallable = bug_to_response ) -> list[vulnerability_pb2.Vulnerability]: """ Perform a query by commit. @@ -1151,7 +1162,7 @@ def query_by_version( ecosystem: str | None, purl: PackageURL | None, version: str, - to_response: Callable = bug_to_response + to_response: ToResponseCallable = bug_to_response ) -> list[vulnerability_pb2.Vulnerability]: """ Query by (fuzzy) version. @@ -1309,7 +1320,7 @@ def _query_by_comparing_versions(context: QueryContext, query: ndb.Query, def query_by_package( context: QueryContext, package_name: str | None, ecosystem: str | None, purl: PackageURL | None, - to_response: Callable) -> list[vulnerability_pb2.Vulnerability]: + to_response: ToResponseCallable) -> list[vulnerability_pb2.Vulnerability]: """ Query by package. diff --git a/osv/models.py b/osv/models.py index b651cdf5ac3..8c26e69f951 100644 --- a/osv/models.py +++ b/osv/models.py @@ -342,7 +342,7 @@ def repo_url(self): return None @classmethod - def get_by_id(cls, vuln_id, *args, **kwargs) -> Self: + def get_by_id(cls, vuln_id, *args, **kwargs) -> Self | None: """Overridden get_by_id to handle OSV allocated IDs.""" result = cls.query(cls.db_id == vuln_id).get() if result: From d89d06a030758159120081ca125c6fca20b6f010 Mon Sep 17 00:00:00 2001 From: Rex P Date: Tue, 3 Sep 2024 14:04:33 +1000 Subject: [PATCH 12/13] Add comment for ValueError raise. --- gcp/api/server.py | 2 ++ osv/models.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/gcp/api/server.py b/gcp/api/server.py index a4b8ad1b753..af27112f420 100644 --- a/gcp/api/server.py +++ b/gcp/api/server.py @@ -771,6 +771,8 @@ def to_response(b: osv.Bug): else: context.service_context.abort(grpc.StatusCode.INVALID_ARGUMENT, 'Invalid query.') + # This will never be reached, and is just here for the type checker, + # to know that control flow breaks here. raise ValueError # Asynchronously retrieve computed aliases and related ids here diff --git a/osv/models.py b/osv/models.py index 8c26e69f951..1a312025996 100644 --- a/osv/models.py +++ b/osv/models.py @@ -20,7 +20,7 @@ import os from urllib.parse import urlparse -from typing import List, Self +from typing import Self from google.cloud import ndb from google.protobuf import json_format @@ -89,8 +89,8 @@ def _repo_name(repo_url: str) -> str: return name -def _maybe_strip_repo_prefixes(versions: List[str], - repo_urls: List[str]) -> str: +def _maybe_strip_repo_prefixes(versions: list[str], + repo_urls: list[str]) -> str: """Try to strip the repo name from tags prior to normalizing. There are some particularly regex-unfriendly tag names that prefix the From d47dccfce889e6915995d122d04ef363014ed89c Mon Sep 17 00:00:00 2001 From: Rex P Date: Mon, 9 Sep 2024 11:14:53 +1000 Subject: [PATCH 13/13] Run poetry lock again --- gcp/api/poetry.lock | 182 ++++++++++++++++++++++++------------------- poetry.lock | 184 +++++++++++++++++++++++++------------------- 2 files changed, 209 insertions(+), 157 deletions(-) diff --git a/gcp/api/poetry.lock b/gcp/api/poetry.lock index 8e4c1909c6b..e90274ad985 100644 --- a/gcp/api/poetry.lock +++ b/gcp/api/poetry.lock @@ -65,78 +65,78 @@ files = [ [[package]] name = "cffi" -version = "1.17.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, - {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, - {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, - {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, - {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, - {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, - {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, - {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, - {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, - {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, - {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, - {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, - {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, - {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, - {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, - {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -812,6 +812,21 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mypy-protobuf" +version = "3.6.0" +description = "Generate mypy stub files from protobuf specs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c"}, + {file = "mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c"}, +] + +[package.dependencies] +protobuf = ">=4.25.3" +types-protobuf = ">=4.24" + [[package]] name = "opentelemetry-api" version = "1.27.0" @@ -886,19 +901,19 @@ pyparsing = ">=2.0.2" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"}, + {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "proto-plus" @@ -1332,13 +1347,13 @@ files = [ [[package]] name = "setuptools" -version = "74.1.1" +version = "74.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-74.1.1-py3-none-any.whl", hash = "sha256:fc91b5f89e392ef5b77fe143b17e32f65d3024744fba66dc3afe07201684d766"}, - {file = "setuptools-74.1.1.tar.gz", hash = "sha256:2353af060c06388be1cecbf5953dcdb1f38362f87a2356c480b6b4d5fcfc8847"}, + {file = "setuptools-74.1.2-py3-none-any.whl", hash = "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308"}, + {file = "setuptools-74.1.2.tar.gz", hash = "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"}, ] [package.extras] @@ -1372,6 +1387,17 @@ files = [ {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] +[[package]] +name = "types-protobuf" +version = "5.27.0.20240907" +description = "Typing stubs for protobuf" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-protobuf-5.27.0.20240907.tar.gz", hash = "sha256:bb6f90f66b18d4d1c75667b6586334b0573a6fcee5eb0142a7348a765a7cbadc"}, + {file = "types_protobuf-5.27.0.20240907-py3-none-any.whl", hash = "sha256:5443270534cc8072909ef7ad9e1421ccff924ca658749a6396c0c43d64c32676"}, +] + [[package]] name = "urllib3" version = "2.2.2" @@ -1506,4 +1532,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "02961e990f6033875f823a460833d9ccf4a18d747498aa170611ad074241f242" +content-hash = "ba882a87cceb578615108c25d664bdb48b23dc2e87ecf94bf5c049b53a64cc54" diff --git a/poetry.lock b/poetry.lock index 0362ed43d10..8e53e49c4e0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "astroid" @@ -65,78 +65,78 @@ files = [ [[package]] name = "cffi" -version = "1.17.0" +version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ - {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, - {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, - {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, - {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, - {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, - {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, - {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, - {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, - {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, - {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, - {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, - {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, - {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, - {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, - {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, - {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, - {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, - {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, - {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, - {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, - {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, - {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, - {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, - {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, - {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, - {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, - {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, - {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, - {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, - {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, - {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] @@ -782,6 +782,21 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mypy-protobuf" +version = "3.6.0" +description = "Generate mypy stub files from protobuf specs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c"}, + {file = "mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c"}, +] + +[package.dependencies] +protobuf = ">=4.25.3" +types-protobuf = ">=4.24" + [[package]] name = "opentelemetry-api" version = "1.27.0" @@ -813,19 +828,19 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "platformdirs" -version = "4.2.2" +version = "4.3.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, + {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"}, + {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "proto-plus" @@ -1259,13 +1274,13 @@ files = [ [[package]] name = "setuptools" -version = "74.1.1" +version = "74.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-74.1.1-py3-none-any.whl", hash = "sha256:fc91b5f89e392ef5b77fe143b17e32f65d3024744fba66dc3afe07201684d766"}, - {file = "setuptools-74.1.1.tar.gz", hash = "sha256:2353af060c06388be1cecbf5953dcdb1f38362f87a2356c480b6b4d5fcfc8847"}, + {file = "setuptools-74.1.2-py3-none-any.whl", hash = "sha256:5f4c08aa4d3ebcb57a50c33b1b07e94315d7fc7230f7115e47fc99776c8ce308"}, + {file = "setuptools-74.1.2.tar.gz", hash = "sha256:95b40ed940a1c67eb70fc099094bd6e99c6ee7c23aa2306f4d2697ba7916f9c6"}, ] [package.extras] @@ -1299,6 +1314,17 @@ files = [ {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] +[[package]] +name = "types-protobuf" +version = "5.27.0.20240907" +description = "Typing stubs for protobuf" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-protobuf-5.27.0.20240907.tar.gz", hash = "sha256:bb6f90f66b18d4d1c75667b6586334b0573a6fcee5eb0142a7348a765a7cbadc"}, + {file = "types_protobuf-5.27.0.20240907-py3-none-any.whl", hash = "sha256:5443270534cc8072909ef7ad9e1421ccff924ca658749a6396c0c43d64c32676"}, +] + [[package]] name = "urllib3" version = "2.2.2" @@ -1433,4 +1459,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "75de6400ddef55dacce3925c9f8d88b739b4100c80747279091a0d59174c4796" +content-hash = "4a08ff8078fad3a261e8e9e3be2f49aa7a3099d627dfcc5fdad40a5b48e89f11"