xrayclient


Namexrayclient JSON
Version 0.1.3 PyPI version JSON
download
home_pagehttps://github.com/arusatech/xrayclient
SummaryPython Client for Xray Test Management for Jira
upload_time2025-08-06 15:48:19
maintainerNone
docs_urlNone
authoryakub@arusatech.com
requires_python>=3.12
licenseMIT
keywords xray jira test-management graphql api-client
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 1.44942s