[docs]def__init__(self,log:BoundLoggerLazyProxy)->None:"""DockerHub provider for getting the information from it. Args: log (BoundLoggerLazyProxy): Log class to inject into the vars. Class: structlog Returns: None """self.endpoint="https://hub.docker.com"self.headers={}self.name="DockerHub"auth_token=getenv("DOCKERHUB_API_TOKEN",default=None)self.log=logself.max_pages=20ifauth_token:self.headers["Authorization"]=f"Bearer {auth_token}"else:self.log.warning("DockerHub Token not found. Using anonymous access.")
[docs]defget_image_versions(self,parent:str,project:str)->TyperImageVersion:"""Query the DockerHub API in order to get the images version availables and return a list of it. Args: parent (str): Namespace or User in DockerHub project (str): Project Name Returns: Return a dict that have image metadata like: {'error': <bool>, 'data': [{'last_update': '<datetime object>", 'name': ['<version1>', ...]},]} """STATUS_CODE_OK=200out=TyperImageVersion({"error":False,"data":[]})endpoint=f"{self.endpoint}/v2/namespaces/{parent}/repositories/{project}/tags"self.log.info(f"Getting image versions from DockerHub for the User/Orgs: {parent} and project: {project}")# Get Page 1req=requests.get(endpoint,headers=self.headers)tmpdb=[]ifreq.status_code==STATUS_CODE_OK:self.log.debug(f"Returned Status code {STATUS_CODE_OK}")foriteminreq.json()["results"]:tmpdb.append(item)ifreq.json()["next"]isnotNone:self.log.info("The response contains a pagination, starting iteration over it.")forpageinrange(0,self.max_pages-1):iter_endpoint=req.json()["next"]self.log.debug(f"Getting {iter_endpoint}")req=requests.get(iter_endpoint,headers=self.headers)foriteminreq.json()["results"]:tmpdb.append(item)ifreq.json()["next"]isNone:breakforitemintmpdb:itemdate=datetime.strptime(item["last_updated"].split(".")[0],"%Y-%m-%dT%H:%M:%S")ifisinstance(item["name"],str):tags=[item["name"]]else:tags=item["name"]out["data"].append({"last_update":itemdate,"name":tags})else:self.log.error(f"Error during getting image, returns: {req.json()}")out["error"]=Truereturnout
[docs]defget_metadata(self,image_repository:str)->TyperMetadata:"""Getting the DockerHub metadata like user and orgs. Args: image_repository (str): Url on docker.io in order to detect the needed data. Returns: Return a dict that have image metadata like: {"error": <bool>, "data": {"parent": "<organization name or user>", "project": "<project name>"}} """DOCKERHUB_SPLITSLASHES=2out=TyperMetadata({"error":False,"data":{"parent":"","project":""}})self.log.info("Getting Metadata from 'DockerHub'")urlparsed=urlparse(f"//{image_repository}")ifurlparsed.netloc=="docker.io":name_split=image_repository.split("/")out["data"]["parent"]=name_split[1]out["data"]["project"]=name_split[2]eliflen(image_repository.split("/"))==DOCKERHUB_SPLITSLASHES:name_split=image_repository.split("/")out["data"]["parent"]=name_split[0]out["data"]["project"]=name_split[1]else:out["data"]["parent"]="library"out["data"]["project"]=image_repositoryifout["data"]["parent"]=="_":out["data"]["parent"]="library"returnout