Metadata-Version: 2.4
Name: sharepoint_v1_api
Version: 1.5.1
Author: Aske Bluhme Klok
License: MIT
Keywords: Sharepoint
Classifier: Programming Language :: Python :: 3
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.32.2
Requires-Dist: requests-ntlm>=1.3.0
Requires-Dist: pytz>=2021.1
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python

# SharePoint API Python Client – Documentation

A modern Python client for SharePoint REST API operations using a client pattern for better abstraction.

## Features

- Site-scoped operations through `SharePointSite` client
- User management via `SharePointUser`
- List item operations with `SharePointListItem`
- NTLM authentication support
- Comprehensive error handling
- Metadata discovery and batch operations

## Installation

```bash
pip install sharepoint-v1-api
```

From source:

```bash
git clone https://github.com/your-org/nc-devops-sharepoint-v1-api.git
cd nc-devops-sharepoint-v1-api
pip install -e .
```

## Authentication & Initialization

```python
import requests
from requests_ntlm import HttpNtlmAuth
from sharepoint import SharePointSite

# Create authenticated session
session = requests.Session()
session.auth = HttpNtlmAuth('your_user', 'your_password')
session.proxies = {}  # Add proxies if needed

# Initialize site client
site = SharePointSite(
    url="https://your.sharepoint.com/_api/Web",
    session=session
)
```

## Core Operations

### List Operations

```python
# Get all lists
all_lists = site.get_lists()

# Get list by title
tasks_list = site.get_list(list_title="Tasks")

# Filter items with OData syntax
active_tasks = tasks_list.get_items(
    filters="Status eq 'Active'",
    select_fields=["Title", "DueDate"]
)

# Get items with pagination (for large lists)
# First page
first_page = tasks_list.get_items_paged(top=100)
for item in first_page["items"]:
    print(f"Item ID: {item.id}")

# Get next page using the skiptoken
if first_page["has_next"]:
    second_page = tasks_list.get_items_paged(
        top=100,
        skiptoken=first_page["next_skiptoken"]
    )

# Iterate through all items in a large list automatically
for item in tasks_list.iterate_all_items(page_size=1000):
    print(f"Processing item {item.id}")
```

### User Management

```python
# Get user by ID
user = site.get_user(42)
print(f"User: {user.Title} ({user.Email})")
```

### List Items

```python
# Get specific item
task_item = tasks_list.get_item(101)

# Update item
update_data = {
    "Status": "Completed",
    "PercentComplete": 1.0
}
task_item.update_item(update_data)

# Check modification history
print(f"Last modified: {task_item.modified}")
```

## Advanced Usage

### Field Management

```python
# Get list fields
fields = tasks_list.get_fields()
required_fields = [f for f in fields if f.required]

# Update field properties (requires 'Manage Lists' permission)
try:
    description_field = next((f for f in fields if f.title == "TaskDescription"), None)
    if description_field:
        description_field.update_field({
            "Description": "Max length increased to 500 characters",
            "MaxLength": 500
        })
except PermissionError:
    print("Update failed - insufficient permissions")

# Delete obsolete field (irreversible operation)
if description_field and not description_field.required and description_field.hidden:
    success = description_field.delete_field()
    if success:
        print(f"Field '{description_field.title}' deleted")
    else:
        print("Field deletion failed")
else:
    print("Skipping deletion - field is required or visible")
    
# Check field metadata
if description_field:
    print(f"Field '{description_field.title}' type: {description_field.type_as_string}")
    print(f"Hidden: {description_field.hidden}, Read-only: {description_field.read_only}")
```

### Site Metadata

```python
print(f"Site Title: {site.title}")
print(f"Created Date: {site.created.strftime('%Y-%m-%d')}")
print(f"Default Language: {site.language_name}")
```

### Working with Large Lists (Pagination)

SharePoint has list view thresholds that prevent retrieving too many items at once. When working with large lists, use the pagination methods:

```python
# For manual pagination control
page_result = tasks_list.get_items_paged(top=1000)
items = page_result["items"]
has_next = page_result["has_next"]
next_token = page_result["next_skiptoken"]

# For automatic pagination through all items
for item in tasks_list.iterate_all_items(page_size=1000):
    # Process each item
    print(f"Processing item {item.id}")
```

### Batch Operations

```python
# Get multiple lists with filtering
recent_lists = site.get_lists(
    filters="Created gt datetime'2023-01-01T00:00:00Z'",
    select_fields=["Title", "ItemCount"],
    top=10
)
```

### Error Handling

```python
from requests.exceptions import ConnectionError

try:
    site.get_lists()
except ConnectionError as e:
    print(f"Network error: {e}")
except PermissionError:
    print("Authentication failed - check credentials")
except FileNotFoundError:
    print("Requested resource not found")
```

## Class Reference

