Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.7.1

* Use only a GET request when no body, otherwise POST

## 1.7.0

* Added type annotations
Expand Down
24 changes: 17 additions & 7 deletions pypi.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
# Tinify

**Tinify** is the official Python client for the [TinyPNG](https://tinypng.com) and [TinyJPG](https://tinyjpg.com) image compression API, enabling developers to optimize PNG, JPEG, and WebP images programmatically.
**Tinify** is the official Python client for the [TinyPNG](https://tinypng.com) and [TinyJPG](https://tinyjpg.com/) image compression API, enabling developers to intelligently compress, resize, convert and optimize PNG, APNG, JPEG, WebP and AVIF images programmatically. Read more at [https://tinify.com](https://tinify.com/developers).

[![PyPI version](https://badge.fury.io/py/tinify.svg)](https://badge.fury.io/py/tinify)
[![Build Status](https://github.com/tinify/tinify-python/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/tinify/tinify-python/)

## Features

- Compress images, reducing file size by 50-80% while preserving visual quality
- Compress and optimize images, reducing file size by 50-80% while preserving visual quality
- Resize and crop images with smart compression
- Convert between PNG, JPEG, and WebP formats
- Convert between PNG, JPEG, WebP and AVIF formats
- Preserve metadata (optional)
- Upload to storage providers like Amazon S3, Google cloud storage.
- Apply visual transformations with the Tinify API
- Supports asynchronous operations
- Comprehensive error handling

## Installation

```python
```bash
pip install tinify
```

Expand Down Expand Up @@ -75,6 +76,15 @@ tinify.from_file("image.png").convert(
).to_file("image.webp")
```

```python
# Convert to smallest format
converted = tinify.from_file("image.png").convert(
type=["image/webp", "image/webp"]
)
extension = converted.result().extension
converted.to_file("image." + extension)
```

### Compression Count Monitoring

```python
Expand Down Expand Up @@ -111,7 +121,7 @@ except Exception as e:

## Requirements

- Python 3.6+
- Python 2.7+
- Requests library

## Documentation
Expand All @@ -124,4 +134,4 @@ This software is licensed under the MIT License. See [LICENSE](https://github.co

## Support

For issues and feature requests, please use our [GitHub Issues](https://github.com/tinify/tinify-python/issues) page.
For issues and feature requests, please use our [GitHub Issues](https://github.com/tinify/tinify-python/issues) page or contact us at [support@tinify.com](mailto:support@tinify.com)
20 changes: 20 additions & 0 deletions test/unit/tinify_source_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ def test_from_url_should_raise_error_when_server_doesnt_return_a_success(
def test_result_should_return_result(self):
assert isinstance(Source.from_buffer(b"png file").result(), Result)

def test_result_should_use_get_when_commands_is_empty(self, mock_requests):
source = Source(b"png file")
source.url = "https://api.tinify.com/some/location"
mock_requests.get(
"https://api.tinify.com/some/location", content=b"compressed file"
)
source.result()
assert mock_requests.call_count == 1
assert mock_requests.last_request.method == "GET"

def test_result_should_use_post_when_commands_is_not_empty(self, mock_requests):
source = Source(b"png file").resize(width=400)
source.url = "https://api.tinify.com/some/location"
mock_requests.post(
"https://api.tinify.com/some/location", content=b"small file"
)
source.result()
assert mock_requests.call_count == 1
assert mock_requests.last_request.method == "POST"

def test_preserve_should_return_source(self, mock_requests):
assert isinstance(
Source.from_buffer(b"png file").preserve("copyright", "location"), Source
Expand Down
5 changes: 4 additions & 1 deletion tinify/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ def store(self, **options): # type: (Any) -> ResultMeta
return ResultMeta(response.headers)

def result(self): # type: () -> Result
response = tinify.get_client().request('GET', self.url, self.commands)
if not self.commands:
response = tinify.get_client().request('GET', self.url, self.commands)
else:
response = tinify.get_client().request('POST', self.url, self.commands)
return Result(response.headers, response.content)

def to_file(self, path): # type: (Union[str, IO]) -> None
Expand Down
2 changes: 1 addition & 1 deletion tinify/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.7.0'
__version__ = '1.7.1'
Loading