Skip to content

Commit 5ed4c0c

Browse files
Feat/getoutline (#14)
* feat: adding getoutline library * chore: update README.md
1 parent fc70a4f commit 5ed4c0c

File tree

3 files changed

+259
-4
lines changed

3 files changed

+259
-4
lines changed

README.md

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,98 @@
1-
# glueops-helper-library
1+
# GlueOps Helpers Library
22

3+
The GlueOps Helpers Library is a collection of utility functions and classes designed to simplify common tasks in Python projects. This library includes helpers for logging, AWS interactions, Kubernetes configuration, and more.
34

4-
The following does an install against tag: v0.0.11
5+
## Installation
6+
7+
To install the GlueOps Helpers Library, you can use pip with the following command:
58

69
```bash
7-
pip install https://github.com/GlueOps/python-glueops-helpers-library/archive/refs/tags/v0.0.11.zip
10+
pip install https://github.com/GlueOps/python-glueops-helpers-library/archive/refs/tags/v0.6.0.zip
11+
```
12+
13+
# Usage
14+
15+
## Logging
16+
17+
The library provides a logging configuration utility that sets up a JSON formatter for structured logging.
18+
19+
```python
20+
import os
21+
from glueops import setup_logging
22+
23+
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
24+
logger = setup_logging.configure(level=LOG_LEVEL)
25+
26+
logger.info("This is an info message")
27+
logger.error("This is an error message")
28+
```
29+
30+
## AWS
31+
The library includes helpers for creating AWS clients and retrieving resources based on tags.
32+
33+
```python
34+
from glueops.aws import create_aws_client, get_resource_arns_using_tags
35+
36+
# Create an AWS client
37+
s3_client = create_aws_client('s3')
38+
39+
# Get resource ARNs using tags
40+
tags = [{'Key': 'Environment', 'Value': 'Production'}]
41+
resource_arns = get_resource_arns_using_tags(tags, ['s3'])
42+
print(resource_arns)
43+
```
44+
45+
## Kubernetes
46+
47+
```python
48+
import os
49+
from glueops.setup_kubernetes import load_kubernetes_config
50+
51+
logger = setup_logging.configure(level="INFO")
52+
v1, custom_api = load_kubernetes_config(logger)
53+
54+
# Example: List all pods in the default namespace
55+
pods = v1.list_namespaced_pod(namespace='default')
56+
for pod in pods.items:
57+
print(pod.metadata.name)
858
```
59+
60+
## Vault
61+
62+
The library includes a client for interacting with HashiCorp Vault, supporting both Kubernetes and Pomerium authentication.
63+
64+
```python
65+
from glueops.vault_client import VaultClient
66+
67+
vault_url = "https://vault.example.com"
68+
kubernetes_role = "my-role"
69+
vault_client = VaultClient(vault_url, kubernetes_role)
70+
71+
# Get data from Vault
72+
secret_path = "secret/data/my-secret"
73+
data = vault_client.get_data_from_vault(secret_path)
74+
print(data)
75+
76+
# Write data to Vault
77+
data_to_write = {"key": "value"}
78+
vault_client.write_data_to_vault(secret_path, data_to_write)
79+
```
80+
81+
## GetOutline
82+
83+
The library provides a client for interacting with the GetOutline API for managing documents.
84+
85+
```python
86+
from glueops.getoutline import GetOutlineClient
87+
88+
api_url = "https://api.getoutline.com"
89+
document_id = "your_document_id"
90+
api_token = "your_api_token"
91+
outline_client = GetOutlineClient(api_url, document_id, api_token)
92+
93+
# Create a new document
94+
parent_document_id = "parent_document_id"
95+
title = "New Document"
96+
text = "This is the content of the new document."
97+
outline_client.create_document(parent_document_id, title, text)
98+
```

glueops/getoutline.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import requests
2+
import os
3+
from glueops import setup_logging
4+
import traceback
5+
6+
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
7+
logger = setup_logging.configure(level=LOG_LEVEL)
8+
9+
class GetOutlineClient:
10+
"""
11+
A client to interact with the Outline API for managing documents.
12+
"""
13+
14+
def __init__(self, api_url, document_id, api_token):
15+
"""
16+
Initializes the GetOutlineClient with the necessary API credentials.
17+
18+
:param api_url: The base URL for the Outline API.
19+
:param document_id: The ID of the document to manage.
20+
:param api_token: The API token for authentication.
21+
"""
22+
self.api_url = api_url.rstrip('/') # Ensure no trailing slash
23+
self.document_id = document_id
24+
self.api_token = api_token
25+
self.headers = {
26+
"Content-Type": "application/json",
27+
"Authorization": f"Bearer {self.api_token}"
28+
}
29+
30+
def update_document(self, markdown_text):
31+
"""
32+
Updates the content of the specified document with new markdown text.
33+
34+
:param markdown_text: The new markdown text to update the document with.
35+
"""
36+
logger.debug("Updating document on Outline.")
37+
url = f"{self.api_url}/api/documents.update"
38+
payload = {
39+
"id": self.document_id,
40+
"text": markdown_text
41+
}
42+
43+
try:
44+
response = requests.post(url, json=payload, headers=self.headers)
45+
response.raise_for_status()
46+
logger.info(f"Updated document with ID: {self.document_id}")
47+
except requests.exceptions.RequestException as e:
48+
logger.error(f"Error updating document: {e}")
49+
logger.error(traceback.format_exc())
50+
raise
51+
52+
def get_document_uuid(self):
53+
"""
54+
Retrieves the UUID of the parent document.
55+
56+
:return: The UUID of the parent document or None if an error occurs.
57+
"""
58+
url = f"{self.api_url}/api/documents.info"
59+
payload = {
60+
"id": self.document_id
61+
}
62+
63+
try:
64+
response = requests.post(url, json=payload, headers=self.headers)
65+
response.raise_for_status()
66+
parent_id = response.json().get("data", {}).get("id")
67+
logger.debug(f"Parent document UUID: {parent_id}")
68+
return parent_id
69+
except requests.exceptions.RequestException as e:
70+
logger.error(f"Error getting parent document UUID: {e}")
71+
logger.error(traceback.format_exc())
72+
raise
73+
74+
75+
def get_children_documents_to_delete(self, parent_document_id):
76+
"""
77+
Retrieves a list of child document IDs under the specified parent document.
78+
79+
:param parent_document_id: The UUID of the parent document.
80+
:return: A list of child document IDs.
81+
"""
82+
url = f"{self.api_url}/api/documents.list"
83+
payload = {
84+
"parentDocumentId": parent_document_id,
85+
"limit": 100,
86+
"offset": 0
87+
}
88+
all_ids = []
89+
90+
try:
91+
while True:
92+
response = requests.post(url, json=payload, headers=self.headers)
93+
response.raise_for_status()
94+
data = response.json()
95+
child_docs = data.get("data", [])
96+
new_ids = [doc.get("id") for doc in child_docs if "id" in doc]
97+
all_ids.extend(new_ids)
98+
99+
# Check if there is a next page
100+
pagination = data.get("pagination", {})
101+
next_path = pagination.get("nextPath")
102+
if len(new_ids) == 0 or not next_path:
103+
break
104+
105+
# Update the payload for the next request
106+
payload["offset"] += payload["limit"]
107+
108+
logger.debug(f"Child document IDs to delete: {all_ids}")
109+
return all_ids
110+
except requests.exceptions.RequestException as e:
111+
logger.error(f"Error getting children documents: {e}")
112+
logger.error(traceback.format_exc())
113+
raise
114+
115+
116+
def delete_document(self, document_id):
117+
"""
118+
Deletes a document with the specified document ID.
119+
120+
:param document_id: The ID of the document to delete.
121+
:return: True if deletion was successful, False otherwise.
122+
"""
123+
url = f"{self.api_url}/api/documents.delete"
124+
payload = {
125+
"id": document_id
126+
}
127+
128+
try:
129+
response = requests.post(url, json=payload, headers=self.headers)
130+
response.raise_for_status()
131+
logger.debug(f"Successfully deleted document with ID: {document_id}")
132+
return True
133+
except requests.exceptions.RequestException as e:
134+
logger.error(f"Error deleting document {document_id}: {e}")
135+
logger.error(traceback.format_exc())
136+
raise
137+
138+
139+
def create_document(self, parent_document_id, title, text):
140+
"""
141+
Creates a new document under the specified parent document.
142+
143+
:param parent_document_id: The UUID of the parent document.
144+
:param title: The title of the new document.
145+
:param text: The markdown text content of the new document.
146+
:return: True if creation was successful, False otherwise.
147+
"""
148+
url = f"{self.api_url}/api/documents.create"
149+
payload = {
150+
"parentDocumentId": parent_document_id,
151+
"title": title,
152+
"text": text,
153+
"publish": True
154+
}
155+
156+
try:
157+
response = requests.post(url, json=payload, headers=self.headers)
158+
response.raise_for_status()
159+
logger.info(f"Successfully created document with title: {title}")
160+
return True
161+
except requests.exceptions.RequestException as e:
162+
logger.error(f"Error creating document '{title}': {e}")
163+
logger.error(traceback.format_exc())
164+
raise
165+

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name='glueops-helpers',
6-
version='0.4.1',
6+
version='0.6.0',
77
packages=find_packages(),
88
install_requires=[
99
'requests',

0 commit comments

Comments
 (0)