agr-curation-api-client


Nameagr-curation-api-client JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryUnified Python client for Alliance of Genome Resources (AGR) curation APIs
upload_time2025-08-05 16:46:45
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords agr alliance genome curation api client
VCS
bugtrack_url
requirements requests pydantic httpx tenacity python-dateutil fastapi_okta
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # AGR Curation API Client

A unified Python client for Alliance of Genome Resources (AGR) curation APIs.

## Features

- **Unified Interface**: Single client for all AGR curation API endpoints
- **Type Safety**: Full type hints and Pydantic models for request/response validation
- **Retry Logic**: Automatic retry with exponential backoff for transient failures
- **Authentication**: Support for API key and Okta token authentication
- **Async Support**: Built on httpx for both sync and async operations
- **Comprehensive Error Handling**: Detailed exceptions for different error scenarios

## Installation

```bash
pip install agr-curation-api-client
```

For development:
```bash
git clone https://github.com/alliance-genome/agr_curation_api_client.git
cd agr_curation_api_client
make install-dev
```

## Authentication

The client supports automatic Okta token generation using the same environment variables as other AGR services:

```bash
export OKTA_DOMAIN="your-okta-domain"
export OKTA_API_AUDIENCE="your-api-audience"
export OKTA_CLIENT_ID="your-client-id"
export OKTA_CLIENT_SECRET="your-client-secret"
```

With these environment variables set, the client will automatically obtain an authentication token when initialized.

## Quick Start

### Basic Usage

```python
from agr_curation_api import AGRCurationAPIClient, APIConfig

# Option 1: Automatic authentication (requires OKTA env vars)
client = AGRCurationAPIClient()

# Option 2: Manual token configuration
config = APIConfig(
    base_url="https://curation.alliancegenome.org/api",
    okta_token="your-okta-token"  # Optional - will auto-retrieve if not provided
)
client = AGRCurationAPIClient(config)

# Use the client
with client:
    # Get genes from WormBase
    genes = client.get_genes(data_provider="WB", limit=10)
    
    for gene in genes:
        symbol = gene.gene_symbol.get("displayText", "") if gene.gene_symbol else ""
        print(f"{gene.curie}: {symbol}")
```

### Working with Genes

```python
from agr_curation_api import AGRCurationAPIClient, Gene

# Use default configuration
client = AGRCurationAPIClient()

# Get genes from a specific data provider
wb_genes = client.get_genes(data_provider="WB", limit=100)
print(f"Found {len(wb_genes)} WormBase genes")

# Get a specific gene by ID
gene = client.get_gene("WB:WBGene00001234")
if gene:
    print(f"Gene: {gene.gene_symbol}")
    print(f"Full name: {gene.gene_full_name}")
    print(f"Species: {gene.taxon}")

# Get all genes (paginated)
all_genes = client.get_genes(limit=5000, page=0)
```

### Working with Species

```python
# Get all species
species_list = client.get_species()

for species in species_list:
    print(f"{species.abbreviation}: {species.display_name}")

# Find a specific species
wb_species = [s for s in species_list if s.abbreviation == "WB"]
if wb_species:
    print(f"WormBase: {wb_species[0].full_name}")
```

### Working with Ontology Terms

```python
# Get GO term root nodes
go_roots = client.get_ontology_root_nodes("goterm")
print(f"Found {len(go_roots)} GO root terms")

# Get children of a specific GO term
children = client.get_ontology_node_children("GO:0008150", "goterm")  # biological_process
for child in children:
    print(f"{child.curie}: {child.name}")

# Get disease ontology terms
disease_roots = client.get_ontology_root_nodes("doterm")

# Get anatomical terms
anatomy_roots = client.get_ontology_root_nodes("anatomicalterm")
```

### Working with Expression Annotations

