Skip to content

Commit

Permalink
Merge pull request #39 from fossology/fix/revert-1.0.17-preparation
Browse files Browse the repository at this point in the history
Fix/revert 1.0.17 preparation
  • Loading branch information
deveaud-m authored Sep 25, 2020
2 parents 2b3c456 + 0bf248d commit fa8ed27
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 482 deletions.
34 changes: 9 additions & 25 deletions fossology/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@
import requests
from datetime import date, timedelta

from fossology.obj import Agents, User, TokenScope, SearchTypes, get_options
from fossology.folders import Folders
from fossology.uploads import Uploads
from fossology.jobs import Jobs
from fossology.report import Report
from fossology.exceptions import (
AuthenticationError,
AuthorizationError,
FossologyApiError,
)
from .obj import Agents, User, TokenScope, SearchTypes
from .folders import Folders
from .uploads import Uploads
from .jobs import Jobs
from .report import Report
from .exceptions import AuthenticationError, FossologyApiError

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
Expand All @@ -40,12 +36,12 @@ def fossology_token(
:param password: the password of the user
:param name: the name of the token
:param scope: the scope of the token (default: READ)
:param expire: the expire date of the token (default: max. 30 days)
:param expire: the expire date of the token (default max. 30 days)
:type url: string
:type username: string
:type password: string
:type name: string
:type scope: TokenScope (default: TokenScope.READ)
:type scope: TokenScope (default TokenScope.READ)
:type expire: string, e.g. 2019-12-25
:return: the new token
:rtype: string
Expand Down Expand Up @@ -212,7 +208,7 @@ def delete_user(self, user):
:raises FossologyApiError: if the REST call failed
"""
response = self.session.delete(f"{self.api}/users/{user.id}")

print(response.json())
if response.status_code == 202:
return
else:
Expand All @@ -228,7 +224,6 @@ def search(
filesizemax=None,
license=None,
copyright=None,
group=None,
):
"""Search for a specific file
Expand All @@ -241,19 +236,16 @@ def search(
:param filesizemax: Max filesize in bytes
:param license: License search filter
:param copyright: Copyright search filter
:param group: the group name to choose while performing search (default: None)
:type searchType: SearchType Enum
:type filename: string
:type tag: string
:type filesizemin: int
:type filesizemax: int
:type license: string
:type copyright: string
:type group: string
:return: list of items corresponding to the search criteria
:rtype: JSON
:raises FossologyApiError: if the REST call failed
:raises AuthorizationError: if the user can't access the group
"""
headers = {"searchType": searchType.value}
if filename:
Expand All @@ -268,18 +260,10 @@ def search(
headers["license"] = license
if copyright:
headers["copyright"] = copyright
if group:
headers["groupName"] = group

response = self.session.get(f"{self.api}/search", headers=headers)

if response.status_code == 200:
return response.json()

elif response.status_code == 403:
description = f"Searching {get_options(group)}not authorized"
raise AuthorizationError(description, response)

else:
description = "Unable to get a result with the given search criteria"
raise FossologyApiError(description, response)
17 changes: 6 additions & 11 deletions fossology/folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import logging

from fossology.obj import Folder, get_options
from fossology.exceptions import AuthorizationError, FossologyApiError
from .obj import Folder
from .exceptions import AuthorizationError, FossologyApiError

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
Expand Down Expand Up @@ -58,7 +58,7 @@ def detail_folder(self, folder_id):
description = f"Error while getting details for folder {folder_id}"
raise FossologyApiError(description, response)

def create_folder(self, parent, name, description=None, group=None):
def create_folder(self, parent, name, description=None):
"""Create a new (sub)folder
The name of the new folder must be unique under the same parent.
Expand All @@ -67,25 +67,20 @@ def create_folder(self, parent, name, description=None, group=None):
:param parent: the parent folder
:param name: the name of the folder
:param description: a meaningful description for the folder (default: None)
:param group: the name of the group chosen to create the folder (default: None)
:param description: a meaningful description for the folder (optional)
:type parent: Folder() object
:type name: str
:type description: str
:type group: string
:return: the folder newly created (or already existing) - or None
:rtype: Folder() object
:raises FossologyApiError: if the REST call failed
:raises AuthorizationError: if the user is not allowed to write in the folder or access the group
:raises AuthorizationError: if the user is not allowed to write in the folder
"""
headers = {
"parentFolder": f"{parent.id}",
"folderName": f"{name}",
"folderDescription": f"{description}",
}
if group:
headers["groupName"] = group

response = self.session.post(f"{self.api}/folders", headers=headers)

if response.status_code == 200:
Expand All @@ -101,7 +96,7 @@ def create_folder(self, parent, name, description=None, group=None):
return self.detail_folder(response.json()["message"])

elif response.status_code == 403:
description = f"Folder creation {get_options(group, parent)}not authorized"
description = f"Folder creation in parent {parent} not authorized"
raise AuthorizationError(description, response)
else:
description = f"Unable to create folder {name} under {parent}"
Expand Down
34 changes: 12 additions & 22 deletions fossology/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import time
import logging

from fossology.obj import Job, get_options
from fossology.exceptions import AuthorizationError, FossologyApiError
from .obj import Job
from .exceptions import FossologyApiError

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
Expand All @@ -15,28 +15,30 @@
class Jobs:
"""Class dedicated to all "jobs" related endpoints"""

def list_jobs(self, page_size=20, page=1, upload=None):
def list_jobs(self, page_size=20, pages=1, upload=None):
"""Get all available jobs
API Endpoint: GET /jobs
The answer is limited to the first page of 20 results by default
:param page_size: the maximum number of results per page
:param page: the number of pages to be retrieved
:param pages: the number of pages to be retrieved
:param upload: list only jobs of the given upload (default: None)
:type page_size: int (default: 20)
:type page: int (default: 1)
:type pages: int (default: 1)
:type upload: Upload
:return: the jobs data
:rtype: list of Job
:raises FossologyApiError: if the REST call failed
"""
params = {}
headers = {"limit": str(page_size), "page": str(page)}
headers = {"limit": str(page_size), "pages": str(pages)}
if upload:
params["upload"] = upload.id
response = self.session.get(f"{self.api}/jobs", params=params, headers=headers)
response = self.session.get(
f"{self.api}/jobs?upload={upload.id}", headers=headers
)
else:
response = self.session.get(f"{self.api}/jobs", headers=headers)
if response.status_code == 200:
jobs_list = list()
for job in response.json():
Expand Down Expand Up @@ -82,7 +84,7 @@ def detail_job(self, job_id, wait=False, timeout=30):
description = f"Error while getting details for job {job_id}"
raise FossologyApiError(description, response)

def schedule_jobs(self, folder, upload, spec, group=None, wait=False, timeout=30):
def schedule_jobs(self, folder, upload, spec, wait=False, timeout=30):
"""Schedule jobs for a specific upload
API Endpoint: POST /jobs
Expand Down Expand Up @@ -121,42 +123,30 @@ def schedule_jobs(self, folder, upload, spec, group=None, wait=False, timeout=30
:param folder: the upload folder
:param upload: the upload for which jobs will be scheduled
:param spec: the job specification
:param group: the group name to choose while scheduling jobs (default: None)
:param wait: wait for the scheduled job to finish (default: False)
:param timeout: stop waiting after x seconds (default: 30)
:type upload: Upload
:type folder: Folder
:type spec: dict
:type group: string
:type wait: boolean
:type timeout: 30
:return: the job id
:rtype: Job
:raises FossologyApiError: if the REST call failed
:raises AuthorizationError: if the user can't access the group
"""
headers = {
"folderId": str(folder.id),
"uploadId": str(upload.id),
"Content-Type": "application/json",
}
if group:
headers["groupName"] = group

response = self.session.post(
f"{self.api}/jobs", headers=headers, data=json.dumps(spec)
)

if response.status_code == 201:
detailled_job = self.detail_job(
response.json()["message"], wait=wait, timeout=timeout
)
return detailled_job

elif response.status_code == 403:
description = f"Scheduling job {get_options(group)}not authorized"
raise AuthorizationError(description, response)

else:
description = "Scheduling jobs for upload {upload.uploadname} failed"
raise FossologyApiError(description, response)
19 changes: 10 additions & 9 deletions fossology/obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ class ClearingStatus(Enum):
REJECTED = "Rejected"


class LicenseAgent(Enum):
"""Available license agents: NOMOS, MONK, NINKA, OJO, REPORTIMPORT"""

NOMOS = "nomos"
MONK = "monk"
NINKA = "ninka"
OJO = "ojo"
REPORTIMPORT = "reportImport"


class Agents(object):

"""FOSSology agents.
Expand Down Expand Up @@ -423,12 +433,3 @@ def __str__(self):
@classmethod
def from_json(cls, json_dict):
return cls(**json_dict)


def get_options(group: str = None, folder: Folder = None) -> str:
options = ""
if group:
options += f"for group {group} "
if folder:
options += f"in folder {folder.id} "
return options
35 changes: 5 additions & 30 deletions fossology/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import logging

from tenacity import retry, TryAgain, stop_after_attempt, retry_if_exception_type
from fossology.exceptions import FossologyApiError, AuthorizationError
from fossology.obj import get_options
from .exceptions import FossologyApiError

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
Expand All @@ -17,52 +16,40 @@ class Report:
"""Class dedicated to all "report" related endpoints"""

@retry(retry=retry_if_exception_type(TryAgain), stop=stop_after_attempt(3))
def generate_report(self, upload, report_format=None, group=None):
def generate_report(self, upload, report_format=None):
"""Generate a report for a given upload
API Endpoint: GET /report
:param upload: the upload which report will be generated
:param format: the report format (default: ReportFormat.READMEOSS)
:param group: the group name to choose while generating the report (default: None)
:param format: the report format (default ReportFormat.READMEOSS)
:type upload: Upload
:type format: ReportFormat
:type group: string
:return: the report id
:rtype: int
:raises FossologyApiError: if the REST call failed
:raises AuthorizationError: if the user can't access the group
"""
headers = {"uploadId": str(upload.id)}
if report_format:
headers["reportFormat"] = report_format.value
else:
headers["reportFormat"] = "readmeoss"
if group:
headers["groupName"] = group

response = self.session.get(f"{self.api}/report", headers=headers)

if response.status_code == 201:
report_id = re.search("[0-9]*$", response.json()["message"])
return report_id[0]

elif response.status_code == 403:
description = f"Generating report for upload {upload.id} {get_options(group)}not authorized"
raise AuthorizationError(description, response)

elif response.status_code == 503:
wait_time = response.headers["Retry-After"]
logger.debug(f"Retry generate report after {wait_time} seconds")
time.sleep(int(wait_time))
raise TryAgain

else:
description = f"Report generation for upload {upload.name} failed"
raise FossologyApiError(description, response)

@retry(retry=retry_if_exception_type(TryAgain), stop=stop_after_attempt(3))
def download_report(self, report_id, as_zip=False, group=None):
def download_report(self, report_id, as_zip=False):
"""Download a report
API Endpoint: GET /report/{id}
Expand All @@ -80,31 +67,19 @@ def download_report(self, report_id, as_zip=False, group=None):
>>> report_file.write(report_content)
:param report_id: the id of the generated report
:param as_zip: control if the report should be generated as ZIP file (default: False)
:param group: the group name to choose while downloading a specific report (default: None)
:param as_zip: control if the report should be generated as ZIP file (default False)
:type report_id: int
:type as_zip: boolean
:type group: string
:raises FossologyApiError: if the REST call failed
:raises AuthorizationError: if the user can't access the group
"""
if as_zip:
headers = {"Accept": "application/zip"}
else:
headers = {"Accept": "text/plain"}
if group:
headers["groupName"] = group

response = self.session.get(f"{self.api}/report/{report_id}", headers=headers)
if response.status_code == 200:
return response.text

elif response.status_code == 403:
description = (
f"Getting report {report_id} {get_options(group)}not authorized"
)
raise AuthorizationError(description, response)

elif response.status_code == 503:
wait_time = response.headers["Retry-After"]
logger.debug(f"Retry get report after {wait_time} seconds")
Expand Down
Loading

0 comments on commit fa8ed27

Please sign in to comment.