def setUp(self):
        options = {
            'DOMAIN': 'https://example.com',
            'API_PREFIX': 'api/v1',
            'TOKEN_TYPE': 'jwt',
            'TOKEN_FORMAT': 'JWT {token}',
            'LOGIN': '******',
            'LOGOUT': 'auth/logout/',
        }

        self.api = Api(options=options)
 def main(self):
     """
     Main function to call to initiate execution.
     1. Get domain name and use to instantiate Api object
     2. Call before_login to allow for work before logging in
     3. Logging into the server
     4. Call after_loging to do actual work with server data
     """
     self.domain = self.get_domain()
     self.api = RestApi(self.get_options())
     self.before_login()
     ok = self.login()
     if ok:
         self.after_login()
class ApiTestCase(unittest.TestCase):
    api = None

    def setUp(self):
        options = {
            'DOMAIN': 'https://example.com',
            'API_PREFIX': 'api/v1',
            'TOKEN_TYPE': 'jwt',
            'TOKEN_FORMAT': 'JWT {token}',
            'LOGIN': '******',
            'LOGOUT': 'auth/logout/',
        }

        self.api = Api(options=options)

    def tearDown(self):
        self.api = None

    def test_init(self):

        self.assertEqual(self.api.base_url, 'https://example.com/api/v1')
        self.assertTrue(self.api.use_token)
        self.assertEqual(self.api.token_type, 'jwt')

    def test_set_token(self):

        self.assertEqual(self.api.token, None)
        self.api.set_token('big-token')
        self.assertEqual(self.api.token, 'big-token')

    @requests_mock.Mocker()
    def test_login(self, m):
        payload = {'jwt': 'big-token', 'username': '******'}
        m.post('https://example.com/api/v1/auth/login/',
               text=json.dumps(payload))

        ok = self.api.login(email='*****@*****.**', password='******')
        self.assertTrue(ok)
        self.assertEqual(self.api.username, 'user1')
        self.assertEqual(self.api.token, 'big-token')

    @requests_mock.Mocker()
    def test_logout(self, m):
        payload = {'jwt': 'big-token', 'username': '******'}
        m.post('https://example.com/api/v1/auth/login/',
               text=json.dumps(payload))
        m.post('https://example.com/api/v1/auth/logout/', status_code=204)

        ok = self.api.login(email='*****@*****.**', password='******')
        self.assertTrue(ok)

        self.api.logout()
        self.assertEqual(self.api.username, None)
        self.assertEqual(self.api.token, None)

    @requests_mock.Mocker()
    def test_get_list(self, m):
        payload = {"result": ["a", "b", "c"]}
        m.get('https://example.com/api/v1/test/', text=json.dumps(payload))

        resp = self.api.test.get()
        self.assertEqual(resp['result'], ['a', 'b', 'c'])

    @requests_mock.Mocker()
    def test_get_detail(self, m):
        payload = {"a": "b", "c": "d"}
        m.get('https://example.com/api/v1/test/my-detail/',
              text=json.dumps(payload))

        resp = self.api.test('my-detail').get()
        self.assertEqual(resp, {'a': 'b', 'c': 'd'})

    @requests_mock.Mocker()
    def test_get_detail_with_action(self, m):
        payload = {"a": "b", "c": "d"}
        m.get('https://example.com/api/v1/test/my-detail/action/',
              text=json.dumps(payload))

        resp = self.api.test('my-detail').action.url()
        self.assertEqual(resp,
                         'https://example.com/api/v1/test/my-detail/action/')
        resp = self.api.test('my-detail').action.get()
        self.assertEqual(resp, {'a': 'b', 'c': 'd'})

    @requests_mock.Mocker()
    def test_get_detail_with_extra_args(self, m):
        payload = {"a": "b", "c": "d"}
        m.get('https://example.com/api/v1/test/my-detail/',
              text=json.dumps(payload))

        resp = self.api.test('my-detail').get(foo='bar')
        self.assertEqual(resp, {'a': 'b', 'c': 'd'})

    @requests_mock.Mocker()
    def test_post(self, m):
        payload = {"foo": ["a", "b", "c"]}
        result = {"id": 1}
        m.post('https://example.com/api/v1/test/', text=json.dumps(result))

        resp = self.api.test.post(payload)
        self.assertEqual(resp['id'], 1)

    @requests_mock.Mocker()
    def test_patch(self, m):
        payload = {"foo": ["a", "b", "c"]}
        result = {"id": 1}
        m.patch('https://example.com/api/v1/test/my-detail/',
                text=json.dumps(result))

        resp = self.api.test('my-detail').patch(payload)
        self.assertEqual(resp['id'], 1)

    @requests_mock.Mocker()
    def test_put(self, m):
        payload = {"foo": ["a", "b", "c"]}
        result = {"id": 1}
        m.put('https://example.com/api/v1/test/my-detail/',
              text=json.dumps(result))

        resp = self.api.test('my-detail').put(payload)
        self.assertEqual(resp['id'], 1)

    @requests_mock.Mocker()
    def test_delete(self, m):
        result = {"id": 1}
        m.delete('https://example.com/api/v1/test/my-detail/',
                 text=json.dumps(result))

        deleted = self.api.test('my-detail').delete()
        self.assertTrue(deleted)

    @requests_mock.Mocker()
    def test_post_with_error(self, m):
        payload = {"foo": ["a", "b", "c"]}
        result = {"id": 1}
        m.post('https://example.com/api/v1/test/',
               status_code=400,
               text=json.dumps(result))

        with self.assertRaises(HttpClientError):
            self.api.test.post(payload)

        m.post('https://example.com/api/v1/test/',
               status_code=404,
               text=json.dumps(result))

        with self.assertRaises(HttpClientError):
            self.api.test.post(payload)

        m.post('https://example.com/api/v1/test/',
               status_code=500,
               text=json.dumps(result))

        with self.assertRaises(HttpServerError):
            self.api.test.post(payload)
