diff --git a/fossology/license.py b/fossology/license.py index 0f5b5c1..a9a5758 100644 --- a/fossology/license.py +++ b/fossology/license.py @@ -195,6 +195,28 @@ def import_licenses_csv( description = f"Unable to import licenses from {csv_file}" raise FossologyApiError(description, response) + def export_licenses_csv(self, license_id: int = 0) -> str: + """Export licenses as CSV. + + API Endpoint: GET /license/export-csv + + :param license_id: id of the license to export, 0 to export all (default: 0) + :type license_id: int + :return: the exported licenses as CSV text + :rtype: str + :raises FossologyApiError: if the REST call failed + """ + response = self.session.get( + f"{self.api}/license/export-csv", params={"id": license_id} + ) + + if response.status_code == 200: + logger.info(f"Exported licenses as CSV (id={license_id})") + return response.text + + description = f"Unable to export licenses as CSV (id={license_id})" + raise FossologyApiError(description, response) + def update_license( self, shortname: str, diff --git a/tests/test_license.py b/tests/test_license.py index 7e1c49a..07b74b3 100644 --- a/tests/test_license.py +++ b/tests/test_license.py @@ -86,6 +86,28 @@ def test_import_licenses_csv_request_payload( assert "shortname,fullname\nFoo,Foo License" in body +def test_export_import_licenses_csv_roundtrip(foss: fossology.Fossology, tmp_path): + # Export the full license set, then re-import it. The export format matches + # the import format, and re-importing existing licenses is idempotent. + exported = foss.export_licenses_csv() + assert isinstance(exported, str) + assert exported + csv_path = tmp_path / "exported.csv" + csv_path.write_text(exported) + message = foss.import_licenses_csv(str(csv_path)) + assert "Read csv" in message + + +@responses.activate +def test_export_licenses_csv_error(foss_server: str, foss: fossology.Fossology): + responses.add( + responses.GET, f"{foss_server}/api/v1/license/export-csv", status=403 + ) + with pytest.raises(FossologyApiError) as excinfo: + foss.export_licenses_csv() + assert "Unable to export licenses as CSV (id=0)" in str(excinfo.value) + + @responses.activate def test_detail_license_error(foss_server: str, foss: fossology.Fossology): responses.add(responses.GET, f"{foss_server}/api/v1/license/Blah", status=500)