from tempfile import SpooledTemporaryFile import requests import binstar_client from binstar_client.requests_ext import stream_multipart from binstar_client.utils import compute_hash, jencode class ProjectUploader(binstar_client.Binstar): def __init__(self, token, **kwargs): domain = kwargs.get('domain', 'https://api.anaconda.org') verify = kwargs.get('verify', True) self.username = kwargs.get('username', None) self.project = kwargs.get('project', None) super(ProjectUploader, self).__init__(token, domain, verify) def exists(self): url = "{}/apps/{}/projects/{}".format( self.domain, self.username, self.project.name) res = self.session.get(url) return res.status_code == 200 def create(self): url = "{}/apps/{}/projects".format(self.domain, self.username) data, headers = jencode(self.project.to_project_creation()) res = self.session.post(url, data=data, headers=headers) return res def stage(self): url = "{}/apps/{}/projects/{}/stage".format( self.domain, self.username, self.project.name) data, headers = jencode(self.project.to_stage()) res = self.session.post(url, data=data, headers=headers) self._check_response(res) return res def commit(self, revision_id): url = "{}/apps/{}/projects/{}/commit/{}".format( self.domain, self.username, self.project.name, revision_id ) data, headers = jencode({}) res = self.session.post(url, data=data, headers=headers) self._check_response(res, [201]) return res def file_upload(self, url, obj): _hexmd5, b64md5, size = compute_hash( self.project.tar, size=self.project.size) s3data = obj['form_data'] s3data['Content-Length'] = size s3data['Content-MD5'] = b64md5 data_stream, headers = stream_multipart( s3data, files={'file': (self.project.basename, self.project.tar)}) s3res = requests.post( url, data=data_stream, verify=self.session.verify, timeout=10 * 60 * 60, headers=headers) if s3res.status_code != 201: raise binstar_client.errors.BinstarError( 'Error uploading package', s3res.status_code) return s3res def projects(self): url = "{}/apps/{}/projects".format(self.domain, self.username) data, headers = jencode(self.project.to_project_creation()) return self.session.get(url, data=data, headers=headers) def upload(self): ''' * Check if project already exists * if it doesn't, then create it * stage a new revision * upload * commit revision ''' if not self.exists(): self.create() data = self.stage().json() self.file_upload(data['post_url'], data) res = self.commit(data['dist_id']) data = res.json() return data