# User Resource

The User resource provides access to 42 School user data and operations.

## Overview

This module allows you to fetch user information from the 42 API, including basic profile data, authentication status, images, and more.

## Classes

### `UserImage`
Represents a user's profile image with different versions.

**Properties:**
- `link` (str): Direct link to the profile image
- `large` (str): URL to large version of the image
- `medium` (str): URL to medium version of the image
- `small` (str): URL to small version of the image
- `micro` (str): URL to micro version of the image

**Methods:**
- `to_dict()`: Convert to dictionary format matching API response

**Example:**
```python
user = client.users.get_by_id(user_id=12345)
print(user.image.link)       # Direct link
print(user.image.large)      # Large version URL
print(user.image.medium)     # Medium version URL
print(user.image.small)      # Small version URL
print(user.image.micro)      # Micro version URL
```

### `User`
Represents a 42 School user with all their associated data.

**Properties:**
- `id` (int): Unique user identifier
- `email` (str): User's email address
- `login` (str): User's login name
- `first_name` (str): User's first name
- `last_name` (str): User's last name
- `usual_full_name` (str): User's display name
- `usual_first_name` (str | None): User's usual first name (may be None)
- `url` (str): API URL for the user
- `phone` (str): User's phone number
- `displayname` (str): User's display name
- `kind` (str): User type/kind (e.g., "student", "staff")
- `image` (UserImage): Profile images with link and versions (large, medium, small, micro)
- `staff` (bool): Whether the user is staff
- `correction_point` (int): Number of correction points
- `pool_month` (str): Pool month (e.g., "september")
- `pool_year` (str): Pool year (e.g., "2022")
- `location` (str | None): Current location (None if not logged in)
- `wallet` (int): Wallet balance
- `anonymize_date` (datetime): Date when user data will be anonymized
- `data_erasure_date` (datetime): Date when user data will be erased
- `created_at` (datetime): Account creation date
- `updated_at` (datetime): Last profile update date
- `alumnized_at` (datetime | None): Date when user became alumni (None if not alumni)
- `alumni` (bool): Whether the user is an alumnus
- `active` (bool): Whether the user account is active
- `cursus_users` (list): List of cursus user enrollments
- `projects_users` (list): List of project completions
- `campus` (list): List of associated campuses
- `campus_users` (list): List of campus user associations

### Resource Classes

#### `GetMe`
Fetches the authenticated user's information.
- **Endpoint:** `/me`
- **Method:** GET
- **Returns:** `User`

#### `GetUserById`
Fetches a single user by their ID.
- **Endpoint:** `/users/{id}`
- **Method:** GET
- **Returns:** `User`

#### `GetUsers`
Fetches all users with optional filtering.
- **Endpoint:** `/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByCoalitionId`
Fetches users belonging to a specific coalition.
- **Endpoint:** `/coalitions/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByDashId`
Fetches users associated with a specific dash.
- **Endpoint:** `/dashes/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByEventId`
Fetches users associated with a specific event.
- **Endpoint:** `/events/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByAccreditationId`
Fetches users associated with a specific accreditation.
- **Endpoint:** `/accreditations/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByTeamId`
Fetches users belonging to a specific team.
- **Endpoint:** `/teams/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByProjectId`
Fetches users associated with a specific project.
- **Endpoint:** `/projects/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByPartnershipId`
Fetches users associated with a specific partnership.
- **Endpoint:** `/partnerships/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByExpertiseId`
Fetches users associated with a specific expertise.
- **Endpoint:** `/expertises/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByCursusId`
Fetches users enrolled in a specific cursus.
- **Endpoint:** `/cursus/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByCampusId`
Fetches users belonging to a specific campus.
- **Endpoint:** `/campus/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByAchievementId`
Fetches users who have earned a specific achievement.
- **Endpoint:** `/achievements/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByTitleId`
Fetches users who have a specific title.
- **Endpoint:** `/titles/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByQuestId`
Fetches users associated with a specific quest.
- **Endpoint:** `/quests/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

#### `GetUsersByGroupId`
Fetches users belonging to a specific group.
- **Endpoint:** `/groups/{id}/users`
- **Method:** GET
- **Returns:** `List[User]`

## Usage Examples

### Using the Manager (Recommended)

```python
from fortytwo import Client
from fortytwo.exceptions import FortyTwoNotFoundException

client = Client(
    ...
)

# Get the authenticated user
me = client.users.get_me()
print(f"Logged in as: {me.login}")

# Get a specific user by ID
try:
    user = client.users.get_by_id(user_id=12345)
    print(f"User: {user.login}")
    print(f"Name: {user.first_name} {user.last_name}")
    print(f"Email: {user.email}")
    print(f"Alumni: {user.alumni}")

    # Access image properties directly (no dict notation needed)
    print(f"Profile Image: {user.image.link}")
    print(f"Large Image: {user.image.large}")
    print(f"Medium Image: {user.image.medium}")
except FortyTwoNotFoundException:
    print("User not found")

# Get all users with pagination
users = client.users.get_all(page=1, page_size=50)
for user in users:
    print(f"{user.id}: {user.login}")
```

### Using Resources Directly

```python
# Get a specific user
user = client.request(GetUserById(12345))

# Get all users
users = client.request(GetUsers())
```

## Data Structure

### User JSON Response
```json
{
  "id": ...,
  "email": "jdoe@student.42campus.org",
  "login": "jdoe",
  "first_name": "John",
  "last_name": "Doe",
  "usual_full_name": "John Doe",
  "usual_first_name": null,
  "url": "https://api.intra.42.fr/v2/users/jdoe",
  "phone": "hidden",
  "displayname": "John Doe",
  "kind": "student",
  "image": {...},
  "staff?": false,
  "correction_point": 5,
  "pool_month": null,
  "pool_year": null,
  "location": null,
  "wallet": 0,
  "anonymize_date": null,
  "data_erasure_date": null,
  "created_at": null,
  "updated_at": null,
  "alumnized_at": null,
  "alumni?": false,
  "active?": true,
  "cursus_users": [...],
  "projects_users": [...],
  "campus": [...],
  "campus_users": [...]
}
```

## Parameters

For detailed information about filtering, sorting, and ranging user queries, see the [User Parameters Documentation](parameter/README.md).

## Error Handling

All methods raise exceptions on errors:

```python
from fortytwo import Client
from fortytwo.exceptions import (
    FortyTwoNotFoundException,
    FortyTwoUnauthorizedException,
    FortyTwoRateLimitException,
    FortyTwoNetworkException,
    FortyTwoRequestException
)

client = Client(
    ...
)

try:
    user = client.users.get_by_id(user_id=99999)
    print(f"Found user: {user.login}")
except FortyTwoNotFoundException:
    print("User not found")
except FortyTwoUnauthorizedException:
    print("Authentication failed")
except FortyTwoRateLimitException as e:
    print(f"Rate limit exceeded. Wait {e.wait_time} seconds")
except FortyTwoNetworkException:
    print("Network error occurred")
except FortyTwoRequestException as e:
    print(f"Request failed: {e}")
```
