From 8419f02839f41e578e6ec785a24a096ba6b2a1a6 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Tue, 29 Oct 2024 10:18:40 -0700 Subject: [PATCH 1/8] Added fullscans.stream_diff method --- README.rst | 19 +++++++ pyproject.toml | 74 ++++++++++++++++++++++++++- socketdev/__init__.py | 37 ++++---------- socketdev/fullscans/__init__.py | 82 +++++++++++------------------- socketdev/purl/__init__.py | 23 ++++----- socketdev/repositories/__init__.py | 35 ++----------- 6 files changed, 146 insertions(+), 124 deletions(-) diff --git a/README.rst b/README.rst index 830fe62..7712081 100644 --- a/README.rst +++ b/README.rst @@ -143,6 +143,25 @@ Delete an existing full scan. - **org_slug (str)** - The organization name - **full_scan_id (str)** - The ID of the full scan +fullscans.stream_diff(org_slug, before, after, preview) +""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Stream a diff scan between two full scans. Returns a diff scan. + +**Usage:** + +.. code-block:: + + from socketdev import socketdev + socket = socketdev(token="REPLACE_ME") + print(socket.fullscans.stream_diff("org_slug", "before_scan_id", "after_scan_id")) + +**PARAMETERS:** + +- **org_slug (str)** - The organization name +- **before (str)** - The base full scan ID +- **after (str)** - The comparison full scan ID +- **preview (bool)** - Create a diff-scan that is not persisted. Defaults to False + fullscans.stream(org_slug, full_scan_id) """""""""""""""""""""""""""""""""""""""" Stream all SBOM artifacts for a full scan. diff --git a/pyproject.toml b/pyproject.toml index c6c6ace..0ca683c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,4 +53,76 @@ include = [ ] [tool.setuptools.dynamic] -version = {attr = "socketdev.__version__"} \ No newline at end of file +version = {attr = "socketdev.__version__"} + +[tool.ruff] +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] + +[tool.ruff.lint] +# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. +# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or +# McCabe complexity (`C901`) by default. +select = ["E4", "E7", "E9", "F"] +ignore = [] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +# Enable auto-formatting of code examples in docstrings. Markdown, +# reStructuredText code/literal blocks and doctests are all supported. +# +# This is currently disabled by default, but it is planned for this +# to be opt-out in the future. +docstring-code-format = false + +# Set the line length limit used when formatting code snippets in +# docstrings. +# +# This only has an effect when the `docstring-code-format` setting is +# enabled. +docstring-code-line-length = "dynamic" \ No newline at end of file diff --git a/socketdev/__init__.py b/socketdev/__init__.py index 19806d0..781876a 100644 --- a/socketdev/__init__.py +++ b/socketdev/__init__.py @@ -18,11 +18,9 @@ from socketdev.exceptions import APIKeyMissing, APIFailure, APIAccessDenied, APIInsufficientQuota, APIResourceNotFound -__author__ = 'socket.dev' -__version__ = '1.0.12' -__all__ = [ - "socketdev" -] +__author__ = "socket.dev" +__version__ = "1.0.12" +__all__ = ["socketdev"] global encoded_key @@ -36,15 +34,11 @@ def encode_key(token: str): global encoded_key - encoded_key = base64.b64encode(token.encode()).decode('ascii') + encoded_key = base64.b64encode(token.encode()).decode("ascii") def do_request( - path: str, - headers: dict = None, - payload: [dict, str] = None, - files: list = None, - method: str = "GET" + path: str, headers: dict = None, payload: [dict, str] = None, files: list = None, method: str = "GET" ) -> Response: """ Shared function for performing the requests against the API. @@ -60,19 +54,14 @@ def do_request( if headers is None: headers = { - 'Authorization': f"Basic {encoded_key}", - 'User-Agent': f'SocketPythonScript/{__version__}', - "accept": "application/json" + "Authorization": f"Basic {encoded_key}", + "User-Agent": f"SocketPythonScript/{__version__}", + "accept": "application/json", } url = f"{api_url}/{path}" try: response = requests.request( - method.upper(), - url, - headers=headers, - data=payload, - files=files, - timeout=request_timeout + method.upper(), url, headers=headers, data=payload, files=files, timeout=request_timeout ) if response.status_code >= 400: raise APIFailure("Bad Request") @@ -85,11 +74,7 @@ def do_request( elif response.status_code == 429: raise APIInsufficientQuota("Insufficient quota for API route") except Exception as error: - response = Response( - text=f"{error}", - error=True, - status_code=500 - ) + response = Response(text=f"{error}", error=True, status_code=500) raise APIFailure(response) return response @@ -104,7 +89,7 @@ class socketdev: quota: Quota report: Report sbom: Sbom - purl: purl + purl: Purl fullscans: FullScans repositories: Repositories settings: Settings diff --git a/socketdev/fullscans/__init__.py b/socketdev/fullscans/__init__.py index 2fd010b..948a222 100644 --- a/socketdev/fullscans/__init__.py +++ b/socketdev/fullscans/__init__.py @@ -2,13 +2,10 @@ from socketdev.tools import load_files import json -class FullScans: +class FullScans: @staticmethod - def create_params_string( - params: dict - ) -> str: - + def create_params_string(params: dict) -> str: param_str = "" for name in params: @@ -19,37 +16,26 @@ def create_params_string( param_str = "?" + param_str.lstrip("&") return param_str - + @staticmethod - def get( - org_slug: str, - params: dict) -> dict: - + def get(org_slug: str, params: dict) -> dict: params_arg = FullScans.create_params_string(params) path = "orgs/" + org_slug + "/full-scans" + str(params_arg) headers = None payload = None - response = socketdev.do_request( - path=path, - headers=headers, - payload=payload - ) + response = socketdev.do_request(path=path, headers=headers, payload=payload) if response.status_code == 200: result = response.json() else: result = {} - + return result @staticmethod - def post( - files: list, - params: dict - ) -> dict: - + def post(files: list, params: dict) -> dict: loaded_files = [] loaded_files = load_files(files, loaded_files) @@ -57,11 +43,7 @@ def post( path = "orgs/" + str(params["org_slug"]) + "/full-scans" + str(params_arg) - response = socketdev.do_request( - path=path, - method="POST", - files=loaded_files - ) + response = socketdev.do_request(path=path, method="POST", files=loaded_files) if response.status_code == 201: result = response.json() @@ -71,35 +53,38 @@ def post( result = response.text return result - + @staticmethod - def delete(org_slug: str, - full_scan_id: str) -> dict: - + def delete(org_slug: str, full_scan_id: str) -> dict: path = "orgs/" + org_slug + "/full-scans/" + full_scan_id - response = socketdev.do_request( - path=path, - method="DELETE" - ) + response = socketdev.do_request(path=path, method="DELETE") if response.status_code == 200: result = response.json() else: result = {} - + return result @staticmethod - def stream(org_slug: str, - full_scan_id: str) -> dict: - + def stream_diff(org_slug: str, before: str, after: str, preview: bool = False) -> dict: + path = f"orgs/{org_slug}/full-scans/stream-diff?before={before}&after={after}&preview={preview}" + + response = socketdev.do_request(path=path, method="GET") + + if response.status_code == 200: + result = response.json() + else: + result = {} + + return result + + @staticmethod + def stream(org_slug: str, full_scan_id: str) -> dict: path = "orgs/" + org_slug + "/full-scans/" + full_scan_id - response = socketdev.do_request( - path=path, - method="GET" - ) + response = socketdev.do_request(path=path, method="GET") if response.status_code == 200: stream_str = [] @@ -112,22 +97,17 @@ def stream(org_slug: str, item = json.loads(line) stream_str.append(item) for val in stream_str: - stream_dict[val['id']] = val + stream_dict[val["id"]] = val else: stream_dict = {} return stream_dict - + @staticmethod - def metadata(org_slug: str, - full_scan_id: str) -> dict: - + def metadata(org_slug: str, full_scan_id: str) -> dict: path = "orgs/" + org_slug + "/full-scans/" + full_scan_id + "/metadata" - response = socketdev.do_request( - path=path, - method="GET" - ) + response = socketdev.do_request(path=path, method="GET") if response.status_code == 200: result = response.json() diff --git a/socketdev/purl/__init__.py b/socketdev/purl/__init__.py index 3db39ac..03166d3 100644 --- a/socketdev/purl/__init__.py +++ b/socketdev/purl/__init__.py @@ -1,19 +1,16 @@ -import socketdev -from urllib.parse import urlencode import json +import socketdev + + class Purl: @staticmethod - def post(license: str="true", components: list=[]) -> dict: - path = "purl?" + "license="+license - components = {"components":components} + def post(license: str = "true", components: list = []) -> dict: + path = "purl?" + "license=" + license + components = {"components": components} components = json.dumps(components) - response = socketdev.do_request( - path=path, - payload=components, - method="POST" - ) + response = socketdev.do_request(path=path, payload=components, method="POST") if response.status_code == 200: purl = [] purl_dict = {} @@ -25,12 +22,10 @@ def post(license: str="true", components: list=[]) -> dict: item = json.loads(line) purl.append(item) for val in purl: - purl_dict[val['id']] = val + purl_dict[val["id"]] = val else: purl_dict = {} print(f"Error posting {components} to the Purl API") print(response.text) - - return purl_dict - \ No newline at end of file + return purl_dict diff --git a/socketdev/repositories/__init__.py b/socketdev/repositories/__init__.py index 4c60f0b..528d254 100644 --- a/socketdev/repositories/__init__.py +++ b/socketdev/repositories/__init__.py @@ -11,40 +11,11 @@ class Repo(TypedDict): default_branch: str +# remove methods except for list, use old endpoint for list class Repositories: @staticmethod - def get(org_slug: str) -> dict: - path = f"orgs/{org_slug}/repos" - response = socketdev.do_request(path=path) - if response.status_code == 200: - repos = response.json() - else: - repos = {} - return repos - - @staticmethod - def post(org_slug: str, body: Repo) -> dict: - path = f"orgs/{org_slug}/repos" - response = socketdev.do_request(path=path, method="POST", payload=body) - if response.status_code == 200: - repos = response.json() - else: - repos = {} - return repos - - @staticmethod - def update(org_slug: str, body: Repo) -> dict: - path = f"orgs/{org_slug}/repos" - response = socketdev.do_request(path=path, method="POST", payload=body) - if response.status_code == 200: - repos = response.json() - else: - repos = {} - return repos - - @staticmethod - def repo(org_slug: str, repo_id: str) -> dict: - path = f"orgs/{org_slug}/repos/{repo_id}" + def list() -> dict: + path = "repos" response = socketdev.do_request(path=path) if response.status_code == 200: repos = response.json() From a6269f27adf72c80038dcb796cdbc177609b6001 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Tue, 29 Oct 2024 10:27:52 -0700 Subject: [PATCH 2/8] incremented version number --- socketdev/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socketdev/__init__.py b/socketdev/__init__.py index 781876a..dfa4c11 100644 --- a/socketdev/__init__.py +++ b/socketdev/__init__.py @@ -19,7 +19,7 @@ __author__ = "socket.dev" -__version__ = "1.0.12" +__version__ = "1.0.13" __all__ = ["socketdev"] From a9408e8f7621caf10de8eca4d7232e30b87ff78d Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Thu, 31 Oct 2024 17:02:41 -0700 Subject: [PATCH 3/8] Implemented exports and refined return types --- socketdev/__init__.py | 12 +++++++----- socketdev/export/__init__.py | 25 +++++++++++++++++++++++++ socketdev/fullscans/__init__.py | 20 +++++++++++++++----- socketdev/openapi/__init__.py | 2 +- socketdev/quota/__init__.py | 2 +- socketdev/settings/__init__.py | 18 ++++++++---------- socketdev/tools/__init__.py | 23 +++++++++-------------- 7 files changed, 66 insertions(+), 36 deletions(-) create mode 100644 socketdev/export/__init__.py diff --git a/socketdev/__init__.py b/socketdev/__init__.py index dfa4c11..3e08aa7 100644 --- a/socketdev/__init__.py +++ b/socketdev/__init__.py @@ -2,20 +2,21 @@ import requests import base64 +from socketdev.core.classes import Response from socketdev.dependencies import Dependencies +from socketdev.exceptions import APIKeyMissing, APIFailure, APIAccessDenied, APIInsufficientQuota, APIResourceNotFound +from socketdev.export import Export +from socketdev.fullscans import FullScans from socketdev.npm import NPM from socketdev.openapi import OpenAPI from socketdev.org import Orgs +from socketdev.purl import Purl from socketdev.quota import Quota from socketdev.report import Report -from socketdev.sbom import Sbom -from socketdev.purl import Purl -from socketdev.fullscans import FullScans from socketdev.repos import Repos from socketdev.repositories import Repositories +from socketdev.sbom import Sbom from socketdev.settings import Settings -from socketdev.core.classes import Response -from socketdev.exceptions import APIKeyMissing, APIFailure, APIAccessDenied, APIInsufficientQuota, APIResourceNotFound __author__ = "socket.dev" @@ -91,6 +92,7 @@ class socketdev: sbom: Sbom purl: Purl fullscans: FullScans + export: Export repositories: Repositories settings: Settings repos: Repos diff --git a/socketdev/export/__init__.py b/socketdev/export/__init__.py new file mode 100644 index 0000000..f3d53f7 --- /dev/null +++ b/socketdev/export/__init__.py @@ -0,0 +1,25 @@ +from socketdev.tools import do_request + + +class Export: + @staticmethod + def cdx_bom(org_slug: str, id: str) -> dict: + path = f"orgs/{org_slug}/export/cdx/{id}" + result = do_request(path=path) + try: + sbom = result.json() + sbom["success"] = True + except Exception as error: + sbom = {"success": False, "message": str(error)} + return sbom + + @staticmethod + def spdx_bom(org_slug: str, id: str) -> bool: + path = f"orgs/{org_slug}/export/spdx/{id}" + result = do_request(path=path) + try: + sbom = result.json() + sbom["success"] = True + except Exception as error: + sbom = {"success": False, "message": str(error)} + return sbom diff --git a/socketdev/fullscans/__init__.py b/socketdev/fullscans/__init__.py index 948a222..7d4d200 100644 --- a/socketdev/fullscans/__init__.py +++ b/socketdev/fullscans/__init__.py @@ -1,6 +1,9 @@ import socketdev from socketdev.tools import load_files import json +import logging + +log = logging.getLogger("socketdev") class FullScans: @@ -29,8 +32,11 @@ def get(org_slug: str, params: dict) -> dict: if response.status_code == 200: result = response.json() - else: - result = {} + result["success"] = True + result["status"] = 200 + return result + + result = {"success": False, "status": response.status_code, "message": response.text} return result @@ -83,7 +89,6 @@ def stream_diff(org_slug: str, before: str, after: str, preview: bool = False) - @staticmethod def stream(org_slug: str, full_scan_id: str) -> dict: path = "orgs/" + org_slug + "/full-scans/" + full_scan_id - response = socketdev.do_request(path=path, method="GET") if response.status_code == 200: @@ -98,8 +103,13 @@ def stream(org_slug: str, full_scan_id: str) -> dict: stream_str.append(item) for val in stream_str: stream_dict[val["id"]] = val - else: - stream_dict = {} + + stream_dict["success"] = True + stream_dict["status"] = 200 + + return stream_dict + + stream_dict = {"success": False, "status": response.status_code, "message": response.text} return stream_dict diff --git a/socketdev/openapi/__init__.py b/socketdev/openapi/__init__.py index 28d9bc9..71c4f03 100644 --- a/socketdev/openapi/__init__.py +++ b/socketdev/openapi/__init__.py @@ -4,7 +4,7 @@ class OpenAPI: @staticmethod def get() -> dict: - path = f"openapi" + path = "openapi" response = socketdev.do_request(path=path) if response.status_code == 200: openapi = response.json() diff --git a/socketdev/quota/__init__.py b/socketdev/quota/__init__.py index 89e50ee..aebadd9 100644 --- a/socketdev/quota/__init__.py +++ b/socketdev/quota/__init__.py @@ -4,7 +4,7 @@ class Quota: @staticmethod def get() -> dict: - path = f"quota" + path = "quota" response = socketdev.do_request(path=path) if response.status_code == 200: quota = response.json() diff --git a/socketdev/settings/__init__.py b/socketdev/settings/__init__.py index b1e3106..4cdcb10 100644 --- a/socketdev/settings/__init__.py +++ b/socketdev/settings/__init__.py @@ -6,15 +6,13 @@ class Settings: @staticmethod def get(org_id: str) -> dict: - path = f"settings" - payload = [ - { - "organization": org_id - } - ] + settings = {} + path = "settings" + payload = [{"organization": org_id}] response = socketdev.do_request(path=path, method="POST", payload=json.dumps(payload)) - if response.status_code == 200: - settings = response.json() - else: - settings = {} + + if response.status_code != 200: + return settings + + settings = response.json() return settings diff --git a/socketdev/tools/__init__.py b/socketdev/tools/__init__.py index 9b81340..507e602 100644 --- a/socketdev/tools/__init__.py +++ b/socketdev/tools/__init__.py @@ -1,5 +1,6 @@ import glob import sys +import platform def find_package_files(folder: str, file_types: list) -> list: @@ -16,26 +17,20 @@ def find_package_files(folder: str, file_types: list) -> list: def fix_file_path(files) -> list: fixed_files = [] for file in files: - file = file.replace("\\", '/') + file = file.replace("\\", "/") fixed_files.append(file) return fixed_files def load_files(files: list, loaded_files: list) -> list: for file in files: + if platform.system() == "Windows": + file = file.replace("\\", "/") if "/" in file: - _, file_name = file.rsplit("/", 1) - elif "\\" in file: - _, file_name = file.rsplit("/", 1) - else: - file_name = file - try: - file_tuple = (file_name, (file_name, open(file, 'rb'), 'text/plain')) - loaded_files.append(file_tuple) - except Exception as error: - print(f"Unable to open {file}") - print(error) - exit(1) + path, name = file.rsplit("/", 1) + full_path = f"{path}/{name}" + payload = (full_path, (name, open(full_path, "rb"))) + loaded_files.append(payload) return loaded_files @@ -50,7 +45,7 @@ def prepare_for_csv(dependencies: list, packages: dict) -> list: package.name, package.version, package.license, - package.repository + package.repository, ] output.append(output_object) return output From 9f49ce8eaf5b746e879d06f6f93997030996ac65 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Thu, 31 Oct 2024 17:50:25 -0700 Subject: [PATCH 4/8] refined and documented export methods --- README.rst | 60 +++++++++++++++++++++++++++++++++++- socketdev/export/__init__.py | 41 ++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 7712081..26e81eb 100644 --- a/README.rst +++ b/README.rst @@ -52,6 +52,64 @@ Retrieve the package information for a purl post - **license (str)** - The license parameter if enabled will show alerts and license information. If disabled will only show the basic package metadata and scores. Default is true - **components (array{dict})** - The components list of packages urls +export.cdx_bom(org_slug, id, query_params) +""""""""""""""""""""""""""""""""""""""""" +Export a Socket SBOM as a CycloneDX SBOM + +**Usage:** + +.. code-block:: + + from socketdev import socketdev + from socketdev.export import ExportQueryParams + + socket = socketdev(token="REPLACE_ME") + query_params = ExportQueryParams( + author="john_doe", + project_name="my-project" + ) + print(socket.export.cdx_bom("org_slug", "sbom_id", query_params)) + +**PARAMETERS:** + +- **org_slug (str)** - The organization name +- **id (str)** - The ID of either a full scan or an SBOM report +- **query_params (ExportQueryParams)** - Optional query parameters for filtering: + - **author (str)** - Filter by author + - **project_group (str)** - Filter by project group + - **project_name (str)** - Filter by project name + - **project_version (str)** - Filter by project version + - **project_id (str)** - Filter by project ID + +export.spdx_bom(org_slug, id, query_params) +"""""""""""""""""""""""""""""""""""""""""" +Export a Socket SBOM as an SPDX SBOM + +**Usage:** + +.. code-block:: + + from socketdev import socketdev + from socketdev.export import ExportQueryParams + + socket = socketdev(token="REPLACE_ME") + query_params = ExportQueryParams( + project_name="my-project", + project_version="1.0.0" + ) + print(socket.export.spdx_bom("org_slug", "sbom_id", query_params)) + +**PARAMETERS:** + +- **org_slug (str)** - The organization name +- **id (str)** - The ID of either a full scan or an SBOM report +- **query_params (ExportQueryParams)** - Optional query parameters for filtering: + - **author (str)** - Filter by author + - **project_group (str)** - Filter by project group + - **project_name (str)** - Filter by project name + - **project_version (str)** - Filter by project version + - **project_id (str)** - Filter by project ID + fullscans.get(org_slug) """"""""""""""""""""""" Retrieve the Fullscans information for around Organization @@ -145,7 +203,7 @@ Delete an existing full scan. fullscans.stream_diff(org_slug, before, after, preview) """"""""""""""""""""""""""""""""""""""""""""""""""""""" -Stream a diff scan between two full scans. Returns a diff scan. +Stream a diff between two full scans. Returns a scan diff. **Usage:** diff --git a/socketdev/export/__init__.py b/socketdev/export/__init__.py index f3d53f7..6f17498 100644 --- a/socketdev/export/__init__.py +++ b/socketdev/export/__init__.py @@ -1,10 +1,38 @@ from socketdev.tools import do_request +from urllib.parse import urlencode +from dataclasses import dataclass, asdict +from typing import Optional + + +@dataclass +class ExportQueryParams: + author: Optional[str] = None + project_group: Optional[str] = None + project_name: Optional[str] = None + project_version: Optional[str] = None + project_id: Optional[str] = None + + def to_query_params(self) -> str: + # Filter out None values and convert to query string + params = {k: v for k, v in asdict(self).items() if v is not None} + if not params: + return "" + return "?" + urlencode(params) class Export: @staticmethod - def cdx_bom(org_slug: str, id: str) -> dict: + def cdx_bom(org_slug: str, id: str, query_params: Optional[ExportQueryParams] = None) -> dict: + """ + Export a Socket SBOM as a CycloneDX SBOM + :param org_slug: String - The slug of the organization + :param id: String - The id of either a full scan or an sbom report + :param query_params: Optional[ExportQueryParams] - Query parameters for filtering + :return: + """ path = f"orgs/{org_slug}/export/cdx/{id}" + if query_params: + path += query_params.to_query_params() result = do_request(path=path) try: sbom = result.json() @@ -14,8 +42,17 @@ def cdx_bom(org_slug: str, id: str) -> dict: return sbom @staticmethod - def spdx_bom(org_slug: str, id: str) -> bool: + def spdx_bom(org_slug: str, id: str, query_params: Optional[ExportQueryParams] = None) -> dict: + """ + Export a Socket SBOM as an SPDX SBOM + :param org_slug: String - The slug of the organization + :param id: String - The id of either a full scan or an sbom report + :param query_params: Optional[ExportQueryParams] - Query parameters for filtering + :return: + """ path = f"orgs/{org_slug}/export/spdx/{id}" + if query_params: + path += query_params.to_query_params() result = do_request(path=path) try: sbom = result.json() From 8066dbd356885646ead4ac70f472e3902df3bd47 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Thu, 31 Oct 2024 17:55:55 -0700 Subject: [PATCH 5/8] PR cleanup --- socketdev/repositories/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/socketdev/repositories/__init__.py b/socketdev/repositories/__init__.py index 528d254..91eab3b 100644 --- a/socketdev/repositories/__init__.py +++ b/socketdev/repositories/__init__.py @@ -11,7 +11,6 @@ class Repo(TypedDict): default_branch: str -# remove methods except for list, use old endpoint for list class Repositories: @staticmethod def list() -> dict: From 79ca7947e9c8cb4d3441dd355a932fd9e0aee430 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Thu, 31 Oct 2024 17:59:26 -0700 Subject: [PATCH 6/8] added dev dependencies --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0ca683c..bf6b8c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,13 @@ requires-python = ">= 3.9" dependencies = [ 'requests' ] + +# modern, faster linter and language server. install with `pip install -e ".[dev]"` +[project.optional-dependencies] +dev = [ + "ruff>=0.3.0", +] + readme = "README.rst" license = {file = "LICENSE"} description = "Socket Security Python SDK" From df7ce793c169f390db79b298dd3b6c47bc904102 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Thu, 31 Oct 2024 18:11:36 -0700 Subject: [PATCH 7/8] fixed do_request import --- socketdev/export/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/socketdev/export/__init__.py b/socketdev/export/__init__.py index 6f17498..4e3907e 100644 --- a/socketdev/export/__init__.py +++ b/socketdev/export/__init__.py @@ -1,7 +1,7 @@ -from socketdev.tools import do_request from urllib.parse import urlencode from dataclasses import dataclass, asdict from typing import Optional +import socketdev @dataclass @@ -33,7 +33,7 @@ def cdx_bom(org_slug: str, id: str, query_params: Optional[ExportQueryParams] = path = f"orgs/{org_slug}/export/cdx/{id}" if query_params: path += query_params.to_query_params() - result = do_request(path=path) + result = socketdev.do_request(path=path) try: sbom = result.json() sbom["success"] = True @@ -53,7 +53,7 @@ def spdx_bom(org_slug: str, id: str, query_params: Optional[ExportQueryParams] = path = f"orgs/{org_slug}/export/spdx/{id}" if query_params: path += query_params.to_query_params() - result = do_request(path=path) + result = socketdev.do_request(path=path) try: sbom = result.json() sbom["success"] = True From f82b9af2ecb27b64f05aa7500fa2b5226a369f11 Mon Sep 17 00:00:00 2001 From: Eric Hibbs Date: Mon, 4 Nov 2024 11:28:26 -0800 Subject: [PATCH 8/8] re-ordered pyproject to allow editable installs --- pyproject.toml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bf6b8c2..ae7e6ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,13 +9,6 @@ requires-python = ">= 3.9" dependencies = [ 'requests' ] - -# modern, faster linter and language server. install with `pip install -e ".[dev]"` -[project.optional-dependencies] -dev = [ - "ruff>=0.3.0", -] - readme = "README.rst" license = {file = "LICENSE"} description = "Socket Security Python SDK" @@ -37,6 +30,12 @@ classifiers = [ "Programming Language :: Python :: 3.14" ] +# modern, faster linter and language server. install with `pip install -e ".[dev]"` +[project.optional-dependencies] +dev = [ + "ruff>=0.3.0", +] + [project.urls] Homepage = "https://github.com/socketdev/socket-sdk-python"