| Class                | Description                                  | Key Methods/Properties           |
|----------------------|----------------------------------------------|----------------------------------|
| `SharePointSite`     | Main entry point for site operations        | `get_lists`, `get_folder`, `get_user` |
| `SharePointUser`     | User profile management                     | `Email`, `UserName`, `Title`     |
| `SharePointList`     | List operations and metadata                | `get_items`, `get_items_paged`, `iterate_all_items`, `get_item`, `get_fields`|
| `SharePointListItem` | Individual item manipulation                | `update_item`, `delete_item`     |
| `SharePointFolder`   | File/folder operations                      | `get_folders`, `get_folder`      |
| `SharePointListField`| Field metadata and validation               | `update_field`, `delete_field`, `title`, `type_as_string`, `required` |

## Best Practices

1. **Reuse Sessions**: Create one `SharePointSite` instance per site and reuse it
2. **Selective Loading**: Use `select_fields` parameter to optimize payload sizes
3. **Error Recovery**: Implement retry logic for transient network errors
4. **Field Validation**: Check `required` and `read_only` properties before updates
5. **Metadata Caching**: Cache frequently accessed metadata like list GUIDs

## Migration from v0.x

```python
# Old style (deprecated)
from sharepoint_api import SharePointAPI
api = SharePointAPI._compact_init(creds)
items = api.get_lists("cases")

# New client pattern
from sharepoint import SharePointSite
site = SharePointSite(url=site_url, session=session)
items = site.get_lists()
```

## Testing

```bash
# Run all tests
task test
```

## License

MIT License - See [LICENSE](LICENSE) for details.


# Changelog

## 1.5.1 – 2026-04-10

### Added

- Field-level data validation with validate_data method implemented for all field types (TextField, NumberField, ChoiceField, MultiChoiceField, DateTimeField, BooleanField, LookupField, PersonOrGroupField)
- Comprehensive test suite for field validation covering all field types with positive and negative test cases

### Changed

- Refactored SharePointList._validate_item_data to use field-level validation approach for more modular code
- Improved RequiredFieldMissingError to include static name information for better debugging
- Optimized validation to only query fields that are actually being validated for better performance
- Enhanced select_fields handling in get_fields method with proper deduplication of field names

## 1.5.0 – 2026-04-09

### Added

- Comprehensive data validation for SharePoint list item creation with new validation exception hierarchy including ValidationError, RequiredFieldMissingError, InvalidChoiceError, InvalidLengthError, InvalidValueRangeError, and InvalidTypeError
- SharePointList.create_item() method now accepts an optional validate parameter (enabled by default) that validates item data against list field constraints before submission
- Field-specific validation methods for Text, Number, Choice, MultiChoice, DateTime, and Boolean field types
- Extensive test suite covering all validation scenarios with positive and negative test cases

### Changed

- SharePointList.create_item() method signature now includes validate: bool = True parameter
- Added import statements for new validation exceptions in sharepoint/list.py

## 1.4.0 – 2026-04-09

### Added

- Enhanced SharePoint list field handling with specialized classes for different field types including ChoiceField, ComputedField, LookupField, DateTimeField, PersonOrGroupField, MultiChoiceField, NumberField, TextField, and BooleanField. The `get_fields()` method now returns appropriately typed objects based on the field's TypeAsString property.

### Changed

- Removed redundant `.flake8` configuration file and consolidated tooling configurations in `pyproject.toml` and `setup.cfg`. Updated Dockerfile and task definitions to reference the new configuration files.

## 1.3.1 – 2026-03-27

### Fixed

- Improved type safety for classmethods in SharePointSite, SharePointUser, and SharePointList
- Enhanced inheritance support with Self typing for from_relative_url methods
- Updated classmethod return type annotations to use Self instead of hardcoded class names

## 1.3.0 – 2026-03-23

### Added

- OData ordering support with orderby_fields parameter across the entire library
- SharePointList methods now support ordering: get_fields(), get_items(), get_items_paged(), iterate_all_items()
- SharePointListItem.get_versions() method now supports ordering
- Comprehensive test suite for ordering functionality with 100% coverage
- Detailed usage examples for all ordering scenarios in examples/list.py and examples/list_item.py

### Changed

- Enhanced build_query_url function in _odata_utils.py to support orderby_fields parameter

## 1.2.0 – 2026-03-09

### Added

- SharePoint file management functionality with complete file operations support (get_content, delete, checkout, checkin, publish, unpublish, undo_checkout, recycle)
- SharePoint folder operations (create_folder, delete, get_files, get_file, add_file)
- get_users method for SharePointGroup with support for OData query parameters
- DELETE method support in SharePointAPI
- Comprehensive examples for all SharePoint entities

### Changed

- Improved type safety throughout the codebase using Optional instead of Union[X, None]
- Replaced os.path.join with urllib.parse.urljoin for proper URL construction
- Enhanced API client with improved parameter handling and documentation
- Modernized SharePoint classes with better typing and return types
- Optimized Docker builds with base image caching

### Fixed

- SharePointListItem delete_item method now properly uses DELETE API
- Datetime utilities with better timezone handling
- Flake8 errors and cleaned up unused imports

### Refactored

- Simplified group and site metadata access patterns
- Improved SharePointList with pagination enhancements
- Enhanced SharePointBase metadata handling for better error resilience

