-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from Copyleaks/features/1207019394509570/add-w…
…riting-feedback-and-ai-detector Features/1207019394509570/add writing feedback and ai detector
- Loading branch information
Showing
10 changed files
with
439 additions
and
1 deletion.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
|
||
''' | ||
The MIT License(MIT) | ||
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com) | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
''' | ||
|
||
from aifc import Error | ||
import requests | ||
from copyleaks.consts import Consts | ||
from copyleaks.helpers.copyleaks_client_helper import CopyleaksClientHelper | ||
|
||
class _AIDetectionClient: | ||
@staticmethod | ||
def __submit(url, auth_token, scan_id, submission): | ||
assert url and scan_id and submission | ||
|
||
CopyleaksClientHelper.verify_auth_token(auth_token) | ||
|
||
headers = { | ||
'Content-Type': 'application/json', | ||
'User-Agent': Consts.USER_AGENT, | ||
'Authorization': f"Bearer {auth_token['access_token']}" | ||
} | ||
json = submission.toJSON() | ||
response = requests.post(url, headers=headers, data=json) | ||
if response.ok: | ||
return response.json() | ||
elif response.status_code == 503: | ||
raise Error() | ||
else: | ||
raise Error(response) | ||
|
||
@staticmethod | ||
def submit_natural_language(auth_token, scan_id, submission): | ||
''' | ||
Use Copyleaks AI Content Detection to differentiate between human texts and AI written texts. | ||
This endpoint will receive submitted text to be checked. At the end of the processing stage, | ||
the result will be shown as classifications. Text classification is divided into sections. | ||
Each section may have a different classification | ||
Raises: | ||
`CommandError`: Server reject the request. See response status code, headers and content for more info. | ||
`UnderMaintenanceError`: Copyleaks servers are unavailable for maintenance. We recommend to implement exponential backoff algorithm as described here: https://api.copyleaks.com/documentation/v3/exponential-backoff | ||
''' | ||
url = f"{Consts.API_SERVER_URI}/v2/writer-detector/{scan_id}/check" | ||
return _AIDetectionClient.__submit(url, auth_token, scan_id, submission) | ||
|
||
|
||
@staticmethod | ||
def submit_source_code(auth_token, scan_id, submission): | ||
''' | ||
Use Copyleaks AI Content Detection to differentiate between human source code and AI written source code. | ||
This endpoint will receive submitted source code to be checked. | ||
At the end of the processing stage, the result will be shown as classifications. | ||
Source code classification is divided into sections. Each section may have a different classification. | ||
Raises: | ||
`CommandError`: Server reject the request. See response status code, headers and content for more info. | ||
`UnderMaintenanceError`: Copyleaks servers are unavailable for maintenance. We recommend to implement exponential backoff algorithm as described here: https://api.copyleaks.com/documentation/v3/exponential-backoff | ||
''' | ||
url = f"{Consts.API_SERVER_URI}/v2/writer-detector/source-code/{scan_id}/check" | ||
return _AIDetectionClient.__submit(url, auth_token, scan_id, submission) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
|
||
''' | ||
The MIT License(MIT) | ||
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com) | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
''' | ||
|
||
import requests | ||
from copyleaks.consts import Consts | ||
from copyleaks.exceptions.command_error import CommandError | ||
from copyleaks.exceptions.under_maintenance_error import UnderMaintenanceError | ||
from copyleaks.helpers.copyleaks_client_helper import CopyleaksClientHelper | ||
|
||
class _WritingAssistantClient: | ||
@staticmethod | ||
def __submit(url, auth_token, scan_id, submission): | ||
assert url and scan_id and submission | ||
|
||
CopyleaksClientHelper.verify_auth_token(auth_token) | ||
|
||
headers = { | ||
'Content-Type': 'application/json', | ||
'User-Agent': Consts.USER_AGENT, | ||
'Authorization': f"Bearer {auth_token['access_token']}" | ||
} | ||
json = submission.toJSON() | ||
response = requests.post(url, headers=headers, data=json) | ||
if response.ok: | ||
return response.json() | ||
elif response.status_code == 503: | ||
raise UnderMaintenanceError() | ||
else: | ||
raise CommandError(response) | ||
|
||
@staticmethod | ||
def submit_text(auth_token, scan_id, submission): | ||
''' | ||
Use Copyleaks Writing Assistant to generate grammar, spelling and sentence corrections for a given text. | ||
This endpoint will receive submitted text to be checked. The response will show the suggested corrections to the input text. | ||
Raises: | ||
`CommandError`: Server reject the request. See response status code, headers and content for more info. | ||
`UnderMaintenanceError`: Copyleaks servers are unavailable for maintenance. We recommend to implement exponential backoff algorithm as described here: https://api.copyleaks.com/documentation/v3/exponential-backoff | ||
''' | ||
url = f"{Consts.API_SERVER_URI}/v1/writing-feedback/{scan_id}/check" | ||
return _WritingAssistantClient.__submit(url, auth_token, scan_id, submission) | ||
|
||
@staticmethod | ||
def get_correction_types(language_code): | ||
''' | ||
Get a list of correction types supported within the Writing Assistant API. | ||
Correction types apply to all supported languages. | ||
The supplied language code for this request is used to determine the language of the texts returned. | ||
Raises: | ||
`CommandError`: Server reject the request. See response status code, headers and content for more info. | ||
`UnderMaintenanceError`: Copyleaks servers are unavailable for maintenance. We recommend to implement exponential backoff algorithm as described here: https://api.copyleaks.com/documentation/v3/exponential-backoff | ||
Returns: | ||
List of supported correction types. | ||
''' | ||
|
||
url = f"{Consts.API_SERVER_URI}/v1/writing-feedback/correction-types/{language_code}" | ||
headers = { | ||
'User-Agent': Consts.USER_AGENT | ||
} | ||
|
||
response = requests.get(url, headers=headers) | ||
if response.ok: | ||
return response.json() | ||
elif response.status_code == 503: | ||
raise UnderMaintenanceError() | ||
else: | ||
raise CommandError(response.content) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from datetime import datetime, timedelta | ||
import dateutil.parser | ||
import pytz | ||
from copyleaks.exceptions.auth_expired_error import AuthExipredError | ||
|
||
class CopyleaksClientHelper: | ||
@staticmethod | ||
def verify_auth_token(auth_token): | ||
''' | ||
Verify that Copyleaks authentication token is exists and not expired. | ||
Parameters: | ||
auth_token: Copyleaks authentication token | ||
Raises: | ||
`AuthExipredError`: authentication expired. Need to login again. | ||
''' | ||
assert auth_token and auth_token['.expires'] and auth_token['access_token'] | ||
|
||
now = pytz.UTC.localize(datetime.utcnow() + timedelta(0, 5 * 60)) # adds 5 minutes ahead for a safety shield. | ||
upTo = dateutil.parser.parse(auth_token['.expires']) | ||
|
||
if upTo <= now: | ||
raise AuthExipredError() # expired |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
''' | ||
The MIT License(MIT) | ||
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com) | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
''' | ||
|
||
from abc import ABC | ||
import json | ||
|
||
class AiDetectionDocument(ABC): | ||
def __init__(self, text): | ||
assert text | ||
self.text = text | ||
|
||
def get_text(self): | ||
return self.text | ||
|
||
def set_text(self, value): | ||
assert value | ||
self.text = value | ||
|
||
def get_sandbox(self): | ||
return self.sandbox | ||
|
||
def set_sandbox(self, value): | ||
self.sandbox = value | ||
|
||
def toJSON(self): | ||
return json.dumps(self, default=lambda o: o.__dict__, | ||
sort_keys=True, indent=4) | ||
|
||
|
||
class NaturalLanguageDocument(AiDetectionDocument): | ||
def __init__(self, text): | ||
super().__init__(text) | ||
|
||
def get_language(self): | ||
return self.language | ||
|
||
def set_language(self, value): | ||
self.language = value | ||
|
||
|
||
class SourceCodeDocument(AiDetectionDocument): | ||
def __init__(self, text, filename): | ||
super().__init__(text) | ||
self.filename = filename | ||
|
||
def get_filename(self): | ||
return self.filename | ||
|
||
def set_filename(self, value): | ||
assert value | ||
self.filename = value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
''' | ||
The MIT License(MIT) | ||
Copyright(c) 2016 Copyleaks LTD (https://copyleaks.com) | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
''' | ||
|
||
class ScoreWeights: | ||
def get_grammar_score_weight(self): | ||
return self.grammarScoreWeight | ||
|
||
def set_grammar_score_weight(self, value): | ||
assert value | ||
self.grammarScoreWeight = value | ||
|
||
def get_mechanics_score_weight(self): | ||
return self.mechanicsScoreWeight | ||
|
||
def set_mechanics_score_weight(self, value): | ||
assert value | ||
self.mechanicsScoreWeight = value | ||
|
||
def get_sentence_structure_score_weight(self): | ||
return self.sentenceStructureScoreWeight | ||
|
||
def set_sentence_structure_score_weight(self, value): | ||
assert value | ||
self.sentenceStructureScoreWeight = value | ||
|
||
def get_word_choice_score_weight(self): | ||
return self.wordChoiceScoreWeight | ||
|
||
def set_word_choice_score_weight(self, value): | ||
self.wordChoiceScoreWeight = value | ||
assert value |
Oops, something went wrong.