Skip to content

Commit 4c695a9

Browse files
committed
get script running
1 parent ce3e697 commit 4c695a9

File tree

4 files changed

+174
-0
lines changed

4 files changed

+174
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import os
2+
from io import BytesIO
3+
import json
4+
from pathlib import Path
5+
import notion_client as n_client
6+
import frontmatter
7+
from ruamel.yaml import YAML
8+
from frontmatter.default_handlers import YAMLHandler, DEFAULT_POST_TEMPLATE
9+
from notion.catalog import PersistenceCatalog
10+
11+
token = os.getenv("NOTION_TOKEN")
12+
markdown_path = "../../src/content/docs/aws/services"
13+
# markdown_path = "../../content/en/user-guide/aws"
14+
persistence_path = "../../src/data/persistence"
15+
persistence_data = os.path.join(persistence_path, "coverage.json")
16+
17+
18+
class CustomYAMLHandler(YAMLHandler):
19+
20+
def load(self, fm: str, **kwargs: object):
21+
yaml = YAML()
22+
yaml.default_flow_style = False
23+
yaml.preserve_quotes = True
24+
return yaml.load(fm, **kwargs) # type: ignore[arg-type]
25+
26+
def export(self, metadata: dict[str, object], **kwargs: object) -> str:
27+
yaml = YAML()
28+
yaml.default_flow_style = False
29+
from io import StringIO
30+
stream = StringIO()
31+
yaml.dump(metadata, stream)
32+
return stream.getvalue()
33+
34+
def format(self, post, **kwargs):
35+
"""
36+
Simple customization to avoid removing the last line.
37+
"""
38+
start_delimiter = kwargs.pop("start_delimiter", self.START_DELIMITER)
39+
end_delimiter = kwargs.pop("end_delimiter", self.END_DELIMITER)
40+
41+
metadata = self.export(post.metadata, **kwargs)
42+
43+
return DEFAULT_POST_TEMPLATE.format(
44+
metadata=metadata,
45+
content=post.content,
46+
start_delimiter=start_delimiter,
47+
end_delimiter=end_delimiter,
48+
).lstrip()
49+
50+
51+
def lookup_full_name(shortname: str) -> str:
52+
"""Given the short default name of a service, looks up for the full name"""
53+
service_lookup = Path("../../src/data/coverage/service_display_name.json")
54+
service_info = {}
55+
if service_lookup.exists() and service_lookup.is_file():
56+
with open(service_lookup, "r") as f:
57+
service_info = json.load(f)
58+
59+
service_name_title = shortname
60+
61+
if service_name_details := service_info.get(shortname, {}):
62+
service_name_title = service_name_details.get("long_name", shortname)
63+
if service_name_title and (short_name := service_name_details.get("short_name")):
64+
service_name_title = f"{short_name} ({service_name_title})"
65+
return service_name_title
66+
67+
68+
def collect_status() -> dict:
69+
"""Reads the catalog on Notion and returns the status of persistence for each service"""
70+
if not token:
71+
print("Aborting, please provide a NOTION_TOKEN in the env")
72+
notion_client = n_client.Client(auth=token)
73+
74+
catalog_db = PersistenceCatalog(notion_client=notion_client)
75+
statuses = {}
76+
for item in catalog_db:
77+
# we do not want some services to be mentioned in the docs (for instance, not yet released)
78+
if item.exclude:
79+
continue
80+
81+
# Skip entries with empty or placeholder names
82+
if not item.name or not item.name.strip():
83+
continue
84+
85+
# Skip template/placeholder entries
86+
if item.name.strip().lower() in ['new service page', 'template', 'placeholder']:
87+
continue
88+
89+
service = item.name.replace('_', '-')
90+
status = item.status.lower()
91+
statuses[service] = {
92+
"service": service,
93+
"full_name": lookup_full_name(service),
94+
"support": status,
95+
"test_suite": item.has_test or False,
96+
# we collect limitations notes only for the services explicitly marked with limitations
97+
"limitations": item.limitations if "limit" in status else ""
98+
}
99+
statuses = dict(sorted(statuses.items()))
100+
101+
# save the data
102+
if not os.path.exists(persistence_path):
103+
os.mkdir(persistence_path)
104+
with open(persistence_data, 'w') as f:
105+
json.dump(statuses, f, indent=2)
106+
return statuses
107+
108+
109+
def update_frontmatter(statuses: dict):
110+
"""Updates the frontmatter of the service page in the user guide Markdown file"""
111+
for service, values in statuses.items():
112+
113+
# a bunch of special cases
114+
if "cognito" in service:
115+
service = "cognito"
116+
if service == "kafka":
117+
service = "msk"
118+
119+
_path = os.path.join(markdown_path, service, "index.md")
120+
if not os.path.exists(_path):
121+
print(f" Can't find index.md file for {service}")
122+
continue
123+
124+
support_value = values.get("support")
125+
is_supported = support_value == "supported" or support_value == "supported with limitations"
126+
if not is_supported:
127+
# we don't want to modify the frontmatter for the services not supporting persistence
128+
continue
129+
130+
# open the markdown file and read the content
131+
content = frontmatter.load(_path, handler=CustomYAMLHandler())
132+
desc = content.metadata["description"]
133+
content.metadata["description"] = desc.strip()
134+
content.metadata["persistence"] = values.get("support", "unknown")
135+
frontmatter.dump(content, _path)
136+
137+
138+
if __name__ == "__main__":
139+
data = collect_status()
140+
# update_frontmatter(statuses=data)

scripts/persistence/notion/__init__.py

Whitespace-only changes.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Models for the notion service catalog https://www.notion.so/localstack/3c0f615e7ffc4ae2a034f1ed9c444bd2"""
2+
3+
from notion_client import Client as NotionClient
4+
5+
from notion_objects import (
6+
Page,
7+
TitlePlainText,
8+
Status,
9+
Database,
10+
Checkbox,
11+
PeopleProperty,
12+
Text
13+
)
14+
15+
DEFAULT_CATALOG_DATABASE_ID = "3c0f615e7ffc4ae2a034f1ed9c444bd2"
16+
17+
18+
class PersistenceServiceItem(Page):
19+
name = TitlePlainText("Name")
20+
status = Status("Persistence")
21+
has_test = Checkbox("Persistence Tests")
22+
primary_owner = PeopleProperty("Primary Owner")
23+
secondary_owner = PeopleProperty("Secondary Owner(s)")
24+
limitations = Text("Limitations (synced with docs)")
25+
exclude = Checkbox("Exclude from docs")
26+
27+
28+
class PersistenceCatalog(Database[PersistenceServiceItem]):
29+
def __init__(self, notion_client: NotionClient, database_id: str | None = None):
30+
super().__init__(PersistenceServiceItem, database_id or DEFAULT_CATALOG_DATABASE_ID, notion_client)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
notion-client==2.2.1
2+
notion-objects==0.6.2
3+
python-frontmatter==1.1.0
4+
ruamel.yaml==0.18.6

0 commit comments

Comments
 (0)