# XrayClient
A comprehensive Python client for interacting with Xray Cloud's GraphQL API for test management in Jira. This library provides a robust interface for managing test plans, test executions, test runs, defects, evidence, and other Xray-related operations through GraphQL queries and mutations.
## Documentation
- **HTML Documentation**: [View Online](https://github.com/arusatech/xrayclient/tree/main/docs/html)
- **API Reference**: [API Docs](https://github.com/arusatech/xrayclient/tree/main/docs/html/xrayclient.html)
## Features
- **Jira Integration**: Full Jira REST API support for issue management
- **Xray GraphQL API**: Complete Xray Cloud GraphQL API integration
- **Test Management**: Create and manage test plans, test executions, and test runs
- **Evidence Management**: Add attachments and evidence to test runs
- **Defect Management**: Create defects from failed test runs
- **Authentication**: Secure authentication with both Jira and Xray Cloud
- **Error Handling**: Comprehensive error handling and logging
- **Type Hints**: Full type annotation support for better development experience
## Installation
```bash
pip install xrayclient
```
Or install from source:
```bash
git clone https://github.com/arusatech/xrayclient.git
cd xrayclient
pip install -e .
```
## Quick Start
### Basic Setup
```python
from xrayclient.xray_client import XrayGraphQL
# Initialize the client
client = XrayGraphQL()
```
### Environment Variables
Create a `.env` file in your project root with the following variables:
```env
# Jira Configuration
JIRA_SERVER=https://your-instance.atlassian.net
JIRA_USER=your-email@company.com
JIRA_API_KEY=your-jira-api-key
# Xray Cloud Configuration
XRAY_CLIENT_ID=your-xray-client-id
XRAY_CLIENT_SECRET=your-xray-client-secret
XRAY_BASE_URL=https://us.xray.cloud.getxray.app
```
## Usage Examples
### Test Plan Operations
```python
# Get all tests from a test plan
test_plan_tests = client.get_tests_from_test_plan("TEST-123")
print(test_plan_tests)
# Output: {'TEST-124': '10001', 'TEST-125': '10002'}
# Get test plan data with parsed tables
test_plan_data = client.get_test_plan_data("TEST-123")
print(test_plan_data)
```
### Test Execution Management
```python
# Create a test execution from a test plan
test_execution = client.create_test_execution_from_test_plan("TEST-123")
print(test_execution)
# Output: {
# 'TEST-124': {
# 'test_run_id': '5f7c3',
# 'test_execution_key': 'TEST-456',
# 'test_plan_key': 'TEST-123'
# }
# }
# Create a test execution with specific tests
test_execution = client.create_test_execution(
test_issue_keys=["TEST-124", "TEST-125"],
project_key="PROJ",
summary="Regression Test Execution",
description="Testing critical features"
)
```
### Test Run Operations
```python
# Get test run status
status, run_id = client.get_test_runstatus("TEST-124", "TEST-456")
print(f"Status: {status}, Run ID: {run_id}")
# Update test run status
success = client.update_test_run_status("test_run_id", "PASS")
print(success) # True
# Update test run comment
success = client.update_test_run_comment("test_run_id", "Test passed successfully")
print(success) # True
# Append to existing comment
success = client.append_test_run_comment("test_run_id", "Additional notes")
print(success) # True
```
### Evidence and Defect Management
```python
# Add evidence to a test run
evidence_added = client.add_evidence_to_test_run("test_run_id", "/path/to/screenshot.png")
print(evidence_added) # True
# Create a defect from a failed test run
defect = client.create_defect_from_test_run(
test_run_id="test_run_id",
project_key="PROJ",
parent_issue_key="TEST-456",
defect_summary="Login functionality broken",
defect_description="Users cannot log in with valid credentials"
)
print(defect)
```
### Test Set Operations
```python
# Get tests from a test set
test_set_tests = client.get_tests_from_test_set("TESTSET-123")
print(test_set_tests)
# Filter test sets by test case
test_sets = client.filter_test_set_by_test_case("TEST-124")
print(test_sets)
# Get tags for a test case
tags = client.filter_tags_by_test_case("TEST-124")
print(tags)
```
### Jira Issue Management
```python
# Create a new Jira issue
issue_key, issue_id = client.create_issue(
project_key="PROJ",
summary="New feature implementation",
description="Implement new login flow",
issue_type="Story",
priority="High",
labels=["feature", "login"],
attachments=["/path/to/screenshot.png"]
)
print(f"Created issue {issue_key} with ID {issue_id}")
# Get issue details
issue = client.get_issue("PROJ-123", fields=["summary", "status", "assignee"])
print(f"Issue: {issue['summary']} - Status: {issue['status']['name']}")
# Update issue summary
success = client.update_issue_summary("PROJ-123", "Updated summary")
print(success) # True
```
## API Reference
### JiraHandler Class
The base class providing Jira REST API functionality.
#### Methods
- `create_issue(project_key, summary, description, **kwargs)` - Create a new Jira issue
- `get_issue(issue_key, fields=None)` - Retrieve a Jira issue
- `update_issue_summary(issue_key, new_summary)` - Update issue summary
- `make_jira_request(jira_key, url, method, payload, **kwargs)` - Make custom Jira requests
- `download_jira_attachment_by_id(attachment_id, mime_type)` - Download attachments
### XrayGraphQL Class
Extends JiraHandler to provide Xray Cloud GraphQL API functionality.
#### Authentication & Setup
- `__init__()` - Initialize XrayGraphQL client
- `_get_auth_token()` - Authenticate with Xray Cloud API
- `_make_graphql_request(query, variables)` - Make GraphQL requests
#### Test Plan Operations
- `get_tests_from_test_plan(test_plan)` - Get tests from test plan
- `get_test_plan_data(test_plan)` - Get parsed test plan data
#### Test Set Operations
- `get_tests_from_test_set(test_set)` - Get tests from test set
- `filter_test_set_by_test_case(test_key)` - Filter test sets by test case
- `filter_tags_by_test_case(test_key)` - Get tags for test case
#### Test Execution Operations
- `get_tests_from_test_execution(test_execution)` - Get tests from test execution
- `get_test_execution(test_execution)` - Get detailed test execution info
- `create_test_execution(test_issue_keys, project_key, summary, description)` - Create test execution
- `create_test_execution_from_test_plan(test_plan)` - Create test execution from plan
- `add_test_execution_to_test_plan(test_plan, test_execution)` - Add execution to plan
#### Test Run Operations
- `get_test_runstatus(test_case, test_execution)` - Get test run status
- `get_test_run_by_id(test_case_id, test_execution_id)` - Get test run by ID
- `update_test_run_status(test_run_id, test_run_status)` - Update test run status
- `update_test_run_comment(test_run_id, test_run_comment)` - Update test run comment
- `get_test_run_comment(test_run_id)` - Get test run comment
- `append_test_run_comment(test_run_id, test_run_comment)` - Append to comment
#### Evidence & Defect Management
- `add_evidence_to_test_run(test_run_id, evidence_path)` - Add evidence
- `create_defect_from_test_run(test_run_id, project_key, parent_issue_key, defect_summary, defect_description)` - Create defect
## Requirements
- Python >= 3.12
- jira >= 3.10.5, < 4.0.0
- jsonpath-nz >= 1.0.6, < 2.0.0
- requests >= 2.31.0, < 3.0.0
## Development
### Setup Development Environment
```bash
git clone https://github.com/arusatech/xrayclient.git
cd xrayclient
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=xrayclient --cov-report=html
# Run specific test categories
pytest -m unit
pytest -m integration
pytest -m slow
```
### Code Quality
The project uses:
- **pytest** for testing
- **pytest-cov** for coverage reporting
- **pytest-mock** for mocking in tests
- **Type hints** for better code documentation
## Error Handling
The library implements comprehensive error handling:
- All methods return `None` for failed operations instead of raising exceptions
- Detailed logging for debugging and error tracking
- Automatic retry logic for transient failures
- Graceful handling of authentication failures
## Security
- Uses environment variables for sensitive configuration
- Supports API key authentication for both Jira and Xray
- Implements proper token management and refresh
- Handles secure file uploads for evidence
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Ensure all tests pass
6. Submit a pull request
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
For support and questions:
- Create an issue on GitHub
- Contact: yakub@arusatech.com
## Changelog
### Version 0.1.0
- Initial release
- Jira REST API integration
- Xray Cloud GraphQL API integration
- Complete test management functionality
- Evidence and defect management
- Comprehensive error handling and logging
## Step 1: Install pdoc
```bash
# Install pdoc
poetry add --group dev pdoc
# Or with pip
pip install pdoc
```
## Step 2: Update pyproject.toml to include pdoc
```toml:pyproject.toml
[project]
name = "xrayclient"
version = "0.1.0"
description = "Python Client for Xray Test Management for Jira"
authors = [
{name = "yakub@arusatech.com"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"jira (>=3.10.5,<4.0.0)",
"jsonpath-nz (>=1.0.6,<2.0.0)",
"requests (>=2.31.0,<3.0.0)"
]
[tool.poetry]
name = "xrayclient"
version = "0.1.0"
description = "Python Client for Xray Test Management for Jira"
authors = ["yakub@arusatech.com"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/arusatech/xrayclient"
repository = "https://github.com/arusatech/xrayclient"
keywords = ["xray", "jira", "test-management", "graphql", "api-client"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Testing",
"Topic :: Software Development :: Libraries :: Python Modules",
]
packages = [{include = "xrayclient"}]
[tool.poetry.dependencies]
python = "^3.12"
jira = "^3.10.5"
jsonpath-nz = "^1.0.6"
requests = "^2.31.0"
[tool.poetry.group.dev.dependencies]
pytest = "^8.4.1"
pytest-cov = "^4.1.0"
pytest-mock = "^3.11.1"
pdoc = "^14.4.0"
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--verbose",
"--tb=short",
"--strict-markers",
"--disable-warnings",
"--cov=xrayclient",
"--cov-report=term-missing",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml"
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Slow running tests"
]
[tool.pdoc]
# pdoc configuration
docformat = "google"
template_directory = "docs/templates"
output_directory = "docs/html"
```
## Step 3: Create Documentation Directory Structure
```bash
# Create documentation directories
mkdir -p docs/html
mkdir -p docs/templates
```
## Step 4: Create a Custom pdoc Template (Optional)
Create `docs/templates/head.html` for custom styling:
```html:docs/templates/head.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{{ module_name }}{% endblock %} - XrayClient Documentation</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2rem;
border-radius: 8px;
margin-bottom: 2rem;
}
.header h1 {
margin: 0;
font-size: 2.5rem;
}
.header p {
margin: 0.5rem 0 0 0;
opacity: 0.9;
}
.content {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
pre {
background: #f5f5f5;
padding: 1rem;
border-radius: 4px;
overflow-x: auto;
}
code {
background: #f0f0f0;
padding: 0.2rem 0.4rem;
border-radius: 3px;
font-family: 'Monaco', 'Menlo', monospace;
}
.method {
margin-bottom: 2rem;
padding: 1rem;
border-left: 4px solid #667eea;
background: #f8f9fa;
}
.method h3 {
margin-top: 0;
color: #667eea;
}
</style>
</head>
<body>
<div class="header">
<h1>XrayClient Documentation</h1>
<p>Python Client for Xray Test Management for Jira</p>
</div>
<div class="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
```
## Step 5: Generate Documentation
```bash
# Generate HTML documentation
poetry run pdoc --html --output-dir docs/html xrayclient
# Or with more options
poetry run pdoc --html --output-dir docs/html --template-dir docs/templates xrayclient
```
## Step 6: Create a Documentation Script
Create `scripts/generate_docs.py`:
```python:scripts/generate_docs.py
#!/usr/bin/env python3
"""
Script to generate documentation using pdoc.
"""
import subprocess
import sys
import os
from pathlib import Path
def generate_docs():
"""Generate HTML documentation using pdoc."""
# Get project root
project_root = Path(__file__).parent.parent
# Create docs directory if it doesn't exist
docs_dir = project_root / "docs" / "html"
docs_dir.mkdir(parents=True, exist_ok=True)
# Run pdoc
cmd = [
sys.executable, "-m", "pdoc",
"--html",
"--output-dir", str(docs_dir),
"--template-dir", str(project_root / "docs" / "templates"),
"xrayclient"
]
print("Generating documentation...")
result = subprocess.run(cmd, cwd=project_root)
if result.returncode == 0:
print(f"Documentation generated successfully in {docs_dir}")
print(f"Open {docs_dir / 'xrayclient.html'} in your browser to view the docs")
else:
print("Failed to generate documentation")
sys.exit(1)
if __name__ == "__main__":
generate_docs()
```
## Step 7: Add Documentation to PyPI Package
Update your `pyproject.toml` to include documentation files:
```toml:pyproject.toml
[project]
name = "xrayclient"
version = "0.1.0"
description = "Python Client for Xray Test Management for Jira"
authors = [
{name = "yakub@arusatech.com"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"jira (>=3.10.5,<4.0.0)",
"jsonpath-nz (>=1.0.6,<2.0.0)",
"requests (>=2.31.0,<3.0.0)"
]
[tool.poetry]
name = "xrayclient"
version = "0.1.0"
description = "Python Client for Xray Test Management for Jira"
authors = ["yakub@arusatech.com"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/arusatech/xrayclient"
repository = "https://github.com/arusatech/xrayclient"
documentation = "https://arusatech.github.io/xrayclient/"
keywords = ["xray", "jira", "test-management", "graphql", "api-client"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Testing",
"Topic :: Software Development :: Libraries :: Python Modules",
]
packages = [{include = "xrayclient"}]
include = [
"docs/html/**/*",
"README.md",
"LICENSE"
]
[tool.poetry.dependencies]
python = "^3.12"
jira = "^3.10.5"
jsonpath-nz = "^1.0.6"
requests = "^2.31.0"
[tool.poetry.group.dev.dependencies]
pytest = "^8.4.1"
pytest-cov = "^4.1.0"
pytest-mock = "^3.11.1"
pdoc = "^14.4.0"
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--verbose",
"--tb=short",
"--strict-markers",
"--disable-warnings",
"--cov=xrayclient",
"--cov-report=term-missing",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml"
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Slow running tests"
]
[tool.pdoc]
docformat = "google"
template_directory = "docs/templates"
output_directory = "docs/html"
```
## Step 8: Create a MANIFEST.in file
Create `MANIFEST.in` to ensure documentation is included:
```text:MANIFEST.in
include README.md
include LICENSE
include CHANGELOG.md
recursive-include docs/html *
recursive-include docs/templates *
```
## Step 9: Update .gitignore
```gitignore:.gitignore
# Add these lines to your existing .gitignore
dist/
build/
*.egg-info/
.pytest_cache/
htmlcov/
coverage.xml
# Don't ignore docs/html (we want to include it in the package)
!docs/html/
```
## Step 10: Create a Documentation Generation Workflow
Create `.github/workflows/docs.yml`:
```yaml:.github/workflows/docs.yml
name: Generate Documentation
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: poetry install
- name: Generate documentation
run: poetry run python scripts/generate_docs.py
- name: Upload documentation artifacts
uses: actions/upload-artifact@v3
with:
name: documentation
path: docs/html/
```
## Step 11: Update README.md with Documentation Links
```markdown:README.md
<code_block_to_apply_changes_from>
```
## Step 12: Build and Publish with Documentation
```bash
# Generate documentation first
poetry run python scripts/generate_docs.py
# Build package (includes documentation)
poetry build
# Publish to PyPI
poetry publish
```
## Step 13: Alternative: Host Documentation on GitHub Pages
Create `.github/workflows/docs-pages.yml`:
```yaml:.github/workflows/docs-pages.yml
name: Deploy Documentation to GitHub Pages
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: poetry install
- name: Generate documentation
run: poetry run python scripts/generate_docs.py
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: docs/html/
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
```
## Step 14: Update pyproject.toml with GitHub Pages URL
```toml:pyproject.toml
[tool.poetry]
# ... existing configuration ...
documentation = "https://arusatech.github.io/xrayclient/"
# ... rest of configuration ...
```
## Complete Documentation Workflow
1. **Generate docs**: `poetry run python scripts/generate_docs.py`
2. **Build package**: `poetry build` (includes docs)
3. **Publish**: `poetry publish`
4. **Deploy to GitHub Pages**: Automatic via GitHub Actions
## Benefits of This Approach
1. **Documentation included in PyPI package** - Users get docs with the package
2. **Automated generation** - Docs are always up-to-date
3. **GitHub Pages hosting** - Public documentation website
4. **Custom styling** - Professional-looking documentation
5. **Version control** - Docs are tracked with code
This setup provides comprehensive documentation that's both included in your PyPI package and hosted online for easy access.
Raw data
{
"_id": null,
"home_page": "https://github.com/arusatech/xrayclient",
"name": "xrayclient",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "xray, jira, test-management, graphql, api-client",
"author": "yakub@arusatech.com",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/2c/cc/49544341f286b8fa87efdccdb4dea64681872e12a81e40c0e85b7f7d8999/xrayclient-0.1.3.tar.gz",
"platform": null,
"description": "# XrayClient\n\nA comprehensive Python client for interacting with Xray Cloud's GraphQL API for test management in Jira. This library provides a robust interface for managing test plans, test executions, test runs, defects, evidence, and other Xray-related operations through GraphQL queries and mutations.\n\n## Documentation\n\n- **HTML Documentation**: [View Online](https://github.com/arusatech/xrayclient/tree/main/docs/html)\n- **API Reference**: [API Docs](https://github.com/arusatech/xrayclient/tree/main/docs/html/xrayclient.html)\n\n## Features\n\n- **Jira Integration**: Full Jira REST API support for issue management\n- **Xray GraphQL API**: Complete Xray Cloud GraphQL API integration\n- **Test Management**: Create and manage test plans, test executions, and test runs\n- **Evidence Management**: Add attachments and evidence to test runs\n- **Defect Management**: Create defects from failed test runs\n- **Authentication**: Secure authentication with both Jira and Xray Cloud\n- **Error Handling**: Comprehensive error handling and logging\n- **Type Hints**: Full type annotation support for better development experience\n\n## Installation\n\n```bash\npip install xrayclient\n```\n\nOr install from source:\n\n```bash\ngit clone https://github.com/arusatech/xrayclient.git\ncd xrayclient\npip install -e .\n```\n\n## Quick Start\n\n### Basic Setup\n\n```python\nfrom xrayclient.xray_client import XrayGraphQL\n\n# Initialize the client\nclient = XrayGraphQL()\n```\n\n### Environment Variables\n\nCreate a `.env` file in your project root with the following variables:\n\n```env\n# Jira Configuration\nJIRA_SERVER=https://your-instance.atlassian.net\nJIRA_USER=your-email@company.com\nJIRA_API_KEY=your-jira-api-key\n\n# Xray Cloud Configuration\nXRAY_CLIENT_ID=your-xray-client-id\nXRAY_CLIENT_SECRET=your-xray-client-secret\nXRAY_BASE_URL=https://us.xray.cloud.getxray.app\n```\n\n## Usage Examples\n\n### Test Plan Operations\n\n```python\n# Get all tests from a test plan\ntest_plan_tests = client.get_tests_from_test_plan(\"TEST-123\")\nprint(test_plan_tests)\n# Output: {'TEST-124': '10001', 'TEST-125': '10002'}\n\n# Get test plan data with parsed tables\ntest_plan_data = client.get_test_plan_data(\"TEST-123\")\nprint(test_plan_data)\n```\n\n### Test Execution Management\n\n```python\n# Create a test execution from a test plan\ntest_execution = client.create_test_execution_from_test_plan(\"TEST-123\")\nprint(test_execution)\n# Output: {\n# 'TEST-124': {\n# 'test_run_id': '5f7c3',\n# 'test_execution_key': 'TEST-456',\n# 'test_plan_key': 'TEST-123'\n# }\n# }\n\n# Create a test execution with specific tests\ntest_execution = client.create_test_execution(\n test_issue_keys=[\"TEST-124\", \"TEST-125\"],\n project_key=\"PROJ\",\n summary=\"Regression Test Execution\",\n description=\"Testing critical features\"\n)\n```\n\n### Test Run Operations\n\n```python\n# Get test run status\nstatus, run_id = client.get_test_runstatus(\"TEST-124\", \"TEST-456\")\nprint(f\"Status: {status}, Run ID: {run_id}\")\n\n# Update test run status\nsuccess = client.update_test_run_status(\"test_run_id\", \"PASS\")\nprint(success) # True\n\n# Update test run comment\nsuccess = client.update_test_run_comment(\"test_run_id\", \"Test passed successfully\")\nprint(success) # True\n\n# Append to existing comment\nsuccess = client.append_test_run_comment(\"test_run_id\", \"Additional notes\")\nprint(success) # True\n```\n\n### Evidence and Defect Management\n\n```python\n# Add evidence to a test run\nevidence_added = client.add_evidence_to_test_run(\"test_run_id\", \"/path/to/screenshot.png\")\nprint(evidence_added) # True\n\n# Create a defect from a failed test run\ndefect = client.create_defect_from_test_run(\n test_run_id=\"test_run_id\",\n project_key=\"PROJ\",\n parent_issue_key=\"TEST-456\",\n defect_summary=\"Login functionality broken\",\n defect_description=\"Users cannot log in with valid credentials\"\n)\nprint(defect)\n```\n\n### Test Set Operations\n\n```python\n# Get tests from a test set\ntest_set_tests = client.get_tests_from_test_set(\"TESTSET-123\")\nprint(test_set_tests)\n\n# Filter test sets by test case\ntest_sets = client.filter_test_set_by_test_case(\"TEST-124\")\nprint(test_sets)\n\n# Get tags for a test case\ntags = client.filter_tags_by_test_case(\"TEST-124\")\nprint(tags)\n```\n\n### Jira Issue Management\n\n```python\n# Create a new Jira issue\nissue_key, issue_id = client.create_issue(\n project_key=\"PROJ\",\n summary=\"New feature implementation\",\n description=\"Implement new login flow\",\n issue_type=\"Story\",\n priority=\"High\",\n labels=[\"feature\", \"login\"],\n attachments=[\"/path/to/screenshot.png\"]\n)\nprint(f\"Created issue {issue_key} with ID {issue_id}\")\n\n# Get issue details\nissue = client.get_issue(\"PROJ-123\", fields=[\"summary\", \"status\", \"assignee\"])\nprint(f\"Issue: {issue['summary']} - Status: {issue['status']['name']}\")\n\n# Update issue summary\nsuccess = client.update_issue_summary(\"PROJ-123\", \"Updated summary\")\nprint(success) # True\n```\n\n## API Reference\n\n### JiraHandler Class\n\nThe base class providing Jira REST API functionality.\n\n#### Methods\n\n- `create_issue(project_key, summary, description, **kwargs)` - Create a new Jira issue\n- `get_issue(issue_key, fields=None)` - Retrieve a Jira issue\n- `update_issue_summary(issue_key, new_summary)` - Update issue summary\n- `make_jira_request(jira_key, url, method, payload, **kwargs)` - Make custom Jira requests\n- `download_jira_attachment_by_id(attachment_id, mime_type)` - Download attachments\n\n### XrayGraphQL Class\n\nExtends JiraHandler to provide Xray Cloud GraphQL API functionality.\n\n#### Authentication & Setup\n- `__init__()` - Initialize XrayGraphQL client\n- `_get_auth_token()` - Authenticate with Xray Cloud API\n- `_make_graphql_request(query, variables)` - Make GraphQL requests\n\n#### Test Plan Operations\n- `get_tests_from_test_plan(test_plan)` - Get tests from test plan\n- `get_test_plan_data(test_plan)` - Get parsed test plan data\n\n#### Test Set Operations\n- `get_tests_from_test_set(test_set)` - Get tests from test set\n- `filter_test_set_by_test_case(test_key)` - Filter test sets by test case\n- `filter_tags_by_test_case(test_key)` - Get tags for test case\n\n#### Test Execution Operations\n- `get_tests_from_test_execution(test_execution)` - Get tests from test execution\n- `get_test_execution(test_execution)` - Get detailed test execution info\n- `create_test_execution(test_issue_keys, project_key, summary, description)` - Create test execution\n- `create_test_execution_from_test_plan(test_plan)` - Create test execution from plan\n- `add_test_execution_to_test_plan(test_plan, test_execution)` - Add execution to plan\n\n#### Test Run Operations\n- `get_test_runstatus(test_case, test_execution)` - Get test run status\n- `get_test_run_by_id(test_case_id, test_execution_id)` - Get test run by ID\n- `update_test_run_status(test_run_id, test_run_status)` - Update test run status\n- `update_test_run_comment(test_run_id, test_run_comment)` - Update test run comment\n- `get_test_run_comment(test_run_id)` - Get test run comment\n- `append_test_run_comment(test_run_id, test_run_comment)` - Append to comment\n\n#### Evidence & Defect Management\n- `add_evidence_to_test_run(test_run_id, evidence_path)` - Add evidence\n- `create_defect_from_test_run(test_run_id, project_key, parent_issue_key, defect_summary, defect_description)` - Create defect\n\n## Requirements\n\n- Python >= 3.12\n- jira >= 3.10.5, < 4.0.0\n- jsonpath-nz >= 1.0.6, < 2.0.0\n- requests >= 2.31.0, < 3.0.0\n\n## Development\n\n### Setup Development Environment\n\n```bash\ngit clone https://github.com/arusatech/xrayclient.git\ncd xrayclient\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=xrayclient --cov-report=html\n\n# Run specific test categories\npytest -m unit\npytest -m integration\npytest -m slow\n```\n\n### Code Quality\n\nThe project uses:\n- **pytest** for testing\n- **pytest-cov** for coverage reporting\n- **pytest-mock** for mocking in tests\n- **Type hints** for better code documentation\n\n## Error Handling\n\nThe library implements comprehensive error handling:\n\n- All methods return `None` for failed operations instead of raising exceptions\n- Detailed logging for debugging and error tracking\n- Automatic retry logic for transient failures\n- Graceful handling of authentication failures\n\n## Security\n\n- Uses environment variables for sensitive configuration\n- Supports API key authentication for both Jira and Xray\n- Implements proper token management and refresh\n- Handles secure file uploads for evidence\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests for new functionality\n5. Ensure all tests pass\n6. Submit a pull request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Support\n\nFor support and questions:\n- Create an issue on GitHub\n- Contact: yakub@arusatech.com\n\n## Changelog\n\n### Version 0.1.0\n- Initial release\n- Jira REST API integration\n- Xray Cloud GraphQL API integration\n- Complete test management functionality\n- Evidence and defect management\n- Comprehensive error handling and logging\n\n## Step 1: Install pdoc\n\n```bash\n# Install pdoc\npoetry add --group dev pdoc\n\n# Or with pip\npip install pdoc\n```\n\n## Step 2: Update pyproject.toml to include pdoc\n\n```toml:pyproject.toml\n[project]\nname = \"xrayclient\"\nversion = \"0.1.0\"\ndescription = \"Python Client for Xray Test Management for Jira\"\nauthors = [\n {name = \"yakub@arusatech.com\"}\n]\nlicense = {text = \"MIT\"}\nreadme = \"README.md\"\nrequires-python = \">=3.12\"\ndependencies = [\n \"jira (>=3.10.5,<4.0.0)\",\n \"jsonpath-nz (>=1.0.6,<2.0.0)\",\n \"requests (>=2.31.0,<3.0.0)\"\n]\n\n[tool.poetry]\nname = \"xrayclient\"\nversion = \"0.1.0\"\ndescription = \"Python Client for Xray Test Management for Jira\"\nauthors = [\"yakub@arusatech.com\"]\nlicense = \"MIT\"\nreadme = \"README.md\"\nhomepage = \"https://github.com/arusatech/xrayclient\"\nrepository = \"https://github.com/arusatech/xrayclient\"\nkeywords = [\"xray\", \"jira\", \"test-management\", \"graphql\", \"api-client\"]\nclassifiers = [\n \"Development Status :: 4 - Beta\",\n \"Intended Audience :: Developers\",\n \"License :: OSI Approved :: MIT License\",\n \"Operating System :: OS Independent\",\n \"Programming Language :: Python :: 3\",\n \"Programming Language :: Python :: 3.12\",\n \"Programming Language :: Python :: 3.13\",\n \"Topic :: Software Development :: Testing\",\n \"Topic :: Software Development :: Libraries :: Python Modules\",\n]\npackages = [{include = \"xrayclient\"}]\n\n[tool.poetry.dependencies]\npython = \"^3.12\"\njira = \"^3.10.5\"\njsonpath-nz = \"^1.0.6\"\nrequests = \"^2.31.0\"\n\n[tool.poetry.group.dev.dependencies]\npytest = \"^8.4.1\"\npytest-cov = \"^4.1.0\"\npytest-mock = \"^3.11.1\"\npdoc = \"^14.4.0\"\n\n[build-system]\nrequires = [\"poetry-core>=2.0.0,<3.0.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\npython_files = [\"test_*.py\"]\npython_classes = [\"Test*\"]\npython_functions = [\"test_*\"]\naddopts = [\n \"--verbose\",\n \"--tb=short\",\n \"--strict-markers\",\n \"--disable-warnings\",\n \"--cov=xrayclient\",\n \"--cov-report=term-missing\",\n \"--cov-report=html:htmlcov\",\n \"--cov-report=xml:coverage.xml\"\n]\nmarkers = [\n \"unit: Unit tests\",\n \"integration: Integration tests\",\n \"slow: Slow running tests\"\n]\n\n[tool.pdoc]\n# pdoc configuration\ndocformat = \"google\"\ntemplate_directory = \"docs/templates\"\noutput_directory = \"docs/html\"\n```\n\n## Step 3: Create Documentation Directory Structure\n\n```bash\n# Create documentation directories\nmkdir -p docs/html\nmkdir -p docs/templates\n```\n\n## Step 4: Create a Custom pdoc Template (Optional)\n\nCreate `docs/templates/head.html` for custom styling:\n\n```html:docs/templates/head.html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>{% block title %}{{ module_name }}{% endblock %} - XrayClient Documentation</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n line-height: 1.6;\n color: #333;\n max-width: 1200px;\n margin: 0 auto;\n padding: 20px;\n }\n .header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n padding: 2rem;\n border-radius: 8px;\n margin-bottom: 2rem;\n }\n .header h1 {\n margin: 0;\n font-size: 2.5rem;\n }\n .header p {\n margin: 0.5rem 0 0 0;\n opacity: 0.9;\n }\n .content {\n background: white;\n padding: 2rem;\n border-radius: 8px;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n }\n pre {\n background: #f5f5f5;\n padding: 1rem;\n border-radius: 4px;\n overflow-x: auto;\n }\n code {\n background: #f0f0f0;\n padding: 0.2rem 0.4rem;\n border-radius: 3px;\n font-family: 'Monaco', 'Menlo', monospace;\n }\n .method {\n margin-bottom: 2rem;\n padding: 1rem;\n border-left: 4px solid #667eea;\n background: #f8f9fa;\n }\n .method h3 {\n margin-top: 0;\n color: #667eea;\n }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>XrayClient Documentation</h1>\n <p>Python Client for Xray Test Management for Jira</p>\n </div>\n <div class=\"content\">\n {% block content %}{% endblock %}\n </div>\n</body>\n</html>\n```\n\n## Step 5: Generate Documentation\n\n```bash\n# Generate HTML documentation\npoetry run pdoc --html --output-dir docs/html xrayclient\n\n# Or with more options\npoetry run pdoc --html --output-dir docs/html --template-dir docs/templates xrayclient\n```\n\n## Step 6: Create a Documentation Script\n\nCreate `scripts/generate_docs.py`:\n\n```python:scripts/generate_docs.py\n#!/usr/bin/env python3\n\"\"\"\nScript to generate documentation using pdoc.\n\"\"\"\n\nimport subprocess\nimport sys\nimport os\nfrom pathlib import Path\n\ndef generate_docs():\n \"\"\"Generate HTML documentation using pdoc.\"\"\"\n \n # Get project root\n project_root = Path(__file__).parent.parent\n \n # Create docs directory if it doesn't exist\n docs_dir = project_root / \"docs\" / \"html\"\n docs_dir.mkdir(parents=True, exist_ok=True)\n \n # Run pdoc\n cmd = [\n sys.executable, \"-m\", \"pdoc\",\n \"--html\",\n \"--output-dir\", str(docs_dir),\n \"--template-dir\", str(project_root / \"docs\" / \"templates\"),\n \"xrayclient\"\n ]\n \n print(\"Generating documentation...\")\n result = subprocess.run(cmd, cwd=project_root)\n \n if result.returncode == 0:\n print(f\"Documentation generated successfully in {docs_dir}\")\n print(f\"Open {docs_dir / 'xrayclient.html'} in your browser to view the docs\")\n else:\n print(\"Failed to generate documentation\")\n sys.exit(1)\n\nif __name__ == \"__main__\":\n generate_docs()\n```\n\n## Step 7: Add Documentation to PyPI Package\n\nUpdate your `pyproject.toml` to include documentation files:\n\n```toml:pyproject.toml\n[project]\nname = \"xrayclient\"\nversion = \"0.1.0\"\ndescription = \"Python Client for Xray Test Management for Jira\"\nauthors = [\n {name = \"yakub@arusatech.com\"}\n]\nlicense = {text = \"MIT\"}\nreadme = \"README.md\"\nrequires-python = \">=3.12\"\ndependencies = [\n \"jira (>=3.10.5,<4.0.0)\",\n \"jsonpath-nz (>=1.0.6,<2.0.0)\",\n \"requests (>=2.31.0,<3.0.0)\"\n]\n\n[tool.poetry]\nname = \"xrayclient\"\nversion = \"0.1.0\"\ndescription = \"Python Client for Xray Test Management for Jira\"\nauthors = [\"yakub@arusatech.com\"]\nlicense = \"MIT\"\nreadme = \"README.md\"\nhomepage = \"https://github.com/arusatech/xrayclient\"\nrepository = \"https://github.com/arusatech/xrayclient\"\ndocumentation = \"https://arusatech.github.io/xrayclient/\"\nkeywords = [\"xray\", \"jira\", \"test-management\", \"graphql\", \"api-client\"]\nclassifiers = [\n \"Development Status :: 4 - Beta\",\n \"Intended Audience :: Developers\",\n \"License :: OSI Approved :: MIT License\",\n \"Operating System :: OS Independent\",\n \"Programming Language :: Python :: 3\",\n \"Programming Language :: Python :: 3.12\",\n \"Programming Language :: Python :: 3.13\",\n \"Topic :: Software Development :: Testing\",\n \"Topic :: Software Development :: Libraries :: Python Modules\",\n]\npackages = [{include = \"xrayclient\"}]\ninclude = [\n \"docs/html/**/*\",\n \"README.md\",\n \"LICENSE\"\n]\n\n[tool.poetry.dependencies]\npython = \"^3.12\"\njira = \"^3.10.5\"\njsonpath-nz = \"^1.0.6\"\nrequests = \"^2.31.0\"\n\n[tool.poetry.group.dev.dependencies]\npytest = \"^8.4.1\"\npytest-cov = \"^4.1.0\"\npytest-mock = \"^3.11.1\"\npdoc = \"^14.4.0\"\n\n[build-system]\nrequires = [\"poetry-core>=2.0.0,<3.0.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\npython_files = [\"test_*.py\"]\npython_classes = [\"Test*\"]\npython_functions = [\"test_*\"]\naddopts = [\n \"--verbose\",\n \"--tb=short\",\n \"--strict-markers\",\n \"--disable-warnings\",\n \"--cov=xrayclient\",\n \"--cov-report=term-missing\",\n \"--cov-report=html:htmlcov\",\n \"--cov-report=xml:coverage.xml\"\n]\nmarkers = [\n \"unit: Unit tests\",\n \"integration: Integration tests\",\n \"slow: Slow running tests\"\n]\n\n[tool.pdoc]\ndocformat = \"google\"\ntemplate_directory = \"docs/templates\"\noutput_directory = \"docs/html\"\n```\n\n## Step 8: Create a MANIFEST.in file\n\nCreate `MANIFEST.in` to ensure documentation is included:\n\n```text:MANIFEST.in\ninclude README.md\ninclude LICENSE\ninclude CHANGELOG.md\nrecursive-include docs/html *\nrecursive-include docs/templates *\n```\n\n## Step 9: Update .gitignore\n\n```gitignore:.gitignore\n# Add these lines to your existing .gitignore\ndist/\nbuild/\n*.egg-info/\n.pytest_cache/\nhtmlcov/\ncoverage.xml\n\n# Don't ignore docs/html (we want to include it in the package)\n!docs/html/\n```\n\n## Step 10: Create a Documentation Generation Workflow\n\nCreate `.github/workflows/docs.yml`:\n\n```yaml:.github/workflows/docs.yml\nname: Generate Documentation\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n docs:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n \n - name: Set up Python\n uses: actions/setup-python@v4\n with:\n python-version: '3.12'\n \n - name: Install Poetry\n run: |\n curl -sSL https://install.python-poetry.org | python3 -\n echo \"$HOME/.local/bin\" >> $GITHUB_PATH\n \n - name: Install dependencies\n run: poetry install\n \n - name: Generate documentation\n run: poetry run python scripts/generate_docs.py\n \n - name: Upload documentation artifacts\n uses: actions/upload-artifact@v3\n with:\n name: documentation\n path: docs/html/\n```\n\n## Step 11: Update README.md with Documentation Links\n\n```markdown:README.md\n<code_block_to_apply_changes_from>\n```\n\n## Step 12: Build and Publish with Documentation\n\n```bash\n# Generate documentation first\npoetry run python scripts/generate_docs.py\n\n# Build package (includes documentation)\npoetry build\n\n# Publish to PyPI\npoetry publish\n```\n\n## Step 13: Alternative: Host Documentation on GitHub Pages\n\nCreate `.github/workflows/docs-pages.yml`:\n\n```yaml:.github/workflows/docs-pages.yml\nname: Deploy Documentation to GitHub Pages\n\non:\n push:\n branches: [ main ]\n\njobs:\n deploy:\n runs-on: ubuntu-latest\n permissions:\n contents: read\n pages: write\n id-token: write\n steps:\n - uses: actions/checkout@v4\n \n - name: Set up Python\n uses: actions/setup-python@v4\n with:\n python-version: '3.12'\n \n - name: Install Poetry\n run: |\n curl -sSL https://install.python-poetry.org | python3 -\n echo \"$HOME/.local/bin\" >> $GITHUB_PATH\n \n - name: Install dependencies\n run: poetry install\n \n - name: Generate documentation\n run: poetry run python scripts/generate_docs.py\n \n - name: Setup Pages\n uses: actions/configure-pages@v3\n \n - name: Upload artifact\n uses: actions/upload-pages-artifact@v2\n with:\n path: docs/html/\n \n - name: Deploy to GitHub Pages\n id: deployment\n uses: actions/deploy-pages@v2\n```\n\n## Step 14: Update pyproject.toml with GitHub Pages URL\n\n```toml:pyproject.toml\n[tool.poetry]\n# ... existing configuration ...\ndocumentation = \"https://arusatech.github.io/xrayclient/\"\n# ... rest of configuration ...\n```\n\n## Complete Documentation Workflow\n\n1. **Generate docs**: `poetry run python scripts/generate_docs.py`\n2. **Build package**: `poetry build` (includes docs)\n3. **Publish**: `poetry publish`\n4. **Deploy to GitHub Pages**: Automatic via GitHub Actions\n\n## Benefits of This Approach\n\n1. **Documentation included in PyPI package** - Users get docs with the package\n2. **Automated generation** - Docs are always up-to-date\n3. **GitHub Pages hosting** - Public documentation website\n4. **Custom styling** - Professional-looking documentation\n5. **Version control** - Docs are tracked with code\n\nThis setup provides comprehensive documentation that's both included in your PyPI package and hosted online for easy access.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python Client for Xray Test Management for Jira",
"version": "0.1.3",
"project_urls": {
"Documentation": "https://github.com/arusatech/xrayclient/tree/main/docs/html",
"Homepage": "https://github.com/arusatech/xrayclient",
"Repository": "https://github.com/arusatech/xrayclient"
},
"split_keywords": [
"xray",
" jira",
" test-management",
" graphql",
" api-client"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b4f8d4749098c961dcef7a62722a6da784a1d1fc65c0afb9ca35697d7b4cf88a",
"md5": "0e834328c2a1f145f6828237bd81911f",
"sha256": "93fb0c5040d10225b3ec85a4f4b3efbe9354a545c13ae8abfb5917700f03249a"
},
"downloads": -1,
"filename": "xrayclient-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0e834328c2a1f145f6828237bd81911f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 29306,
"upload_time": "2025-08-06T15:48:18",
"upload_time_iso_8601": "2025-08-06T15:48:18.055267Z",
"url": "https://files.pythonhosted.org/packages/b4/f8/d4749098c961dcef7a62722a6da784a1d1fc65c0afb9ca35697d7b4cf88a/xrayclient-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2ccc49544341f286b8fa87efdccdb4dea64681872e12a81e40c0e85b7f7d8999",
"md5": "69290ffd641cfd020e7f4b6d86981bc8",
"sha256": "6d92adef3f8fb4d4da7b835a8237718438b6c16d07e7f5579648e04cd3405595"
},
"downloads": -1,
"filename": "xrayclient-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "69290ffd641cfd020e7f4b6d86981bc8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 371486,
"upload_time": "2025-08-06T15:48:19",
"upload_time_iso_8601": "2025-08-06T15:48:19.204459Z",
"url": "https://files.pythonhosted.org/packages/2c/cc/49544341f286b8fa87efdccdb4dea64681872e12a81e40c0e85b7f7d8999/xrayclient-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 15:48:19",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "arusatech",
"github_project": "xrayclient",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "xrayclient"
}