Source code for pacifica.downloader.cartapi

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Cart API module for interacting with carts."""
import logging
from uuid import uuid4 as uuid
import time
from json import dumps
from .common import CommonBase


LOGGER = logging.getLogger(__name__)


[docs]class CartAPI(CommonBase): """ Cart api object for manipulating carts. This class has two methods used for setting up a cart and waiting for completion. """ _proto = None _addr = None _port = None _cart_api_url = None _auth = None
[docs] def __init__(self, **kwargs): """ Constructor for cart api. The constructor takes a required URL to the Cart API. Optionally, there can be passed a `requests <https://docs.python-requests.org>`_ session via keyword arguments. Also, an optional requests authentication dictionary can be passed via keyword arguments. """ super(CartAPI, self).__init__() self._setup_requests_session() self.session = kwargs.get('session', self.session) self._server_url( [ ('proto', 'http'), ('port', '8081'), ('addr', '127.0.0.1'), ('cart_api_url', None), ], 'CARTD', kwargs ) if self._cart_api_url is None: self._cart_api_url = '{}://{}:{}'.format(self._proto, self._addr, self._port) self._auth = kwargs.get('auth', {}) LOGGER.debug('CartAPI URL %s auth %s', self._cart_api_url, self._auth)
@property def auth(self): """Return the requests authentication dictionary.""" return self._auth @property def cart_api_url(self): """Return the CartAPI URL.""" return self._cart_api_url
[docs] def setup_cart(self, yield_files): """ Setup a cart from the method and return url to the download. This method takes a callable argument that returns an iterator. The iterator is used to generate a list that is directly sent to the `Cartd API <https://github.com/pacifica/pacifica-cartd>`_. This method returns the full url to the cart created. """ cart_url = '{}/{}'.format(self._cart_api_url, uuid()) resp = self.session.post( cart_url, data=dumps({ 'fileids': [file_obj for file_obj in yield_files()] }), headers={'Content-Type': 'application/json'}, **self._auth ) LOGGER.debug('CartAPI Setup code %s', resp.status_code) assert resp.status_code == 201 return cart_url
[docs] def wait_for_cart(self, cart_url, timeout=120): """ Wait for cart completion to finish. This method takes a cart url returned from the `setup_cart()` method and polls the endpoint until the cart is ready to download. """ while timeout > 0: resp = self.session.head(cart_url, **self._auth) resp_status = resp.headers['X-Pacifica-Status'] resp_message = resp.headers['X-Pacifica-Message'] resp_code = resp.status_code LOGGER.debug('CartAPI Wait code %s status %s message %s', resp_code, resp_status, resp_message.replace('"', '\\"')) if resp_code == 204 and resp_status != 'staging': break if resp_code == 500: # pragma: no cover logging.error(resp_message) break time.sleep(1) timeout -= 1 assert resp_status == 'ready' assert resp_code == 204 return cart_url