예제 #4
0
logger = logging.getLogger(__name__)

username = input('Email? ')
password = getpass.getpass()

options = {
    'DOMAIN': 'http://127.0.0.1:8000',
    'API_PREFIX': 'api/v1',
    'TOKEN_TYPE': 'jwt',
    'TOKEN_FORMAT': 'JWT {token}',
    'USERNAME_KEY': 'username',
    'LOGIN': '******',
    'LOGOUT': 'auth/logout/',
}

c = RestApi(options)

ok = c.login(username=username, password=password)
if ok:

    # GET some data
    my_objects = c.org.get()
    for obj in my_objects['results']:
        pprint(obj)
        logger.info('------------------------------')

    logger.info('------------------------------')
    logger.info('------------------------------')
    # If the URL includes "-", add under parenthesis:
    # GET: /api/v1/someresource/some-path/
    my_object = c.someresource('some-path').get()
class BaseMain(object):
    parser = None
    args = None
    api = None
    options = {
        'DOMAIN': None,
        'API_PREFIX': 'api/v1',
        'TOKEN_TYPE': 'jwt',
        'TOKEN_FORMAT': 'JWT {token}',
        'USERNAME_KEY': 'username',
        'LOGIN': '******',
        'LOGOUT': 'auth/logout/',
    }
    logging_level = logging.INFO

    def __init__(self):
        """
        Initialize Logging configuration
        Initialize argument parsing
        Process any extra arguments
        Only hard codes one required argument: --user
        Additional arguments can be configured by overwriting the add_extra_args() method
        Logging configuration can be changed by overwritting the config_logging() method
        """
        self.parser = argparse.ArgumentParser(description=__doc__)
        self.parser.add_argument('-u',
                                 '--user',
                                 dest='username',
                                 type=str,
                                 required=True,
                                 help='Username used for login')
        self.parser.add_argument('--server',
                                 dest='server',
                                 type=str,
                                 required=True,
                                 help='Server Domain Name to use')

        self.add_extra_args()

        self.args = self.parser.parse_args()
        self.config_logging()

    def _critical_exit(self, msg):
        LOG.error(msg)
        sys.exit(1)

    def main(self):
        """
        Main function to call to initiate execution.
        1. Get domain name and use to instantiate Api object
        2. Call before_login to allow for work before logging in
        3. Logging into the server
        4. Call after_loging to do actual work with server data
        """
        self.domain = self.get_domain()
        self.api = RestApi(self.get_options())
        self.before_login()
        ok = self.login()
        if ok:
            self.after_login()

    # Following functions can be overwritten if needed
    # ================================================

    def get_options(self):
        options = self.options
        options['DOMAIN'] = self.domain
        return options

    def config_logging(self):
        """
        Overwrite to change the way the logging package is configured
        :return: Nothing
        """
        logging.basicConfig(
            level=self.logging_level,
            format='[%(asctime)-15s] %(levelname)-6s %(message)s',
            datefmt='%d/%b/%Y %H:%M:%S')

    def add_extra_args(self):
        """
        Overwrite to change the way extra arguments are added to the args parser
        :return: Nothing
        """
        pass

    def get_domain(self) -> str:
        """
        Figure out server domain URL based on --server and --customer args
        """
        if 'https://' not in self.args.server:
            return f'https://{self.args.server}'
        return self.args.server

    def login(self) -> bool:
        """
        Get password from user and login
        """
        password = getpass.getpass()
        ok = self.api.login(username=self.args.username, password=password)
        if ok:
            LOG.info('Welcome {0}'.format(self.args.username))
        return ok

    def before_login(self):
        """
        Overwrite to do work after parsing, but before logging in to the server
        This is a good place to do additional custom argument checks
        :return: Nothing
        """
        pass

    def after_login(self):
        """
        This function MUST be overwritten to do actual work after logging into the Server
        :return: Nothing
        """
        LOG.warning('No actual work done')