Skip to content

Commit 0a3956f

Browse files
authored
Merge pull request #33 from Copyleaks/add-ai-image-detection
added image detection service to copyleaks sdk
2 parents d7e8efb + 0869083 commit 0a3956f

21 files changed

+802
-180
lines changed

README.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ from copyleaks.models.submit.properties.score_weights import ScoreWeights
107107
scan_id = "your-scan-id"
108108

109109
# Define the text to be assessed
110-
sample_text = "This text have some grammer mistake and it is not good written."
110+
sample_text = "Copyleaks is a comprehensive plagiarism detection platform that performs extensive searches across 60 trillion websites, 15,000+ academic journals, 20+ code data repositories, and 1M+ internal documents. Using AI-powered text analysis, easily scan documents, raw text, code, and URLs and instantly receive detailed reporting on the findings."
111111

112112
# Configure score weights for different aspects of writing quality
113113
score_weight = ScoreWeights()
@@ -169,12 +169,47 @@ For a full guide please refer to our step by step [Guide](https://docs.copyleaks
169169

170170
For a detailed understanding of the Text moderation process, refer to the Copyleaks text moderation Endpoint [Documentation](https://docs.copyleaks.com/reference/actions/text-moderation/check/)
171171
##
172-
## Further Resources
172+
### Image Detection
173+
Determine if a given image was generated or partially generated by an AI.
174+
175+
```python
176+
import base64
177+
from copyleaks.models.ImageDetection.Requests.CopyleaksAiImageDetectionRequestModel import CopyleaksAiImageDetectionRequestModel
178+
from copyleaks.copyleaks import Copyleaks
179+
from copyleaks.models.constants.CopyleaksAiImageDetectionModels import CopyleaksAiImageDetectionModels
180+
181+
scan_id = "your-scan-id"
182+
print("Submitting a new image for AI image detection...")
183+
184+
# Update the path to your image file
185+
image_path = r"PATH TO IMAGE"
186+
187+
with open(image_path, 'rb') as image_file:
188+
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
189+
190+
payload = CopyleaksAiImageDetectionRequestModel(
191+
base64=base64_image,
192+
file_name='my-image.png',
193+
sandbox=True,
194+
model=CopyleaksAiImageDetectionModels.AI_IMAGE_1_ULTRA
195+
)
196+
response = Copyleaks.ImageDetectionClient.submit(auth_token, scan_id, payload)
197+
198+
print("Image Detection Response:")
199+
print(response.model_dump_json())
200+
201+
202+
```
203+
For a full guide please refer to our step by step [Guide](https://docs.copyleaks.com/guides/ai-detector/ai-image-detection/)
204+
205+
For a detailed understanding of the Image detection process, refer to the Copyleaks image detection Endpoint [Documentation](https://docs.copyleaks.com/reference/actions/ai-image-detector/check/)
206+
##
207+
### Further Resources
173208

174209
* **Copyleaks API Dashboard:** Manage your API keys, monitor usage, and view analytics from your personalized dashboard. [Access Dashboard](https://api.copyleaks.com/dashboard)
175210
* **Copyleaks SDK Documentation:** Explore comprehensive guides, API references, and code examples for seamless integration. [Read Documentation](https://docs.copyleaks.com/resources/sdks/overview/)
176211

177-
178-
## Support
212+
##
213+
### Support
179214
* If you need assistance, please contact Copyleaks Support via our support portal: Contact Copyleaks [Support](https://help.copyleaks.com/s/contactsupport).
180215
* To arrange a product demonstration, book a demo here: [Booking Link](https://copyleaks.com/book-a-demo).
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'''
2+
The MIT License(MIT)
3+
4+
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com)
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
'''
24+
25+
import requests
26+
from copyleaks.consts import Consts
27+
from copyleaks.exceptions.command_error import CommandError
28+
from copyleaks.exceptions.under_maintenance_error import UnderMaintenanceError
29+
from copyleaks.helpers.copyleaks_client_helper import CopyleaksClientHelper
30+
from copyleaks.models.ImageDetection.Responses.CopyleaksAiImageDetectionResponseModel import CopyleaksAiImageDetectionResponseModel
31+
32+
33+
class _AiImageDetectionClient:
34+
@staticmethod
35+
def __submit(url, auth_token, scan_id, requestModel):
36+
assert url and scan_id and requestModel
37+
38+
CopyleaksClientHelper.verify_auth_token(auth_token)
39+
40+
headers = {
41+
'Content-Type': 'application/json',
42+
'User-Agent': Consts.USER_AGENT,
43+
'Authorization': f"Bearer {auth_token['access_token']}"
44+
}
45+
46+
json_data = requestModel.model_dump_json(by_alias=True)
47+
48+
response = requests.post(url, headers=headers, data=json_data)
49+
50+
if response.ok:
51+
return CopyleaksAiImageDetectionResponseModel(**response.json())
52+
elif response.status_code == 503:
53+
print(f"Error: Service under maintenance (HTTP {response.status_code})")
54+
print(f"Response: {response.text}")
55+
raise UnderMaintenanceError()
56+
else:
57+
print(f"Error: AI Image Detection request failed (HTTP {response.status_code})")
58+
print(f"Response: {response.text}")
59+
raise CommandError(response)
60+
61+
@staticmethod
62+
def submit(auth_token, scan_id, submission):
63+
64+
url = f"{Consts.API_SERVER_URI}/v1/ai-image-detector/{scan_id}/check"
65+
return _AiImageDetectionClient.__submit(url, auth_token, scan_id, submission)

copyleaks/copyleaks.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@
3636
from copyleaks.clients.ai_detection_client import _AIDetectionClient
3737
from copyleaks.clients.writing_assistant_client import _WritingAssistantClient
3838
from copyleaks.clients.TextModerationClient import _TextModerationClient
39-
import os
39+
from copyleaks.clients.AiImageDetectionClient import _AiImageDetectionClient
4040

4141
class Copyleaks(object):
4242

4343
WritingAssistantClient = _WritingAssistantClient
4444
AiDetectionClient = _AIDetectionClient
45-
TextModerationClient=_TextModerationClient
45+
TextModerationClient= _TextModerationClient
46+
ImageDetectionClient= _AiImageDetectionClient
4647

4748
@staticmethod
4849
def set_identity_uri(uri):
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
'''
2+
The MIT License(MIT)
3+
4+
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com)
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
'''
24+
25+
from pydantic import BaseModel, Field, field_validator, validator
26+
27+
28+
class CopyleaksAiImageDetectionRequestModel(BaseModel):
29+
"""
30+
Request model for Copyleaks AI image detection.
31+
The request body is a JSON object containing the image to analyze.
32+
"""
33+
34+
base64: str = Field(
35+
...,
36+
description="The base64-encoded image data to be analyzed for AI generation.",
37+
example="aGVsbG8gd29ybGQ=",
38+
alias="base64"
39+
)
40+
41+
file_name: str = Field(
42+
...,
43+
description="The name of the image file including its extension.",
44+
example="my-image.png",
45+
alias="filename",
46+
max_length=255
47+
)
48+
49+
model: str = Field(
50+
...,
51+
description="The AI detection model to use for analysis. You can use either the full model name or its alias.",
52+
example="ai-image-1-ultra",
53+
alias="model"
54+
)
55+
56+
sandbox: bool = Field(
57+
default=False,
58+
description="Use sandbox mode to test your integration with the Copyleaks API without consuming any credits.",
59+
example=False,
60+
alias="sandbox"
61+
)
62+
63+
def __init__(self, base64: str, file_name: str, model: str, sandbox: bool = False, **data):
64+
"""
65+
Initialize the CopyleaksAiImageDetectionRequestModel.
66+
67+
Args:
68+
base64: The base64-encoded image data to be analyzed for AI generation.
69+
Requirements:
70+
- Minimum 512×512px, maximum 16 megapixels, less than 32MB
71+
- Supported formats: PNG, JPEG, BMP, WebP, HEIC/HEIF
72+
file_name: The name of the image file including its extension.
73+
Requirements:
74+
- Supported extensions: .png, .bmp, .jpg, .jpeg, .webp, .heic, .heif
75+
- Maximum 255 characters
76+
model: The AI detection model to use for analysis.
77+
Available models:
78+
- AI Image 1 Ultra: "ai-image-1-ultra-01-09-2025" (full name) or "ai-image-1-ultra" (alias)
79+
AI image detection model. Produces an overlay of the detected AI segments.
80+
sandbox: Use sandbox mode to test your integration with the Copyleaks API without consuming any credits.
81+
Submit images for AI detection and get returned mock results, simulating Copyleaks' API functionality
82+
to ensure you have successfully integrated the API.
83+
This feature is intended to be used for development purposes only.
84+
Default value is False.
85+
"""
86+
super().__init__(base64=base64, filename=file_name, model=model, sandbox=sandbox, **data)
87+
88+
@field_validator('file_name')
89+
def validate_file_name(cls, v):
90+
"""Validate the file name has a supported extension."""
91+
if not v:
92+
raise ValueError('File name is required')
93+
94+
supported_extensions = ['.png', '.bmp', '.jpg', '.jpeg', '.webp', '.heic', '.heif']
95+
if not any(v.lower().endswith(ext) for ext in supported_extensions):
96+
raise ValueError(f'File name must have one of the supported extensions: {", ".join(supported_extensions)}')
97+
98+
return v
99+
100+
@field_validator('base64')
101+
def validate_base64(cls, v):
102+
"""Validate base64 string is not empty."""
103+
if not v or not v.strip():
104+
raise ValueError('Base64 data is required and cannot be empty')
105+
return v
106+
107+
@field_validator('model')
108+
def validate_model(cls, v):
109+
"""Validate model name is not empty."""
110+
if not v or not v.strip():
111+
raise ValueError('Model name is required and cannot be empty')
112+
return v
113+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'''
2+
The MIT License(MIT)
3+
4+
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com)
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
'''
24+
25+
from typing import Optional
26+
from pydantic import BaseModel, Field
27+
28+
from copyleaks.models.ImageDetection.Responses.CopyleaksImageMetadataModel import CopyleaksImageMetadataModel
29+
from copyleaks.models.ImageDetection.Responses.CopyleaksImageShapeModel import CopyleaksImageShapeModel
30+
31+
32+
class CopyleaksAiImageDetectionImageInfoModel(BaseModel):
33+
"""
34+
Information about the analyzed image.
35+
"""
36+
37+
shape: Optional[CopyleaksImageShapeModel] = Field(
38+
default=None,
39+
description="Dimensions of the analyzed image.",
40+
alias="shape"
41+
)
42+
43+
metadata: Optional[CopyleaksImageMetadataModel] = Field(
44+
default=None,
45+
description="Optional metadata extracted from the image.",
46+
alias="metadata"
47+
)
48+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'''
2+
The MIT License(MIT)
3+
4+
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com)
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
'''
24+
25+
from pydantic import BaseModel, Field
26+
from copyleaks.models.ImageDetection.Responses.CopyleaksAiImageDetectionImageInfoModel import CopyleaksAiImageDetectionImageInfoModel
27+
from copyleaks.models.ImageDetection.Responses.CopyleaksAiImageDetectionResultModel import CopyleaksAiImageDetectionResultModel
28+
from copyleaks.models.ImageDetection.Responses.CopyleaksAiImageDetectionScannedDocumentModel import CopyleaksAiImageDetectionScannedDocumentModel
29+
from copyleaks.models.ImageDetection.Responses.CopyleaksAiImageDetectionSummaryModel import CopyleaksAiImageDetectionSummaryModel
30+
31+
32+
33+
class CopyleaksAiImageDetectionResponseModel(BaseModel):
34+
"""
35+
Response model for Copyleaks AI image detection analysis.
36+
Contains the AI detection results, image information, and scan metadata.
37+
"""
38+
39+
model: str = Field(
40+
...,
41+
description="The version of the AI detection model used for analysis.",
42+
alias="model"
43+
)
44+
45+
result: CopyleaksAiImageDetectionResultModel = Field(
46+
...,
47+
description="RLE-encoded mask data containing arrays of start positions and lengths for AI-detected regions.",
48+
alias="result"
49+
)
50+
51+
summary: CopyleaksAiImageDetectionSummaryModel = Field(
52+
...,
53+
description="Summary statistics of the AI detection analysis.",
54+
alias="summary"
55+
)
56+
57+
image_info: CopyleaksAiImageDetectionImageInfoModel = Field(
58+
...,
59+
description="Information about the analyzed image.",
60+
alias="imageInfo"
61+
)
62+
63+
scanned_document: CopyleaksAiImageDetectionScannedDocumentModel = Field(
64+
...,
65+
description="Metadata about the scan operation.",
66+
alias="scannedDocument"
67+
)

0 commit comments

Comments
 (0)