Hey there, fellow developer! Ready to dive into the world of Workflowy API integration? Let's roll up our sleeves and get coding!
Workflowy's API is a powerful tool that lets you programmatically interact with your outlines. Whether you're looking to automate your workflow or build a custom integration, this guide will walk you through the process. We'll be using Python, so make sure you've got your favorite IDE fired up!
Before we jump in, make sure you've got:
requests
library (pip install requests
)If you're missing any of these, take a quick detour to get set up. Don't worry, we'll wait!
First things first, let's authenticate:
import requests CLIENT_ID = 'your_client_id' CLIENT_SECRET = 'your_client_secret' auth_url = 'https://workflowy.com/api/auth' response = requests.post(auth_url, json={ 'clientId': CLIENT_ID, 'clientSecret': CLIENT_SECRET }) access_token = response.json()['access_token']
Great! Now we've got our access token. Let's set up our base URL:
BASE_URL = 'https://workflowy.com/api/v1' headers = {'Authorization': f'Bearer {access_token}'}
Now for the fun part! Let's start with some basic operations:
response = requests.get(f'{BASE_URL}/outline', headers=headers) outline = response.json()
new_node = { 'name': 'My new node', 'parentId': 'some_parent_id' } response = requests.post(f'{BASE_URL}/nodes', json=new_node, headers=headers)
updated_node = { 'id': 'node_id_to_update', 'name': 'Updated node name' } response = requests.put(f'{BASE_URL}/nodes/{updated_node["id"]}', json=updated_node, headers=headers)
node_id_to_delete = 'some_node_id' response = requests.delete(f'{BASE_URL}/nodes/{node_id_to_delete}', headers=headers)
Ready to level up? Let's tackle some more complex operations:
def add_tag(node_id, tag): node = requests.get(f'{BASE_URL}/nodes/{node_id}', headers=headers).json() node['name'] += f' #{tag}' requests.put(f'{BASE_URL}/nodes/{node_id}', json=node, headers=headers)
def move_node(node_id, new_parent_id): node = {'id': node_id, 'parentId': new_parent_id} requests.put(f'{BASE_URL}/nodes/{node_id}', json=node, headers=headers)
def bulk_create_nodes(parent_id, node_names): nodes = [{'name': name, 'parentId': parent_id} for name in node_names] requests.post(f'{BASE_URL}/nodes/bulk', json={'nodes': nodes}, headers=headers)
Always be prepared for things to go wrong:
def api_request(method, endpoint, **kwargs): try: response = requests.request(method, f'{BASE_URL}/{endpoint}', headers=headers, **kwargs) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"API request failed: {e}") return None
Don't forget about rate limiting! Be kind to the API:
import time def rate_limited_request(*args, **kwargs): response = api_request(*args, **kwargs) if response and 'X-RateLimit-Remaining' in response.headers: if int(response.headers['X-RateLimit-Remaining']) < 10: time.sleep(1) return response
Let's put it all together with a simple CLI tool:
import argparse def main(): parser = argparse.ArgumentParser(description='Workflowy CLI') parser.add_argument('action', choices=['add', 'update', 'delete']) parser.add_argument('node_id', nargs='?') parser.add_argument('--name', '-n') args = parser.parse_args() if args.action == 'add': new_node = {'name': args.name, 'parentId': args.node_id or 'root'} response = api_request('POST', 'nodes', json=new_node) print(f"Node created: {response['id']}") elif args.action == 'update': updated_node = {'id': args.node_id, 'name': args.name} api_request('PUT', f'nodes/{args.node_id}', json=updated_node) print(f"Node updated: {args.node_id}") elif args.action == 'delete': api_request('DELETE', f'nodes/{args.node_id}') print(f"Node deleted: {args.node_id}") if __name__ == '__main__': main()
Don't forget to test your code! Here's a quick example using unittest
and unittest.mock
:
import unittest from unittest.mock import patch from your_module import api_request class TestWorkflowyAPI(unittest.TestCase): @patch('your_module.requests.request') def test_api_request(self, mock_request): mock_request.return_value.json.return_value = {'id': '123'} result = api_request('GET', 'nodes/123') self.assertEqual(result, {'id': '123'}) mock_request.assert_called_once() if __name__ == '__main__': unittest.main()
And there you have it! You've just built a Workflowy API integration in Python. From basic operations to advanced features, you're now equipped to create some seriously cool automations and tools.
Remember, the Workflowy API is your playground. Don't be afraid to experiment and push the boundaries of what's possible. Happy coding, and may your outlines always be organized!
For more details, check out the official Workflowy API documentation. Now go forth and build something awesome!