Skip to content

Commit 01784ec

Browse files
dandyecopybara-github
authored andcommitted
Add samples for Append to/Remove from existing Reference List.
PiperOrigin-RevId: 627744437
1 parent c85c9b6 commit 01784ec

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed

lists/append_to_list.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2024 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
"""Executable and reusable sample for appending to a list."""
18+
19+
import argparse
20+
from typing import Sequence
21+
22+
from common import chronicle_auth
23+
from common import regions
24+
25+
from google.auth.transport import requests
26+
27+
from . import get_list
28+
29+
BACKSTORY_API_BASE_URL = "https://backstory.googleapis.com"
30+
31+
32+
# pylint: disable=bad-continuation
33+
def append_to_list(http_session: requests.AuthorizedSession,
34+
list_api_url: str,
35+
list_id: str,
36+
content_lines: Sequence[str]) -> str:
37+
"""Append items to an existing reference list.
38+
39+
Args:
40+
http_session: Authorized session for HTTP requests.
41+
list_api_url: Regionalizied API endpoint.
42+
list_id: ID of existing list.
43+
content_lines: Iterable containing items to append to the existing list.
44+
45+
Returns:
46+
List update timestamp.
47+
48+
Raises:
49+
requests.exceptions.HTTPError: HTTP request resulted in an error
50+
(response.status_code >= 400).
51+
"""
52+
current_list = get_list.get_list(http_session, list_id)
53+
seen = set(current_list)
54+
deduplicated_list = [x for x in content_lines
55+
if not (x in seen or seen.add(x))]
56+
content_lines = current_list + deduplicated_list
57+
58+
body = {
59+
"name": list_id,
60+
"lines": content_lines,
61+
}
62+
update_fields = ["list.lines"]
63+
params = {"update_mask": ",".join(update_fields)}
64+
65+
response = http_session.request("PATCH",
66+
list_api_url,
67+
params=params,
68+
json=body)
69+
# Expected server response:
70+
# {
71+
# "name": "<list name>",
72+
# "description": "<list description>",
73+
# "createTime": "yyyy-mm-ddThh:mm:ss.ssssssZ",
74+
# "lines": [
75+
# "<line 1>",
76+
# "<line 2>",
77+
# ...
78+
# ],
79+
# "contentType": "<content type. omitted if type is STRING list.>"
80+
# }
81+
82+
if response.status_code >= 400:
83+
print(response.text)
84+
response.raise_for_status()
85+
return response.json()["createTime"]
86+
87+
88+
if __name__ == "__main__":
89+
parser = argparse.ArgumentParser()
90+
chronicle_auth.add_argument_credentials_file(parser)
91+
regions.add_argument_region(parser)
92+
parser.add_argument(
93+
"-n", "--name", type=str, required=True, help="unique name for the list")
94+
parser.add_argument(
95+
"-f",
96+
"--list_file",
97+
type=argparse.FileType("r"),
98+
required=True,
99+
# File example:
100+
# python3 -m lists.append_to_list <other args> -f <path>
101+
# STDIN example:
102+
# cat <path> | python3 -m lists.append_to_list <other args> -f -
103+
help="path to file containing the list content to append, or - for STDIN")
104+
args = parser.parse_args()
105+
106+
session = chronicle_auth.initialize_http_session(args.credentials_file)
107+
api_url = f"{regions.url(BACKSTORY_API_BASE_URL, args.region)}/v2/lists"
108+
new_list_create_time = append_to_list(
109+
session,
110+
api_url,
111+
args.name,
112+
args.list_file.read().splitlines()
113+
)
114+
print(f"List successfully appended at {new_list_create_time}")

lists/remove_from_list.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2024 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
"""Executable and reusable sample for appending to an existing reference list."""
18+
19+
import argparse
20+
from typing import Sequence
21+
22+
from common import chronicle_auth
23+
from common import regions
24+
25+
from google.auth.transport import requests
26+
27+
from . import get_list
28+
29+
BACKSTORY_API_BASE_URL = "https://backstory.googleapis.com"
30+
31+
32+
# pylint: disable=bad-continuation
33+
def remove_from_list(http_session: requests.AuthorizedSession,
34+
list_api_url: str,
35+
list_id: str,
36+
content_lines: Sequence[str]) -> str:
37+
"""Remove items from an existing reference list.
38+
39+
Args:
40+
http_session: Authorized session for HTTP requests.
41+
list_api_url: Regionalizied API endpoint.
42+
list_id: ID of existing list.
43+
content_lines: Iterable containing items to remove from the existing list.
44+
45+
Returns:
46+
List update timestamp.
47+
48+
Raises:
49+
requests.exceptions.HTTPError: HTTP request resulted in an error
50+
(response.status_code >= 400).
51+
"""
52+
current_list = get_list.get_list(http_session, list_id)
53+
to_remove = set(content_lines)
54+
updated_list = [x for x in current_list if x not in to_remove]
55+
56+
body = {
57+
"name": list_id,
58+
"lines": updated_list,
59+
}
60+
update_fields = ["list.lines"]
61+
params = {"update_mask": ",".join(update_fields)}
62+
63+
response = http_session.request("PATCH",
64+
list_api_url,
65+
params=params,
66+
json=body)
67+
# Expected server response:
68+
# {
69+
# "name": "<list name>",
70+
# "description": "<list description>",
71+
# "createTime": "yyyy-mm-ddThh:mm:ss.ssssssZ",
72+
# "lines": [
73+
# "<line 1>",
74+
# "<line 2>",
75+
# ...
76+
# ],
77+
# "contentType": "<content type. omitted if type is STRING list.>"
78+
# }
79+
80+
if response.status_code >= 400:
81+
print(response.text)
82+
response.raise_for_status()
83+
return response.json()["createTime"]
84+
85+
86+
if __name__ == "__main__":
87+
parser = argparse.ArgumentParser()
88+
chronicle_auth.add_argument_credentials_file(parser)
89+
regions.add_argument_region(parser)
90+
parser.add_argument(
91+
"-n", "--name", type=str, required=True, help="unique name for the list")
92+
parser.add_argument(
93+
"-f",
94+
"--list_file",
95+
type=argparse.FileType("r"),
96+
required=True,
97+
# File example:
98+
# python3 -m lists.remove_from_list <other args> -f <path>
99+
# STDIN example:
100+
# cat <path> | python3 -m lists.remove_from_list <other args> -f -
101+
help="path to file containing the list content to remove, "
102+
"or - for STDIN")
103+
args = parser.parse_args()
104+
105+
api_url = f"{regions.url(BACKSTORY_API_BASE_URL, args.region)}/v2/lists"
106+
session = chronicle_auth.initialize_http_session(args.credentials_file)
107+
new_list_create_time = remove_from_list(session,
108+
api_url,
109+
args.name,
110+
args.list_file.read().splitlines()
111+
)
112+
print(f"Items successfully removed from list at {new_list_create_time}")

0 commit comments

Comments
 (0)