## 1.1.0 – 2026-02-27

### Added

- Lookup field support in SharePointBase with expand_lookup method
- Dockerized test suite for consistent testing environment
- AGENTS.md with development guidelines

### Changed

- Dockerize test suite and update development documentation
- Add Dockerfile in tests directory for containerized testing
- Update Taskfile.yml to run tests in Docker container and ensure tests run before publish
- Update setup.py to require Python >=3.12 and add pytz dependency
- Add .dockerignore to exclude Dockerfile from build context
- Update README.md to document Docker-based testing approach
- Fix form_digestive_value handling for item updates

### Fixed

- Form digest value handling for item updates
- Test parameter mock issues
- Debug comments removal

## 1.0.2 – 2026-01-22

### Added

- Pagination support for SharePoint list items using $skiptoken
- New methods in SharePointList: `get_items_paged()` and `iterate_all_items()`
- Support for skiptoken parameter in OData query building

### Documentation

- Updated README.md to accurately reflect current implementation
- Fixed parameter names and method references in examples
- Removed references to non-existent functionality
- Corrected class reference table with accurate method names

## 1.0.1 – 2025-01-16

### Changed

- Fix documentation, using url instead of site_url

## 1.0.0 – 2025-12-15

### Added

- New client classes: `SharePointSite`, `SharePointUser`, `SharePointList`, `SharePointListItem`, `SharePointFolder`
- `SharePointListField` class for field-level metadata and operations
- Comprehensive type hints throughout the codebase
- Lazy-loaded metadata pattern for all client objects
- Batch operation support for list items and fields
- New documentation examples for field management

### Deprecated

- `SharePointAPI` class and `_compact_init` method - replaced by client pattern
- Legacy method names using camelCase (e.g. `getListByName` -> `get_list_by_name`)

### Changed

- **BREAKING**: Complete restructuring into client pattern
- Unified snake_case naming convention for all methods and properties
- Improved error handling with specific exception types (PermissionError, FileNotFoundError)
- Updated documentation with migration guide and new API examples
- Revised authentication flow to use standard requests.Session

### Security

- Enhanced validation for GUID parameters
- Stricter type checking for all API inputs
- Mandatory form digest validation for write operations

## 0.2.9 – 2025-12-11

### Added

- Using a pre-defined session when initializing.
- Support for merging session-level headers in API calls, preserving custom session headers.

### Changed

- Added deprecation warnings for `_compact_init`.

## 0.2.8 – 2025-12-05

### Added

- Added a central datetime handler method to ensure timezone-aware datetimes.

## 0.2.6 – 2025-12-05

### Added

- Added select_fields option to the `get_site_metadata` method

## 0.2.5 – 2025-12-05

### Changed

- Replace `_resolve_sp_list` with `_resolve_sp_list_url` returning a URL fragment, simplifying GUID handling.
- Update all API calls to use the new URL fragment across list retrieval, item operations, and metadata fetching.
- Simplify `SharePointListItem` constructor by removing explicit `list_guid` argument and adding a lazy `list_guid` property that extracts GUID from the parent list URI.

## 0.2.4 – 2025-12-03

### Added

- New high-level `SharePointSite` object providing lazy-loaded site metadata

## 0.2.3 – 2025-12-02

### Added

- GUID validation for list identifiers with fallback to list title lookup via `GetByTitle`.
- New helper method `_is_valid_guid` in `SharePointAPI`.
- Centralized list resolution helper `_resolve_sp_list` for GUID, title, or `SharePointList` instances.
- New method `get_list_metadata` to fetch only list metadata without items.
- Type hint enhancements: added `Optional`, `Tuple` imports; updated method signatures (e.g., `get_item_versions` now uses `Optional[List[str]]`).
- Updated `get_list` to return the resolved `SharePointList` object after appending items.
- Refactored multiple methods (`get_item`, `create_item`, `update_item`, `attach_file`, `get_item_versions`, `get_case`) to use `_resolve_sp_list`, removing redundant GUID validation logic.

### Changed

- Cleaned up stray `else:` blocks and syntax errors.
- Improved consistency of return objects across list-related methods.
- Updated imports and docstrings accordingly.

## 0.2.2 – 2025-11-28

### Added

- `SharePointList.fields` property to retrieve list field definitions

## 0.2.1 – 2025-11-06

### Added

- Optional `select_fields` parameters to list retrieval methods for more efficient queries.
- New public API methods:
  - `SharePointAPI.get_group_users` – fetch users of a SharePoint group.
- Improved error handling with explicit `TypeError` exceptions.
- Detailed docstrings for core classes and methods (enhances IDE support).

### Changed

- HTTP header handling unified; corrected `X-HTTP-Method: PUT` for full updates.
- Error handling improved: generic `sys.exit(1)` replaced with explicit `TypeError`/`ConnectionError` exceptions.

### Fixed

- Fixed incorrect PUT header that previously sent a MERGE header.
- Minor docstring formatting issues.

### Security

- Enforced NTLM authentication across all request helpers.
