def _get_organization(api: APIClient, organization_id: Optional[int] = None) -> dict: if organization_id is None: user_url = get_json(api.get("auth/user"))["url"] organziation_url = get_json(api.get_url(user_url))["organization"] res = api.get_url(organziation_url) else: res = api.get(f"organizations/{organization_id}") return get_json(res)
class TestAPIClient: api_client = APIClient(None) def test_get_token_success(self, requests_mock, isolated_cli_runner): requests_mock.post(LOGIN_URL, json={"key": TOKEN}) with isolated_cli_runner.isolation(): assert TOKEN == self.api_client.get_token() def test_get_token_failed(self, requests_mock, isolated_cli_runner): requests_mock.post(LOGIN_URL, status_code=401) with isolated_cli_runner.isolation(), pytest.raises(click.ClickException) as e: self.api_client.get_token() assert "Login failed with the provided credentials." == str(e.value) def test_get_token_error(self, requests_mock, isolated_cli_runner): error_json = {"password": ["required"]} requests_mock.post(LOGIN_URL, status_code=400, json=error_json) with isolated_cli_runner.isolation(), pytest.raises(click.ClickException) as e: self.api_client.get_token() assert f"Invalid response [{LOGIN_URL}]: {json.dumps(error_json)}" == str(e.value) @pytest.mark.usefixtures("mock_login_request") def test_user_agent_header(self, requests_mock, isolated_cli_runner): requests_mock.get(API_URL + "/v1/", request_headers=REQUEST_HEADERS) with isolated_cli_runner.isolation(): self.api_client.get("") assert requests_mock.called
def change_command( id_: str, queue_id: Tuple[str], group: Optional[str], locale: Optional[str], password: Optional[str], ) -> None: if not any([queue_id, group, locale, password]): return data: Dict[str, Any] = {} if password is not None: data["password"] = password with APIClient() as api_client: if queue_id: data["queues"] = [ get_json(api_client.get(f"queues/{queue}"))["url"] for queue in queue_id ] if group is not None: data["groups"] = get_groups(api_client, group) if locale is not None: ui_settings = get_json( api_client.get(f"users/{id_}"))["ui_settings"] data["ui_settings"] = {**ui_settings, "locale": locale} api_client.patch(f"users/{id_}", data)
class TestAPIClient: api_client = APIClient(None) username = "******" password = "******" login_data = {"username": username, "password": password} def test_get_token_success(self, requests_mock, isolated_cli_runner): requests_mock.post( LOGIN_URL, additional_matcher=partial(match_uploaded_json, self.login_data), json={"key": TOKEN}, ) with isolated_cli_runner.isolation(): assert TOKEN == self.api_client.get_token() def test_get_token_with_custom_lifetime(self, requests_mock): token_lifetime = 3600 login_data = { "username": self.username, "password": self.password, "max_token_lifetime_s": token_lifetime, } requests_mock.post( LOGIN_URL, additional_matcher=partial(match_uploaded_json, login_data), json={"key": TOKEN}, ) assert TOKEN == APIClient( None, max_token_lifetime=token_lifetime).get_token() def test_get_token_failed(self, requests_mock): requests_mock.post( LOGIN_URL, additional_matcher=partial(match_uploaded_json, self.login_data), status_code=401, ) with pytest.raises(click.ClickException) as e: self.api_client.get_token() assert "Login failed with the provided credentials." == str(e.value) def test_get_token_error(self, requests_mock): error_json = {"password": ["required"]} requests_mock.post( LOGIN_URL, additional_matcher=partial(match_uploaded_json, self.login_data), status_code=400, json=error_json, ) with pytest.raises(click.ClickException) as e: self.api_client.get_token() assert f"Invalid response [{LOGIN_URL}]: {json.dumps(error_json)}" == str( e.value) @pytest.mark.usefixtures("mock_login_request") def test_user_agent_header(self, requests_mock, isolated_cli_runner): requests_mock.get(API_URL + "/v1/", request_headers=REQUEST_HEADERS) with isolated_cli_runner.isolation(): self.api_client.get("") assert requests_mock.called
class TestSideload: api_client = APIClient(None) url = f"{API_URL}/v1/tests" obj_url = f"{url}/1" sideloaded_obj = {"url": obj_url, "some": "test"} TESTS = APIObject("tests") def test_sideload_singular(self, requests_mock, isolated_cli_runner): requests_mock.get(self.url, json=self._paginated_rsp()) with isolated_cli_runner.isolation(): res = self.api_client._sideload([{ "test": self.obj_url }], (self.TESTS, )) assert res == [{"test": self.sideloaded_obj}] def test_sideload_plural(self, requests_mock, isolated_cli_runner): requests_mock.get(self.url, json=self._paginated_rsp()) with isolated_cli_runner.isolation(): res = self.api_client._sideload([{ "tests": [self.obj_url] }], (self.TESTS, )) assert res == [{"tests": [self.sideloaded_obj]}] def test_sideload_not_reachable_singular(self, requests_mock, isolated_cli_runner): requests_mock.get(self.url, json=self._paginated_rsp(0)) with isolated_cli_runner.isolation(): res = self.api_client._sideload([{ "test": self.obj_url }], (self.TESTS, )) assert res == [{"test": {}}] def test_sideload_not_reachable_plural(self, requests_mock, isolated_cli_runner): requests_mock.get(self.url, json=self._paginated_rsp(0)) with isolated_cli_runner.isolation(): res = self.api_client._sideload([{ "tests": [self.obj_url] }], (self.TESTS, )) assert res == [{"tests": []}] def _paginated_rsp(self, total: int = 1): assert total <= 1, "URL in sideloaded_obj is not unique." return { "results": [self.sideloaded_obj for _ in range(total)], "pagination": { "next": None, "total": total }, }
def test_get_token_with_custom_lifetime(self, requests_mock): token_lifetime = 3600 login_data = { "username": self.username, "password": self.password, "max_token_lifetime_s": token_lifetime, } requests_mock.post( LOGIN_URL, additional_matcher=partial(match_uploaded_json, login_data), json={"key": TOKEN}, ) assert TOKEN == APIClient( None, max_token_lifetime=token_lifetime).get_token()
def download_command(ctx: click.Context, start: datetime.datetime, stop: datetime.datetime, float_step: float) -> None: api_client = APIClient.csv() step = datetime.timedelta(days=float_step) dfs = [] while stop > start: start += step rsp = api_client.get( f"byperiod/{ceil(step.total_seconds())}/{int(start.timestamp())}") dfs.append(pd.read_csv(StringIO(get_text(rsp)), sep=";")) df = pd.concat(dfs) with StringIO() as buffer: df.to_csv(buffer, sep=";", index=False) click.echo(buffer.getvalue())
def list_command(): with APIClient() as api_client: users_list, _ = api_client.get_paginated("users", {"is_active": True}) groups_list, _ = api_client.get_paginated("groups") queues_list, _ = api_client.get_paginated("queues") groups = {group["url"]: group.get("name", "") for group in groups_list} queues = {queue["url"]: queue.get("id", "") for queue in queues_list} table = [[ user["id"], user["username"], ", ".join(str(groups[g]) for g in user["groups"]), ", ".join(str(queues[q]) for q in user["queues"]), ] for user in users_list] click.echo(tabulate(table, headers=["id", "username", "groups", "queues"]))
def download_command( ctx: click.Context, start: datetime.datetime, stop: datetime.datetime, float_step: float ) -> None: api_client = APIClient.csv(context=ctx.obj) step = datetime.timedelta(days=float_step) dfs = [] while stop > start: start += step rsp = api_client.get(f"byperiod/{ceil(step.total_seconds())}/{int(start.timestamp())}") dfs.append(pd.read_csv(StringIO(get_text(rsp)), sep=";")) df = pd.concat(dfs) with StringIO() as buffer: # set line_terminator to ensure universal newline support for all the OS df.to_csv(buffer, sep=";", index=False, line_terminator="\n") click.echo(buffer.getvalue())
def download_command( ctx: click.Context, id_: str, indent: int, ensure_ascii: bool, format_: str, output_file: Optional[IO[str]], ): with APIClient(context=ctx.obj) as api_client: schema_dict = get_json(api_client.get(f"schemas/{id_}")) if format_ == "json": schema_file = json.dumps(schema_dict["content"], indent=indent, ensure_ascii=ensure_ascii, sort_keys=True).encode("utf-8") else: schema_file = SchemaToXlsx().convert(schema_dict["content"]) click.echo(schema_file, file=output_file, nl=False)
def create_command( username: str, password: Optional[str], queue_id: Tuple[int], organization_id: Optional[int], group: str, locale: str, ) -> None: """ Create user with USERNAME and add him to QUEUES specified by ids. """ password = password or _generate_password() with APIClient() as api: _check_user_does_not_exists(api, username) organization_dict = _get_organization(api, organization_id) workspace_urls = { w["url"] for w in get_json(api.get("workspaces", {"organization": organization_dict["id"]}))[ "results" ] } queue_urls = [] for queue in queue_id: queue_dict = get_json(api.get(f"queues/{queue}")) if queue_dict["workspace"] in workspace_urls: queue_urls.append(queue_dict["url"]) response = api.post( "users", { "username": username, "email": username, "organization": organization_dict["url"], "password": password, "groups": get_groups(api, group), "queues": queue_urls, "ui_settings": {"locale": locale}, }, ) click.echo(f"{get_json(response)['id']}, {password}")
def get_groups(api: APIClient, group_name: Optional[str]) -> List[str]: if group_name is None: return [] return [g["url"] for g in get_json(api.get("groups", {"name": group_name}))["results"]]
def _check_user_does_not_exists(api: APIClient, username: str) -> None: total_users = get_json(api.get(f"users", {"username": username}))["pagination"]["total"] if total_users: raise click.ClickException(f"User with username {username} already exists.")
def delete_command(id_: str) -> None: with APIClient() as api_client: api_client.patch(f"users/{id_}", {"is_active": False})