Skip to content
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
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Runnable examples are available in the [`examples/`](./examples) directory:

- [`examples/basic_usage.py`](./examples/basic_usage.py) - Client setup, connections, integrations, and webhooks
- [`examples/proxy_api.py`](./examples/proxy_api.py) - Proxy API GET request with a connection
- [`examples/unify_api.py`](./examples/unify_api.py) - Unify Chat, Git, and PM endpoint usage
- [`examples/unify_api.py`](./examples/unify_api.py) - Unify Chat, Git, and Ticketing endpoint usage
- [`examples/README.md`](./examples/README.md) - Setup and execution instructions

## Quick Start
Expand Down Expand Up @@ -933,20 +933,20 @@ print(f"Releases: {result['data']}")
}
```

#### Project Management API
#### Ticketing API

The PM API provides a unified interface for project management platforms like Jira, Linear, and Asana.
The Ticketing API provides a unified interface for ticketing and project management platforms like Jira, Linear, and Asana.

##### List Issues
##### List Tickets

```python
result = unify.pm.issues({
result = unify.ticketing.tickets({
'limit': 100,
'after': None,
'include_raw': False
})

print(f"Issues: {result['data']}")
print(f"Tickets: {result['data']}")
```

**Response:**
Expand All @@ -973,7 +973,7 @@ print(f"Issues: {result['data']}")
**Filtering and sorting:**

```python
open_issues = [issue for issue in result['data'] if issue['status'] == 'open']
open_tickets = [ticket for ticket in result['data'] if ticket['status'] == 'open']
sorted_by_date = sorted(
result['data'],
key=lambda x: x['created_at'],
Expand Down Expand Up @@ -1045,7 +1045,7 @@ bundleup/
├── base.py # Base Unify class
├── chat.py # Chat Unify API
├── git.py # Git Unify API
└── pm.py # PM Unify API
└── ticketing.py # Ticketing Unify API
tests/ # Test files
```

Expand Down
4 changes: 2 additions & 2 deletions bundleup/unify/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from .chat import Chat
from .git import Git
from .pm import PM
from .ticketing import Ticketing


class Unify:
def __init__(self, api_key: str, connection_id: str):
# Initialize
self.chat = Chat(api_key, connection_id)
self.git = Git(api_key, connection_id)
self.pm = PM(api_key, connection_id)
self.ticketing = Ticketing(api_key, connection_id)
15 changes: 0 additions & 15 deletions bundleup/unify/pm.py

This file was deleted.

15 changes: 15 additions & 0 deletions bundleup/unify/ticketing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from .base import Base


class Ticketing(Base):
def tickets(self, params: dict = None):
"""
List ticketing tickets
"""
url = self._build_url("ticketing/tickets")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Point ticketing calls at the published PM endpoint

The currently published BundleUp Unified API reference still documents the Jira/Linear issue list route as GET /v1/pm/issues (https://bundleup.mintlify.app/api-reference/project-management/list-issues), not /v1/ticketing/tickets. With this path, every unify.ticketing.tickets() call against the documented production API will hit an undocumented route and fail with 404 instead of returning issues, unless the server-side migration is deployed first or a compatibility alias is added.

Useful? React with 👍 / 👎.

response = self._connection.get(url, params=params)

if not response.ok:
raise Exception(f"Failed to fetch ticketing/tickets: {response.status_code}")

return response.json()
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ python examples/unify_api.py

- `basic_usage.py` — initialize the SDK and list connections, integrations, and webhooks
- `proxy_api.py` — send a GET request through the Proxy API
- `unify_api.py` — call Unify Chat, Git, and PM endpoints
- `unify_api.py` — call Unify Chat, Git, and Ticketing endpoints
6 changes: 3 additions & 3 deletions examples/unify_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
print(f"Failed to fetch git repos: {error}")

try:
issues = unify.pm.issues({"limit": 10})
print(f"PM issues: {len(issues.get('data', []))}")
tickets = unify.ticketing.tickets({"limit": 10})
print(f"Ticketing tickets: {len(tickets.get('data', []))}")
except Exception as error:
print(f"Failed to fetch PM issues: {error}")
print(f"Failed to fetch tickets: {error}")
2 changes: 1 addition & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The test suite includes **87 tests** covering all major components of the SDK:

7. **test_unify.py** (15 tests) - Unify API client
- Unify class initialization
- Chat, Git, and PM subclients
- Chat, Git, and Ticketing subclients
- Method signatures and parameters
- Base class configuration

Expand Down
4 changes: 2 additions & 2 deletions tests/test_bundleup.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def test_unify_with_connection_id(self, api_key, connection_id):
assert unify.chat._connection_id == connection_id
assert unify.git._api_key == api_key
assert unify.git._connection_id == connection_id
assert unify.pm._api_key == api_key
assert unify.pm._connection_id == connection_id
assert unify.ticketing._api_key == api_key
assert unify.ticketing._connection_id == connection_id

def test_unify_without_connection_id(self, api_key):
"""Test creating a unify client without connection ID raises exception."""
Expand Down
38 changes: 19 additions & 19 deletions tests/test_unify.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from bundleup.unify import Unify
from bundleup.unify.chat import Chat
from bundleup.unify.git import Git
from bundleup.unify.pm import PM
from bundleup.unify.ticketing import Ticketing


class TestUnifyInitialization:
Expand All @@ -17,7 +17,7 @@ def test_init_with_valid_params(self, api_key, connection_id):

assert isinstance(unify.chat, Chat)
assert isinstance(unify.git, Git)
assert isinstance(unify.pm, PM)
assert isinstance(unify.ticketing, Ticketing)

def test_chat_has_correct_params(self, api_key, connection_id):
"""Test that chat client has correct parameters."""
Expand All @@ -33,12 +33,12 @@ def test_git_has_correct_params(self, api_key, connection_id):
assert unify.git._api_key == api_key
assert unify.git._connection_id == connection_id

def test_pm_has_correct_params(self, api_key, connection_id):
"""Test that pm client has correct parameters."""
def test_ticketing_has_correct_params(self, api_key, connection_id):
"""Test that ticketing client has correct parameters."""
unify = Unify(api_key, connection_id)

assert unify.pm._api_key == api_key
assert unify.pm._connection_id == connection_id
assert unify.ticketing._api_key == api_key
assert unify.ticketing._connection_id == connection_id


class TestChatInitialization:
Expand Down Expand Up @@ -100,23 +100,23 @@ def test_has_releases_method(self, api_key, connection_id):
assert callable(git.releases)


class TestPMInitialization:
"""Test PM class initialization."""
class TestTicketingInitialization:
"""Test Ticketing class initialization."""

def test_init_with_valid_params(self, api_key, connection_id):
"""Test initialization with valid API key and connection ID."""
pm = PM(api_key, connection_id)
ticketing = Ticketing(api_key, connection_id)

assert pm._api_key == api_key
assert pm._connection_id == connection_id
assert pm.base_url == "https://unify.bundleup.io"
assert ticketing._api_key == api_key
assert ticketing._connection_id == connection_id
assert ticketing.base_url == "https://unify.bundleup.io"

def test_has_issues_method(self, api_key, connection_id):
"""Test that PM has issues method."""
pm = PM(api_key, connection_id)
def test_has_tickets_method(self, api_key, connection_id):
"""Test that Ticketing has tickets method."""
ticketing = Ticketing(api_key, connection_id)

assert hasattr(pm, 'issues')
assert callable(pm.issues)
assert hasattr(ticketing, 'tickets')
assert callable(ticketing.tickets)


class TestUnifyBaseClass:
Expand All @@ -126,11 +126,11 @@ def test_base_url_is_set(self, api_key, connection_id):
"""Test that base URL is correctly set."""
chat = Chat(api_key, connection_id)
git = Git(api_key, connection_id)
pm = PM(api_key, connection_id)
ticketing = Ticketing(api_key, connection_id)

assert chat.base_url == "https://unify.bundleup.io"
assert git.base_url == "https://unify.bundleup.io"
assert pm.base_url == "https://unify.bundleup.io"
assert ticketing.base_url == "https://unify.bundleup.io"


class TestUnifyMethodSignatures:
Expand Down
Loading