```python
# Get expression annotations for WormBase
wb_expressions = client.get_expression_annotations(
    data_provider="WB",
    limit=100
)

for expr in wb_expressions:
    if expr.expression_annotation_subject:
        gene_id = expr.expression_annotation_subject.get("primaryExternalId")
        gene_symbol = expr.expression_annotation_subject.get("geneSymbol", {}).get("displayText")
        print(f"Gene: {gene_id} ({gene_symbol})")
        
    if expr.expression_pattern:
        anatomy = expr.expression_pattern.get("whereExpressed", {}).get("anatomicalStructure", {}).get("curie")
        print(f"  Expressed in: {anatomy}")
```

### Working with Alleles

```python
# Get alleles from a specific data provider
wb_alleles = client.get_alleles(data_provider="WB", limit=50)

for allele in wb_alleles:
    symbol = allele.allele_symbol.get("displayText", "") if allele.allele_symbol else ""
    print(f"{allele.curie}: {symbol}")

# Get a specific allele
allele = client.get_allele("WB:WBVar00001234")
if allele:
    print(f"Allele: {allele.allele_symbol}")
    print(f"Full name: {allele.allele_full_name}")
```

### Generic Search

```python
# Generic entity search
search_filters = {
    "dataProvider.abbreviation": "WB",
    "geneSymbol.displayText": "daf-16"
}

results = client.search_entities(
    entity_type="gene",
    search_filters=search_filters,
    limit=10
)

print(f"Total results: {results.total_results}")
print(f"Returned: {results.returned_records}")

for gene_data in results.results:
    print(f"Found gene: {gene_data}")
```

### Error Handling

```python
from agr_curation_api import (
    AGRAPIError,
    AGRAuthenticationError,
    AGRConnectionError,
    AGRTimeoutError,
    AGRValidationError
)

try:
    reference = client.get_reference("invalid-id")
except AGRAuthenticationError:
    print("Authentication failed - check your credentials")
except AGRValidationError as e:
    print(f"Invalid data: {e}")
except AGRTimeoutError:
    print("Request timed out - try again later")
except AGRConnectionError:
    print("Connection failed - check network")
except AGRAPIError as e:
    print(f"API error: {e}")
    if e.status_code:
        print(f"Status code: {e.status_code}")
```

## Configuration Options

The `APIConfig` class supports the following options:

- `base_url`: Base URL for the A-Team Curation API (default: "https://curation.alliancegenome.org/api")
- `okta_token`: Okta bearer token for authentication (auto-retrieved if not provided)
- `timeout`: Request timeout in seconds (default: 30)
- `max_retries`: Maximum retry attempts (default: 3)
- `retry_delay`: Initial delay between retries in seconds (default: 1)
- `verify_ssl`: Whether to verify SSL certificates (default: True)
- `headers`: Additional headers to include in requests

### Environment Variables

The client uses the following environment variables for configuration:

- `ATEAM_API`: Override the default A-Team API URL (default: uses production curation API)
- `OKTA_DOMAIN`: Your Okta domain (required for automatic authentication)
- `OKTA_API_AUDIENCE`: Your API audience (required for automatic authentication)
- `OKTA_CLIENT_ID`: Your Okta client ID (required for automatic authentication)
- `OKTA_CLIENT_SECRET`: Your Okta client secret (required for automatic authentication)

## Development

### Running Tests

```bash
make test
```

### Code Quality

```bash
# Run linting
make lint

# Run type checking
make type-check

# Format code
make format

# Run all checks
make check
```

### Building Documentation

```bash
cd docs
make html
```

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Support

