diff --git a/README.rst b/README.rst index af60129..a3aaecf 100644 --- a/README.rst +++ b/README.rst @@ -5,10 +5,10 @@ .. |Python Version| image:: https://img.shields.io/badge/python-3.6%2C3.7%2C3.8-blue?logo=python :target: https://www.python.org/doc/versions/ - + .. |Downloads| image:: https://pypip.in/download/dependency-track/badge.svg?period=week :target: https://pypi.python.org/pypi/dependency-track/ - + A simple wrapper for the Dependency Track REST API. Usage @@ -41,17 +41,19 @@ Using the API dt = DependencyTrack(url, api_key) dt.list_projects() - + dt.get_project_property('ab36ead0-c7b0-47f5-89ac-7f92a0bbe12e') - + dt.list_components() dt.get_project_dependency('ab36ead0-c7b0-47f5-89ac-7f92a0bbe12e') - + dt.get_component_dependency('db6157c2-f0a3-447c-902d-aecd360958bd') - + dt.list_concise_licenses()[0] - + dt.get_license('MIT') dt.search('dnsmasq-2.0') + + dt.upload_bom('bom.xml') \ No newline at end of file diff --git a/VERSION b/VERSION index bbdeab6..1750564 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.5 +0.0.6 diff --git a/dependencytrack/__init__.py b/dependencytrack/__init__.py index 9db6e07..6f4a62b 100644 --- a/dependencytrack/__init__.py +++ b/dependencytrack/__init__.py @@ -7,12 +7,13 @@ from .projects import Projects from .components import Components from .licenses import Licenses +from .bom import Bom from .exceptions import AuthenticationError, DependencyTrackApiError logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) -class DependencyTrack(Projects, Components, Licenses): +class DependencyTrack(Projects, Components, Licenses, Bom): """Main DependencyTrack API class @@ -24,7 +25,7 @@ class DependencyTrack(Projects, Components, Licenses): >>> dt = DependencyTrack(url, api_key) .. note:: - + The class instantiation exits if the session with the DependencyTrack server can't be established @@ -52,18 +53,18 @@ def __init__(self, url, api_key): logger.info( f"DependencyTrack instance against {self.host} using {self.api}" ) - + def close(self): self.session.close() def search(self, query): """Search from the server - + API endpoint: GET /search/{query} - + :Example: >>> dt.search('dnsmasq-2.78')['results']['component'] - + :return: the seatch result :rtype: dict {'license': [], 'project': [], 'component': [], 'vulnerability': []} :raises DependencyTrackApiError: if the REST call failed @@ -74,15 +75,15 @@ def search(self, query): else: description = f"Error while searching" raise DependencyTrackApiError(description, response) - + def search_component(self, query): """Search component from the server - + API endpoint: GET /component/?searchText={query} - + :Example: >>> dt.search_component('dnsmasq-2.78') - + :return: the seatch result :rtype: dict :raises DependencyTrackApiError: if the REST call failed @@ -96,12 +97,12 @@ def search_component(self, query): def search_project(self, query): """Search project from the server - + API endpoint: GET /project/?searchText={query} - + :Example: >>> dt.search_project('my project')['results']['component'] - + :return: the seatch result :rtype: dict :raises DependencyTrackApiError: if the REST call failed @@ -115,12 +116,12 @@ def search_project(self, query): def search_vulnerability(self, query): """Search vulnerability from the server - + API endpoint: GET /vulnerability/?searchText={query} - + :Example: >>> dt.search_vulnerability('my vulnerability') - + :return: the seatch result :rtype: dict :raises DependencyTrackApiError: if the REST call failed @@ -134,12 +135,12 @@ def search_vulnerability(self, query): def search_license(self, query): """Search license from the server - + API endpoint: GET /license/?searchText={query} - + :Example: >>> dt.search_license('my license') - + :return: the seatch result :rtype: dict :raises DependencyTrackApiError: if the REST call failed diff --git a/dependencytrack/bom.py b/dependencytrack/bom.py new file mode 100644 index 0000000..d87e5d6 --- /dev/null +++ b/dependencytrack/bom.py @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0+ + +from .exceptions import DependencyTrackApiError + + +class Bom: + """Class dedicated to all "bom" related endpoints""" + + def upload_bom( + self, + file_name, + project_id=None, + project_name=None, + project_version=None, + auto_create=False, + ): + """Upload a supported bill of material format document + + API Endpoint: POST /bom + + :return: UUID-Token + :rtype: string + :raises DependencyTrackApiError: if the REST call failed + """ + multipart_form_data = {} + multipart_form_data["bom"] = ("bom", open(file_name, "r")) + + if project_id: + multipart_form_data["project"] = project_id + if project_name: + multipart_form_data["projectName"] = project_name + if project_version: + multipart_form_data["projectVersion"] = project_version + multipart_form_data["autoCreate"] = auto_create + response = self.session.post( + self.api + "/bom", + params=self.paginated_param_payload, + files=multipart_form_data, + ) + if response.status_code == 200: + return response.json() + else: + description = f"Unable to upload BOM file" + raise DependencyTrackApiError(description, response) diff --git a/setup.py b/setup.py index bdbceeb..418ba5e 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="dependency-track", - version="0.0.4", + version="0.0.6", author="Alvin Chen", author_email="sonoma001@gmail.com", description="A simple wrapper for the Dependency Track REST API.",