s3-lifecycle


Names3-lifecycle JSON
Version 0.1.2 PyPI version JSON
download
home_pagehttps://github.com/FernandoOLI/s3_lifecycle
SummaryA Python library to manage S3 lifecycle policies
upload_time2025-08-28 12:52:02
maintainerNone
docs_urlNone
authorFernando Oliveira Pereira
requires_python>=3.6
licenseMIT
keywords aws s3 s3_lifecycle
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# s3-lifecycle

![PyPI](https://img.shields.io/pypi/v/s3-lifecycle?label=PyPI&color=blue)
![TestPyPI](https://img.shields.io/badge/TestPyPI-v0.1.1-orange)

A small Python library to **compute and apply policies** on AWS S3 lifecycle policies—especially focused on safe, declarative **storage class transitions**—with dry-run, validation, and minimal disruption.

---

## Problem

AWS S3 lifecycle policies are typically applied by overwriting the entire configuration. That makes automated changes brittle, error-prone, and risky when you only want to tweak transitions (e.g., change from `STANDARD` → `GLACIER` after 90 days) without accidentally deleting other rules.

This library:

- Introspects the current lifecycle policy
- Compares it to the desired policy
- Shows what would change (dry-run)
- Validates rules
- Applies only the intended change safely

---

## Features

- Declarative lifecycle policy definitions (via Python / JSON)
- Diff engine: detects rule adds / updates / deletes
- Safe apply with `dry-run`
- Validation of transition semantics (e.g., non-decreasing days)
- Idempotent behavior
- Pluggable for custom validation or rule logic

---

## Quickstart

### 1. Set Up AWS Environment

Before using `s3-lifecycle`, configure AWS credentials.

#### a) Using AWS CLI

```bash
aws configure
```

Provide:

```
AWS Access Key ID [None]: <YOUR_ACCESS_KEY>
AWS Secret Access Key [None]: <YOUR_SECRET_KEY>
Default region name [None]: <YOUR_DEFAULT_REGION>  # e.g., us-east-1
Default output format [None]: json
```

#### b) Using environment variables

**Linux/macOS:**

```bash
export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY>
export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_KEY>
export AWS_DEFAULT_REGION=us-east-1
```

**Windows (PowerShell):**

```powershell
setx AWS_ACCESS_KEY_ID "<YOUR_ACCESS_KEY>"
setx AWS_SECRET_ACCESS_KEY "<YOUR_SECRET_KEY>"
setx AWS_DEFAULT_REGION "us-east-1"
```

> ⚠️ Ensure your IAM user has `s3:GetLifecycleConfiguration` and `s3:PutLifecycleConfiguration` permissions.

---

### 2. Install the Library

```bash
git clone https://github.com/FernandoOLI/s3-lifecycle.git
cd s3-lifecycle
pip install -e .
```

---

### 3. Basic Usage

```python
from s3_lifecycle import LifecyclePolicy, LifecycleManager, validate_policy, ValidationError, ApplyError

# Example lifecycle policy dictionary
desired_policy_dict = {
    "Rules": [
        {
            "ID": "archive-log",
            "Filter": {"Prefix": "logs/"},
            "Status": "Enabled",
            "Transitions": [
                {"Days": 300, "StorageClass": "GLACIER"},
                {"Days": 390, "StorageClass": "DEEP_ARCHIVE"}
            ],
            "Expiration": {'Days': 500},
            "NoncurrentVersionTransitions": [
                {"NoncurrentDays": 30, "StorageClass": "GLACIER"},
                {"NoncurrentDays": 150, "StorageClass": "DEEP_ARCHIVE"}
            ],
            "NoncurrentVersionExpiration": {'NoncurrentDays': 700}
        }
    ]
}

def main():
    try:
        # Create and validate policy
        policy = LifecyclePolicy.from_dict(desired_policy_dict)
        validate_policy(policy)

        bucket = "lifecycle-management-bucket"

        # Initialize manager (will create boto3 client if not passed)
        manager = LifecycleManager()

        # Compute input vs current S3 bucket policy
        diff_result = manager.compute(bucket, policy)

        # Apply changes safely (dry_run=True prints summary only)
        manager.apply(bucket, diff_result, policy, dry_run=True)

    except ValidationError as ve:
        print(f"Policy validation error: {ve}, details: {ve.details}")
    except ApplyError as ae:
        print(f"Failed to apply lifecycle policy: {ae}")
    except Exception as e:
        print(f"Unexpected error: {e}")

if __name__ == "__main__":
    main()
```

---

### 4. Notes

- `dry_run=True` only prints changes; no modifications are applied.  
- Always validate IAM permissions before running `apply`.  
- Supports declarative JSON/Python policy definitions for safe incremental updates.

---

## Contributing

1. Fork the repository  
2. Create a feature branch (`git checkout -b feature/my-feature`)  
3. Make your changes  
4. Run tests and ensure coverage  
5. Submit a Pull Request  

---

## License

MIT License

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/FernandoOLI/s3_lifecycle",
    "name": "s3-lifecycle",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "aws, s3, s3_lifecycle",
    "author": "Fernando Oliveira Pereira",
    "author_email": "Fernando Oliveira Pereira <oliveira-fernando1@hotmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/c3/38/ed2c1ca85663fd24ca2cc9c71522ed786f908d07c09e730e4ebcf1f632dd/s3_lifecycle-0.1.2.tar.gz",
    "platform": null,
    "description": "\n# s3-lifecycle\n\n![PyPI](https://img.shields.io/pypi/v/s3-lifecycle?label=PyPI&color=blue)\n![TestPyPI](https://img.shields.io/badge/TestPyPI-v0.1.1-orange)\n\nA small Python library to **compute and apply policies** on AWS S3 lifecycle policies\u2014especially focused on safe, declarative **storage class transitions**\u2014with dry-run, validation, and minimal disruption.\n\n---\n\n## Problem\n\nAWS S3 lifecycle policies are typically applied by overwriting the entire configuration. That makes automated changes brittle, error-prone, and risky when you only want to tweak transitions (e.g., change from `STANDARD` \u2192 `GLACIER` after 90 days) without accidentally deleting other rules.\n\nThis library:\n\n- Introspects the current lifecycle policy\n- Compares it to the desired policy\n- Shows what would change (dry-run)\n- Validates rules\n- Applies only the intended change safely\n\n---\n\n## Features\n\n- Declarative lifecycle policy definitions (via Python / JSON)\n- Diff engine: detects rule adds / updates / deletes\n- Safe apply with `dry-run`\n- Validation of transition semantics (e.g., non-decreasing days)\n- Idempotent behavior\n- Pluggable for custom validation or rule logic\n\n---\n\n## Quickstart\n\n### 1. Set Up AWS Environment\n\nBefore using `s3-lifecycle`, configure AWS credentials.\n\n#### a) Using AWS CLI\n\n```bash\naws configure\n```\n\nProvide:\n\n```\nAWS Access Key ID [None]: <YOUR_ACCESS_KEY>\nAWS Secret Access Key [None]: <YOUR_SECRET_KEY>\nDefault region name [None]: <YOUR_DEFAULT_REGION>  # e.g., us-east-1\nDefault output format [None]: json\n```\n\n#### b) Using environment variables\n\n**Linux/macOS:**\n\n```bash\nexport AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY>\nexport AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_KEY>\nexport AWS_DEFAULT_REGION=us-east-1\n```\n\n**Windows (PowerShell):**\n\n```powershell\nsetx AWS_ACCESS_KEY_ID \"<YOUR_ACCESS_KEY>\"\nsetx AWS_SECRET_ACCESS_KEY \"<YOUR_SECRET_KEY>\"\nsetx AWS_DEFAULT_REGION \"us-east-1\"\n```\n\n> \u26a0\ufe0f Ensure your IAM user has `s3:GetLifecycleConfiguration` and `s3:PutLifecycleConfiguration` permissions.\n\n---\n\n### 2. Install the Library\n\n```bash\ngit clone https://github.com/FernandoOLI/s3-lifecycle.git\ncd s3-lifecycle\npip install -e .\n```\n\n---\n\n### 3. Basic Usage\n\n```python\nfrom s3_lifecycle import LifecyclePolicy, LifecycleManager, validate_policy, ValidationError, ApplyError\n\n# Example lifecycle policy dictionary\ndesired_policy_dict = {\n    \"Rules\": [\n        {\n            \"ID\": \"archive-log\",\n            \"Filter\": {\"Prefix\": \"logs/\"},\n            \"Status\": \"Enabled\",\n            \"Transitions\": [\n                {\"Days\": 300, \"StorageClass\": \"GLACIER\"},\n                {\"Days\": 390, \"StorageClass\": \"DEEP_ARCHIVE\"}\n            ],\n            \"Expiration\": {'Days': 500},\n            \"NoncurrentVersionTransitions\": [\n                {\"NoncurrentDays\": 30, \"StorageClass\": \"GLACIER\"},\n                {\"NoncurrentDays\": 150, \"StorageClass\": \"DEEP_ARCHIVE\"}\n            ],\n            \"NoncurrentVersionExpiration\": {'NoncurrentDays': 700}\n        }\n    ]\n}\n\ndef main():\n    try:\n        # Create and validate policy\n        policy = LifecyclePolicy.from_dict(desired_policy_dict)\n        validate_policy(policy)\n\n        bucket = \"lifecycle-management-bucket\"\n\n        # Initialize manager (will create boto3 client if not passed)\n        manager = LifecycleManager()\n\n        # Compute input vs current S3 bucket policy\n        diff_result = manager.compute(bucket, policy)\n\n        # Apply changes safely (dry_run=True prints summary only)\n        manager.apply(bucket, diff_result, policy, dry_run=True)\n\n    except ValidationError as ve:\n        print(f\"Policy validation error: {ve}, details: {ve.details}\")\n    except ApplyError as ae:\n        print(f\"Failed to apply lifecycle policy: {ae}\")\n    except Exception as e:\n        print(f\"Unexpected error: {e}\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n---\n\n### 4. Notes\n\n- `dry_run=True` only prints changes; no modifications are applied.  \n- Always validate IAM permissions before running `apply`.  \n- Supports declarative JSON/Python policy definitions for safe incremental updates.\n\n---\n\n## Contributing\n\n1. Fork the repository  \n2. Create a feature branch (`git checkout -b feature/my-feature`)  \n3. Make your changes  \n4. Run tests and ensure coverage  \n5. Submit a Pull Request  \n\n---\n\n## License\n\nMIT License\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Python library to manage S3 lifecycle policies",
    "version": "0.1.2",
    "project_urls": {
        "Homepage": "https://github.com/FernandoOLI/s3_lifecycle",
        "Issues": "https://github.com/FernandoOLI/s3_lifecycle/issues"
    },
    "split_keywords": [
        "aws",
        " s3",
        " s3_lifecycle"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2f2e56f617b10501bd204a6b2b5c5d86fdf2eb0aace36f6217e1faf2ce0209c4",
                "md5": "bbd9f96a3a202630b43e9de48e87be0e",
                "sha256": "87471dab15d5153264f6184887e549e2ecf4f0303659226ec96c51b73f4a0f04"
            },
            "downloads": -1,
            "filename": "s3_lifecycle-0.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "bbd9f96a3a202630b43e9de48e87be0e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 9929,
            "upload_time": "2025-08-28T12:52:00",
            "upload_time_iso_8601": "2025-08-28T12:52:00.863025Z",
            "url": "https://files.pythonhosted.org/packages/2f/2e/56f617b10501bd204a6b2b5c5d86fdf2eb0aace36f6217e1faf2ce0209c4/s3_lifecycle-0.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c338ed2c1ca85663fd24ca2cc9c71522ed786f908d07c09e730e4ebcf1f632dd",
                "md5": "2a506f7f0f5f9ce514ec699d7c59425c",
                "sha256": "3bcaebc78a558215623ead2c97ee1a46470df4db1db0081ac5554700c9ebdaf4"
            },
            "downloads": -1,
            "filename": "s3_lifecycle-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "2a506f7f0f5f9ce514ec699d7c59425c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 7908,
            "upload_time": "2025-08-28T12:52:02",
            "upload_time_iso_8601": "2025-08-28T12:52:02.089690Z",
            "url": "https://files.pythonhosted.org/packages/c3/38/ed2c1ca85663fd24ca2cc9c71522ed786f908d07c09e730e4ebcf1f632dd/s3_lifecycle-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-28 12:52:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "FernandoOLI",
    "github_project": "s3_lifecycle",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "s3-lifecycle"
}
        
Elapsed time: 0.45964s