Skip to content

Feat/getoutline #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 93 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,98 @@
# glueops-helper-library
# GlueOps Helpers Library

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.

The following does an install against tag: v0.0.11
## Installation

To install the GlueOps Helpers Library, you can use pip with the following command:

```bash
pip install https://github.com/GlueOps/python-glueops-helpers-library/archive/refs/tags/v0.0.11.zip
pip install https://github.com/GlueOps/python-glueops-helpers-library/archive/refs/tags/v0.6.0.zip
```

# Usage

## Logging

The library provides a logging configuration utility that sets up a JSON formatter for structured logging.

```python
import os
from glueops import setup_logging

LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
logger = setup_logging.configure(level=LOG_LEVEL)

logger.info("This is an info message")
logger.error("This is an error message")
```

## AWS
The library includes helpers for creating AWS clients and retrieving resources based on tags.

```python
from glueops.aws import create_aws_client, get_resource_arns_using_tags

# Create an AWS client
s3_client = create_aws_client('s3')

# Get resource ARNs using tags
tags = [{'Key': 'Environment', 'Value': 'Production'}]
resource_arns = get_resource_arns_using_tags(tags, ['s3'])
print(resource_arns)
```

## Kubernetes

```python
import os
from glueops.setup_kubernetes import load_kubernetes_config

logger = setup_logging.configure(level="INFO")
v1, custom_api = load_kubernetes_config(logger)

# Example: List all pods in the default namespace
pods = v1.list_namespaced_pod(namespace='default')
for pod in pods.items:
print(pod.metadata.name)
```

## Vault

The library includes a client for interacting with HashiCorp Vault, supporting both Kubernetes and Pomerium authentication.

```python
from glueops.vault_client import VaultClient

vault_url = "https://vault.example.com"
kubernetes_role = "my-role"
vault_client = VaultClient(vault_url, kubernetes_role)

# Get data from Vault
secret_path = "secret/data/my-secret"
data = vault_client.get_data_from_vault(secret_path)
print(data)

# Write data to Vault
data_to_write = {"key": "value"}
vault_client.write_data_to_vault(secret_path, data_to_write)
```

## GetOutline

The library provides a client for interacting with the GetOutline API for managing documents.

```python
from glueops.getoutline import GetOutlineClient

api_url = "https://api.getoutline.com"
document_id = "your_document_id"
api_token = "your_api_token"
outline_client = GetOutlineClient(api_url, document_id, api_token)

# Create a new document
parent_document_id = "parent_document_id"
title = "New Document"
text = "This is the content of the new document."
outline_client.create_document(parent_document_id, title, text)
```
165 changes: 165 additions & 0 deletions glueops/getoutline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import requests
import os
from glueops import setup_logging
import traceback

LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
logger = setup_logging.configure(level=LOG_LEVEL)

class GetOutlineClient:
"""
A client to interact with the Outline API for managing documents.
"""

def __init__(self, api_url, document_id, api_token):
"""
Initializes the GetOutlineClient with the necessary API credentials.

:param api_url: The base URL for the Outline API.
:param document_id: The ID of the document to manage.
:param api_token: The API token for authentication.
"""
self.api_url = api_url.rstrip('/') # Ensure no trailing slash
self.document_id = document_id
self.api_token = api_token
self.headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_token}"
}

def update_document(self, markdown_text):
"""
Updates the content of the specified document with new markdown text.

:param markdown_text: The new markdown text to update the document with.
"""
logger.debug("Updating document on Outline.")
url = f"{self.api_url}/api/documents.update"
payload = {
"id": self.document_id,
"text": markdown_text
}

try:
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
logger.info(f"Updated document with ID: {self.document_id}")
except requests.exceptions.RequestException as e:
logger.error(f"Error updating document: {e}")
logger.error(traceback.format_exc())
raise

def get_document_uuid(self):
"""
Retrieves the UUID of the parent document.

:return: The UUID of the parent document or None if an error occurs.
"""
url = f"{self.api_url}/api/documents.info"
payload = {
"id": self.document_id
}

try:
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
parent_id = response.json().get("data", {}).get("id")
logger.debug(f"Parent document UUID: {parent_id}")
return parent_id
except requests.exceptions.RequestException as e:
logger.error(f"Error getting parent document UUID: {e}")
logger.error(traceback.format_exc())
raise


def get_children_documents_to_delete(self, parent_document_id):
"""
Retrieves a list of child document IDs under the specified parent document.

:param parent_document_id: The UUID of the parent document.
:return: A list of child document IDs.
"""
url = f"{self.api_url}/api/documents.list"
payload = {
"parentDocumentId": parent_document_id,
"limit": 100,
"offset": 0
}
all_ids = []

try:
while True:
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
data = response.json()
child_docs = data.get("data", [])
new_ids = [doc.get("id") for doc in child_docs if "id" in doc]
all_ids.extend(new_ids)

# Check if there is a next page
pagination = data.get("pagination", {})
next_path = pagination.get("nextPath")
if len(new_ids) == 0 or not next_path:
break

# Update the payload for the next request
payload["offset"] += payload["limit"]

logger.debug(f"Child document IDs to delete: {all_ids}")
return all_ids
except requests.exceptions.RequestException as e:
logger.error(f"Error getting children documents: {e}")
logger.error(traceback.format_exc())
raise


def delete_document(self, document_id):
"""
Deletes a document with the specified document ID.

:param document_id: The ID of the document to delete.
:return: True if deletion was successful, False otherwise.
"""
url = f"{self.api_url}/api/documents.delete"
payload = {
"id": document_id
}

try:
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
logger.debug(f"Successfully deleted document with ID: {document_id}")
return True
except requests.exceptions.RequestException as e:
logger.error(f"Error deleting document {document_id}: {e}")
logger.error(traceback.format_exc())
raise


def create_document(self, parent_document_id, title, text):
"""
Creates a new document under the specified parent document.

:param parent_document_id: The UUID of the parent document.
:param title: The title of the new document.
:param text: The markdown text content of the new document.
:return: True if creation was successful, False otherwise.
"""
url = f"{self.api_url}/api/documents.create"
payload = {
"parentDocumentId": parent_document_id,
"title": title,
"text": text,
"publish": True
}

try:
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
logger.info(f"Successfully created document with title: {title}")
return True
except requests.exceptions.RequestException as e:
logger.error(f"Error creating document '{title}': {e}")
logger.error(traceback.format_exc())
raise

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

setup(
name='glueops-helpers',
version='0.4.1',
version='0.6.0',
packages=find_packages(),
install_requires=[
'requests',
Expand Down