Source code for topchef_client.models.service

"""
Describes a TopChef service
"""
import requests
from topchef_client.exceptions import NetworkError
from topchef_client.models.validator import Validator
from .job import Job


[docs]class Service(object): """ Represents a TopChef service """ _JSON_header = {'Content-Type': 'application/json'} HTTP_STATUS_CODE_OK = 200 HTTP_STATUS_CODE_CREATED = 201
[docs] def __init__(self, service_id, topchef_url, http_library=requests): """ :param service_id: The ID for the service :param topchef_url: The base URL for the TopChef API :param http_library: The library to use for HTTP requests """ self.service_id = service_id self.topchef_url = topchef_url self._http_library = http_library
@property def _service_endpoint(self): """ :return: A URL for getting details for a particular service :rtype: str """ return '{0}/services/{1}'.format(self.topchef_url, self.service_id) @property def does_service_exist(self): """ :return: A boolean that is true if the service exists. A sufficient condition for existence of the service is if the GET request to the service endpoint returns the OK status code """ response = self._http_library.get( self._service_endpoint, headers=self._JSON_header ) return response.status_code == self.HTTP_STATUS_CODE_OK @property def new_job_endpoint(self): return '{0}/services/{1}/jobs'.format( self.topchef_url, self.service_id ) @property def job_registration_schema(self): """ :return: The schema that must be satisfied in order to post jobs to this service :rtype: dict """ data = self._get_data() return data['job_registration_schema']
[docs] def new_job(self, parameters, validator_factory=Validator): """ :param dict parameters: The parameters to use for the job :param type validator_factory: The JSON Schema validator to use for checking the parameters :return: The newly-created job :rtype: Job """ validator = validator_factory(self.topchef_url, self._http_library) validator.assert_instance_matches_schema( parameters, self.job_registration_schema ) new_job_response = self._http_library.post( self.new_job_endpoint, headers=self._JSON_header, json={'parameters': parameters} ) if new_job_response.status_code != self.HTTP_STATUS_CODE_CREATED: self._handle_job_not_created_error(new_job_response.status_code) new_job_id = new_job_response.json()['data']['job_details']['id'] return Job(self.topchef_url, new_job_id, self._http_library)
[docs] def _get_data(self): """ :return: A dictionary representing the details for a service """ job_data_response = self._http_library.get( self._service_endpoint, headers=self._JSON_header ) if job_data_response.status_code != self.HTTP_STATUS_CODE_OK: self._handle_http_error(job_data_response.status_code) else: return job_data_response.json()['data']
@staticmethod
[docs] def _handle_http_error(response_code): """ :param response_code: The offending status code :raises: NetworkError """ raise NetworkError( 'Unable to contact server. Request for data ' 'returned status code %s' % response_code )
@staticmethod
[docs] def _handle_job_not_created_error(status_code): """ :param status_code: The offending status code :raises: NetworkError """ raise NetworkError( 'Attempting to create job returned unexpected status code %s' % status_code )
def __repr__(self): return '<%s(service_id=%s, topchef_url=%s, http_library=%s)>' % ( self.__class__.__name__, self.service_id, self.topchef_url, self._http_library )