#!/usr/bin/env python import os from dm.common.exceptions.configurationError import ConfigurationError from dm.common.api.dmSudsApi import DmSudsApi from dm.aps_bss.impl.bssClient import BssClient class ApsBssApi(DmSudsApi): ''' Data Management API for APS Beamline Scheduling System. ''' def __init__(self, beamlineName=None, username=None, password=None, loginFile=None): ''' Constructor. :param beamlineName: beamline name (if not provided, environment variable DM_BEAMLINE_NAME must be set) :type beamlineName: str :param username: BSS username (if not provided, loginFile must be specified, or environment variable DM_BSS_LOGIN_FILE must be set) :type username: str :param password: BSS password (if not provided, loginFile must be specified, environment variable DM_BSS_LOGIN_FILE must be set) :type password: str :param loginFile: BSS login file (not used if username/password are provided; it can be replaced by environment variable DM_BSS_LOGIN_FILE) :type loginFile: str :raises ConfigurationError: in case beamline name or username/password are not provided, and corresponding environment variables are not set Note that environment variable DM_BSS_LOGIN_FILE should contain path to a file containing BSS username and password as a single line in the '<username>|<password>' form. >>> api = ApsBssApi(beamlineName='1-ID-B,C,E', username='dm', password='XYZ') ''' DmSudsApi.__init__(self) if not username or not password: if not loginFile: loginFile = os.environ.get('DM_BSS_LOGIN_FILE') if loginFile: try: # Assume form <username>|<password> tokenList = open(loginFile).readline().split('|') if len(tokenList) == 2: username = tokenList[0].strip() password = tokenList[1].strip() except Exception, ex: raise ConfigurationError('Could not determine username/password from BSS login file: %s' % str(ex)) if not username or not password: raise ConfigurationError('Username and/or password were not provided, and DM_BSS_LOGIN_FILE is not set.') if not beamlineName: beamlineName = os.environ.get('DM_BEAMLINE_NAME') if not beamlineName: raise ConfigurationError('Beamline name was not provided, and DM_BEAMLINE_NAME is not set.') self.beamlineName = beamlineName self.bssClient = BssClient(username, password) @DmSudsApi.executeSudsCall def listRuns(self): ''' List all available runs. :returns: list of RunInfo objects :raises DmException: for any error >>> runs = api.listRuns() >>> for run in runs: >>> print run['name'] ''' return self.bssClient.listRuns() @DmSudsApi.executeSudsCall def getCurrentRun(self): ''' Find current run. :returns: RunInfo object :raises DmException: for any error >>> run = api.getCurrentRun() ''' return self.bssClient.getCurrentRun() @DmSudsApi.executeSudsCall def listBeamlineProposals(self, runName=None): ''' List beamline proposals for a given run. :param runName: run name (if not provided, current run name will be used) :type runName: str :returns: list of ProposalInfo objects :raises DmException: for any error >>> proposals = api.listBeamlineProposals() >>> for proposal in proposals: >>> print proposal['title'] ''' if not runName: runName = self.getCurrentRun()['name'] return self.bssClient.listBeamlineProposals(self.beamlineName, runName) @DmSudsApi.executeSudsCall def getBeamlineProposal(self, proposalId, runName=None): ''' Get beamline proposal with a given id. :param proposalId: proposal id :type proposalId: str :param runName: run name (if not provided, current run name will be used) :type runName: str :returns: ProposalInfo object :raises ObjectNotFound: if proposal with the given id does not exist :raises DmException: for any other error >>> proposal = api.getBeamlineProposal(42096) >>> for experimenter in proposal['experimenters']: >>> print experimenter['badge'], experimenter['lastName'] ''' if not runName: runName = self.getCurrentRun()['name'] return self.bssClient.getBeamlineProposal(proposalId, self.beamlineName, runName) ####################################################################### # Testing. if __name__ == '__main__': api = ApsBssApi('1-ID-B,C,E') print 'RUNS', api.listRuns() print 'CURRRENT RUN: ', api.getCurrentRun() print 'PROPOSALS: ', api.listBeamlineProposals() print print 'FIND PROPOSAL: ', api.getBeamlineProposal(42096) print 'FIND PROPOSAL: ', api.getBeamlineProposal(52096)