diff --git a/.github/workflows/container-local-test.yml b/.github/workflows/container-local-test.yml index 6021e2c0..447e6053 100644 --- a/.github/workflows/container-local-test.yml +++ b/.github/workflows/container-local-test.yml @@ -5,10 +5,10 @@ on: workflow_dispatch: push: branches: - - 'main' + - "main" pull_request: branches: - - 'main' + - "main" env: IMAGE_BASE: scanoss/scanoss-py-base @@ -27,7 +27,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.9.x' + python-version: "3.9.x" - name: Install Dependencies run: | @@ -91,10 +91,11 @@ jobs: docker image ls -a docker run ${{ env.IMAGE_NAME }} version docker run ${{ env.IMAGE_NAME }} utils fast - docker run -v "$(pwd)":"/scanoss" ${{ env.IMAGE_NAME }} scan -o results.json tests + docker run -e SCANOSS_API_KEY="${{ secrets.SC_API_KEY }}" -v "$(pwd)":"/scanoss" ${{ env.IMAGE_NAME }} scan -o results.json tests id_count=$(cat results.json | grep '"id":' | wc -l) echo "ID Count: $id_count" if [[ $id_count -lt 1 ]]; then echo "Error: Scan test did not produce any results. Failing" exit 1 fi + diff --git a/.github/workflows/container-publish-ghcr.yml b/.github/workflows/container-publish-ghcr.yml index 14125a6e..3d8fb39d 100644 --- a/.github/workflows/container-publish-ghcr.yml +++ b/.github/workflows/container-publish-ghcr.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9.x" + python-version: '3.9.x' - name: Install Dependencies run: | @@ -130,7 +130,7 @@ jobs: docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest docker run ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} version docker run ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} utils fast - docker run -v "$(pwd)":"/scanoss" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} scan -o results.json tests + docker run -e SCANOSS_API_KEY="${{ secrets.SC_API_KEY }}" -v "$(pwd)":"/scanoss" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} scan -o results.json tests id_count=$(cat results.json | grep '"id":' | wc -l) echo "ID Count: $id_count" if [[ $id_count -lt 1 ]]; then diff --git a/.github/workflows/python-local-test.yml b/.github/workflows/python-local-test.yml index 24f36026..50e13960 100644 --- a/.github/workflows/python-local-test.yml +++ b/.github/workflows/python-local-test.yml @@ -13,6 +13,9 @@ on: permissions: contents: read +env: + SCANOSS_API_KEY: ${{ secrets.SC_API_KEY }} + jobs: build: runs-on: ubuntu-latest @@ -71,6 +74,7 @@ jobs: echo "Error: Scan test did not produce any results. Failing" exit 1 fi + - name: Run Tests HPSM (fast winnowing) run: | @@ -85,6 +89,7 @@ jobs: echo "Error: WFP test did not produce any results. Failing" exit 1 fi + - name: Run Unit Tests run: | diff --git a/.github/workflows/python-publish-pypi.yml b/.github/workflows/python-publish-pypi.yml index 793692c3..2838bed9 100644 --- a/.github/workflows/python-publish-pypi.yml +++ b/.github/workflows/python-publish-pypi.yml @@ -7,6 +7,9 @@ on: tags: - "v*.*.*" +env: + SCANOSS_API_KEY: ${{ secrets.SC_API_KEY }} + jobs: deploy: runs-on: ubuntu-latest @@ -16,7 +19,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9.x" + python-version: '3.9.x' - name: Install dependencies run: | @@ -70,7 +73,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9.x" + python-version: '3.9.x' - name: Install Remote Package uses: nick-fields/retry@v3 diff --git a/.github/workflows/python-publish-testpypi.yml b/.github/workflows/python-publish-testpypi.yml index e0ecfa1c..d44c02a0 100644 --- a/.github/workflows/python-publish-testpypi.yml +++ b/.github/workflows/python-publish-testpypi.yml @@ -6,6 +6,9 @@ on: [workflow_dispatch] permissions: contents: read +env: + SCANOSS_API_KEY: ${{ secrets.SC_API_KEY }} + jobs: deploy: runs-on: ubuntu-latest @@ -15,7 +18,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9.x" + python-version: '3.9.x' - name: Install Dependencies run: | @@ -65,7 +68,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9.x" + python-version: '3.9.x' - name: Install Remote Package run: | diff --git a/.github/workflows/version-tag.yml b/.github/workflows/version-tag.yml index 0d333050..55afecb0 100644 --- a/.github/workflows/version-tag.yml +++ b/.github/workflows/version-tag.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9.x" + python-version: '3.9.x' - name: Determine Tag id: taggerVersion run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index fb3d1d38..663c4eb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Upcoming changes... +## [1.33.0] - 2025-09-19 +### Added +- Add `licenses` sub-command to `component` command +- Add support for ingesting CDX to all decoration commands +- Add CDX input validation + ## [1.32.0] - 2025-09-01 ### Added - Switched vulnerability and dependency APIs to use REST by default @@ -176,7 +182,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.20.2] - 2025-02-26 ### Fixed -- Fixed provenance command +- Fixed provenance command ## [1.20.1] - 2025-02-18 ### Added @@ -238,7 +244,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.17.5] - 2024-11-12 ### Fixed - Fix dependencies scan result structure - + ## [1.17.4] - 2024-11-08 ### Fixed - Fix backslashes in file paths on Windows @@ -255,7 +261,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added supplier to SPDX packages ### Changed -- Changed undeclared summary output +- Changed undeclared summary output ## [1.17.1] - 2024-10-24 ### Fixed @@ -288,7 +294,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for Python3.12 - Module `pkg_resources` has been replaced with `importlib_resources` -- Added support for UTF-16 filenames +- Added support for UTF-16 filenames ## [1.13.0] - 2024-06-05 ### Added @@ -367,11 +373,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.6.0] - 2023-06-16 ### Added - Added support for High Precision Snippet Matching (`--hpsm` or `-H`) while scanning - - `scanoss-py scan --hpsm ...` + - `scanoss-py scan --hpsm ...` ## [1.5.2] - 2023-06-13 ### Added -- Added retry limit option (`--retry`) while scanning +- Added retry limit option (`--retry`) while scanning - `--retry 0` will fail immediately ## [1.5.1] - 2023-04-21 @@ -660,4 +666,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [1.31.3]: https://github.com/scanoss/scanoss.py/compare/v1.31.2...v1.31.3 [1.31.4]: https://github.com/scanoss/scanoss.py/compare/v1.31.3...v1.31.4 [1.31.5]: https://github.com/scanoss/scanoss.py/compare/v1.31.4...v1.31.5 -[1.31.5]: https://github.com/scanoss/scanoss.py/compare/v1.31.5...v1.32.0 +[1.32.0]: https://github.com/scanoss/scanoss.py/compare/v1.31.5...v1.32.0 +[1.33.0]: https://github.com/scanoss/scanoss.py/compare/v1.32.0...v1.33.0 diff --git a/CLIENT_HELP.md b/CLIENT_HELP.md index e6f3e865..5707adbc 100644 --- a/CLIENT_HELP.md +++ b/CLIENT_HELP.md @@ -337,6 +337,44 @@ The following command provides the capability to search the SCANOSS KB for compo scanoss-py comp prov -p "pkg:github/unoconv/unoconv" --origin ``` +#### Component Licenses +The following command provides the capability to search the SCANOSS KB for licenses for Open Source components: +```bash +scanoss-py comp licenses -p "pkg:github/jquery/jquery" -p "pkg:npm/express" +``` +It is possible to supply multiple PURLs by repeating the `-p pkg` option, or providing a purl input file `-i purl-input.json` ([for example](tests/data/purl-input.json)): +```bash +scanoss-py comp licenses -i purl-input.json -o component-licenses.json +``` + +The licenses command also supports CycloneDX (CDX) input files. You can provide a CycloneDX SBOM file and retrieve license information for all components: +```bash +scanoss-py comp licenses -i cyclonedx-sbom.json -o component-licenses.json +``` + +### CDX Input Support for Component Commands +Several component commands now support CycloneDX (CDX) input files. This allows you to analyze components from existing SBOM files: + +**Supported commands with CDX input:** +- `comp vulns` - Analyze vulnerabilities from CDX file +- `comp licenses` - Retrieve licenses from CDX file +- `comp crypto` - Detect cryptographic algorithms from CDX file +- `comp semgrep` - Find semgrep issues from CDX file + +**Example using CDX input:** +```bash +# Analyze vulnerabilities from a CycloneDX SBOM +scanoss-py comp vulns -i sbom.cdx.json -o vulnerabilities.json + +# Get licenses for all components in a CycloneDX SBOM +scanoss-py comp licenses -i sbom.cdx.json -o licenses.json + +# Detect cryptographic usage from CDX +scanoss-py comp crypto -i sbom.cdx.json -o crypto-findings.json +``` + +The CDX input file is automatically validated to ensure it's a valid CycloneDX format before processing. + ### Results Commands The `results` command provides the capability to operate on scan results. For example: diff --git a/Dockerfile b/Dockerfile index f1fb4648..2005bc3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,7 @@ RUN pip3 install --no-cache-dir /install/scanoss-*-py3-none-any.whl RUN pip3 install --no-cache-dir scanoss_winnowing RUN pip3 install --no-cache-dir -r /install/requirements-dev.txt RUN pip3 install --no-cache-dir scancode-toolkit-mini +RUN pip3 install --no-cache-dir click==8.2.1 # Temporary workaround for scancode-toolkit-mini (https://github.com/aboutcode-org/scancode-toolkit/issues/4573) # Download compile and install typecode-libmagic from source (as there is not ARM wheel available) ADD https://github.com/nexB/typecode_libmagic_from_sources/archive/refs/tags/v5.39.210212.tar.gz /install/ @@ -66,7 +67,7 @@ RUN curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | # Setup working directory and user WORKDIR /scanoss # Run scancode once to setup any initial files, etc. so that it'll run faster later -RUN scancode -p --only-findings --quiet --json /scanoss/scancode-dependencies.json /scanoss && rm -f /scanoss/scancode-dependencies.json +RUN scancode --package --only-findings --quiet --json /scanoss/scancode-dependencies.json /scanoss && rm -f /scanoss/scancode-dependencies.json # Image with no default entry point FROM no_entry_point AS jenkins diff --git a/requirements.txt b/requirements.txt index 1d3fc07c..9beb5da0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,9 @@ requests crc32c>=2.2 binaryornot progress -grpcio>1.42.0 -protobuf>3.19.1 +grpcio>=1.73.1 +protobuf>=6.3.1 +protoc-gen-openapiv2 pypac urllib3 pyOpenSSL @@ -13,5 +14,4 @@ packageurl-python pathspec jsonschema crc -protoc-gen-openapiv2 cyclonedx-python-lib[validation] \ No newline at end of file diff --git a/scanoss.json b/scanoss.json index 813b121a..954cd89a 100644 --- a/scanoss.json +++ b/scanoss.json @@ -3,9 +3,9 @@ "skip": { "patterns": { "scanning": [ - "src/protoc_gen_swagger/", - "src/scanoss/api/", - "docs/make.bat" + "src/protoc_gen_swagger", + "docs", + "scanoss_common_pb2_grpc.py" ] }, "sizes": {} @@ -16,6 +16,8 @@ { "purl": "pkg:github/scanoss/scanoss.py" } - ] + ], + "remove": [] } -} \ No newline at end of file +} + diff --git a/setup.cfg b/setup.cfg index cb37a860..602b0b3e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,8 +29,9 @@ install_requires = crc32c>=2.2 binaryornot progress - grpcio>1.42.0 - protobuf>3.19.1 + grpcio>=1.73.1 + protobuf>=6.3.1 + protoc-gen-openapiv2 pypac pyOpenSSL google-api-core diff --git a/src/protoc_gen_swagger/options/annotations_pb2.py b/src/protoc_gen_swagger/options/annotations_pb2.py index c568f388..d08ab680 100644 --- a/src/protoc_gen_swagger/options/annotations_pb2.py +++ b/src/protoc_gen_swagger/options/annotations_pb2.py @@ -1,11 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: protoc-gen-swagger/options/annotations.proto +# Protobuf Python Version: 6.31.0 """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 0, + '', + 'protoc-gen-swagger/options/annotations.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -17,15 +28,10 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,protoc-gen-swagger/options/annotations.proto\x12\'grpc.gateway.protoc_gen_swagger.options\x1a google/protobuf/descriptor.proto\x1a*protoc-gen-swagger/options/openapiv2.proto:j\n\x11openapiv2_swagger\x12\x1c.google.protobuf.FileOptions\x18\x92\x08 \x01(\x0b\x32\x30.grpc.gateway.protoc_gen_swagger.options.Swagger:p\n\x13openapiv2_operation\x12\x1e.google.protobuf.MethodOptions\x18\x92\x08 \x01(\x0b\x32\x32.grpc.gateway.protoc_gen_swagger.options.Operation:k\n\x10openapiv2_schema\x12\x1f.google.protobuf.MessageOptions\x18\x92\x08 \x01(\x0b\x32/.grpc.gateway.protoc_gen_swagger.options.Schema:e\n\ropenapiv2_tag\x12\x1f.google.protobuf.ServiceOptions\x18\x92\x08 \x01(\x0b\x32,.grpc.gateway.protoc_gen_swagger.options.Tag:l\n\x0fopenapiv2_field\x12\x1d.google.protobuf.FieldOptions\x18\x92\x08 \x01(\x0b\x32\x33.grpc.gateway.protoc_gen_swagger.options.JSONSchemaBCZAgithub.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/optionsb\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'protoc_gen_swagger.options.annotations_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(openapiv2_swagger) - google_dot_protobuf_dot_descriptor__pb2.MethodOptions.RegisterExtension(openapiv2_operation) - google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(openapiv2_schema) - google_dot_protobuf_dot_descriptor__pb2.ServiceOptions.RegisterExtension(openapiv2_tag) - google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(openapiv2_field) - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'ZAgithub.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options' +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'protoc_gen_swagger.options.annotations_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'ZAgithub.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options' # @@protoc_insertion_point(module_scope) diff --git a/src/protoc_gen_swagger/options/annotations_pb2.pyi b/src/protoc_gen_swagger/options/annotations_pb2.pyi new file mode 100644 index 00000000..82a4bd56 --- /dev/null +++ b/src/protoc_gen_swagger/options/annotations_pb2.pyi @@ -0,0 +1,48 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.descriptor_pb2 +import google.protobuf.internal.extension_dict +import protoc_gen_swagger.options.openapiv2_pb2 + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +OPENAPIV2_SWAGGER_FIELD_NUMBER: builtins.int +OPENAPIV2_OPERATION_FIELD_NUMBER: builtins.int +OPENAPIV2_SCHEMA_FIELD_NUMBER: builtins.int +OPENAPIV2_TAG_FIELD_NUMBER: builtins.int +OPENAPIV2_FIELD_FIELD_NUMBER: builtins.int +openapiv2_swagger: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FileOptions, protoc_gen_swagger.options.openapiv2_pb2.Swagger] +"""ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project. + +All IDs are the same, as assigned. It is okay that they are the same, as they extend +different descriptor messages. +""" +openapiv2_operation: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MethodOptions, protoc_gen_swagger.options.openapiv2_pb2.Operation] +"""ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project. + +All IDs are the same, as assigned. It is okay that they are the same, as they extend +different descriptor messages. +""" +openapiv2_schema: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, protoc_gen_swagger.options.openapiv2_pb2.Schema] +"""ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project. + +All IDs are the same, as assigned. It is okay that they are the same, as they extend +different descriptor messages. +""" +openapiv2_tag: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.ServiceOptions, protoc_gen_swagger.options.openapiv2_pb2.Tag] +"""ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project. + +All IDs are the same, as assigned. It is okay that they are the same, as they extend +different descriptor messages. +""" +openapiv2_field: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, protoc_gen_swagger.options.openapiv2_pb2.JSONSchema] +"""ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project. + +All IDs are the same, as assigned. It is okay that they are the same, as they extend +different descriptor messages. +""" diff --git a/src/protoc_gen_swagger/options/annotations_pb2_grpc.py b/src/protoc_gen_swagger/options/annotations_pb2_grpc.py index 2daafffe..d1e1d60e 100644 --- a/src/protoc_gen_swagger/options/annotations_pb2_grpc.py +++ b/src/protoc_gen_swagger/options/annotations_pb2_grpc.py @@ -1,4 +1,24 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings + +GRPC_GENERATED_VERSION = '1.73.1' +GRPC_VERSION = grpc.__version__ +_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: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in protoc_gen_swagger/options/annotations_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}.' + ) diff --git a/src/protoc_gen_swagger/options/openapiv2_pb2.py b/src/protoc_gen_swagger/options/openapiv2_pb2.py index 0df96e43..b0db8ffe 100644 --- a/src/protoc_gen_swagger/options/openapiv2_pb2.py +++ b/src/protoc_gen_swagger/options/openapiv2_pb2.py @@ -1,11 +1,22 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE # source: protoc-gen-swagger/options/openapiv2.proto +# Protobuf Python Version: 6.31.0 """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 0, + '', + 'protoc-gen-swagger/options/openapiv2.proto' +) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -17,102 +28,102 @@ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*protoc-gen-swagger/options/openapiv2.proto\x12\'grpc.gateway.protoc_gen_swagger.options\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xa0\x07\n\x07Swagger\x12\x0f\n\x07swagger\x18\x01 \x01(\t\x12;\n\x04info\x18\x02 \x01(\x0b\x32-.grpc.gateway.protoc_gen_swagger.options.Info\x12\x0c\n\x04host\x18\x03 \x01(\t\x12\x11\n\tbase_path\x18\x04 \x01(\t\x12O\n\x07schemes\x18\x05 \x03(\x0e\x32>.grpc.gateway.protoc_gen_swagger.options.Swagger.SwaggerScheme\x12\x10\n\x08\x63onsumes\x18\x06 \x03(\t\x12\x10\n\x08produces\x18\x07 \x03(\t\x12R\n\tresponses\x18\n \x03(\x0b\x32?.grpc.gateway.protoc_gen_swagger.options.Swagger.ResponsesEntry\x12Z\n\x14security_definitions\x18\x0b \x01(\x0b\x32<.grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions\x12N\n\x08security\x18\x0c \x03(\x0b\x32<.grpc.gateway.protoc_gen_swagger.options.SecurityRequirement\x12U\n\rexternal_docs\x18\x0e \x01(\x0b\x32>.grpc.gateway.protoc_gen_swagger.options.ExternalDocumentation\x12T\n\nextensions\x18\x0f \x03(\x0b\x32@.grpc.gateway.protoc_gen_swagger.options.Swagger.ExtensionsEntry\x1a\x63\n\x0eResponsesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12@\n\x05value\x18\x02 \x01(\x0b\x32\x31.grpc.gateway.protoc_gen_swagger.options.Response:\x02\x38\x01\x1aI\n\x0f\x45xtensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"B\n\rSwaggerScheme\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04HTTP\x10\x01\x12\t\n\x05HTTPS\x10\x02\x12\x06\n\x02WS\x10\x03\x12\x07\n\x03WSS\x10\x04J\x04\x08\x08\x10\tJ\x04\x08\t\x10\nJ\x04\x08\r\x10\x0e\"\xa9\x05\n\tOperation\x12\x0c\n\x04tags\x18\x01 \x03(\t\x12\x0f\n\x07summary\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12U\n\rexternal_docs\x18\x04 \x01(\x0b\x32>.grpc.gateway.protoc_gen_swagger.options.ExternalDocumentation\x12\x14\n\x0coperation_id\x18\x05 \x01(\t\x12\x10\n\x08\x63onsumes\x18\x06 \x03(\t\x12\x10\n\x08produces\x18\x07 \x03(\t\x12T\n\tresponses\x18\t \x03(\x0b\x32\x41.grpc.gateway.protoc_gen_swagger.options.Operation.ResponsesEntry\x12\x0f\n\x07schemes\x18\n \x03(\t\x12\x12\n\ndeprecated\x18\x0b \x01(\x08\x12N\n\x08security\x18\x0c \x03(\x0b\x32<.grpc.gateway.protoc_gen_swagger.options.SecurityRequirement\x12V\n\nextensions\x18\r \x03(\x0b\x32\x42.grpc.gateway.protoc_gen_swagger.options.Operation.ExtensionsEntry\x1a\x63\n\x0eResponsesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12@\n\x05value\x18\x02 \x01(\x0b\x32\x31.grpc.gateway.protoc_gen_swagger.options.Response:\x02\x38\x01\x1aI\n\x0f\x45xtensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01J\x04\x08\x08\x10\t\"\xab\x01\n\x06Header\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0e\n\x06\x66ormat\x18\x03 \x01(\t\x12\x0f\n\x07\x64\x65\x66\x61ult\x18\x06 \x01(\t\x12\x0f\n\x07pattern\x18\r \x01(\tJ\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\tJ\x04\x08\t\x10\nJ\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\x0cJ\x04\x08\x0c\x10\rJ\x04\x08\x0e\x10\x0fJ\x04\x08\x0f\x10\x10J\x04\x08\x10\x10\x11J\x04\x08\x11\x10\x12J\x04\x08\x12\x10\x13\"\xb8\x04\n\x08Response\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12?\n\x06schema\x18\x02 \x01(\x0b\x32/.grpc.gateway.protoc_gen_swagger.options.Schema\x12O\n\x07headers\x18\x03 \x03(\x0b\x32>.grpc.gateway.protoc_gen_swagger.options.Response.HeadersEntry\x12Q\n\x08\x65xamples\x18\x04 \x03(\x0b\x32?.grpc.gateway.protoc_gen_swagger.options.Response.ExamplesEntry\x12U\n\nextensions\x18\x05 \x03(\x0b\x32\x41.grpc.gateway.protoc_gen_swagger.options.Response.ExtensionsEntry\x1a_\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12>\n\x05value\x18\x02 \x01(\x0b\x32/.grpc.gateway.protoc_gen_swagger.options.Header:\x02\x38\x01\x1a/\n\rExamplesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aI\n\x0f\x45xtensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"\xf9\x02\n\x04Info\x12\r\n\x05title\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x18\n\x10terms_of_service\x18\x03 \x01(\t\x12\x41\n\x07\x63ontact\x18\x04 \x01(\x0b\x32\x30.grpc.gateway.protoc_gen_swagger.options.Contact\x12\x41\n\x07license\x18\x05 \x01(\x0b\x32\x30.grpc.gateway.protoc_gen_swagger.options.License\x12\x0f\n\x07version\x18\x06 \x01(\t\x12Q\n\nextensions\x18\x07 \x03(\x0b\x32=.grpc.gateway.protoc_gen_swagger.options.Info.ExtensionsEntry\x1aI\n\x0f\x45xtensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"3\n\x07\x43ontact\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\r\n\x05\x65mail\x18\x03 \x01(\t\"$\n\x07License\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\"9\n\x15\x45xternalDocumentation\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\"\x9c\x02\n\x06Schema\x12H\n\x0bjson_schema\x18\x01 \x01(\x0b\x32\x33.grpc.gateway.protoc_gen_swagger.options.JSONSchema\x12\x15\n\rdiscriminator\x18\x02 \x01(\t\x12\x11\n\tread_only\x18\x03 \x01(\x08\x12U\n\rexternal_docs\x18\x05 \x01(\x0b\x32>.grpc.gateway.protoc_gen_swagger.options.ExternalDocumentation\x12)\n\x07\x65xample\x18\x06 \x01(\x0b\x32\x14.google.protobuf.AnyB\x02\x18\x01\x12\x16\n\x0e\x65xample_string\x18\x07 \x01(\tJ\x04\x08\x04\x10\x05\"\xe3\x05\n\nJSONSchema\x12\x0b\n\x03ref\x18\x03 \x01(\t\x12\r\n\x05title\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x0f\n\x07\x64\x65\x66\x61ult\x18\x07 \x01(\t\x12\x11\n\tread_only\x18\x08 \x01(\x08\x12\x0f\n\x07\x65xample\x18\t \x01(\t\x12\x13\n\x0bmultiple_of\x18\n \x01(\x01\x12\x0f\n\x07maximum\x18\x0b \x01(\x01\x12\x19\n\x11\x65xclusive_maximum\x18\x0c \x01(\x08\x12\x0f\n\x07minimum\x18\r \x01(\x01\x12\x19\n\x11\x65xclusive_minimum\x18\x0e \x01(\x08\x12\x12\n\nmax_length\x18\x0f \x01(\x04\x12\x12\n\nmin_length\x18\x10 \x01(\x04\x12\x0f\n\x07pattern\x18\x11 \x01(\t\x12\x11\n\tmax_items\x18\x14 \x01(\x04\x12\x11\n\tmin_items\x18\x15 \x01(\x04\x12\x14\n\x0cunique_items\x18\x16 \x01(\x08\x12\x16\n\x0emax_properties\x18\x18 \x01(\x04\x12\x16\n\x0emin_properties\x18\x19 \x01(\x04\x12\x10\n\x08required\x18\x1a \x03(\t\x12\r\n\x05\x61rray\x18\" \x03(\t\x12W\n\x04type\x18# \x03(\x0e\x32I.grpc.gateway.protoc_gen_swagger.options.JSONSchema.JSONSchemaSimpleTypes\x12\x0e\n\x06\x66ormat\x18$ \x01(\t\x12\x0c\n\x04\x65num\x18. \x03(\t\"w\n\x15JSONSchemaSimpleTypes\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05\x41RRAY\x10\x01\x12\x0b\n\x07\x42OOLEAN\x10\x02\x12\x0b\n\x07INTEGER\x10\x03\x12\x08\n\x04NULL\x10\x04\x12\n\n\x06NUMBER\x10\x05\x12\n\n\x06OBJECT\x10\x06\x12\n\n\x06STRING\x10\x07J\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x04\x10\x05J\x04\x08\x12\x10\x13J\x04\x08\x13\x10\x14J\x04\x08\x17\x10\x18J\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1d\x10\x1eJ\x04\x08\x1e\x10\"J\x04\x08%\x10*J\x04\x08*\x10+J\x04\x08+\x10.\"w\n\x03Tag\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12U\n\rexternal_docs\x18\x03 \x01(\x0b\x32>.grpc.gateway.protoc_gen_swagger.options.ExternalDocumentationJ\x04\x08\x01\x10\x02\"\xdd\x01\n\x13SecurityDefinitions\x12\\\n\x08security\x18\x01 \x03(\x0b\x32J.grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions.SecurityEntry\x1ah\n\rSecurityEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.grpc.gateway.protoc_gen_swagger.options.SecurityScheme:\x02\x38\x01\"\x96\x06\n\x0eSecurityScheme\x12J\n\x04type\x18\x01 \x01(\x0e\x32<.grpc.gateway.protoc_gen_swagger.options.SecurityScheme.Type\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x46\n\x02in\x18\x04 \x01(\x0e\x32:.grpc.gateway.protoc_gen_swagger.options.SecurityScheme.In\x12J\n\x04\x66low\x18\x05 \x01(\x0e\x32<.grpc.gateway.protoc_gen_swagger.options.SecurityScheme.Flow\x12\x19\n\x11\x61uthorization_url\x18\x06 \x01(\t\x12\x11\n\ttoken_url\x18\x07 \x01(\t\x12?\n\x06scopes\x18\x08 \x01(\x0b\x32/.grpc.gateway.protoc_gen_swagger.options.Scopes\x12[\n\nextensions\x18\t \x03(\x0b\x32G.grpc.gateway.protoc_gen_swagger.options.SecurityScheme.ExtensionsEntry\x1aI\n\x0f\x45xtensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"K\n\x04Type\x12\x10\n\x0cTYPE_INVALID\x10\x00\x12\x0e\n\nTYPE_BASIC\x10\x01\x12\x10\n\x0cTYPE_API_KEY\x10\x02\x12\x0f\n\x0bTYPE_OAUTH2\x10\x03\"1\n\x02In\x12\x0e\n\nIN_INVALID\x10\x00\x12\x0c\n\x08IN_QUERY\x10\x01\x12\r\n\tIN_HEADER\x10\x02\"j\n\x04\x46low\x12\x10\n\x0c\x46LOW_INVALID\x10\x00\x12\x11\n\rFLOW_IMPLICIT\x10\x01\x12\x11\n\rFLOW_PASSWORD\x10\x02\x12\x14\n\x10\x46LOW_APPLICATION\x10\x03\x12\x14\n\x10\x46LOW_ACCESS_CODE\x10\x04\"\xc9\x02\n\x13SecurityRequirement\x12s\n\x14security_requirement\x18\x01 \x03(\x0b\x32U.grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementEntry\x1a)\n\x18SecurityRequirementValue\x12\r\n\x05scope\x18\x01 \x03(\t\x1a\x91\x01\n\x18SecurityRequirementEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x64\n\x05value\x18\x02 \x01(\x0b\x32U.grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementValue:\x02\x38\x01\"\x81\x01\n\x06Scopes\x12I\n\x05scope\x18\x01 \x03(\x0b\x32:.grpc.gateway.protoc_gen_swagger.options.Scopes.ScopeEntry\x1a,\n\nScopeEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x43ZAgithub.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/optionsb\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'protoc_gen_swagger.options.openapiv2_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'ZAgithub.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options' - _SWAGGER_RESPONSESENTRY._options = None - _SWAGGER_RESPONSESENTRY._serialized_options = b'8\001' - _SWAGGER_EXTENSIONSENTRY._options = None - _SWAGGER_EXTENSIONSENTRY._serialized_options = b'8\001' - _OPERATION_RESPONSESENTRY._options = None - _OPERATION_RESPONSESENTRY._serialized_options = b'8\001' - _OPERATION_EXTENSIONSENTRY._options = None - _OPERATION_EXTENSIONSENTRY._serialized_options = b'8\001' - _RESPONSE_HEADERSENTRY._options = None - _RESPONSE_HEADERSENTRY._serialized_options = b'8\001' - _RESPONSE_EXAMPLESENTRY._options = None - _RESPONSE_EXAMPLESENTRY._serialized_options = b'8\001' - _RESPONSE_EXTENSIONSENTRY._options = None - _RESPONSE_EXTENSIONSENTRY._serialized_options = b'8\001' - _INFO_EXTENSIONSENTRY._options = None - _INFO_EXTENSIONSENTRY._serialized_options = b'8\001' - _SCHEMA.fields_by_name['example']._options = None - _SCHEMA.fields_by_name['example']._serialized_options = b'\030\001' - _SECURITYDEFINITIONS_SECURITYENTRY._options = None - _SECURITYDEFINITIONS_SECURITYENTRY._serialized_options = b'8\001' - _SECURITYSCHEME_EXTENSIONSENTRY._options = None - _SECURITYSCHEME_EXTENSIONSENTRY._serialized_options = b'8\001' - _SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY._options = None - _SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY._serialized_options = b'8\001' - _SCOPES_SCOPEENTRY._options = None - _SCOPES_SCOPEENTRY._serialized_options = b'8\001' - _SWAGGER._serialized_start=145 - _SWAGGER._serialized_end=1073 - _SWAGGER_RESPONSESENTRY._serialized_start=813 - _SWAGGER_RESPONSESENTRY._serialized_end=912 - _SWAGGER_EXTENSIONSENTRY._serialized_start=914 - _SWAGGER_EXTENSIONSENTRY._serialized_end=987 - _SWAGGER_SWAGGERSCHEME._serialized_start=989 - _SWAGGER_SWAGGERSCHEME._serialized_end=1055 - _OPERATION._serialized_start=1076 - _OPERATION._serialized_end=1757 - _OPERATION_RESPONSESENTRY._serialized_start=813 - _OPERATION_RESPONSESENTRY._serialized_end=912 - _OPERATION_EXTENSIONSENTRY._serialized_start=914 - _OPERATION_EXTENSIONSENTRY._serialized_end=987 - _HEADER._serialized_start=1760 - _HEADER._serialized_end=1931 - _RESPONSE._serialized_start=1934 - _RESPONSE._serialized_end=2502 - _RESPONSE_HEADERSENTRY._serialized_start=2283 - _RESPONSE_HEADERSENTRY._serialized_end=2378 - _RESPONSE_EXAMPLESENTRY._serialized_start=2380 - _RESPONSE_EXAMPLESENTRY._serialized_end=2427 - _RESPONSE_EXTENSIONSENTRY._serialized_start=914 - _RESPONSE_EXTENSIONSENTRY._serialized_end=987 - _INFO._serialized_start=2505 - _INFO._serialized_end=2882 - _INFO_EXTENSIONSENTRY._serialized_start=914 - _INFO_EXTENSIONSENTRY._serialized_end=987 - _CONTACT._serialized_start=2884 - _CONTACT._serialized_end=2935 - _LICENSE._serialized_start=2937 - _LICENSE._serialized_end=2973 - _EXTERNALDOCUMENTATION._serialized_start=2975 - _EXTERNALDOCUMENTATION._serialized_end=3032 - _SCHEMA._serialized_start=3035 - _SCHEMA._serialized_end=3319 - _JSONSCHEMA._serialized_start=3322 - _JSONSCHEMA._serialized_end=4061 - _JSONSCHEMA_JSONSCHEMASIMPLETYPES._serialized_start=3864 - _JSONSCHEMA_JSONSCHEMASIMPLETYPES._serialized_end=3983 - _TAG._serialized_start=4063 - _TAG._serialized_end=4182 - _SECURITYDEFINITIONS._serialized_start=4185 - _SECURITYDEFINITIONS._serialized_end=4406 - _SECURITYDEFINITIONS_SECURITYENTRY._serialized_start=4302 - _SECURITYDEFINITIONS_SECURITYENTRY._serialized_end=4406 - _SECURITYSCHEME._serialized_start=4409 - _SECURITYSCHEME._serialized_end=5199 - _SECURITYSCHEME_EXTENSIONSENTRY._serialized_start=914 - _SECURITYSCHEME_EXTENSIONSENTRY._serialized_end=987 - _SECURITYSCHEME_TYPE._serialized_start=4965 - _SECURITYSCHEME_TYPE._serialized_end=5040 - _SECURITYSCHEME_IN._serialized_start=5042 - _SECURITYSCHEME_IN._serialized_end=5091 - _SECURITYSCHEME_FLOW._serialized_start=5093 - _SECURITYSCHEME_FLOW._serialized_end=5199 - _SECURITYREQUIREMENT._serialized_start=5202 - _SECURITYREQUIREMENT._serialized_end=5531 - _SECURITYREQUIREMENT_SECURITYREQUIREMENTVALUE._serialized_start=5342 - _SECURITYREQUIREMENT_SECURITYREQUIREMENTVALUE._serialized_end=5383 - _SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY._serialized_start=5386 - _SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY._serialized_end=5531 - _SCOPES._serialized_start=5534 - _SCOPES._serialized_end=5663 - _SCOPES_SCOPEENTRY._serialized_start=5619 - _SCOPES_SCOPEENTRY._serialized_end=5663 +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'protoc_gen_swagger.options.openapiv2_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'ZAgithub.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options' + _globals['_SWAGGER_RESPONSESENTRY']._loaded_options = None + _globals['_SWAGGER_RESPONSESENTRY']._serialized_options = b'8\001' + _globals['_SWAGGER_EXTENSIONSENTRY']._loaded_options = None + _globals['_SWAGGER_EXTENSIONSENTRY']._serialized_options = b'8\001' + _globals['_OPERATION_RESPONSESENTRY']._loaded_options = None + _globals['_OPERATION_RESPONSESENTRY']._serialized_options = b'8\001' + _globals['_OPERATION_EXTENSIONSENTRY']._loaded_options = None + _globals['_OPERATION_EXTENSIONSENTRY']._serialized_options = b'8\001' + _globals['_RESPONSE_HEADERSENTRY']._loaded_options = None + _globals['_RESPONSE_HEADERSENTRY']._serialized_options = b'8\001' + _globals['_RESPONSE_EXAMPLESENTRY']._loaded_options = None + _globals['_RESPONSE_EXAMPLESENTRY']._serialized_options = b'8\001' + _globals['_RESPONSE_EXTENSIONSENTRY']._loaded_options = None + _globals['_RESPONSE_EXTENSIONSENTRY']._serialized_options = b'8\001' + _globals['_INFO_EXTENSIONSENTRY']._loaded_options = None + _globals['_INFO_EXTENSIONSENTRY']._serialized_options = b'8\001' + _globals['_SCHEMA'].fields_by_name['example']._loaded_options = None + _globals['_SCHEMA'].fields_by_name['example']._serialized_options = b'\030\001' + _globals['_SECURITYDEFINITIONS_SECURITYENTRY']._loaded_options = None + _globals['_SECURITYDEFINITIONS_SECURITYENTRY']._serialized_options = b'8\001' + _globals['_SECURITYSCHEME_EXTENSIONSENTRY']._loaded_options = None + _globals['_SECURITYSCHEME_EXTENSIONSENTRY']._serialized_options = b'8\001' + _globals['_SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY']._loaded_options = None + _globals['_SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY']._serialized_options = b'8\001' + _globals['_SCOPES_SCOPEENTRY']._loaded_options = None + _globals['_SCOPES_SCOPEENTRY']._serialized_options = b'8\001' + _globals['_SWAGGER']._serialized_start=145 + _globals['_SWAGGER']._serialized_end=1073 + _globals['_SWAGGER_RESPONSESENTRY']._serialized_start=813 + _globals['_SWAGGER_RESPONSESENTRY']._serialized_end=912 + _globals['_SWAGGER_EXTENSIONSENTRY']._serialized_start=914 + _globals['_SWAGGER_EXTENSIONSENTRY']._serialized_end=987 + _globals['_SWAGGER_SWAGGERSCHEME']._serialized_start=989 + _globals['_SWAGGER_SWAGGERSCHEME']._serialized_end=1055 + _globals['_OPERATION']._serialized_start=1076 + _globals['_OPERATION']._serialized_end=1757 + _globals['_OPERATION_RESPONSESENTRY']._serialized_start=813 + _globals['_OPERATION_RESPONSESENTRY']._serialized_end=912 + _globals['_OPERATION_EXTENSIONSENTRY']._serialized_start=914 + _globals['_OPERATION_EXTENSIONSENTRY']._serialized_end=987 + _globals['_HEADER']._serialized_start=1760 + _globals['_HEADER']._serialized_end=1931 + _globals['_RESPONSE']._serialized_start=1934 + _globals['_RESPONSE']._serialized_end=2502 + _globals['_RESPONSE_HEADERSENTRY']._serialized_start=2283 + _globals['_RESPONSE_HEADERSENTRY']._serialized_end=2378 + _globals['_RESPONSE_EXAMPLESENTRY']._serialized_start=2380 + _globals['_RESPONSE_EXAMPLESENTRY']._serialized_end=2427 + _globals['_RESPONSE_EXTENSIONSENTRY']._serialized_start=914 + _globals['_RESPONSE_EXTENSIONSENTRY']._serialized_end=987 + _globals['_INFO']._serialized_start=2505 + _globals['_INFO']._serialized_end=2882 + _globals['_INFO_EXTENSIONSENTRY']._serialized_start=914 + _globals['_INFO_EXTENSIONSENTRY']._serialized_end=987 + _globals['_CONTACT']._serialized_start=2884 + _globals['_CONTACT']._serialized_end=2935 + _globals['_LICENSE']._serialized_start=2937 + _globals['_LICENSE']._serialized_end=2973 + _globals['_EXTERNALDOCUMENTATION']._serialized_start=2975 + _globals['_EXTERNALDOCUMENTATION']._serialized_end=3032 + _globals['_SCHEMA']._serialized_start=3035 + _globals['_SCHEMA']._serialized_end=3319 + _globals['_JSONSCHEMA']._serialized_start=3322 + _globals['_JSONSCHEMA']._serialized_end=4061 + _globals['_JSONSCHEMA_JSONSCHEMASIMPLETYPES']._serialized_start=3864 + _globals['_JSONSCHEMA_JSONSCHEMASIMPLETYPES']._serialized_end=3983 + _globals['_TAG']._serialized_start=4063 + _globals['_TAG']._serialized_end=4182 + _globals['_SECURITYDEFINITIONS']._serialized_start=4185 + _globals['_SECURITYDEFINITIONS']._serialized_end=4406 + _globals['_SECURITYDEFINITIONS_SECURITYENTRY']._serialized_start=4302 + _globals['_SECURITYDEFINITIONS_SECURITYENTRY']._serialized_end=4406 + _globals['_SECURITYSCHEME']._serialized_start=4409 + _globals['_SECURITYSCHEME']._serialized_end=5199 + _globals['_SECURITYSCHEME_EXTENSIONSENTRY']._serialized_start=914 + _globals['_SECURITYSCHEME_EXTENSIONSENTRY']._serialized_end=987 + _globals['_SECURITYSCHEME_TYPE']._serialized_start=4965 + _globals['_SECURITYSCHEME_TYPE']._serialized_end=5040 + _globals['_SECURITYSCHEME_IN']._serialized_start=5042 + _globals['_SECURITYSCHEME_IN']._serialized_end=5091 + _globals['_SECURITYSCHEME_FLOW']._serialized_start=5093 + _globals['_SECURITYSCHEME_FLOW']._serialized_end=5199 + _globals['_SECURITYREQUIREMENT']._serialized_start=5202 + _globals['_SECURITYREQUIREMENT']._serialized_end=5531 + _globals['_SECURITYREQUIREMENT_SECURITYREQUIREMENTVALUE']._serialized_start=5342 + _globals['_SECURITYREQUIREMENT_SECURITYREQUIREMENTVALUE']._serialized_end=5383 + _globals['_SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY']._serialized_start=5386 + _globals['_SECURITYREQUIREMENT_SECURITYREQUIREMENTENTRY']._serialized_end=5531 + _globals['_SCOPES']._serialized_start=5534 + _globals['_SCOPES']._serialized_end=5663 + _globals['_SCOPES_SCOPEENTRY']._serialized_start=5619 + _globals['_SCOPES_SCOPEENTRY']._serialized_end=5663 # @@protoc_insertion_point(module_scope) diff --git a/src/protoc_gen_swagger/options/openapiv2_pb2.pyi b/src/protoc_gen_swagger/options/openapiv2_pb2.pyi new file mode 100644 index 00000000..b8bfbaf0 --- /dev/null +++ b/src/protoc_gen_swagger/options/openapiv2_pb2.pyi @@ -0,0 +1,1317 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import collections.abc +import google.protobuf.any_pb2 +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 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 Swagger(google.protobuf.message.Message): + """`Swagger` is a representation of OpenAPI v2 specification's Swagger object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject + + Example: + + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Echo API"; + version: "1.0"; + description: "; + contact: { + name: "gRPC-Gateway project"; + url: "https://github.com/grpc-ecosystem/grpc-gateway"; + email: "none@example.com"; + }; + license: { + name: "BSD 3-Clause License"; + url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt"; + }; + }; + schemes: HTTPS; + consumes: "application/json"; + produces: "application/json"; + }; + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _SwaggerScheme: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _SwaggerSchemeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Swagger._SwaggerScheme.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNKNOWN: Swagger._SwaggerScheme.ValueType # 0 + HTTP: Swagger._SwaggerScheme.ValueType # 1 + HTTPS: Swagger._SwaggerScheme.ValueType # 2 + WS: Swagger._SwaggerScheme.ValueType # 3 + WSS: Swagger._SwaggerScheme.ValueType # 4 + + class SwaggerScheme(_SwaggerScheme, metaclass=_SwaggerSchemeEnumTypeWrapper): ... + UNKNOWN: Swagger.SwaggerScheme.ValueType # 0 + HTTP: Swagger.SwaggerScheme.ValueType # 1 + HTTPS: Swagger.SwaggerScheme.ValueType # 2 + WS: Swagger.SwaggerScheme.ValueType # 3 + WSS: Swagger.SwaggerScheme.ValueType # 4 + + @typing.final + class ResponsesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___Response: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___Response | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + @typing.final + class ExtensionsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> google.protobuf.struct_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: google.protobuf.struct_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + SWAGGER_FIELD_NUMBER: builtins.int + INFO_FIELD_NUMBER: builtins.int + HOST_FIELD_NUMBER: builtins.int + BASE_PATH_FIELD_NUMBER: builtins.int + SCHEMES_FIELD_NUMBER: builtins.int + CONSUMES_FIELD_NUMBER: builtins.int + PRODUCES_FIELD_NUMBER: builtins.int + RESPONSES_FIELD_NUMBER: builtins.int + SECURITY_DEFINITIONS_FIELD_NUMBER: builtins.int + SECURITY_FIELD_NUMBER: builtins.int + EXTERNAL_DOCS_FIELD_NUMBER: builtins.int + EXTENSIONS_FIELD_NUMBER: builtins.int + swagger: builtins.str + """Specifies the Swagger Specification version being used. It can be + used by the Swagger UI and other clients to interpret the API listing. The + value MUST be "2.0". + """ + host: builtins.str + """The host (name or ip) serving the API. This MUST be the host only and does + not include the scheme nor sub-paths. It MAY include a port. If the host is + not included, the host serving the documentation is to be used (including + the port). The host does not support path templating. + """ + base_path: builtins.str + """The base path on which the API is served, which is relative to the host. If + it is not included, the API is served directly under the host. The value + MUST start with a leading slash (/). The basePath does not support path + templating. + Note that using `base_path` does not change the endpoint paths that are + generated in the resulting Swagger file. If you wish to use `base_path` + with relatively generated Swagger paths, the `base_path` prefix must be + manually removed from your `google.api.http` paths and your code changed to + serve the API from the `base_path`. + """ + @property + def info(self) -> global___Info: + """Provides metadata about the API. The metadata can be used by the + clients if needed. + """ + + @property + def schemes(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___Swagger.SwaggerScheme.ValueType]: + """The transfer protocol of the API. Values MUST be from the list: "http", + "https", "ws", "wss". If the schemes is not included, the default scheme to + be used is the one used to access the Swagger definition itself. + """ + + @property + def consumes(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A list of MIME types the APIs can consume. This is global to all APIs but + can be overridden on specific API calls. Value MUST be as described under + Mime Types. + """ + + @property + def produces(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A list of MIME types the APIs can produce. This is global to all APIs but + can be overridden on specific API calls. Value MUST be as described under + Mime Types. + """ + + @property + def responses(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Response]: + """An object to hold responses that can be used across operations. This + property does not define global responses for all operations. + """ + + @property + def security_definitions(self) -> global___SecurityDefinitions: + """Security scheme definitions that can be used across the specification.""" + + @property + def security(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SecurityRequirement]: + """A declaration of which security schemes are applied for the API as a whole. + The list of values describes alternative security schemes that can be used + (that is, there is a logical OR between the security requirements). + Individual operations can override this definition. + """ + + @property + def external_docs(self) -> global___ExternalDocumentation: + """Additional external documentation.""" + + @property + def extensions(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, google.protobuf.struct_pb2.Value]: ... + def __init__( + self, + *, + swagger: builtins.str = ..., + info: global___Info | None = ..., + host: builtins.str = ..., + base_path: builtins.str = ..., + schemes: collections.abc.Iterable[global___Swagger.SwaggerScheme.ValueType] | None = ..., + consumes: collections.abc.Iterable[builtins.str] | None = ..., + produces: collections.abc.Iterable[builtins.str] | None = ..., + responses: collections.abc.Mapping[builtins.str, global___Response] | None = ..., + security_definitions: global___SecurityDefinitions | None = ..., + security: collections.abc.Iterable[global___SecurityRequirement] | None = ..., + external_docs: global___ExternalDocumentation | None = ..., + extensions: collections.abc.Mapping[builtins.str, google.protobuf.struct_pb2.Value] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["external_docs", b"external_docs", "info", b"info", "security_definitions", b"security_definitions"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["base_path", b"base_path", "consumes", b"consumes", "extensions", b"extensions", "external_docs", b"external_docs", "host", b"host", "info", b"info", "produces", b"produces", "responses", b"responses", "schemes", b"schemes", "security", b"security", "security_definitions", b"security_definitions", "swagger", b"swagger"]) -> None: ... + +global___Swagger = Swagger + +@typing.final +class Operation(google.protobuf.message.Message): + """`Operation` is a representation of OpenAPI v2 specification's Operation object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject + + Example: + + service EchoService { + rpc Echo(SimpleMessage) returns (SimpleMessage) { + option (google.api.http) = { + get: "/v1/example/echo/{id}" + }; + + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + summary: "Get a message."; + operation_id: "getMessage"; + tags: "echo"; + responses: { + key: "200" + value: { + description: "OK"; + } + } + }; + } + } + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class ResponsesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___Response: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___Response | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + @typing.final + class ExtensionsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> google.protobuf.struct_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: google.protobuf.struct_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + TAGS_FIELD_NUMBER: builtins.int + SUMMARY_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + EXTERNAL_DOCS_FIELD_NUMBER: builtins.int + OPERATION_ID_FIELD_NUMBER: builtins.int + CONSUMES_FIELD_NUMBER: builtins.int + PRODUCES_FIELD_NUMBER: builtins.int + RESPONSES_FIELD_NUMBER: builtins.int + SCHEMES_FIELD_NUMBER: builtins.int + DEPRECATED_FIELD_NUMBER: builtins.int + SECURITY_FIELD_NUMBER: builtins.int + EXTENSIONS_FIELD_NUMBER: builtins.int + summary: builtins.str + """A short summary of what the operation does. For maximum readability in the + swagger-ui, this field SHOULD be less than 120 characters. + """ + description: builtins.str + """A verbose explanation of the operation behavior. GFM syntax can be used for + rich text representation. + """ + operation_id: builtins.str + """Unique string used to identify the operation. The id MUST be unique among + all operations described in the API. Tools and libraries MAY use the + operationId to uniquely identify an operation, therefore, it is recommended + to follow common programming naming conventions. + """ + deprecated: builtins.bool + """Declares this operation to be deprecated. Usage of the declared operation + should be refrained. Default value is false. + """ + @property + def tags(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A list of tags for API documentation control. Tags can be used for logical + grouping of operations by resources or any other qualifier. + """ + + @property + def external_docs(self) -> global___ExternalDocumentation: + """Additional external documentation for this operation.""" + + @property + def consumes(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A list of MIME types the operation can consume. This overrides the consumes + definition at the Swagger Object. An empty value MAY be used to clear the + global definition. Value MUST be as described under Mime Types. + """ + + @property + def produces(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A list of MIME types the operation can produce. This overrides the produces + definition at the Swagger Object. An empty value MAY be used to clear the + global definition. Value MUST be as described under Mime Types. + """ + + @property + def responses(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Response]: + """The list of possible responses as they are returned from executing this + operation. + """ + + @property + def schemes(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """The transfer protocol for the operation. Values MUST be from the list: + "http", "https", "ws", "wss". The value overrides the Swagger Object + schemes definition. + """ + + @property + def security(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SecurityRequirement]: + """A declaration of which security schemes are applied for this operation. The + list of values describes alternative security schemes that can be used + (that is, there is a logical OR between the security requirements). This + definition overrides any declared top-level security. To remove a top-level + security declaration, an empty array can be used. + """ + + @property + def extensions(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, google.protobuf.struct_pb2.Value]: ... + def __init__( + self, + *, + tags: collections.abc.Iterable[builtins.str] | None = ..., + summary: builtins.str = ..., + description: builtins.str = ..., + external_docs: global___ExternalDocumentation | None = ..., + operation_id: builtins.str = ..., + consumes: collections.abc.Iterable[builtins.str] | None = ..., + produces: collections.abc.Iterable[builtins.str] | None = ..., + responses: collections.abc.Mapping[builtins.str, global___Response] | None = ..., + schemes: collections.abc.Iterable[builtins.str] | None = ..., + deprecated: builtins.bool = ..., + security: collections.abc.Iterable[global___SecurityRequirement] | None = ..., + extensions: collections.abc.Mapping[builtins.str, google.protobuf.struct_pb2.Value] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["external_docs", b"external_docs"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["consumes", b"consumes", "deprecated", b"deprecated", "description", b"description", "extensions", b"extensions", "external_docs", b"external_docs", "operation_id", b"operation_id", "produces", b"produces", "responses", b"responses", "schemes", b"schemes", "security", b"security", "summary", b"summary", "tags", b"tags"]) -> None: ... + +global___Operation = Operation + +@typing.final +class Header(google.protobuf.message.Message): + """`Header` is a representation of OpenAPI v2 specification's Header object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#headerObject + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DESCRIPTION_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + FORMAT_FIELD_NUMBER: builtins.int + DEFAULT_FIELD_NUMBER: builtins.int + PATTERN_FIELD_NUMBER: builtins.int + description: builtins.str + """`Description` is a short description of the header.""" + type: builtins.str + """The type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported.""" + format: builtins.str + """`Format` The extending format for the previously mentioned type.""" + default: builtins.str + """`Default` Declares the value of the header that the server will use if none is provided. + See: https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2. + Unlike JSON Schema this value MUST conform to the defined type for the header. + """ + pattern: builtins.str + """'Pattern' See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3.""" + def __init__( + self, + *, + description: builtins.str = ..., + type: builtins.str = ..., + format: builtins.str = ..., + default: builtins.str = ..., + pattern: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["default", b"default", "description", b"description", "format", b"format", "pattern", b"pattern", "type", b"type"]) -> None: ... + +global___Header = Header + +@typing.final +class Response(google.protobuf.message.Message): + """`Response` is a representation of OpenAPI v2 specification's Response object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class HeadersEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___Header: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___Header | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + @typing.final + class ExamplesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + value: builtins.str + def __init__( + self, + *, + key: builtins.str = ..., + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + @typing.final + class ExtensionsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> google.protobuf.struct_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: google.protobuf.struct_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + DESCRIPTION_FIELD_NUMBER: builtins.int + SCHEMA_FIELD_NUMBER: builtins.int + HEADERS_FIELD_NUMBER: builtins.int + EXAMPLES_FIELD_NUMBER: builtins.int + EXTENSIONS_FIELD_NUMBER: builtins.int + description: builtins.str + """`Description` is a short description of the response. + GFM syntax can be used for rich text representation. + """ + @property + def schema(self) -> global___Schema: + """`Schema` optionally defines the structure of the response. + If `Schema` is not provided, it means there is no content to the response. + """ + + @property + def headers(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Header]: + """`Headers` A list of headers that are sent with the response. + `Header` name is expected to be a string in the canonical format of the MIME header key + See: https://golang.org/pkg/net/textproto/#CanonicalMIMEHeaderKey + """ + + @property + def examples(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: + """`Examples` gives per-mimetype response examples. + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#example-object + """ + + @property + def extensions(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, google.protobuf.struct_pb2.Value]: ... + def __init__( + self, + *, + description: builtins.str = ..., + schema: global___Schema | None = ..., + headers: collections.abc.Mapping[builtins.str, global___Header] | None = ..., + examples: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + extensions: collections.abc.Mapping[builtins.str, google.protobuf.struct_pb2.Value] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["schema", b"schema"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["description", b"description", "examples", b"examples", "extensions", b"extensions", "headers", b"headers", "schema", b"schema"]) -> None: ... + +global___Response = Response + +@typing.final +class Info(google.protobuf.message.Message): + """`Info` is a representation of OpenAPI v2 specification's Info object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject + + Example: + + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Echo API"; + version: "1.0"; + description: "; + contact: { + name: "gRPC-Gateway project"; + url: "https://github.com/grpc-ecosystem/grpc-gateway"; + email: "none@example.com"; + }; + license: { + name: "BSD 3-Clause License"; + url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt"; + }; + }; + ... + }; + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class ExtensionsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> google.protobuf.struct_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: google.protobuf.struct_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + TITLE_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + TERMS_OF_SERVICE_FIELD_NUMBER: builtins.int + CONTACT_FIELD_NUMBER: builtins.int + LICENSE_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + EXTENSIONS_FIELD_NUMBER: builtins.int + title: builtins.str + """The title of the application.""" + description: builtins.str + """A short description of the application. GFM syntax can be used for rich + text representation. + """ + terms_of_service: builtins.str + """The Terms of Service for the API.""" + version: builtins.str + """Provides the version of the application API (not to be confused + with the specification version). + """ + @property + def contact(self) -> global___Contact: + """The contact information for the exposed API.""" + + @property + def license(self) -> global___License: + """The license information for the exposed API.""" + + @property + def extensions(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, google.protobuf.struct_pb2.Value]: ... + def __init__( + self, + *, + title: builtins.str = ..., + description: builtins.str = ..., + terms_of_service: builtins.str = ..., + contact: global___Contact | None = ..., + license: global___License | None = ..., + version: builtins.str = ..., + extensions: collections.abc.Mapping[builtins.str, google.protobuf.struct_pb2.Value] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["contact", b"contact", "license", b"license"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["contact", b"contact", "description", b"description", "extensions", b"extensions", "license", b"license", "terms_of_service", b"terms_of_service", "title", b"title", "version", b"version"]) -> None: ... + +global___Info = Info + +@typing.final +class Contact(google.protobuf.message.Message): + """`Contact` is a representation of OpenAPI v2 specification's Contact object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject + + Example: + + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + ... + contact: { + name: "gRPC-Gateway project"; + url: "https://github.com/grpc-ecosystem/grpc-gateway"; + email: "none@example.com"; + }; + ... + }; + ... + }; + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + URL_FIELD_NUMBER: builtins.int + EMAIL_FIELD_NUMBER: builtins.int + name: builtins.str + """The identifying name of the contact person/organization.""" + url: builtins.str + """The URL pointing to the contact information. MUST be in the format of a + URL. + """ + email: builtins.str + """The email address of the contact person/organization. MUST be in the format + of an email address. + """ + def __init__( + self, + *, + name: builtins.str = ..., + url: builtins.str = ..., + email: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["email", b"email", "name", b"name", "url", b"url"]) -> None: ... + +global___Contact = Contact + +@typing.final +class License(google.protobuf.message.Message): + """`License` is a representation of OpenAPI v2 specification's License object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject + + Example: + + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + ... + license: { + name: "BSD 3-Clause License"; + url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt"; + }; + ... + }; + ... + }; + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + URL_FIELD_NUMBER: builtins.int + name: builtins.str + """The license name used for the API.""" + url: builtins.str + """A URL to the license used for the API. MUST be in the format of a URL.""" + def __init__( + self, + *, + name: builtins.str = ..., + url: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["name", b"name", "url", b"url"]) -> None: ... + +global___License = License + +@typing.final +class ExternalDocumentation(google.protobuf.message.Message): + """`ExternalDocumentation` is a representation of OpenAPI v2 specification's + ExternalDocumentation object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject + + Example: + + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + ... + external_docs: { + description: "More about gRPC-Gateway"; + url: "https://github.com/grpc-ecosystem/grpc-gateway"; + } + ... + }; + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DESCRIPTION_FIELD_NUMBER: builtins.int + URL_FIELD_NUMBER: builtins.int + description: builtins.str + """A short description of the target documentation. GFM syntax can be used for + rich text representation. + """ + url: builtins.str + """The URL for the target documentation. Value MUST be in the format + of a URL. + """ + def __init__( + self, + *, + description: builtins.str = ..., + url: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["description", b"description", "url", b"url"]) -> None: ... + +global___ExternalDocumentation = ExternalDocumentation + +@typing.final +class Schema(google.protobuf.message.Message): + """`Schema` is a representation of OpenAPI v2 specification's Schema object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + JSON_SCHEMA_FIELD_NUMBER: builtins.int + DISCRIMINATOR_FIELD_NUMBER: builtins.int + READ_ONLY_FIELD_NUMBER: builtins.int + EXTERNAL_DOCS_FIELD_NUMBER: builtins.int + EXAMPLE_FIELD_NUMBER: builtins.int + EXAMPLE_STRING_FIELD_NUMBER: builtins.int + discriminator: builtins.str + """Adds support for polymorphism. The discriminator is the schema property + name that is used to differentiate between other schema that inherit this + schema. The property name used MUST be defined at this schema and it MUST + be in the required property list. When used, the value MUST be the name of + this schema or any schema that inherits it. + """ + read_only: builtins.bool + """Relevant only for Schema "properties" definitions. Declares the property as + "read only". This means that it MAY be sent as part of a response but MUST + NOT be sent as part of the request. Properties marked as readOnly being + true SHOULD NOT be in the required list of the defined schema. Default + value is false. + """ + example_string: builtins.str + """A free-form property to include a JSON example of this field. This is copied + verbatim to the output swagger.json. Quotes must be escaped. + """ + @property + def json_schema(self) -> global___JSONSchema: ... + @property + def external_docs(self) -> global___ExternalDocumentation: + """Additional external documentation for this schema.""" + + @property + def example(self) -> google.protobuf.any_pb2.Any: + """A free-form property to include an example of an instance for this schema. + Deprecated, please use example_string instead. + """ + + def __init__( + self, + *, + json_schema: global___JSONSchema | None = ..., + discriminator: builtins.str = ..., + read_only: builtins.bool = ..., + external_docs: global___ExternalDocumentation | None = ..., + example: google.protobuf.any_pb2.Any | None = ..., + example_string: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["example", b"example", "external_docs", b"external_docs", "json_schema", b"json_schema"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["discriminator", b"discriminator", "example", b"example", "example_string", b"example_string", "external_docs", b"external_docs", "json_schema", b"json_schema", "read_only", b"read_only"]) -> None: ... + +global___Schema = Schema + +@typing.final +class JSONSchema(google.protobuf.message.Message): + """`JSONSchema` represents properties from JSON Schema taken, and as used, in + the OpenAPI v2 spec. + + This includes changes made by OpenAPI v2. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject + + See also: https://cswr.github.io/JsonSchema/spec/basic_types/, + https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json + + Example: + + message SimpleMessage { + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_schema) = { + json_schema: { + title: "SimpleMessage" + description: "A simple message." + required: ["id"] + } + }; + + // Id represents the message identifier. + string id = 1; [ + (grpc.gateway.protoc_gen_swagger.options.openapiv2_field) = { + {description: "The unique identifier of the simple message." + }]; + } + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _JSONSchemaSimpleTypes: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _JSONSchemaSimpleTypesEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[JSONSchema._JSONSchemaSimpleTypes.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNKNOWN: JSONSchema._JSONSchemaSimpleTypes.ValueType # 0 + ARRAY: JSONSchema._JSONSchemaSimpleTypes.ValueType # 1 + BOOLEAN: JSONSchema._JSONSchemaSimpleTypes.ValueType # 2 + INTEGER: JSONSchema._JSONSchemaSimpleTypes.ValueType # 3 + NULL: JSONSchema._JSONSchemaSimpleTypes.ValueType # 4 + NUMBER: JSONSchema._JSONSchemaSimpleTypes.ValueType # 5 + OBJECT: JSONSchema._JSONSchemaSimpleTypes.ValueType # 6 + STRING: JSONSchema._JSONSchemaSimpleTypes.ValueType # 7 + + class JSONSchemaSimpleTypes(_JSONSchemaSimpleTypes, metaclass=_JSONSchemaSimpleTypesEnumTypeWrapper): ... + UNKNOWN: JSONSchema.JSONSchemaSimpleTypes.ValueType # 0 + ARRAY: JSONSchema.JSONSchemaSimpleTypes.ValueType # 1 + BOOLEAN: JSONSchema.JSONSchemaSimpleTypes.ValueType # 2 + INTEGER: JSONSchema.JSONSchemaSimpleTypes.ValueType # 3 + NULL: JSONSchema.JSONSchemaSimpleTypes.ValueType # 4 + NUMBER: JSONSchema.JSONSchemaSimpleTypes.ValueType # 5 + OBJECT: JSONSchema.JSONSchemaSimpleTypes.ValueType # 6 + STRING: JSONSchema.JSONSchemaSimpleTypes.ValueType # 7 + + REF_FIELD_NUMBER: builtins.int + TITLE_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + DEFAULT_FIELD_NUMBER: builtins.int + READ_ONLY_FIELD_NUMBER: builtins.int + EXAMPLE_FIELD_NUMBER: builtins.int + MULTIPLE_OF_FIELD_NUMBER: builtins.int + MAXIMUM_FIELD_NUMBER: builtins.int + EXCLUSIVE_MAXIMUM_FIELD_NUMBER: builtins.int + MINIMUM_FIELD_NUMBER: builtins.int + EXCLUSIVE_MINIMUM_FIELD_NUMBER: builtins.int + MAX_LENGTH_FIELD_NUMBER: builtins.int + MIN_LENGTH_FIELD_NUMBER: builtins.int + PATTERN_FIELD_NUMBER: builtins.int + MAX_ITEMS_FIELD_NUMBER: builtins.int + MIN_ITEMS_FIELD_NUMBER: builtins.int + UNIQUE_ITEMS_FIELD_NUMBER: builtins.int + MAX_PROPERTIES_FIELD_NUMBER: builtins.int + MIN_PROPERTIES_FIELD_NUMBER: builtins.int + REQUIRED_FIELD_NUMBER: builtins.int + ARRAY_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + FORMAT_FIELD_NUMBER: builtins.int + ENUM_FIELD_NUMBER: builtins.int + ref: builtins.str + """Ref is used to define an external reference to include in the message. + This could be a fully qualified proto message reference, and that type must + be imported into the protofile. If no message is identified, the Ref will + be used verbatim in the output. + For example: + `ref: ".google.protobuf.Timestamp"`. + """ + title: builtins.str + """The title of the schema.""" + description: builtins.str + """A short description of the schema.""" + default: builtins.str + read_only: builtins.bool + example: builtins.str + """A free-form property to include a JSON example of this field. This is copied + verbatim to the output swagger.json. Quotes must be escaped. + This property is the same for 2.0 and 3.0.0 https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schemaObject https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject + """ + multiple_of: builtins.float + maximum: builtins.float + """Maximum represents an inclusive upper limit for a numeric instance. The + value of MUST be a number, + """ + exclusive_maximum: builtins.bool + minimum: builtins.float + """minimum represents an inclusive lower limit for a numeric instance. The + value of MUST be a number, + """ + exclusive_minimum: builtins.bool + max_length: builtins.int + min_length: builtins.int + pattern: builtins.str + max_items: builtins.int + min_items: builtins.int + unique_items: builtins.bool + max_properties: builtins.int + min_properties: builtins.int + format: builtins.str + """`Format`""" + @property + def required(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... + @property + def array(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Items in 'array' must be unique.""" + + @property + def type(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___JSONSchema.JSONSchemaSimpleTypes.ValueType]: ... + @property + def enum(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Items in `enum` must be unique https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1""" + + def __init__( + self, + *, + ref: builtins.str = ..., + title: builtins.str = ..., + description: builtins.str = ..., + default: builtins.str = ..., + read_only: builtins.bool = ..., + example: builtins.str = ..., + multiple_of: builtins.float = ..., + maximum: builtins.float = ..., + exclusive_maximum: builtins.bool = ..., + minimum: builtins.float = ..., + exclusive_minimum: builtins.bool = ..., + max_length: builtins.int = ..., + min_length: builtins.int = ..., + pattern: builtins.str = ..., + max_items: builtins.int = ..., + min_items: builtins.int = ..., + unique_items: builtins.bool = ..., + max_properties: builtins.int = ..., + min_properties: builtins.int = ..., + required: collections.abc.Iterable[builtins.str] | None = ..., + array: collections.abc.Iterable[builtins.str] | None = ..., + type: collections.abc.Iterable[global___JSONSchema.JSONSchemaSimpleTypes.ValueType] | None = ..., + format: builtins.str = ..., + enum: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["array", b"array", "default", b"default", "description", b"description", "enum", b"enum", "example", b"example", "exclusive_maximum", b"exclusive_maximum", "exclusive_minimum", b"exclusive_minimum", "format", b"format", "max_items", b"max_items", "max_length", b"max_length", "max_properties", b"max_properties", "maximum", b"maximum", "min_items", b"min_items", "min_length", b"min_length", "min_properties", b"min_properties", "minimum", b"minimum", "multiple_of", b"multiple_of", "pattern", b"pattern", "read_only", b"read_only", "ref", b"ref", "required", b"required", "title", b"title", "type", b"type", "unique_items", b"unique_items"]) -> None: ... + +global___JSONSchema = JSONSchema + +@typing.final +class Tag(google.protobuf.message.Message): + """`Tag` is a representation of OpenAPI v2 specification's Tag object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DESCRIPTION_FIELD_NUMBER: builtins.int + EXTERNAL_DOCS_FIELD_NUMBER: builtins.int + description: builtins.str + """A short description for the tag. GFM syntax can be used for rich text + representation. + """ + @property + def external_docs(self) -> global___ExternalDocumentation: + """Additional external documentation for this tag.""" + + def __init__( + self, + *, + description: builtins.str = ..., + external_docs: global___ExternalDocumentation | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["external_docs", b"external_docs"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["description", b"description", "external_docs", b"external_docs"]) -> None: ... + +global___Tag = Tag + +@typing.final +class SecurityDefinitions(google.protobuf.message.Message): + """`SecurityDefinitions` is a representation of OpenAPI v2 specification's + Security Definitions object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject + + A declaration of the security schemes available to be used in the + specification. This does not enforce the security schemes on the operations + and only serves to provide the relevant details for each scheme. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class SecurityEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___SecurityScheme: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___SecurityScheme | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + SECURITY_FIELD_NUMBER: builtins.int + @property + def security(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___SecurityScheme]: + """A single security scheme definition, mapping a "name" to the scheme it + defines. + """ + + def __init__( + self, + *, + security: collections.abc.Mapping[builtins.str, global___SecurityScheme] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["security", b"security"]) -> None: ... + +global___SecurityDefinitions = SecurityDefinitions + +@typing.final +class SecurityScheme(google.protobuf.message.Message): + """`SecurityScheme` is a representation of OpenAPI v2 specification's + Security Scheme object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject + + Allows the definition of a security scheme that can be used by the + operations. Supported schemes are basic authentication, an API key (either as + a header or as a query parameter) and OAuth2's common flows (implicit, + password, application and access code). + """ + + 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[SecurityScheme._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + TYPE_INVALID: SecurityScheme._Type.ValueType # 0 + TYPE_BASIC: SecurityScheme._Type.ValueType # 1 + TYPE_API_KEY: SecurityScheme._Type.ValueType # 2 + TYPE_OAUTH2: SecurityScheme._Type.ValueType # 3 + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): + """The type of the security scheme. Valid values are "basic", + "apiKey" or "oauth2". + """ + + TYPE_INVALID: SecurityScheme.Type.ValueType # 0 + TYPE_BASIC: SecurityScheme.Type.ValueType # 1 + TYPE_API_KEY: SecurityScheme.Type.ValueType # 2 + TYPE_OAUTH2: SecurityScheme.Type.ValueType # 3 + + class _In: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _InEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SecurityScheme._In.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + IN_INVALID: SecurityScheme._In.ValueType # 0 + IN_QUERY: SecurityScheme._In.ValueType # 1 + IN_HEADER: SecurityScheme._In.ValueType # 2 + + class In(_In, metaclass=_InEnumTypeWrapper): + """The location of the API key. Valid values are "query" or "header".""" + + IN_INVALID: SecurityScheme.In.ValueType # 0 + IN_QUERY: SecurityScheme.In.ValueType # 1 + IN_HEADER: SecurityScheme.In.ValueType # 2 + + class _Flow: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _FlowEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SecurityScheme._Flow.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + FLOW_INVALID: SecurityScheme._Flow.ValueType # 0 + FLOW_IMPLICIT: SecurityScheme._Flow.ValueType # 1 + FLOW_PASSWORD: SecurityScheme._Flow.ValueType # 2 + FLOW_APPLICATION: SecurityScheme._Flow.ValueType # 3 + FLOW_ACCESS_CODE: SecurityScheme._Flow.ValueType # 4 + + class Flow(_Flow, metaclass=_FlowEnumTypeWrapper): + """The flow used by the OAuth2 security scheme. Valid values are + "implicit", "password", "application" or "accessCode". + """ + + FLOW_INVALID: SecurityScheme.Flow.ValueType # 0 + FLOW_IMPLICIT: SecurityScheme.Flow.ValueType # 1 + FLOW_PASSWORD: SecurityScheme.Flow.ValueType # 2 + FLOW_APPLICATION: SecurityScheme.Flow.ValueType # 3 + FLOW_ACCESS_CODE: SecurityScheme.Flow.ValueType # 4 + + @typing.final + class ExtensionsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> google.protobuf.struct_pb2.Value: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: google.protobuf.struct_pb2.Value | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + TYPE_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + IN_FIELD_NUMBER: builtins.int + FLOW_FIELD_NUMBER: builtins.int + AUTHORIZATION_URL_FIELD_NUMBER: builtins.int + TOKEN_URL_FIELD_NUMBER: builtins.int + SCOPES_FIELD_NUMBER: builtins.int + EXTENSIONS_FIELD_NUMBER: builtins.int + type: global___SecurityScheme.Type.ValueType + """The type of the security scheme. Valid values are "basic", + "apiKey" or "oauth2". + """ + description: builtins.str + """A short description for security scheme.""" + name: builtins.str + """The name of the header or query parameter to be used. + Valid for apiKey. + """ + flow: global___SecurityScheme.Flow.ValueType + """The flow used by the OAuth2 security scheme. Valid values are + "implicit", "password", "application" or "accessCode". + Valid for oauth2. + """ + authorization_url: builtins.str + """The authorization URL to be used for this flow. This SHOULD be in + the form of a URL. + Valid for oauth2/implicit and oauth2/accessCode. + """ + token_url: builtins.str + """The token URL to be used for this flow. This SHOULD be in the + form of a URL. + Valid for oauth2/password, oauth2/application and oauth2/accessCode. + """ + @property + def scopes(self) -> global___Scopes: + """The available scopes for the OAuth2 security scheme. + Valid for oauth2. + """ + + @property + def extensions(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, google.protobuf.struct_pb2.Value]: ... + def __init__( + self, + *, + type: global___SecurityScheme.Type.ValueType = ..., + description: builtins.str = ..., + name: builtins.str = ..., + flow: global___SecurityScheme.Flow.ValueType = ..., + authorization_url: builtins.str = ..., + token_url: builtins.str = ..., + scopes: global___Scopes | None = ..., + extensions: collections.abc.Mapping[builtins.str, google.protobuf.struct_pb2.Value] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["scopes", b"scopes"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["authorization_url", b"authorization_url", "description", b"description", "extensions", b"extensions", "flow", b"flow", "in", b"in", "name", b"name", "scopes", b"scopes", "token_url", b"token_url", "type", b"type"]) -> None: ... + +global___SecurityScheme = SecurityScheme + +@typing.final +class SecurityRequirement(google.protobuf.message.Message): + """`SecurityRequirement` is a representation of OpenAPI v2 specification's + Security Requirement object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject + + Lists the required security schemes to execute this operation. The object can + have multiple security schemes declared in it which are all required (that + is, there is a logical AND between the schemes). + + The name used for each property MUST correspond to a security scheme + declared in the Security Definitions. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class SecurityRequirementValue(google.protobuf.message.Message): + """If the security scheme is of type "oauth2", then the value is a list of + scope names required for the execution. For other security scheme types, + the array MUST be empty. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCOPE_FIELD_NUMBER: builtins.int + @property + def scope(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... + def __init__( + self, + *, + scope: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["scope", b"scope"]) -> None: ... + + @typing.final + class SecurityRequirementEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___SecurityRequirement.SecurityRequirementValue: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___SecurityRequirement.SecurityRequirementValue | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + SECURITY_REQUIREMENT_FIELD_NUMBER: builtins.int + @property + def security_requirement(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___SecurityRequirement.SecurityRequirementValue]: + """Each name must correspond to a security scheme which is declared in + the Security Definitions. If the security scheme is of type "oauth2", + then the value is a list of scope names required for the execution. + For other security scheme types, the array MUST be empty. + """ + + def __init__( + self, + *, + security_requirement: collections.abc.Mapping[builtins.str, global___SecurityRequirement.SecurityRequirementValue] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["security_requirement", b"security_requirement"]) -> None: ... + +global___SecurityRequirement = SecurityRequirement + +@typing.final +class Scopes(google.protobuf.message.Message): + """`Scopes` is a representation of OpenAPI v2 specification's Scopes object. + + See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject + + Lists the available scopes for an OAuth2 security scheme. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing.final + class ScopeEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + value: builtins.str + def __init__( + self, + *, + key: builtins.str = ..., + value: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + SCOPE_FIELD_NUMBER: builtins.int + @property + def scope(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: + """Maps between a name of a scope to a short description of it (as the value + of the property). + """ + + def __init__( + self, + *, + scope: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["scope", b"scope"]) -> None: ... + +global___Scopes = Scopes diff --git a/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py b/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py index 2daafffe..929d0253 100644 --- a/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py +++ b/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py @@ -1,4 +1,24 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings + +GRPC_GENERATED_VERSION = '1.73.1' +GRPC_VERSION = grpc.__version__ +_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: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in protoc_gen_swagger/options/openapiv2_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}.' + ) diff --git a/src/scanoss/__init__.py b/src/scanoss/__init__.py index 77eed9d1..2a69dd2a 100644 --- a/src/scanoss/__init__.py +++ b/src/scanoss/__init__.py @@ -22,4 +22,4 @@ THE SOFTWARE. """ -__version__ = '1.32.0' +__version__ = '1.33.0' diff --git a/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py b/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py index b5c3c03c..addf36f2 100644 --- a/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py +++ b/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py @@ -1,8 +1,12 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" -import grpc import warnings +import grpc + +GRPC_GENERATED_VERSION = '1.73.1' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False GRPC_GENERATED_VERSION = '1.73.1' GRPC_VERSION = grpc.__version__ diff --git a/src/scanoss/cli.py b/src/scanoss/cli.py index 983d773d..97bed902 100644 --- a/src/scanoss/cli.py +++ b/src/scanoss/cli.py @@ -34,7 +34,9 @@ from scanoss.cryptography import Cryptography, create_cryptography_config_from_args from scanoss.export.dependency_track import DependencyTrackExporter -from scanoss.inspection.dependency_track.project_violation import DependencyTrackProjectViolationPolicyCheck +from scanoss.inspection.dependency_track.project_violation import ( + DependencyTrackProjectViolationPolicyCheck, +) from scanoss.inspection.raw.component_summary import ComponentSummary from scanoss.inspection.raw.license_summary import LicenseSummary from scanoss.scanners.container_scanner import ( @@ -310,6 +312,16 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 c_vulns.set_defaults(func=comp_vulns) c_vulns.add_argument('--grpc', action='store_true', help='Enable gRPC support') + # Component Sub-command: component licenses + c_licenses = comp_sub.add_parser( + 'licenses', + aliases=['lics'], + description=f'Show License details: {__version__}', + help='Retrieve licenses for the given components', + ) + c_licenses.add_argument('--grpc', action='store_true', help='Enable gRPC support') + c_licenses.set_defaults(func=comp_licenses) + # Component Sub-command: component semgrep c_semgrep = comp_sub.add_parser( 'semgrep', @@ -411,7 +423,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 p_crypto_versions_in_range.set_defaults(func=crypto_versions_in_range) # Common purl Component sub-command options - for p in [c_vulns, c_semgrep, c_provenance, p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range]: + for p in [ + c_vulns, + c_semgrep, + c_provenance, + p_crypto_algorithms, + p_crypto_hints, + p_crypto_versions_in_range, + c_licenses, + ]: p.add_argument('--purl', '-p', type=str, nargs='*', help='Package URL - PURL to process.') p.add_argument('--input', '-i', type=str, help='Input file name') @@ -425,6 +445,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range, + c_licenses, ]: p.add_argument( '--timeout', @@ -541,32 +562,32 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 # ========================================================================= # INSPECT SUBCOMMAND - Analysis and validation of scan results # ========================================================================= - + # Main inspect parser - provides tools for analyzing scan results p_inspect = subparsers.add_parser( - 'inspect', - aliases=['insp', 'ins'], + 'inspect', + aliases=['insp', 'ins'], description=f'Inspect and analyse scan results: {__version__}', - help='Inspect and analyse scan results' + help='Inspect and analyse scan results', ) # Inspect sub-commands parser p_inspect_sub = p_inspect.add_subparsers( - title='Inspect Commands', - dest='subparsercmd', - description='Available inspection sub-commands', - help='Choose an inspection type' + title='Inspect Commands', + dest='subparsercmd', + description='Available inspection sub-commands', + help='Choose an inspection type', ) # ------------------------------------------------------------------------- # RAW RESULTS INSPECTION - Analyse raw scan output # ------------------------------------------------------------------------- - + # Raw results parser - handles inspection of unprocessed scan results p_inspect_raw = p_inspect_sub.add_parser( 'raw', description='Inspect and analyse SCANOSS raw scan results', - help='Analyse raw scan results for various compliance issues' + help='Analyse raw scan results for various compliance issues', ) # Raw results sub-commands parser @@ -574,15 +595,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 title='Raw Results Inspection Commands', dest='subparser_subcmd', description='Tools for analyzing raw scan results', - help='Choose a raw results analysis type' + help='Choose a raw results analysis type', ) # Copyleft license inspection - identifies copyleft license violations p_inspect_raw_copyleft = p_inspect_raw_sub.add_parser( - 'copyleft', - aliases=['cp'], - description='Identify components with copyleft licenses that may require compliance action', - help='Find copyleft license violations' + 'copyleft', + aliases=['cp'], + description='Identify components with copyleft licenses that may require compliance action', + help='Find copyleft license violations', ) # License summary inspection - provides overview of all detected licenses @@ -590,7 +611,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'license-summary', aliases=['lic-summary', 'licsum'], description='Generate comprehensive summary of all licenses found in scan results', - help='Generate license summary report' + help='Generate license summary report', ) # Component summary inspection - provides overview of all detected components @@ -598,7 +619,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'component-summary', aliases=['comp-summary', 'compsum'], description='Generate comprehensive summary of all components found in scan results', - help='Generate component summary report' + help='Generate component summary report', ) # Undeclared components inspection - finds components not declared in SBOM @@ -606,7 +627,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'undeclared', aliases=['un'], description='Identify components present in code but not declared in SBOM files', - help='Find undeclared components' + help='Find undeclared components', ) # SBOM format option for undeclared components inspection p_inspect_raw_undeclared.add_argument( @@ -614,19 +635,19 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 required=False, choices=['legacy', 'settings'], default='settings', - help='SBOM format type for comparison: legacy or settings (default)' + help='SBOM format type for comparison: legacy or settings (default)', ) # ------------------------------------------------------------------------- # BACKWARD COMPATIBILITY - Support old inspect command format # ------------------------------------------------------------------------- - + # Legacy copyleft inspection - backward compatibility for 'scanoss-py inspect copyleft' p_inspect_legacy_copyleft = p_inspect_sub.add_parser( - 'copyleft', - aliases=['cp'], - description='Identify components with copyleft licenses that may require compliance action', - help='Find copyleft license violations (legacy format)' + 'copyleft', + aliases=['cp'], + description='Identify components with copyleft licenses that may require compliance action', + help='Find copyleft license violations (legacy format)', ) # Legacy undeclared components inspection - backward compatibility for 'scanoss-py inspect undeclared' @@ -634,16 +655,16 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'undeclared', aliases=['un'], description='Identify components present in code but not declared in SBOM files', - help='Find undeclared components (legacy format)' + help='Find undeclared components (legacy format)', ) - + # SBOM format option for legacy undeclared components inspection p_inspect_legacy_undeclared.add_argument( '--sbom-format', required=False, choices=['legacy', 'settings'], default='settings', - help='SBOM format type for comparison: legacy or settings (default)' + help='SBOM format type for comparison: legacy or settings (default)', ) # Legacy license summary inspection - backward compatibility for 'scanoss-py inspect license-summary' @@ -651,7 +672,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'license-summary', aliases=['lic-summary', 'licsum'], description='Generate comprehensive summary of all licenses found in scan results', - help='Generate license summary report (legacy format)' + help='Generate license summary report (legacy format)', ) # Legacy component summary inspection - backward compatibility for 'scanoss-py inspect component-summary' @@ -659,83 +680,63 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'component-summary', aliases=['comp-summary', 'compsum'], description='Generate comprehensive summary of all components found in scan results', - help='Generate component summary report (legacy format)' + help='Generate component summary report (legacy format)', ) # Applies the same configuration to both legacy and raw versions # License filtering options - common to (legacy) copyleft and license summary commands - for p in [p_inspect_raw_copyleft, p_inspect_raw_license_summary, - p_inspect_legacy_copyleft, p_inspect_legacy_license_summary]: - p.add_argument( - '--include', - help='Additional licenses to include in analysis (comma-separated list)' - ) - p.add_argument( - '--exclude', - help='Licenses to exclude from analysis (comma-separated list)' - ) - p.add_argument( - '--explicit', - help='Use only these specific licenses for analysis (comma-separated list)' - ) + for p in [ + p_inspect_raw_copyleft, + p_inspect_raw_license_summary, + p_inspect_legacy_copyleft, + p_inspect_legacy_license_summary, + ]: + p.add_argument('--include', help='Additional licenses to include in analysis (comma-separated list)') + p.add_argument('--exclude', help='Licenses to exclude from analysis (comma-separated list)') + p.add_argument('--explicit', help='Use only these specific licenses for analysis (comma-separated list)') # Common options for (legacy) copyleft and undeclared component inspection for p in [p_inspect_raw_copyleft, p_inspect_raw_undeclared, p_inspect_legacy_copyleft, p_inspect_legacy_undeclared]: + p.add_argument('-i', '--input', nargs='?', help='Path to scan results file to analyse') p.add_argument( - '-i', '--input', - nargs='?', - help='Path to scan results file to analyse' - ) - p.add_argument( - '-f', '--format', + '-f', + '--format', required=False, choices=['json', 'md', 'jira_md'], default='json', - help='Output format: json (default), md (Markdown), or jira_md (JIRA Markdown)' - ) - p.add_argument( - '-o', '--output', - type=str, - help='Save detailed results to specified file' - ) - p.add_argument( - '-s', '--status', - type=str, - help='Save summary status report to Markdown file' + help='Output format: json (default), md (Markdown), or jira_md (JIRA Markdown)', ) + p.add_argument('-o', '--output', type=str, help='Save detailed results to specified file') + p.add_argument('-s', '--status', type=str, help='Save summary status report to Markdown file') # Common options for (legacy) license and component summary commands - for p in [p_inspect_raw_license_summary, p_inspect_raw_component_summary, - p_inspect_legacy_license_summary, p_inspect_legacy_component_summary]: - p.add_argument( - '-i', '--input', - nargs='?', - help='Path to scan results file to analyse' - ) - p.add_argument( - '-o', '--output', - type=str, - help='Save summary report to specified file' - ) + for p in [ + p_inspect_raw_license_summary, + p_inspect_raw_component_summary, + p_inspect_legacy_license_summary, + p_inspect_legacy_component_summary, + ]: + p.add_argument('-i', '--input', nargs='?', help='Path to scan results file to analyse') + p.add_argument('-o', '--output', type=str, help='Save summary report to specified file') # ------------------------------------------------------------------------- # DEPENDENCY TRACK INSPECTION - Analyse Dependency Track project data # ------------------------------------------------------------------------- - + # Dependency Track parser - handles inspection of DT project status and violations p_dep_track_sub = p_inspect_sub.add_parser( 'dependency-track', aliases=['dt'], description='Inspect and analyse Dependency Track project status and policy violations', - help='Analyse Dependency Track projects' + help='Analyse Dependency Track projects', ) - + # Dependency Track sub-commands parser p_inspect_dep_track_sub = p_dep_track_sub.add_subparsers( title='Dependency Track Inspection Commands', dest='subparser_subcmd', description='Tools for analysing Dependency Track project data', - help='Choose a Dependency Track analysis type' + help='Choose a Dependency Track analysis type', ) # Project violations inspection - analyses policy violations in DT projects @@ -743,70 +744,52 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 'project-violations', aliases=['pv'], description='Analyse policy violations and compliance issues in Dependency Track projects', - help='Inspect project policy violations' + help='Inspect project policy violations', ) # Dependency Track connection and authentication options p_inspect_dt_project_violation.add_argument( - '--url', - required=True, - type=str, - help='Dependency Track server base URL (e.g., https://dtrack.example.com)' + '--url', required=True, type=str, help='Dependency Track server base URL (e.g., https://dtrack.example.com)' ) p_inspect_dt_project_violation.add_argument( - '--upload-token', '-ut', + '--upload-token', + '-ut', required=False, - type=str, - help='Project-specific upload token for accessing DT project data' + type=str, + help='Project-specific upload token for accessing DT project data', ) p_inspect_dt_project_violation.add_argument( - '--project-id', '-pid', - required=False, - type=str, - help='Dependency Track project UUID to inspect' + '--project-id', '-pid', required=False, type=str, help='Dependency Track project UUID to inspect' ) p_inspect_dt_project_violation.add_argument( - '--apikey', '-k', - required=True, - type=str, - help='Dependency Track API key for authentication' + '--apikey', '-k', required=True, type=str, help='Dependency Track API key for authentication' ) p_inspect_dt_project_violation.add_argument( - '--project-name', '-pn', - required=False, - type=str, - help='Dependency Track project name' + '--project-name', '-pn', required=False, type=str, help='Dependency Track project name' ) p_inspect_dt_project_violation.add_argument( - '--project-version', '-pv', - required=False, - type=str, - help='Dependency Track project version' + '--project-version', '-pv', required=False, type=str, help='Dependency Track project version' ) p_inspect_dt_project_violation.add_argument( - '--output', '-o', - required=False, - type=str, - help='Save inspection results to specified file' + '--output', '-o', required=False, type=str, help='Save inspection results to specified file' ) p_inspect_dt_project_violation.add_argument( - '--status', - required=False, - type=str, - help='Save summary status report to specified file' + '--status', required=False, type=str, help='Save summary status report to specified file' ) p_inspect_dt_project_violation.add_argument( - '--format', '-f', + '--format', + '-f', required=False, choices=['json', 'md', 'jira_md'], default='json', - help='Output format: json (default), md (Markdown) or jira_md (JIRA Markdown)' + help='Output format: json (default), md (Markdown) or jira_md (JIRA Markdown)', ) p_inspect_dt_project_violation.add_argument( - '--timeout', '-M', + '--timeout', + '-M', required=False, default=300, type=float, - help='Timeout (in seconds) for API communication (optional - default 300 sec)' + help='Timeout (in seconds) for API communication (optional - default 300 sec)', ) # TODO Move to the command call def location @@ -852,7 +835,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 e_dt.add_argument('-i', '--input', type=str, required=True, help='Input SBOM file (CycloneDX JSON format)') e_dt.add_argument('--url', type=str, required=True, help='Dependency Track base URL') e_dt.add_argument('--apikey', '-k', type=str, required=True, help='Dependency Track API key') - e_dt.add_argument('--output', '-o', type=str, help='File to save export token and uuid into') + e_dt.add_argument('--output', '-o', type=str, help='File to save export token and uuid into') e_dt.add_argument('--project-id', '-pid', type=str, help='Dependency Track project UUID') e_dt.add_argument('--project-name', '-pn', type=str, help='Dependency Track project name') e_dt.add_argument('--project-version', '-pv', type=str, help='Dependency Track project version') @@ -927,6 +910,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range, + c_licenses, ]: p.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).') @@ -1001,6 +985,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range, + c_licenses, ]: p.add_argument( '--key', '-k', type=str, help='SCANOSS API Key token (optional - not required for default OSSKB URL)' @@ -1039,6 +1024,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range, + c_licenses, ]: p.add_argument( '--api2url', type=str, help='SCANOSS gRPC API 2.0 URL (optional - default: https://api.osskb.org)' @@ -1104,6 +1090,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915 p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range, + c_licenses, e_dt, ]: p.add_argument('--debug', '-d', action='store_true', help='Enable debug messages') @@ -1420,7 +1407,7 @@ def scan(parser, args): # noqa: PLR0912, PLR0915 strip_snippet_ids=args.strip_snippet, scan_settings=scan_settings, req_headers=process_req_headers(args.header), - use_grpc=args.grpc + use_grpc=args.grpc, ) if args.wfp: if not scanner.is_file_or_snippet_scan(): @@ -1554,13 +1541,14 @@ def convert(parser, args): # INSPECT COMMAND HANDLERS - Functions that execute inspection operations # ============================================================================= + def inspect_copyleft(parser, args): """ Handle copyleft license inspection command. - + Analyses scan results to identify components using copyleft licenses that may require compliance actions such as source code disclosure. - + Parameters ---------- parser : ArgumentParser @@ -1594,9 +1582,9 @@ def inspect_copyleft(parser, args): format_type=args.format, status=args.status, output=args.output, - include=args.include, # Additional licenses to check - exclude=args.exclude, # Licenses to ignore - explicit=args.explicit, # Explicit license list + include=args.include, # Additional licenses to check + exclude=args.exclude, # Licenses to ignore + explicit=args.explicit, # Explicit license list ) # Execute inspection and exit with appropriate status code @@ -1612,11 +1600,11 @@ def inspect_copyleft(parser, args): def inspect_undeclared(parser, args): """ Handle undeclared components inspection command. - + Analyses scan results to identify components that are present in the codebase but not declared in SBOM or manifest files, which may indicate security or compliance risks. - + Parameters ---------- parser : ArgumentParser @@ -1634,7 +1622,7 @@ def inspect_undeclared(parser, args): print_stderr('ERROR: Input file is required for undeclared component inspection') parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h']) sys.exit(1) - + # Initialise output file if specified if args.output: initialise_empty_file(args.output) @@ -1669,10 +1657,10 @@ def inspect_undeclared(parser, args): def inspect_license_summary(parser, args): """ Handle license summary inspection command. - + Generates comprehensive summary of all licenses detected in scan results, including license counts, risk levels, and compliance recommendations. - + Parameters ---------- parser : ArgumentParser @@ -1688,7 +1676,7 @@ def inspect_license_summary(parser, args): print_stderr('ERROR: Input file is required for license summary') parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h']) sys.exit(1) - + # Initialise output file if specified if args.output: initialise_empty_file(args.output) @@ -1700,9 +1688,9 @@ def inspect_license_summary(parser, args): quiet=args.quiet, filepath=args.input, output=args.output, - include=args.include, # Additional licenses to include - exclude=args.exclude, # Licenses to exclude from summary - explicit=args.explicit, # Explicit license list to summarize + include=args.include, # Additional licenses to include + exclude=args.exclude, # Licenses to exclude from summary + explicit=args.explicit, # Explicit license list to summarize ) try: # Execute summary generation @@ -1713,13 +1701,14 @@ def inspect_license_summary(parser, args): traceback.print_exc() sys.exit(1) + def inspect_component_summary(parser, args): """ Handle component summary inspection command. - + Generates a comprehensive summary of all components detected in scan results, including component counts, versions, match types, and security information. - + Parameters ---------- parser : ArgumentParser @@ -1734,10 +1723,10 @@ def inspect_component_summary(parser, args): print_stderr('ERROR: Input file is required for component summary') parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h']) sys.exit(1) - + # Initialise an output file if specified if args.output: - initialise_empty_file(args.output) # Create/clear output file + initialise_empty_file(args.output) # Create/clear output file # Create and configure component summary generator i_component_summary = ComponentSummary( @@ -1757,14 +1746,15 @@ def inspect_component_summary(parser, args): traceback.print_exc() sys.exit(1) + def inspect_dep_track_project_violations(parser, args): """ Handle Dependency Track project inspection command. - + Analyses Dependency Track projects for policy violations, security issues, and compliance status. Connects to DT API to retrieve project data and generate detailed violation reports. - + Parameters ---------- parser : ArgumentParser @@ -1794,14 +1784,14 @@ def inspect_dep_track_project_violations(parser, args): trace=args.trace, quiet=args.quiet, output=args.output, - status= args.status, + status=args.status, format_type=args.format, - url=args.url, # DT server URL - api_key=args.apikey, # Authentication key - project_id=args.project_id, # Target project UUID + url=args.url, # DT server URL + api_key=args.apikey, # Authentication key + project_id=args.project_id, # Target project UUID upload_token=args.upload_token, # Upload access token - project_name=args.project_name, # DT project name - project_version=args.project_version, # DT project version + project_name=args.project_name, # DT project name + project_version=args.project_version, # DT project version timeout=args.timeout, ) # Execute inspection and exit with appropriate status code @@ -1818,6 +1808,7 @@ def inspect_dep_track_project_violations(parser, args): # END INSPECT COMMAND HANDLERS # ============================================================================= + def export_dt(parser, args): """ Validates and exports a Software Bill of Materials (SBOM) to a Dependency-Track server. @@ -1845,8 +1836,9 @@ def export_dt(parser, args): trace=args.trace, quiet=args.quiet, ) - success = dt_exporter.upload_sbom_file(args.input, args.project_id, args.project_name, - args.project_version, args.output) + success = dt_exporter.upload_sbom_file( + args.input, args.project_id, args.project_name, args.project_version, args.output + ) if not success: sys.exit(1) except Exception as e: @@ -1855,6 +1847,7 @@ def export_dt(parser, args): traceback.print_exc() sys.exit(1) + def _dt_args_validator(parser, args): """ Validates command-line arguments related to project identification. @@ -1884,6 +1877,7 @@ def _dt_args_validator(parser, args): print_stderr('Please supply a project name (--project-name) and version (--project-version)') sys.exit(1) + def utils_certloc(*_): """ Run the "utils certloc" sub-command @@ -2307,6 +2301,42 @@ def comp_provenance(parser, args): sys.exit(1) +def comp_licenses(parser, args): + """ + Run the "component licenses" sub-command + Parameters + ---------- + parser: ArgumentParser + command line parser object + args: Namespace + Parsed arguments + """ + if (not args.purl and not args.input) or (args.purl and args.input): + print_stderr('ERROR: Please specify an input file or purl to decorate (--purl or --input)') + parser.parse_args([args.subparser, args.subparsercmd, '-h']) + sys.exit(1) + if args.ca_cert and not os.path.exists(args.ca_cert): + print_stderr(f'ERROR: Certificate file does not exist: {args.ca_cert}.') + sys.exit(1) + pac_file = get_pac_file(args.pac) + comps = Components( + debug=args.debug, + trace=args.trace, + quiet=args.quiet, + grpc_url=args.api2url, + api_key=args.key, + ca_cert=args.ca_cert, + proxy=args.proxy, + grpc_proxy=args.grpc_proxy, + pac=pac_file, + timeout=args.timeout, + req_headers=process_req_headers(args.header), + use_grpc=args.grpc, + ) + if not comps.get_licenses(args.input, args.purl, args.output): + sys.exit(1) + + def results(parser, args): """ Run the "results" sub-command diff --git a/src/scanoss/components.py b/src/scanoss/components.py index 6756fc82..25224fbe 100644 --- a/src/scanoss/components.py +++ b/src/scanoss/components.py @@ -29,6 +29,9 @@ from pypac.parser import PACFile +from scanoss.cyclonedx import CycloneDx +from scanoss.utils.file import validate_json_file + from .scanner import Scanner from .scanossbase import ScanossBase from .scanossgrpc import ScanossGrpc @@ -90,8 +93,9 @@ def __init__( # noqa: PLR0913, PLR0915 ignore_cert_errors=ignore_cert_errors, use_grpc=use_grpc, ) + self.cdx = CycloneDx(debug=self.debug) - def load_comps(self, json_file: Optional[str] = None, purls: Optional[List[str]] = None)-> Optional[dict]: + def load_comps(self, json_file: Optional[str] = None, purls: Optional[List[str]] = None) -> Optional[dict]: """ Load the specified components and return a dictionary @@ -101,8 +105,9 @@ def load_comps(self, json_file: Optional[str] = None, purls: Optional[List[str]] """ return self.load_purls(json_file, purls, 'components') - def load_purls(self, json_file: Optional[str] = None, purls: Optional[List[str]] = None, field:str = 'purls' - ) -> Optional[dict]: + def load_purls( + self, json_file: Optional[str] = None, purls: Optional[List[str]] = None, field: str = 'purls' + ) -> Optional[dict]: """ Load the specified purls and return a dictionary @@ -112,15 +117,15 @@ def load_purls(self, json_file: Optional[str] = None, purls: Optional[List[str]] :return: PURL Request dictionary or None """ if json_file: - if not os.path.isfile(json_file) or not os.access(json_file, os.R_OK): - self.print_stderr(f'ERROR: JSON file does not exist, is not a file, or is not readable: {json_file}') + result = validate_json_file(json_file) + if not result.is_valid: + self.print_stderr(f'ERROR: Problem parsing input JSON: {result.error}') return None - with open(json_file, 'r') as f: - try: - purl_request = json.loads(f.read()) - except Exception as e: - self.print_stderr(f'ERROR: Problem parsing input JSON: {e}') - return None + + if self.cdx.is_cyclonedx_json(json.dumps(result.data)): + purl_request = self.cdx.get_purls_request_from_cdx(result.data, field) + else: + purl_request = result.data elif purls: if not all(isinstance(purl, str) for purl in purls): self.print_stderr('ERROR: PURLs must be a list of strings.') @@ -384,3 +389,35 @@ def get_provenance_details( self.print_msg(f'Results written to: {output_file}') self._close_file(output_file, file) return success + + def get_licenses(self, json_file: str = None, purls: [] = None, output_file: str = None) -> bool: + """ + Retrieve the license details for the supplied PURLs + + Args: + json_file (str, optional): Input JSON file. Defaults to None. + purls (None, optional): PURLs to retrieve license details for. Defaults to None. + output_file (str, optional): Output file. Defaults to None. + + Returns: + bool: True on success, False otherwise + """ + success = False + + purls_request = self.load_purls(json_file, purls) + if not purls_request: + return False + file = self._open_file_or_sdtout(output_file) + if file is None: + return False + + # We'll use the new ComponentBatchRequest instead of deprecated PurlRequest for the license api + component_batch_request = {'components': purls_request.get('purls')} + response = self.grpc_api.get_licenses(component_batch_request) + if response: + print(json.dumps(response, indent=2, sort_keys=True), file=file) + success = True + if output_file: + self.print_msg(f'Results written to: {output_file}') + self._close_file(output_file, file) + return success diff --git a/src/scanoss/cryptography.py b/src/scanoss/cryptography.py index 9f367ba3..7957609f 100644 --- a/src/scanoss/cryptography.py +++ b/src/scanoss/cryptography.py @@ -2,6 +2,7 @@ from dataclasses import dataclass from typing import Dict, List, Optional +from scanoss.cyclonedx import CycloneDx from scanoss.scanossbase import ScanossBase from scanoss.scanossgrpc import ScanossGrpc from scanoss.utils.abstract_presenter import AbstractPresenter @@ -26,6 +27,38 @@ class CryptographyConfig: quiet: bool = False with_range: bool = False + def _process_input_file(self) -> dict: + """ + Process and validate the input file, returning the validated purl_request. + + Returns: + dict: The validated purl_request dictionary + + Raises: + ScanossCryptographyError: If the input file is invalid + """ + result = validate_json_file(self.input_file) + if not result.is_valid: + raise ScanossCryptographyError( + f'There was a problem with the purl input file. {result.error}' + ) + + cdx = CycloneDx(debug=self.debug) + if cdx.is_cyclonedx_json(json.dumps(result.data)): + purl_request = cdx.get_purls_request_from_cdx(result.data) + else: + purl_request = result.data + + if ( + not isinstance(purl_request, dict) + or 'purls' not in purl_request + or not isinstance(purl_request['purls'], list) + or not all(isinstance(p, dict) and 'purl' in p for p in purl_request['purls']) + ): + raise ScanossCryptographyError('The supplied input file is not in the correct PurlRequest format.') + + return purl_request + def __post_init__(self): """ Validate that the configuration is valid. @@ -39,19 +72,8 @@ def __post_init__(self): f'Invalid PURL format: "{purl}".' f'It must include a version (e.g., pkg:type/name@version)' ) if self.input_file: - input_file_validation = validate_json_file(self.input_file) - if not input_file_validation.is_valid: - raise ScanossCryptographyError( - f'There was a problem with the purl input file. {input_file_validation.error}' - ) - if ( - not isinstance(input_file_validation.data, dict) - or 'purls' not in input_file_validation.data - or not isinstance(input_file_validation.data['purls'], list) - or not all(isinstance(p, dict) and 'purl' in p for p in input_file_validation.data['purls']) - ): - raise ScanossCryptographyError('The supplied input file is not in the correct PurlRequest format.') - purls = input_file_validation.data['purls'] + purl_request = self._process_input_file() + purls = purl_request['purls'] purls_with_requirement = [] if self.with_range and any('requirement' not in p for p in purls): raise ScanossCryptographyError( @@ -182,16 +204,10 @@ def get_versions_in_range(self) -> Optional[Dict]: return self.results - def _build_purls_request( - self, - ) -> Optional[dict]: + def _build_purls_request(self) -> Optional[dict]: """ Load the specified purls from a JSON file or a list of PURLs and return a dictionary - Args: - json_file (Optional[str], optional): The JSON file containing the PURLs. Defaults to None. - purls (Optional[List[str]], optional): The list of PURLs. Defaults to None. - Returns: Optional[dict]: The dictionary containing the PURLs """ diff --git a/src/scanoss/cyclonedx.py b/src/scanoss/cyclonedx.py index f3685a97..555ba4ad 100644 --- a/src/scanoss/cyclonedx.py +++ b/src/scanoss/cyclonedx.py @@ -394,6 +394,7 @@ def _sev_lookup(value: str): def is_cyclonedx_json(self, json_string: str) -> bool: """ Validate if the given JSON string is a valid CycloneDX JSON string + Args: json_string (str): JSON string to validate Returns: @@ -410,6 +411,27 @@ def is_cyclonedx_json(self, json_string: str) -> bool: self.print_stderr(f'ERROR: Problem parsing input JSON: {e}') return False + def get_purls_request_from_cdx(self, cdx_dict: dict, field: str = 'purls') -> dict: + """ + Get the list of PURL requests (purl + requirement) from the given CDX dictionary + + Args: + cdx_dict (dict): CDX dictionary to parse + field (str): Field to extract from the CDX dictionary + Returns: + list[dict]: List of PURL requests (purl + requirement) + """ + components = cdx_dict.get('components', []) + parsed_purls = [] + for component in components: + version = component.get('version') + if version: + parsed_purls.append({'purl': component.get('purl'), 'requirement': version}) + else: + parsed_purls.append({'purl': component.get('purl')}) + purl_request = {field: parsed_purls} + return purl_request + # # End of CycloneDX Class diff --git a/src/scanoss/scanossgrpc.py b/src/scanoss/scanossgrpc.py index fc3d3be3..deed00b6 100644 --- a/src/scanoss/scanossgrpc.py +++ b/src/scanoss/scanossgrpc.py @@ -44,6 +44,8 @@ from pypac.resolver import ProxyResolver from urllib3.exceptions import InsecureRequestWarning +from scanoss.api.licenses.v2.scanoss_licenses_pb2 import ComponentsLicenseResponse +from scanoss.api.licenses.v2.scanoss_licenses_pb2_grpc import LicenseStub from scanoss.api.scanning.v2.scanoss_scanning_pb2_grpc import ScanningStub from scanoss.constants import DEFAULT_TIMEOUT @@ -71,7 +73,9 @@ from .api.scanning.v2.scanoss_scanning_pb2 import HFHRequest from .api.semgrep.v2.scanoss_semgrep_pb2 import SemgrepResponse from .api.semgrep.v2.scanoss_semgrep_pb2_grpc import SemgrepStub -from .api.vulnerabilities.v2.scanoss_vulnerabilities_pb2 import ComponentsVulnerabilityResponse +from .api.vulnerabilities.v2.scanoss_vulnerabilities_pb2 import ( + ComponentsVulnerabilityResponse, +) from .api.vulnerabilities.v2.scanoss_vulnerabilities_pb2_grpc import VulnerabilitiesStub from .scanossbase import ScanossBase @@ -81,18 +85,20 @@ SCANOSS_API_KEY = os.environ.get('SCANOSS_API_KEY') if os.environ.get('SCANOSS_API_KEY') else '' DEFAULT_URI_PREFIX = '/v2' -MAX_CONCURRENT_REQUESTS = 5 # Maximum number of concurrent requests to make +MAX_CONCURRENT_REQUESTS = 5 # Maximum number of concurrent requests to make class ScanossGrpcError(Exception): """ Custom exception for SCANOSS gRPC errors """ + pass class ScanossGrpcStatusCode(IntEnum): """Status codes for SCANOSS gRPC responses""" + SUCCESS = 1 SUCCESS_WITH_WARNINGS = 2 FAILED_WITH_WARNINGS = 3 @@ -208,6 +214,7 @@ def __init__( # noqa: PLR0912, PLR0913, PLR0915 self.vuln_stub = VulnerabilitiesStub(grpc.insecure_channel(self.url)) self.provenance_stub = GeoProvenanceStub(grpc.insecure_channel(self.url)) self.scanning_stub = ScanningStub(grpc.insecure_channel(self.url)) + self.license_stub = LicenseStub(grpc.insecure_channel(self.url)) else: if ca_cert is not None: credentials = grpc.ssl_channel_credentials(cert_data) # secure with specified certificate @@ -220,6 +227,7 @@ def __init__( # noqa: PLR0912, PLR0913, PLR0915 self.vuln_stub = VulnerabilitiesStub(grpc.secure_channel(self.url, credentials)) self.provenance_stub = GeoProvenanceStub(grpc.secure_channel(self.url, credentials)) self.scanning_stub = ScanningStub(grpc.secure_channel(self.url, credentials)) + self.license_stub = LicenseStub(grpc.secure_channel(self.url, credentials)) @classmethod def _load_cert(cls, cert_file: str) -> bytes: @@ -700,7 +708,38 @@ def get_versions_in_range_for_purl(self, request: Dict) -> Optional[Dict]: 'Sending data for cryptographic versions in range decoration (rqId: {rqId})...', ) - def load_generic_headers(self, url): + def get_licenses(self, request: Dict) -> Optional[Dict]: + """ + Client function to call the rpc for Licenses GetComponentsLicenses + It will either use REST (default) or gRPC depending on the use_grpc flag + + Args: + request (Dict): ComponentsRequest + Returns: + Optional[Dict]: ComponentsLicenseResponse, or None if the request was not successfull + """ + if self.use_grpc: + return self._get_licenses_grpc(request) + else: + return self._get_licenses_rest(request) + + def _get_licenses_grpc(self, request: Dict) -> Optional[Dict]: + """ + Client function to call the rpc for GetComponentsLicenses + + Args: + request (Dict): ComponentsRequest + Returns: + Optional[Dict]: ComponentsLicenseResponse, or None if the request was not successfull + """ + return self._call_rpc( + self.license_stub.GetComponentsLicenses, + request, + ComponentsRequest, + 'Sending data for license decoration (rqId: {rqId})...', + ) + + def load_generic_headers(self, url: str = None): """ Adds custom headers from req_headers to metadata. @@ -764,6 +803,33 @@ def rest_post(self, uri: str, request_id: str, data: dict) -> dict: raise Exception(f'ERROR: The SCANOSS Decoration API request failed for {uri}') from e return None + def _get_licenses_rest(self, purls: Dict) -> Optional[Dict]: + """ + Get the licenses for the given purls using REST API + + Args: + purls (Dict): Purl Request dictionary + Returns: + Optional[Dict]: ComponentsLicenseResponse, or None if the request was not successfull + """ + if not purls: + self.print_stderr('ERROR: No message supplied to send to REST decoration service.') + return None + request_id = str(uuid.uuid4()) + self.print_debug(f'Sending data for Licenses via REST (request id: {request_id})...') + response = self.rest_post(f'{self.orig_url}{DEFAULT_URI_PREFIX}/licenses/components', request_id, purls) + self.print_trace(f'Received response for Licenses via REST (request id: {request_id}): {response}') + if response: + # Parse the JSON/Dict into the purl response + resp_obj = ParseDict(response, ComponentsLicenseResponse(), True) + if resp_obj: + self.print_debug(f'License Response: {resp_obj}') + if not self._check_status_response(resp_obj.status, request_id): + return None + del response['status'] + return response + return None + def _get_vulnerabilities_rest(self, purls: dict): """ Get the vulnerabilities for the given purls using REST API @@ -799,17 +865,20 @@ def _process_dep_file_rest(self, file, depth: int = 1) -> dict: request_id = str(uuid.uuid4()) self.print_debug(f'Sending data for Dependencies via REST (request id: {request_id})...') file_request = {'files': [file], 'depth': depth} - response = self.rest_post(f'{self.orig_url}{DEFAULT_URI_PREFIX}/dependencies/dependencies', - request_id, file_request - ) + response = self.rest_post( + f'{self.orig_url}{DEFAULT_URI_PREFIX}/dependencies/dependencies', request_id, file_request + ) self.print_trace(f'Received response for Dependencies via REST (request id: {request_id}): {response}') if response: return response return None + + # # End of ScanossGrpc Class # + @dataclass class GrpcConfig: url: str = DEFAULT_URL @@ -840,6 +909,7 @@ def create_grpc_config_from_args(args) -> GrpcConfig: grpc_proxy=getattr(args, 'grpc_proxy', None), ) + # # End of GrpcConfig class -# \ No newline at end of file +# diff --git a/tests/data/requirements.txt b/tests/data/requirements.txt index 6237a069..93683ed9 100644 --- a/tests/data/requirements.txt +++ b/tests/data/requirements.txt @@ -2,5 +2,5 @@ requests crc32c>=2.2 binaryornot progress -grpcio>1.42.0 -protobuf>3.19.1 +grpcio>=1.73.1 +protobuf>=6.3.1