Metadata-Version: 2.4
Name: qodev-linkedin-api
Version: 0.3.0
Summary: Async Python client for LinkedIn data export API
Project-URL: Homepage, https://github.com/qodevai/linkedin-api
Project-URL: Repository, https://github.com/qodevai/linkedin-api
Project-URL: Changelog, https://github.com/qodevai/linkedin-api/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/qodevai/linkedin-api/issues
Author-email: Jan Scheffler <jan.scheffler@qodev.ai>
License: MIT
License-File: LICENSE
Keywords: api,async,client,data-export,linkedin
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pyright>=1.1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.12.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Description-Content-Type: text/markdown

# qodev-linkedin-api

Async Python client for LinkedIn data export API.

## Installation

### From PyPI (recommended)

```bash
pip install qodev-linkedin-api
# or
uv add qodev-linkedin-api
```

### From GitHub (alternative)

```bash
uv add qodev-linkedin-api --source git+ssh://git@github.com/qodevai/linkedin-api.git
```

### For development

```bash
git clone git@github.com:qodevai/linkedin-api.git
cd linkedin-api
make install
make install-hooks  # Set up pre-commit hooks
```

## Quick Start

```bash
make install        # Install dependencies
make install-hooks  # Set up pre-commit hooks (recommended)
make check          # Run all quality checks
make test           # Run tests with coverage
```

## Usage

### Basic Usage

```python
import asyncio
from linkedin import LinkedInClient

async def main():
    async with LinkedInClient() as client:
        # Get all connections
        connections = await client.get_connections()
        for conn in connections:
            print(f"{conn.first_name} {conn.last_name} - {conn.company}")

        # Get invitations (both sent and received)
        invitations = await client.get_invitations()

        # Get only outgoing invitations
        sent = await client.get_outgoing_invitations()

        # Get inbox messages
        messages = await client.get_inbox()

        # Get changelog (API changes tracking)
        changelog = await client.get_changelog()

asyncio.run(main())
```

### Configuration

```python
from linkedin import LinkedInClient

# Auth token from environment variable (default)
# Set LINKEDIN_AUTH_TOKEN env var
client = LinkedInClient()

# Or pass token directly
client = LinkedInClient(auth_token="your-token-here")

# Custom API version and timeout
client = LinkedInClient(
    api_version="202312",  # LinkedIn API version
    timeout=60.0,          # Request timeout in seconds
)
```

### Error Handling

```python
from linkedin import (
    LinkedInClient,
    AuthenticationError,
    RateLimitError,
    APIError,
)

async def fetch_with_retry():
    try:
        async with LinkedInClient() as client:
            return await client.get_connections()
    except AuthenticationError:
        print("Invalid or expired token")
    except RateLimitError as e:
        print(f"Rate limited. Retry after: {e.retry_after} seconds")
    except APIError as e:
        print(f"API error {e.status_code}: {e}")
```

### Models

All responses are typed Pydantic models:

```python
from linkedin import Connection, Invitation, Message, ChangeLogEntry

# Connection fields
conn: Connection
conn.url           # LinkedIn profile URL
conn.first_name
conn.last_name
conn.email         # Optional
conn.company       # Optional
conn.position      # Optional
conn.connected_on  # Date string

# Invitation fields
inv: Invitation
inv.to
inv.invitee_profile_url
inv.message        # Optional
inv.direction      # "OUTGOING" or "INCOMING"
inv.sent_at        # Date string

# Message fields
msg: Message
msg.conversation_id
msg.from_member
msg.to_member      # Optional
msg.content
msg.date           # Date string
msg.subject        # Optional
msg.folder         # Optional

# ChangeLogEntry fields
entry: ChangeLogEntry
entry.id
entry.method
entry.resource_name
entry.captured_at          # Unix timestamp (ms)
entry.processed_at         # Unix timestamp (ms)
entry.captured_datetime    # Property: datetime object
entry.processed_datetime   # Property: datetime object
```

## Development

### Available Commands

```bash
make help           # Show all available commands
make install        # Install all dependencies
make install-hooks  # Install pre-commit hooks
make check          # Run all checks (lint, format, typecheck, typos)
make test           # Run tests with coverage
make test-fast      # Run tests without coverage
make lint           # Lint code with ruff
make lint-fix       # Auto-fix lint issues
make format         # Format code with ruff
make typecheck      # Run type checking with pyright
make typos          # Check for typos
make build          # Build package (sdist + wheel)
make clean          # Clean generated files
```

### Pre-commit Hooks

Pre-commit hooks run automatically on every commit:

```bash
make install-hooks  # Install once
```

Hooks include:
- YAML/TOML/JSON validation
- Trailing whitespace removal
- Ruff linting and formatting
- Typos spell checking

### Running Checks Manually

```bash
# Run all checks (recommended before committing)
make check

# Or run individual checks
make lint
make format-check
make typecheck
make typos
```

## Environment Variables

| Variable | Description |
|----------|-------------|
| `LINKEDIN_AUTH_TOKEN` | LinkedIn API auth token (required if not passed to client) |

## Requirements

- Python 3.11+
- [uv](https://docs.astral.sh/uv/) (for development)

## License

MIT
