Neue Skills, Referenzen & OpenWiki-Doku integriert

Umfangreiche Erweiterung der Skill-Bibliothek: Neue Skills für Humanisierung (Englisch/PT-BR), Design-Validierung, AI-SEO und Coolify-Deployment inkl. Regelwerke, Presets, Pattern-Referenzen, Testfälle und Automatisierungsskripte. Zusätzliche Skills für Revenue-Centric Design, Pier Cloud, OKF, Lebenslauf- und LinkedIn-Optimierung sowie zahlreiche Referenzdateien, Checklisten und YAML/JSON/Markdown-Templates. Einführung einer vollständigen OpenWiki-Dokumentation mit Architektur-, Domain- und Workflow-Beschreibungen, zentralem Index und automatisierten Updates. Modularer Aufbau, restriktive Lizenzen und umfassende Qualitäts- und Evaluationsmechanismen für alle neuen Inhalte.
This commit is contained in:
Tim Krampitz
2026-07-26 14:00:58 +02:00
parent 070727d5cd
commit 01046b01e4
202 changed files with 31290 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
# Scripts da API Pier Cloud
Scripts prontos para consumir a API Pier Cloud (Lighthouse).
## Prerequisitos
```bash
pip install requests python-dotenv
```
## Configuracao
Crie arquivo `.env` na raiz do projeto:
```env
PIERCLOUD_CLIENT_ID=seu_client_id
PIERCLOUD_CLIENT_SECRET=seu_client_secret
PIERCLOUD_TENANCY_ID=seu_tenancy_id
```
> **Nota**: O `TENANCY_ID` corresponde ao antigo `BUSINESS_ID`. Se voce ja tem `PIERCLOUD_BUSINESS_ID` no `.env`, os scripts usam como fallback automaticamente.
## API - Mudanca de Endpoints (Fev 2026)
A API Pier Cloud atualizou seus endpoints:
- **Antes**: `/lighthouse/orgs/{org_id}/businesses/{business_id}/...`
- **Agora**: `/lighthouse/tenancies/{tenancy_id}/...`
O `PIERCLOUD_ORG_ID` nao e mais necessario. O `tenancy_id` equivale ao antigo `BUSINESS_ID`.
Documentacao oficial: https://docs.piercloud.com/api-docs-pier-cloud
## Scripts Disponiveis
### 1. pier-cloud-auth.py
Autentica e obtem token JWT.
```bash
python scripts/pier-cloud-auth.py
```
### 2. pier-cloud-list-contexts.py
Lista todos os contextos disponiveis.
```bash
python scripts/pier-cloud-list-contexts.py
```
### 3. pier-cloud-list-workspaces.py
Lista workspaces com paginacao.
```bash
# Padrao (pagina 1, 10 itens)
python scripts/pier-cloud-list-workspaces.py
# Pagina especifica
python scripts/pier-cloud-list-workspaces.py --page 2 --page-size 50
# Ordenar por data
python scripts/pier-cloud-list-workspaces.py --sort-field created_at --sort-order DESC
```
### 4. pier-cloud-get-workspace.py
Obtem detalhes de workspace especifico.
```bash
python scripts/pier-cloud-get-workspace.py --workspace-id 16969
```
### 5. pier-cloud-get-all-workspaces.py
Obtem todos os workspaces com paginacao automatica.
```bash
# Exibir no terminal
python scripts/pier-cloud-get-all-workspaces.py
# Salvar em JSON
python scripts/pier-cloud-get-all-workspaces.py --output workspaces.json
# Salvar em CSV
python scripts/pier-cloud-get-all-workspaces.py --output workspaces.csv --format csv
```
### 6. pier-cloud-list-views.py
Lista visualizacoes de um workspace.
```bash
python scripts/pier-cloud-list-views.py --workspace-id 16969
```
### 7. pier-cloud-get-view.py
Obtem informacoes de visualizacao especifica.
```bash
python scripts/pier-cloud-get-view.py --view-id 193195
```
### 8. pier-cloud-get-view-data.py
Obtem dados de uma visualizacao com filtros.
```bash
# Basico
python scripts/pier-cloud-get-view-data.py --view-id 193195
# Com periodo
python scripts/pier-cloud-get-view-data.py --view-id 193195 \
--start-date 2026-01-01 --end-date 2026-01-31
# Com filtros
python scripts/pier-cloud-get-view-data.py --view-id 193195 \
--filters '[{"name":"lineitem/usageaccountid","data_type":"string","role":"filter","filters":[{"expression":"IS","value":["123456"],"negative_expression":false}]}]'
# Salvar em arquivo
python scripts/pier-cloud-get-view-data.py --view-id 193195 \
--start-date 2026-01-01 --end-date 2026-01-31 --output dados.json
```
### 9. pier_cloud_client.py
Cliente robusto com CLI e biblioteca reutilizavel.
**Como CLI**:
```bash
# Listar contextos
python scripts/pier_cloud_client.py --action list-contexts
# Listar workspaces
python scripts/pier_cloud_client.py --action list-workspaces --page 1 --page-size 20
# Obter workspace
python scripts/pier_cloud_client.py --action get-workspace --workspace-id 16969
# Obter todos
python scripts/pier_cloud_client.py --action get-all-workspaces --output results.json
```
### 10. appscript-pier-cloud.gs
Codigo Google Apps Script para integrar com Google Sheets.
Veja instrucoes no proprio arquivo.
## Endpoints da API (Atualizado Fev 2026)
| Metodo | Endpoint | Descricao |
|--------|----------|-----------|
| POST | `/auth` | Obter token JWT |
| GET | `/lighthouse/tenancies/{tenancy_id}/contexts` | Listar contextos |
| GET | `/lighthouse/tenancies/{tenancy_id}/workspaces` | Listar workspaces |
| GET | `/lighthouse/tenancies/{tenancy_id}/workspaces/{id}` | Obter workspace |
| GET | `/lighthouse/tenancies/{tenancy_id}/workspaces/{workspace_id}/views` | Listar views |
| GET | `/lighthouse/tenancies/{tenancy_id}/views/{id}` | Obter view |
| GET | `/lighthouse/tenancies/{tenancy_id}/views/{id}/data` | Obter dados da view |
## Troubleshooting
### Erro: Variaveis faltando
Verifique se o arquivo `.env` existe e contem `PIERCLOUD_TENANCY_ID` (ou `PIERCLOUD_BUSINESS_ID` como fallback).
### Erro 401
Credenciais invalidas. Verifique CLIENT_ID e CLIENT_SECRET.
### Erro 403
Sem permissao. Verifique TENANCY_ID.
### Erro 404
Recurso nao encontrado. Verifique IDs fornecidos.

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""
Script to authenticate with the Pier Cloud API and obtain a JWT token.
"""
import requests
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
def authenticate():
"""Obtain authentication token"""
print("Authenticating with Pier Cloud API...")
url = f"{API_BASE}/auth"
payload = {
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET
}
try:
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
data = response.json()
token = data['data']['access_token']
expires_in = data['data']['expires_in']
print(f"\n✓ Token obtained successfully!")
print(f"Token: {token[:50]}...")
print(f"Expires in: {expires_in} seconds ({expires_in//60} minutes)")
print(f"Type: {data['data']['token_type']}")
return token
else:
print(f"\n✗ Authentication error (Status {response.status_code})")
print(f"Response: {response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"\n✗ Connection error: {e}")
return None
if __name__ == "__main__":
# Validate environment variables
if not CLIENT_ID or not CLIENT_SECRET:
print("✗ Error: PIERCLOUD_CLIENT_ID and PIERCLOUD_CLIENT_SECRET must be defined in .env")
exit(1)
token = authenticate()
if token:
print("\n✓ Authentication completed successfully!")
else:
print("\n✗ Authentication failed")
exit(1)

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""
Script para obter todos os workspaces da API Pier Cloud com paginacao automatica.
"""
import requests
import os
import argparse
import json
import csv
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def get_all_workspaces(token):
"""Obter todos os workspaces com paginacao automatica"""
all_workspaces = []
page = 1
page_size = 100 # Maximo permitido
while True:
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/workspaces"
headers = {"Authorization": f"Bearer {token}"}
params = {"page": page, "page_size": page_size}
response = requests.get(url, headers=headers, params=params, timeout=30)
if response.status_code != 200:
raise Exception(f"Erro na pagina {page}: {response.text}")
data = response.json()
workspaces = data['data']['workspaces']
meta = data['meta']
all_workspaces.extend(workspaces)
print(f"OK Pagina {page}: {len(workspaces)} workspaces obtidos")
# Verificar se ha mais paginas
if page * page_size >= meta['total']:
break
page += 1
return all_workspaces
def save_json(workspaces, filename):
"""Salvar workspaces em arquivo JSON"""
with open(filename, 'w', encoding='utf-8') as f:
json.dump(workspaces, f, indent=2, ensure_ascii=False)
print(f"OK Salvo em {filename}")
def save_csv(workspaces, filename):
"""Salvar workspaces em arquivo CSV"""
if not workspaces:
print("Nenhum workspace para salvar")
return
keys = ['id', 'name', 'description', 'access_scope', 'count_views', 'created_at']
with open(filename, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
for ws in workspaces:
row = {k: ws.get(k, '') for k in keys}
writer.writerow(row)
print(f"OK Salvo em {filename}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Obter todos os workspaces da API Pier Cloud")
parser.add_argument("--output", help="Arquivo de saida (JSON ou CSV)")
parser.add_argument("--format", choices=["json", "csv"], default="json", help="Formato de saida")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado\n")
print("Obtendo todos os workspaces...")
workspaces = get_all_workspaces(token)
print(f"\nOK Total: {len(workspaces)} workspaces obtidos")
# Salvar em arquivo se especificado
if args.output:
if args.format == "json":
save_json(workspaces, args.output)
else:
save_csv(workspaces, args.output)
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env python3
"""
Script para obter dados de uma visualizacao da API Pier Cloud com filtros.
"""
import requests
import os
import argparse
import json
from datetime import datetime, timedelta
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def get_view_data(token, view_id, start_date=None, end_date=None, date_type="date", filters=None):
"""Obter dados de uma visualizacao"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/views/{view_id}/data"
headers = {"Authorization": f"Bearer {token}"}
# Parametros de query
params = {}
if start_date:
params['start_date'] = start_date
if end_date:
params['end_date'] = end_date
if date_type:
params['date_type'] = date_type
if filters:
params['filters'] = json.dumps(filters)
response = requests.get(url, headers=headers, params=params, timeout=60)
if response.status_code == 200:
data = response.json()
results = data['data']
print(f"\n=== Dados da Visualizacao {view_id} ===")
print(f"Periodo: {start_date or 'inicio do mes'} ate {end_date or 'fim do mes'}")
print(f"Tipo de data: {date_type}")
print(f"Total de registros: {len(results)}\n")
if results:
# Mostrar primeiros registros
print("Primeiros registros:")
for i, record in enumerate(results[:5]):
print(f"\nRegistro {i+1}:")
for key, value in record.items():
print(f" {key}: {value}")
if len(results) > 5:
print(f"\n... e mais {len(results) - 5} registros")
return results
else:
raise Exception(f"Erro ao obter dados: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Obter dados de visualizacao da API Pier Cloud")
parser.add_argument("--view-id", "--view_id", dest="view_id", type=int, required=True, help="ID da visualizacao")
parser.add_argument("--start-date", "--start_date", dest="start_date", help="Data inicial (YYYY-MM-DD)")
parser.add_argument("--end-date", "--end_date", dest="end_date", help="Data final (YYYY-MM-DD)")
parser.add_argument("--date-type", "--date_type", dest="date_type", choices=["date", "month"], default="date",
help="Tipo de filtro de data (date ou month)")
parser.add_argument("--filters", help="Filtros em formato JSON")
parser.add_argument("--output", help="Arquivo de saida JSON")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
# Parse filters se fornecido
filters = None
if args.filters:
try:
filters = json.loads(args.filters)
except json.JSONDecodeError as e:
print(f"X Erro ao parsear filtros JSON: {e}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado")
results = get_view_data(
token,
args.view_id,
start_date=args.start_date,
end_date=args.end_date,
date_type=args.date_type,
filters=filters
)
# Salvar em arquivo se especificado
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2, ensure_ascii=False)
print(f"\nOK Salvo em {args.output}")
print(f"\nOK Total: {len(results)} registros obtidos")
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""
Script para obter informacoes de uma visualizacao especifica da API Pier Cloud.
"""
import requests
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def get_view(token, view_id):
"""Obter informacoes de uma visualizacao especifica"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/views/{view_id}"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 200:
data = response.json()
view = data['data']
print(f"\n=== Visualizacao: {view['name']} ===\n")
print(f"ID: {view['id']}")
print(f"Nome: {view['name']}")
print(f"Descricao: {view.get('description', 'N/A')}")
if 'workspace' in view:
print(f"\nWorkspace:")
print(f" ID: {view['workspace']['id']}")
print(f" Nome: {view['workspace']['name']}")
return view
else:
raise Exception(f"Erro ao obter visualizacao: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Obter informacoes de visualizacao da API Pier Cloud")
parser.add_argument("--view-id", "--view_id", dest="view_id", type=int, required=True, help="ID da visualizacao")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado")
view = get_view(token, args.view_id)
print(f"\nOK Visualizacao obtida com sucesso")
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,93 @@
#!/usr/bin/env python3
"""
Script para obter detalhes de um grupo de workspace especifico da API Pier Cloud.
"""
import requests
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def get_workspace_group(token, group_id):
"""Obter detalhes de um grupo de workspace especifico"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/workspace-groups/{group_id}"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 200:
data = response.json()
group = data['data']
print(f"\n=== Grupo de Workspace: {group['name']} ===\n")
print(f"ID: {group['id']}")
print(f"Nome: {group['name']}")
print(f"Descricao: {group.get('description', 'N/A')}")
print(f"Acesso: {group['access_scope']}")
print(f"Context ID: {group['context_id']}")
print(f"Business ID: {group['business_id']}")
print(f"Criado em: {group['created_at']}")
print(f"Atualizado em: {group['updated_at']}")
if 'workspaces' in group and group['workspaces']:
print(f"\n--- Workspaces ({len(group['workspaces'])}) ---")
for ws in group['workspaces']:
print(f"\n ID: {ws['id']}")
print(f" Nome: {ws['name']}")
print(f" Descricao: {ws.get('description', 'N/A')}")
print(f" Acesso: {ws['access_scope']}")
print(f" Criado em: {ws['created_at']}")
else:
print("\nNenhum workspace neste grupo.")
return group
else:
raise Exception(f"Erro ao obter grupo: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Obter detalhes de grupo de workspace da API Pier Cloud")
parser.add_argument("--group-id", "--group_id", dest="group_id", required=True, help="ID do grupo de workspace (numerico ou UUID)")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado")
group = get_workspace_group(token, args.group_id)
print(f"\nOK Grupo obtido com sucesso")
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""
Script para obter detalhes de um workspace especifico da API Pier Cloud.
"""
import requests
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def get_workspace(token, workspace_id):
"""Obter detalhes de um workspace especifico"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/workspaces/{workspace_id}"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 200:
data = response.json()
ws = data['data']
print(f"\n=== Workspace: {ws['name']} ===\n")
print(f"ID: {ws['id']}")
print(f"Descricao: {ws.get('description', 'N/A')}")
print(f"Acesso: {ws['access_scope']}")
print(f"Grupo: {ws['workspace_group_id']}")
if 'views' in ws and ws['views']:
print(f"\n--- Visualizacoes ({len(ws['views'])}) ---")
for view in ws['views']:
print(f"\n ID: {view['id']}")
print(f" Nome: {view['name']}")
print(f" Descricao: {view.get('description', 'N/A')}")
print(f" Criado em: {view['created_at']}")
else:
print("\nNenhuma visualizacao encontrada.")
return ws
else:
raise Exception(f"Erro ao obter workspace: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Obter detalhes de workspace da API Pier Cloud")
parser.add_argument("--workspace-id", "--workspace_id", dest="workspace_id", type=int, required=True, help="ID do workspace")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado")
workspace = get_workspace(token, args.workspace_id)
print(f"\nOK Workspace obtido com sucesso")
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""
Script to list contexts from the Pier Cloud API.
"""
import requests
import os
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obtain authentication token"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Authentication error: {response.text}")
def list_contexts(token):
"""List all contexts"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/contexts"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 200:
data = response.json()
contexts = data['data']['contexts']
print(f"\n=== Contexts ({len(contexts)} found) ===\n")
for ctx in contexts:
print(f"ID: {ctx['id']}")
print(f"Name: {ctx['name']}")
print(f"Provider: {ctx['provider']}")
print(f"Currency: {ctx['currency']}")
print(f"Default: {'Yes' if ctx['is_default'] else 'No'}")
print("-" * 60)
return contexts
else:
raise Exception(f"Error listing contexts: {response.text}")
if __name__ == "__main__":
# Validate variables
if not TENANCY_ID:
print("X Error: PIERCLOUD_TENANCY_ID (or PIERCLOUD_BUSINESS_ID) must be defined in .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"✗ Error: Missing variables in .env: {missing}")
exit(1)
try:
print("Authenticating...")
token = authenticate()
print("✓ Authenticated")
contexts = list_contexts(token)
print(f"\n✓ Total: {len(contexts)} contexts")
except Exception as e:
print(f"\n✗ Error: {e}")
exit(1)

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""
Script para listar visualizacoes de um workspace da API Pier Cloud.
"""
import requests
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def list_views(token, workspace_id):
"""Listar visualizacoes de um workspace"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/workspaces/{workspace_id}/views"
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 200:
data = response.json()
views = data['data']['views']
total = data['data']['total']
print(f"\n=== Visualizacoes do Workspace {workspace_id} ===")
print(f"Total: {total} visualizacoes\n")
for view in views:
print(f"ID: {view['id']}")
print(f"Nome: {view['name']}")
print(f"Descricao: {view.get('description', 'N/A')}")
print(f"Criado em: {view['created_at']}")
print("-" * 60)
return views
else:
raise Exception(f"Erro ao listar visualizacoes: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Listar visualizacoes de workspace da API Pier Cloud")
parser.add_argument("--workspace-id", "--workspace_id", dest="workspace_id", type=int, required=True, help="ID do workspace")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado")
views = list_views(token, args.workspace_id)
print(f"\nOK Total: {len(views)} visualizacoes")
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,101 @@
#!/usr/bin/env python3
"""
Script para listar grupos de workspaces da API Pier Cloud.
"""
import requests
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obter token de autenticacao"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Erro na autenticacao: {response.text}")
def list_workspace_groups(token, page=1, page_size=10):
"""Listar grupos de workspaces"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/workspace-groups"
headers = {"Authorization": f"Bearer {token}"}
params = {"page": page, "page_size": page_size}
response = requests.get(url, headers=headers, params=params, timeout=30)
if response.status_code == 200:
data = response.json()
groups = data['data']
meta = data['meta']
print(f"\n=== Grupos de Workspaces (Pagina {meta['page']}) ===")
print(f"Total: {meta['total']} grupos\n")
for i, group in enumerate(groups, 1):
print(f"\n{'='*60}")
print(f"GRUPO {i}")
print(f"{'='*60}")
print(f"ID COMPLETO: {group['id']}")
print(f"Nome: {group['name']}")
print(f"Descricao: {group.get('description', 'N/A')}")
print(f"Acesso: {group['access_scope']}")
print(f"Context ID: {group.get('context_id', 'N/A')}")
print(f"Business ID: {group.get('business_id', 'N/A')}")
print(f"Criado em: {group['created_at']}")
print(f"Atualizado em: {group.get('updated_at', 'N/A')}")
print(f"Workspaces: {len(group.get('workspaces', []))}")
if group.get('workspaces'):
print("\n Workspaces incluidos:")
for ws in group['workspaces']:
print(f" - [{ws['id']}] {ws['name']}")
print(f"\n Comando para obter detalhes:")
print(f" python scripts/pier-cloud-get-workspace-group.py --group-id {group['id']}")
print(f"{'='*60}")
return groups, meta
else:
raise Exception(f"Erro ao listar grupos: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Listar grupos de workspaces da API Pier Cloud")
parser.add_argument("--page", type=int, default=1, help="Numero da pagina (padrao: 1)")
parser.add_argument("--page-size", "--page_size", dest="page_size", type=int, default=10, help="Itens por pagina (padrao: 10)")
args = parser.parse_args()
# Validar variaveis
if not TENANCY_ID:
print("X Erro: PIERCLOUD_TENANCY_ID (ou PIERCLOUD_BUSINESS_ID) deve estar definido no .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"X Erro: Variaveis faltando no .env: {missing}")
exit(1)
try:
print("Autenticando...")
token = authenticate()
print("OK Autenticado")
groups, meta = list_workspace_groups(token, page=args.page, page_size=args.page_size)
print(f"\nOK Exibidos {len(groups)} grupos de {meta['total']} total")
except Exception as e:
print(f"\nX Erro: {e}")
exit(1)

View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""
Script to list workspaces from the Pier Cloud API with pagination.
"""
import requests
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
API_BASE = "https://api.piercloud.io"
CLIENT_ID = os.getenv("PIERCLOUD_CLIENT_ID")
CLIENT_SECRET = os.getenv("PIERCLOUD_CLIENT_SECRET")
TENANCY_ID = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
def authenticate():
"""Obtain authentication token"""
url = f"{API_BASE}/auth"
payload = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
response = requests.post(url, json=payload, timeout=30)
if response.status_code == 201:
return response.json()['data']['access_token']
else:
raise Exception(f"Authentication error: {response.text}")
def list_workspaces(token, page=1, page_size=10, sort_field="name", sort_order="ASC"):
"""List workspaces with pagination"""
url = f"{API_BASE}/lighthouse/tenancies/{TENANCY_ID}/workspaces"
headers = {"Authorization": f"Bearer {token}"}
params = {
"page": page,
"page_size": page_size,
"sort_field": sort_field,
"sort_order": sort_order
}
response = requests.get(url, headers=headers, params=params, timeout=30)
if response.status_code == 200:
data = response.json()
workspaces = data['data']['workspaces']
meta = data['meta']
total_pages = (meta['total'] - 1) // meta['pageSize'] + 1
print(f"\n=== Workspaces (Page {meta['page']}/{total_pages}) ===")
print(f"Total: {meta['total']} workspaces")
print(f"Sort: {meta['sortBy']['field']} {meta['sortBy']['order']}\n")
for ws in workspaces:
print(f"ID: {ws['id']}")
print(f"Name: {ws['name']}")
print(f"Description: {ws.get('description', 'N/A')}")
print(f"Views: {ws['count_views']}")
print(f"Access: {ws['access_scope']}")
print(f"Created at: {ws['created_at']}")
print("-" * 60)
return workspaces, meta
else:
raise Exception(f"Error listing workspaces: {response.text}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="List workspaces from the Pier Cloud API")
parser.add_argument("--page", type=int, default=1, help="Page number (default: 1)")
parser.add_argument("--page-size", "--page_size", dest="page_size", type=int, default=10, help="Items per page (default: 10, max: 100)")
parser.add_argument("--sort-field", "--sort_field", dest="sort_field", choices=["name", "created_at"], default="name", help="Sort field")
parser.add_argument("--sort-order", "--sort_order", dest="sort_order", choices=["ASC", "DESC"], default="ASC", help="Sort order")
args = parser.parse_args()
# Validate variables
if not TENANCY_ID:
print("X Error: PIERCLOUD_TENANCY_ID (or PIERCLOUD_BUSINESS_ID) must be defined in .env")
exit(1)
required = ["CLIENT_ID", "CLIENT_SECRET"]
missing = [v for v in required if not os.getenv(f"PIERCLOUD_{v}")]
if missing:
print(f"✗ Error: Missing variables in .env: {missing}")
exit(1)
try:
print("Authenticating...")
token = authenticate()
print("✓ Authenticated")
workspaces, meta = list_workspaces(
token,
page=args.page,
page_size=args.page_size,
sort_field=args.sort_field,
sort_order=args.sort_order
)
print(f"\n✓ Displayed {len(workspaces)} workspaces of {meta['total']} total")
except Exception as e:
print(f"\n✗ Error: {e}")
exit(1)

View File

@@ -0,0 +1,199 @@
#!/usr/bin/env python3
"""
Cliente robusto para API Pier Cloud com retry, renovacao automatica e CLI.
"""
import requests
import os
import time
import logging
import argparse
import json
from dotenv import load_dotenv
# Configurar logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
class PierCloudClient:
"""Cliente robusto para API Pier Cloud"""
def __init__(self):
load_dotenv()
self.api_base = "https://api.piercloud.io"
self.client_id = os.getenv("PIERCLOUD_CLIENT_ID")
self.client_secret = os.getenv("PIERCLOUD_CLIENT_SECRET")
self.tenancy_id = os.getenv("PIERCLOUD_TENANCY_ID", os.getenv("PIERCLOUD_BUSINESS_ID"))
self.token = None
self.token_expires = None
self._validate_config()
def _validate_config(self):
"""Validar configuracao necessaria"""
required = ["client_id", "client_secret", "tenancy_id"]
missing = [k for k in required if not getattr(self, k)]
if missing:
raise ValueError(f"Configuracao faltando: {missing}")
def authenticate(self):
"""Autenticar e obter token"""
logger.info("Autenticando...")
response = requests.post(
f"{self.api_base}/auth",
json={"client_id": self.client_id, "client_secret": self.client_secret},
timeout=30
)
if response.status_code == 201:
data = response.json()['data']
self.token = data['access_token']
# Renovar 5 minutos antes de expirar
self.token_expires = time.time() + data['expires_in'] - 300
logger.info("OK Autenticado com sucesso")
return True
else:
logger.error(f"X Falha na autenticacao: {response.text}")
return False
def ensure_authenticated(self):
"""Garantir token valido"""
if not self.token or time.time() >= self.token_expires:
return self.authenticate()
return True
def make_request(self, method, endpoint, **kwargs):
"""Fazer requisicao com retry e renovacao automatica"""
max_retries = 3
for attempt in range(max_retries):
try:
if not self.ensure_authenticated():
raise Exception("Falha na autenticacao")
headers = kwargs.get('headers', {})
headers['Authorization'] = f"Bearer {self.token}"
kwargs['headers'] = headers
kwargs.setdefault('timeout', 30)
response = requests.request(method, f"{self.api_base}{endpoint}", **kwargs)
if response.status_code == 401:
logger.warning("Token expirado, renovando...")
self.authenticate()
continue
if response.status_code == 429:
wait_time = 2 ** attempt
logger.warning(f"Rate limit. Aguardando {wait_time}s...")
time.sleep(wait_time)
continue
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
logger.error(f"Erro na tentativa {attempt + 1}: {e}")
if attempt == max_retries - 1:
raise
time.sleep(2 ** attempt)
return None
def list_contexts(self):
"""Listar contextos"""
endpoint = f"/lighthouse/tenancies/{self.tenancy_id}/contexts"
return self.make_request('GET', endpoint)
def list_workspaces(self, page=1, page_size=10):
"""Listar workspaces"""
endpoint = f"/lighthouse/tenancies/{self.tenancy_id}/workspaces"
params = {"page": page, "page_size": page_size}
return self.make_request('GET', endpoint, params=params)
def get_workspace(self, workspace_id):
"""Obter workspace especifico"""
endpoint = f"/lighthouse/tenancies/{self.tenancy_id}/workspaces/{workspace_id}"
return self.make_request('GET', endpoint)
def get_all_workspaces(self):
"""Obter todos os workspaces com paginacao automatica"""
all_workspaces = []
page = 1
page_size = 100
while True:
result = self.list_workspaces(page=page, page_size=page_size)
workspaces = result['data']['workspaces']
meta = result['meta']
all_workspaces.extend(workspaces)
logger.info(f"Pagina {page}: {len(workspaces)} workspaces")
if page * page_size >= meta['total']:
break
page += 1
return all_workspaces
def main():
parser = argparse.ArgumentParser(description="Cliente CLI para API Pier Cloud")
parser.add_argument("--action", required=True,
choices=["list-contexts", "list-workspaces", "get-workspace", "get-all-workspaces"],
help="Acao a executar")
parser.add_argument("--workspace-id", type=int, help="ID do workspace (para get-workspace)")
parser.add_argument("--page", type=int, default=1, help="Numero da pagina")
parser.add_argument("--page-size", type=int, default=10, help="Itens por pagina")
parser.add_argument("--output", help="Arquivo de saida JSON")
args = parser.parse_args()
try:
client = PierCloudClient()
if args.action == "list-contexts":
result = client.list_contexts()
contexts = result['data']['contexts']
print(f"\nContextos: {len(contexts)}")
for ctx in contexts:
print(f" - {ctx['name']} ({ctx['provider']})")
elif args.action == "list-workspaces":
result = client.list_workspaces(page=args.page, page_size=args.page_size)
workspaces = result['data']['workspaces']
meta = result['meta']
print(f"\nWorkspaces: {len(workspaces)} de {meta['total']}")
for ws in workspaces:
print(f" - [{ws['id']}] {ws['name']}")
elif args.action == "get-workspace":
if not args.workspace_id:
print("X Erro: --workspace-id e obrigatorio")
exit(1)
result = client.get_workspace(args.workspace_id)
ws = result['data']
print(f"\nWorkspace: {ws['name']}")
print(f"ID: {ws['id']}")
print(f"Visualizacoes: {len(ws.get('views', []))}")
elif args.action == "get-all-workspaces":
workspaces = client.get_all_workspaces()
print(f"\nTotal: {len(workspaces)} workspaces")
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
json.dump(workspaces, f, indent=2, ensure_ascii=False)
print(f"OK Salvo em {args.output}")
except Exception as e:
logger.error(f"X Erro: {e}")
exit(1)
if __name__ == "__main__":
main()