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
11 changes: 11 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Change Log

## v0.0.2.10

### New Features

- Core: add enum LogLevel
- Core: add method set_log_level to change the log level

### Breaking Changes

- Core: init: parameter for logger has been added, if not provided, a new logger will be created

## v0.0.2.9

### New Features
Expand Down
97 changes: 75 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,46 @@ This module is used to interact with the Xurrent API. It provides a set of class
baseUrl = "https://api.4me.qa/v1"
account = "account-name"

logger = setup_logger(verbose=True)

x_api_helper = XurrentApiHelper(baseUrl, apitoken, account)

# change log level (default: INFO)
x_api_helper.set_log_level("DEBUG")

# Plain API Call
uri = "/requests?subject=Example Subject"
connection_object.api_call(uri, 'GET')

```

### Requests
#### People

```python
from xurrent.people import Person

people = Person.get_by_id(x_api_helper, <id>)

api_user = Person.get_me(x_api_helper)

# get all people with a specific subject
people = Person.get_people(x_api_helper,queryfilter={
"name": "Werner"
})

# enable
people.enable()

#disable
people.disable()
#archive
people.archive()
#trash
people.trash()
#restore
people.restore()

```

#### Requests

```python
from xurrent.requests import Request
Expand Down Expand Up @@ -60,7 +89,7 @@ This module is used to interact with the Xurrent API. It provides a set of class

```

#### Request Notes
##### Request Notes

```python
from xurrent.requests import Request
Expand All @@ -80,24 +109,7 @@ This module is used to interact with the Xurrent API. It provides a set of class

```

### Workflows

```python

from xurrent.workflows import Workflow

workflow = Workflow.get_by_id(x_api_helper, <id>)

#close
workflow.close() # completion reason: completed, note: closed
# close with completion reason
workflow.close(completion_reason="withdrawn")
#close with completion reason and note
workflow.close(completion_reason="withdrawn", note="This is a test note")

```

### Tasks
#### Tasks

```python
from xurrent.tasks import Task
Expand Down Expand Up @@ -125,3 +137,44 @@ This module is used to interact with the Xurrent API. It provides a set of class


```

#### Teams

```python
from xurrent.teams import Team

team = Team.get_by_id(x_api_helper, <id>)

# get all teams with a specific subject
teams = Team.get_team(x_api_helper,predifinedFilter="enabled")

# enable
team.enable()

#disable
team.disable()
#archive
team.archive()
#trash
team.trash()
#restore
team.restore()

```

#### Workflows

```python

from xurrent.workflows import Workflow

workflow = Workflow.get_by_id(x_api_helper, <id>)

#close
workflow.close() # completion reason: completed, note: closed
# close with completion reason
workflow.close(completion_reason="withdrawn")
#close with completion reason and note
workflow.close(completion_reason="withdrawn", note="This is a test note")

```
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "xurrent"
version = "0.0.2.9"
version = "0.0.2.10"
authors = [
{ name="Fabian Steiner", email="fabian@stei-ner.net" },
]
Expand All @@ -18,7 +18,7 @@ Homepage = "https://github.com/fasteiner/xurrent-python"
Issues = "https://github.com/fasteiner/xurrent-python/issues"
[tool.poetry]
name = "xurrent"
version = "0.0.2.9"
version = "0.0.2.10"
description = "A python module to interact with the Xurrent API."
authors = ["Ing. Fabian Franz Steiner BSc. <fabian.steiner@tttech.com>"]
readme = "README.md"
Expand Down
55 changes: 53 additions & 2 deletions src/xurrent/core.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
from __future__ import annotations # Needed for forward references
from datetime import datetime
from enum import Enum
import time
import requests
import logging
import json
import re

class LogLevel(Enum):
DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
ERROR = logging.ERROR
CRITICAL = logging.CRITICAL

class JsonSerializableDict(dict):
def __init__(self, **kwargs):
# Initialize with keyword arguments as dictionary items
Expand Down Expand Up @@ -37,11 +45,23 @@ class XurrentApiHelper:
api_user: Person # Forward declaration with a string
api_user_teams: List[Team] # Forward declaration with a string

def __init__(self, base_url, api_key, api_account, resolve_user=True):
def __init__(self, base_url, api_key, api_account,resolve_user=True, logger: Logger=None):
"""
Initialize the Xurrent API helper.

:param base_url: Base URL of the Xurrent API
:param api_key: API key to authenticate with
:param api_account: Account name to use
:param resolve_user: Resolve the API user and their teams (default: True)
:param logger: Logger to use (optional), otherwise a new logger is created
"""
self.base_url = base_url
self.api_key = api_key
self.api_account = api_account
self.logger = logging.getLogger(__name__)
if logger:
self.logger = logger
else:
self.logger = self.create_logger(False)
if resolve_user:
# Import Person lazily
from .people import Person
Expand Down Expand Up @@ -77,6 +97,37 @@ def __append_per_page(self, uri, per_page=100):
return f'{uri}?per_page={per_page}'
return uri

def create_logger(self, verbose) -> Logger:
"""
Create a logger for the API helper.
:param verbose: Enable verbose logging (debug level)
:return: Logger instance
"""
logger = logging.getLogger()
log_stream = logging.StreamHandler()

if verbose:
logger.setLevel(logging.DEBUG)
log_stream.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
log_stream.setLevel(logging.INFO)

formatter = logging.Formatter('%(levelname)s - %(message)s')
log_stream.setFormatter(formatter)
logger.addHandler(log_stream)
return logger

def set_log_level(self, level: LogLevel):
"""
Set the log level for the logger and all handlers.

:param level: Log level to set
"""
self.logger.setLevel(level)
for handler in self.logger.handlers:
handler.setLevel(level)


def api_call(self, uri: str, method='GET', data=None, per_page=100):
"""
Expand Down
9 changes: 9 additions & 0 deletions src/xurrent/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class RequestStatus(str, Enum):
project_pending = "project_pending" # Project Pending
completed = "completed" # Completed

def __str__(self):
return self.value

class CompletionReason(str, Enum):
solved = "solved" # Solved - Root Cause Analysis Not Required
workaround = "workaround" # Workaround - Root Cause Not Removed
Expand All @@ -45,6 +48,9 @@ class CompletionReason(str, Enum):
declined = "declined" # Declined - Declined by Service Provider
unsolvable = "unsolvable" # Unsolvable - Unable to Solve

def __str__(self):
return self.value


class PredefinedFilter(str, Enum):
completed = "completed" # /requests/completed
Expand All @@ -56,6 +62,9 @@ class PredefinedFilter(str, Enum):
problem_management_review = "problem_management_review" # /requests/problem_management_review
sla_accountability = "sla_accountability" # /requests/sla_accountability

def __str__(self):
return self.value

class PredefinedNotesFilter(str, Enum):
public = "public" # /requests/public
internal = "internal" # /requests/internal
Expand Down
9 changes: 9 additions & 0 deletions tests/integration/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import sys
from dotenv import load_dotenv
import logging

# Add the `../src` directory to sys.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../src")))
Expand Down Expand Up @@ -46,5 +47,13 @@ def test_api_helper_setup(x_api_helper):
assert isinstance(x_api_helper.api_user_teams, list)
for team in x_api_helper.api_user_teams:
assert isinstance(team, Team)

assert x_api_helper.logger.level == logging.INFO

def test_set_log_level(x_api_helper):
x_api_helper.set_log_level("DEBUG")
assert x_api_helper.logger.level == logging.DEBUG
x_api_helper.set_log_level(logging.WARNING)
assert x_api_helper.logger.level == logging.WARNING


Loading