- **Issues**: [GitHub Issues](https://github.com/alliance-genome/agr_curation_api_client/issues)
- **Documentation**: [API Documentation](https://alliancegenome.org/api-docs)
- **Contact**: software@alliancegenome.org

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "agr-curation-api-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "Alliance Blue Team <valearna@caltech.edu>",
    "keywords": "agr, alliance, genome, curation, api, client",
    "author": null,
    "author_email": "Alliance of Genome Resources <valearna@caltech.edu>",
    "download_url": "https://files.pythonhosted.org/packages/09/03/fe15453ae2010ffa220c162279aca7e0377739c37411df7654a18947a0b5/agr_curation_api_client-0.1.0.tar.gz",
    "platform": null,
    "description": "# AGR Curation API Client\n\nA unified Python client for Alliance of Genome Resources (AGR) curation APIs.\n\n## Features\n\n- **Unified Interface**: Single client for all AGR curation API endpoints\n- **Type Safety**: Full type hints and Pydantic models for request/response validation\n- **Retry Logic**: Automatic retry with exponential backoff for transient failures\n- **Authentication**: Support for API key and Okta token authentication\n- **Async Support**: Built on httpx for both sync and async operations\n- **Comprehensive Error Handling**: Detailed exceptions for different error scenarios\n\n## Installation\n\n```bash\npip install agr-curation-api-client\n```\n\nFor development:\n```bash\ngit clone https://github.com/alliance-genome/agr_curation_api_client.git\ncd agr_curation_api_client\nmake install-dev\n```\n\n## Authentication\n\nThe client supports automatic Okta token generation using the same environment variables as other AGR services:\n\n```bash\nexport OKTA_DOMAIN=\"your-okta-domain\"\nexport OKTA_API_AUDIENCE=\"your-api-audience\"\nexport OKTA_CLIENT_ID=\"your-client-id\"\nexport OKTA_CLIENT_SECRET=\"your-client-secret\"\n```\n\nWith these environment variables set, the client will automatically obtain an authentication token when initialized.\n\n## Quick Start\n\n### Basic Usage\n\n```python\nfrom agr_curation_api import AGRCurationAPIClient, APIConfig\n\n# Option 1: Automatic authentication (requires OKTA env vars)\nclient = AGRCurationAPIClient()\n\n# Option 2: Manual token configuration\nconfig = APIConfig(\n    base_url=\"https://curation.alliancegenome.org/api\",\n    okta_token=\"your-okta-token\"  # Optional - will auto-retrieve if not provided\n)\nclient = AGRCurationAPIClient(config)\n\n# Use the client\nwith client:\n    # Get genes from WormBase\n    genes = client.get_genes(data_provider=\"WB\", limit=10)\n    \n    for gene in genes:\n        symbol = gene.gene_symbol.get(\"displayText\", \"\") if gene.gene_symbol else \"\"\n        print(f\"{gene.curie}: {symbol}\")\n```\n\n### Working with Genes\n\n```python\nfrom agr_curation_api import AGRCurationAPIClient, Gene\n\n# Use default configuration\nclient = AGRCurationAPIClient()\n\n# Get genes from a specific data provider\nwb_genes = client.get_genes(data_provider=\"WB\", limit=100)\nprint(f\"Found {len(wb_genes)} WormBase genes\")\n\n# Get a specific gene by ID\ngene = client.get_gene(\"WB:WBGene00001234\")\nif gene:\n    print(f\"Gene: {gene.gene_symbol}\")\n    print(f\"Full name: {gene.gene_full_name}\")\n    print(f\"Species: {gene.taxon}\")\n\n# Get all genes (paginated)\nall_genes = client.get_genes(limit=5000, page=0)\n```\n\n### Working with Species\n\n```python\n# Get all species\nspecies_list = client.get_species()\n\nfor species in species_list:\n    print(f\"{species.abbreviation}: {species.display_name}\")\n\n# Find a specific species\nwb_species = [s for s in species_list if s.abbreviation == \"WB\"]\nif wb_species:\n    print(f\"WormBase: {wb_species[0].full_name}\")\n```\n\n### Working with Ontology Terms\n\n```python\n# Get GO term root nodes\ngo_roots = client.get_ontology_root_nodes(\"goterm\")\nprint(f\"Found {len(go_roots)} GO root terms\")\n\n# Get children of a specific GO term\nchildren = client.get_ontology_node_children(\"GO:0008150\", \"goterm\")  # biological_process\nfor child in children:\n    print(f\"{child.curie}: {child.name}\")\n\n# Get disease ontology terms\ndisease_roots = client.get_ontology_root_nodes(\"doterm\")\n\n# Get anatomical terms\nanatomy_roots = client.get_ontology_root_nodes(\"anatomicalterm\")\n```\n\n### Working with Expression Annotations\n\n```python\n# Get expression annotations for WormBase\nwb_expressions = client.get_expression_annotations(\n    data_provider=\"WB\",\n    limit=100\n)\n\nfor expr in wb_expressions:\n    if expr.expression_annotation_subject:\n        gene_id = expr.expression_annotation_subject.get(\"primaryExternalId\")\n        gene_symbol = expr.expression_annotation_subject.get(\"geneSymbol\", {}).get(\"displayText\")\n        print(f\"Gene: {gene_id} ({gene_symbol})\")\n        \n    if expr.expression_pattern:\n        anatomy = expr.expression_pattern.get(\"whereExpressed\", {}).get(\"anatomicalStructure\", {}).get(\"curie\")\n        print(f\"  Expressed in: {anatomy}\")\n```\n\n### Working with Alleles\n\n```python\n# Get alleles from a specific data provider\nwb_alleles = client.get_alleles(data_provider=\"WB\", limit=50)\n\nfor allele in wb_alleles:\n    symbol = allele.allele_symbol.get(\"displayText\", \"\") if allele.allele_symbol else \"\"\n    print(f\"{allele.curie}: {symbol}\")\n\n# Get a specific allele\nallele = client.get_allele(\"WB:WBVar00001234\")\nif allele:\n    print(f\"Allele: {allele.allele_symbol}\")\n    print(f\"Full name: {allele.allele_full_name}\")\n```\n\n### Generic Search\n\n```python\n# Generic entity search\nsearch_filters = {\n    \"dataProvider.abbreviation\": \"WB\",\n    \"geneSymbol.displayText\": \"daf-16\"\n}\n\nresults = client.search_entities(\n    entity_type=\"gene\",\n    search_filters=search_filters,\n    limit=10\n)\n\nprint(f\"Total results: {results.total_results}\")\nprint(f\"Returned: {results.returned_records}\")\n\nfor gene_data in results.results:\n    print(f\"Found gene: {gene_data}\")\n```\n\n### Error Handling\n\n```python\nfrom agr_curation_api import (\n    AGRAPIError,\n    AGRAuthenticationError,\n    AGRConnectionError,\n    AGRTimeoutError,\n    AGRValidationError\n)\n\ntry:\n    reference = client.get_reference(\"invalid-id\")\nexcept AGRAuthenticationError:\n    print(\"Authentication failed - check your credentials\")\nexcept AGRValidationError as e:\n    print(f\"Invalid data: {e}\")\nexcept AGRTimeoutError:\n    print(\"Request timed out - try again later\")\nexcept AGRConnectionError:\n    print(\"Connection failed - check network\")\nexcept AGRAPIError as e:\n    print(f\"API error: {e}\")\n    if e.status_code:\n        print(f\"Status code: {e.status_code}\")\n```\n\n## Configuration Options\n\nThe `APIConfig` class supports the following options:\n\n- `base_url`: Base URL for the A-Team Curation API (default: \"https://curation.alliancegenome.org/api\")\n- `okta_token`: Okta bearer token for authentication (auto-retrieved if not provided)\n- `timeout`: Request timeout in seconds (default: 30)\n- `max_retries`: Maximum retry attempts (default: 3)\n- `retry_delay`: Initial delay between retries in seconds (default: 1)\n- `verify_ssl`: Whether to verify SSL certificates (default: True)\n- `headers`: Additional headers to include in requests\n\n### Environment Variables\n\nThe client uses the following environment variables for configuration:\n\n- `ATEAM_API`: Override the default A-Team API URL (default: uses production curation API)\n- `OKTA_DOMAIN`: Your Okta domain (required for automatic authentication)\n- `OKTA_API_AUDIENCE`: Your API audience (required for automatic authentication)\n- `OKTA_CLIENT_ID`: Your Okta client ID (required for automatic authentication)\n- `OKTA_CLIENT_SECRET`: Your Okta client secret (required for automatic authentication)\n\n## Development\n\n### Running Tests\n\n```bash\nmake test\n```\n\n### Code Quality\n\n```bash\n# Run linting\nmake lint\n\n# Run type checking\nmake type-check\n\n# Format code\nmake format\n\n# Run all checks\nmake check\n```\n\n### Building Documentation\n\n```bash\ncd docs\nmake html\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'feat: add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/alliance-genome/agr_curation_api_client/issues)\n- **Documentation**: [API Documentation](https://alliancegenome.org/api-docs)\n- **Contact**: software@alliancegenome.org\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Unified Python client for Alliance of Genome Resources (AGR) curation APIs",
    "version": "0.1.0",
    "project_urls": {
        "Bug Reports": "https://github.com/alliance-genome/agr_curation_api_client/issues",
        "Documentation": "https://github.com/alliance-genome/agr_curation_api_client#readme",
        "Homepage": "https://github.com/alliance-genome/agr_curation_api_client",
        "Source": "https://github.com/alliance-genome/agr_curation_api_client"
    },
    "split_keywords": [
        "agr",
        " alliance",
        " genome",
        " curation",
        " api",
        " client"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8b012552685a2569f7c2dfa68be0e7dc3fe23115e063140a43f1343a61357992",
                "md5": "3347938a7dbbc93e31bf62b5e7d6a54c",
                "sha256": "65ed4f819513154f3d0b8a978fa77b7c26e633ea619f857dfdc7806430aa4210"
            },
            "downloads": -1,
            "filename": "agr_curation_api_client-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3347938a7dbbc93e31bf62b5e7d6a54c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 10581,
            "upload_time": "2025-08-05T16:46:44",
            "upload_time_iso_8601": "2025-08-05T16:46:44.391606Z",
            "url": "https://files.pythonhosted.org/packages/8b/01/2552685a2569f7c2dfa68be0e7dc3fe23115e063140a43f1343a61357992/agr_curation_api_client-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0903fe15453ae2010ffa220c162279aca7e0377739c37411df7654a18947a0b5",
                "md5": "d19e10243f47a272a9d847d807c3a1bb",
                "sha256": "b4363a49a582bf400259e184726aae5ad677a50c2a43401ba9430330d17a715a"
            },
            "downloads": -1,
            "filename": "agr_curation_api_client-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "d19e10243f47a272a9d847d807c3a1bb",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 13706,
            "upload_time": "2025-08-05T16:46:45",
            "upload_time_iso_8601": "2025-08-05T16:46:45.569489Z",
            "url": "https://files.pythonhosted.org/packages/09/03/fe15453ae2010ffa220c162279aca7e0377739c37411df7654a18947a0b5/agr_curation_api_client-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-05 16:46:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "alliance-genome",
    "github_project": "agr_curation_api_client",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "requests",
            "specs": [
                [
                    ">=",
                    "2.28.0"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    ">=",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "httpx",
            "specs": [
                [
                    ">=",
                    "0.24.0"
                ]
            ]
        },
        {
            "name": "tenacity",
            "specs": [
                [
                    ">=",
                    "8.0.0"
                ]
            ]
        },
        {
            "name": "python-dateutil",
            "specs": [
                [
                    ">=",
                    "2.8.0"
                ]
            ]
        },
        {
            "name": "fastapi_okta",
            "specs": []
        }
    ],
    "lcname": "agr-curation-api-client"
}
        
Elapsed time: 0.53273s