liminal-sdk-python 2024.3.3__tar.gz → 2024.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/PKG-INFO +1 -7
  2. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/README.md +0 -6
  3. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/client.py +18 -14
  4. liminal_sdk_python-2024.3.4/liminal/const.py +6 -0
  5. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/auth/__init__.py +8 -4
  6. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/auth/models.py +1 -2
  7. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/llm/__init__.py +6 -6
  8. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/prompt/__init__.py +2 -0
  9. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/thread/__init__.py +2 -0
  10. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/helpers/model.py +1 -1
  11. liminal_sdk_python-2024.3.4/pyproject.toml +441 -0
  12. liminal_sdk_python-2024.3.3/liminal/const.py +0 -5
  13. liminal_sdk_python-2024.3.3/pyproject.toml +0 -119
  14. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/LICENSE +0 -0
  15. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/__init__.py +0 -0
  16. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/__init__.py +0 -0
  17. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/llm/models.py +0 -0
  18. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/prompt/models.py +0 -0
  19. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/endpoints/thread/models.py +0 -0
  20. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/errors.py +0 -0
  21. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/helpers/__init__.py +0 -0
  22. {liminal_sdk_python-2024.3.3 → liminal_sdk_python-2024.3.4}/liminal/helpers/typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: liminal-sdk-python
3
- Version: 2024.3.3
3
+ Version: 2024.3.4
4
4
  Summary: The Liminal SDK for Python
5
5
  Home-page: https://github.com/liminal-ai-security/liminal-sdk-python
6
6
  License: Apache-2.0
@@ -64,8 +64,6 @@ from liminal.endpoints.auth import MicrosoftAuthProvider
64
64
 
65
65
  async def main() -> None:
66
66
  """Create the aiohttp session and run the example."""
67
- logging.basicConfig(level=logging.DEBUG)
68
-
69
67
  # Create an auth provider to authenticate the user:
70
68
  microsoft_auth_provider = MicrosoftAuthProvider("<TENANT_ID>", "<CLIENT_ID>")
71
69
 
@@ -117,8 +115,6 @@ from liminal.endpoints.auth import MicrosoftAuthProvider
117
115
 
118
116
  async def main() -> None:
119
117
  """Create the aiohttp session and run the example."""
120
- logging.basicConfig(level=logging.DEBUG)
121
-
122
118
  # Create an auth provider to authenticate the user:
123
119
  microsoft_auth_provider = MicrosoftAuthProvider("<TENANT_ID>", "<CLIENT_ID>")
124
120
 
@@ -170,8 +166,6 @@ from liminal.endpoints.auth import MicrosoftAuthProvider
170
166
 
171
167
  async def main() -> None:
172
168
  """Create the aiohttp session and run the example."""
173
- logging.basicConfig(level=logging.DEBUG)
174
-
175
169
  # Create an auth provider to authenticate the user:
176
170
  microsoft_auth_provider = MicrosoftAuthProvider("<TENANT_ID>", "<CLIENT_ID>")
177
171
 
@@ -39,8 +39,6 @@ from liminal.endpoints.auth import MicrosoftAuthProvider
39
39
 
40
40
  async def main() -> None:
41
41
  """Create the aiohttp session and run the example."""
42
- logging.basicConfig(level=logging.DEBUG)
43
-
44
42
  # Create an auth provider to authenticate the user:
45
43
  microsoft_auth_provider = MicrosoftAuthProvider("<TENANT_ID>", "<CLIENT_ID>")
46
44
 
@@ -92,8 +90,6 @@ from liminal.endpoints.auth import MicrosoftAuthProvider
92
90
 
93
91
  async def main() -> None:
94
92
  """Create the aiohttp session and run the example."""
95
- logging.basicConfig(level=logging.DEBUG)
96
-
97
93
  # Create an auth provider to authenticate the user:
98
94
  microsoft_auth_provider = MicrosoftAuthProvider("<TENANT_ID>", "<CLIENT_ID>")
99
95
 
@@ -145,8 +141,6 @@ from liminal.endpoints.auth import MicrosoftAuthProvider
145
141
 
146
142
  async def main() -> None:
147
143
  """Create the aiohttp session and run the example."""
148
- logging.basicConfig(level=logging.DEBUG)
149
-
150
144
  # Create an auth provider to authenticate the user:
151
145
  microsoft_auth_provider = MicrosoftAuthProvider("<TENANT_ID>", "<CLIENT_ID>")
152
146
 
@@ -1,8 +1,11 @@
1
1
  """Define the client module."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import asyncio
4
6
  from collections.abc import Callable
5
7
  from datetime import UTC, datetime
8
+ from typing import Final
6
9
 
7
10
  from httpx import AsyncClient, Cookies, HTTPStatusError, Request, Response
8
11
  from mashumaro.codecs.json import json_decode
@@ -20,8 +23,8 @@ from liminal.endpoints.thread import ThreadEndpoint
20
23
  from liminal.errors import AuthError, RequestError
21
24
  from liminal.helpers.typing import ValidatedResponseT
22
25
 
23
- DEFAULT_REQUEST_TIMEOUT = 60
24
- DEFAULT_SOURCE = "sdk"
26
+ DEFAULT_REQUEST_TIMEOUT: Final[int] = 60
27
+ DEFAULT_SOURCE: Final[str] = "sdk"
25
28
 
26
29
 
27
30
  class Client:
@@ -131,9 +134,10 @@ class Client:
131
134
  try:
132
135
  response.raise_for_status()
133
136
  except HTTPStatusError as err:
134
- raise RequestError(
137
+ msg = (
135
138
  f"Error while sending request to {url}: {err.response.content.decode()}"
136
- ) from err
139
+ )
140
+ raise RequestError(msg) from err
137
141
 
138
142
  if not running_client:
139
143
  await client.aclose()
@@ -182,7 +186,8 @@ class Client:
182
186
  SuitableVariantNotFoundError,
183
187
  UnserializableDataError,
184
188
  ) as err:
185
- raise RequestError(f"Could not validate response: {err}") from err
189
+ msg = f"Could not validate response: {err}"
190
+ raise RequestError(msg) from err
186
191
 
187
192
  def _save_tokens_from_auth_response(self, auth_response: Response) -> None:
188
193
  """Save tokens from an auth response.
@@ -248,25 +253,24 @@ class Client:
248
253
  authenticated yet.
249
254
 
250
255
  """
251
- if refresh_token is None and self._refresh_token is None:
252
- raise AuthError("No valid refresh token provided")
256
+ if not refresh_token:
257
+ refresh_token = self._refresh_token
258
+
259
+ if not refresh_token:
260
+ msg = "No valid refresh token provided"
261
+ raise AuthError(msg)
253
262
 
254
263
  self._refreshing = True
255
264
 
256
265
  async with self._refresh_lock:
257
- # If a refresh token is explicitly provided, use it:
258
- if refresh_token:
259
- self._refresh_token = refresh_token
260
-
261
- assert self._refresh_token is not None
262
-
263
266
  self._refresh_event.clear()
264
267
 
265
268
  try:
266
269
  refresh_token_response = await self._request(
267
270
  "POST",
268
271
  "/api/v1/auth/refresh-token",
269
- cookies=Cookies({"refreshToken": self._refresh_token}),
272
+ refresh_request=True,
273
+ cookies=Cookies({"refreshToken": refresh_token}),
270
274
  )
271
275
  self._save_tokens_from_auth_response(refresh_token_response)
272
276
  finally:
@@ -0,0 +1,6 @@
1
+ """Define package constants."""
2
+
3
+ import logging
4
+ from typing import Final
5
+
6
+ LOGGER: Final[logging.Logger] = logging.getLogger(__package__)
@@ -1,6 +1,9 @@
1
1
  """Define the auth endpoint."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import asyncio
6
+ from typing import Final
4
7
 
5
8
  from msal import PublicClientApplication
6
9
 
@@ -12,14 +15,14 @@ from liminal.endpoints.auth.models import (
12
15
  )
13
16
  from liminal.errors import AuthError
14
17
 
15
- DEFAULT_AUTH_CHALLENGE_TIMEOUT = 60
18
+ DEFAULT_AUTH_CHALLENGE_TIMEOUT: Final[int] = 60
16
19
 
17
20
 
18
21
  class MicrosoftAuthProvider(AuthProvider):
19
22
  """Define a Microsoft auth provider."""
20
23
 
21
- AUTHORITY_URL = "https://login.microsoftonline.com"
22
- DEFAULT_SCOPES = ["User.Read"]
24
+ AUTHORITY_URL: Final[str] = "https://login.microsoftonline.com"
25
+ DEFAULT_SCOPES: Final[list[str]] = ["User.Read"]
23
26
 
24
27
  def __init__(
25
28
  self,
@@ -76,7 +79,8 @@ class MicrosoftAuthProvider(AuthProvider):
76
79
  # Setting the flow to expire immediately will effectively kill the future
77
80
  # that we're awaiting:
78
81
  flow["expires_at"] = 0
79
- raise AuthError("Timed out waiting for authentication challenge") from err
82
+ msg = "Timed out waiting for authentication challenge"
83
+ raise AuthError(msg) from err
80
84
 
81
85
  identity_provider_response = MSALIdentityProviderTokenResponse.from_dict(result)
82
86
  return identity_provider_response.access_token
@@ -2,14 +2,13 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from abc import ABC
6
5
  from dataclasses import dataclass
7
6
  from typing import Literal
8
7
 
9
8
  from liminal.helpers.model import BaseModel
10
9
 
11
10
 
12
- class AuthProvider(ABC):
11
+ class AuthProvider:
13
12
  """Define an auth provider abstract base class."""
14
13
 
15
14
  async def get_access_token(self) -> str:
@@ -1,5 +1,7 @@
1
1
  """Define the LLM endpoint."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from collections.abc import Awaitable, Callable
4
6
  from typing import cast
5
7
 
@@ -58,13 +60,11 @@ class LLMEndpoint:
58
60
  if instance.name == model_instance_name
59
61
  )
60
62
  except StopIteration as err:
61
- raise ModelInstanceUnknownError(
62
- f"Unknown model instance name: {model_instance_name}"
63
- ) from err
63
+ msg = f"Unknown model instance name: {model_instance_name}"
64
+ raise ModelInstanceUnknownError(msg) from err
64
65
 
65
66
  if model_instance.model_connection is None:
66
- raise ModelInstanceUnknownError(
67
- f"Unknown model instance name: {model_instance_name}"
68
- )
67
+ msg = f"Unknown model instance name: {model_instance_name}"
68
+ raise ModelInstanceUnknownError(msg)
69
69
 
70
70
  return model_instance
@@ -1,5 +1,7 @@
1
1
  """Define the prompts endpoint."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from collections.abc import Awaitable, Callable
4
6
  from typing import cast
5
7
 
@@ -1,5 +1,7 @@
1
1
  """Define the threads endpoint."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from collections.abc import Awaitable, Callable
4
6
  from typing import cast
5
7
 
@@ -10,4 +10,4 @@ class BaseModel(DataClassDictMixin):
10
10
  class Config(BaseConfig):
11
11
  """Define the configuration."""
12
12
 
13
- code_generation_options = ["TO_DICT_ADD_BY_ALIAS_FLAG"]
13
+ code_generation_options = ["TO_DICT_ADD_BY_ALIAS_FLAG"] # noqa: RUF012
@@ -0,0 +1,441 @@
1
+ [build-system]
2
+ requires = ["poetry-core==1.9.0"]
3
+ build-backend = "poetry.core.masonry.api"
4
+
5
+ [tool.coverage.report]
6
+ exclude_lines = [
7
+ "TYPE_CHECKING",
8
+ "raise NotImplementedError",
9
+ ]
10
+ fail_under = 100
11
+ show_missing = true
12
+
13
+ [tool.coverage.run]
14
+ source = ["liminal"]
15
+
16
+ [tool.mypy]
17
+ check_untyped_defs = true
18
+ disallow_incomplete_defs = true
19
+ disallow_subclassing_any = true
20
+ disallow_untyped_calls = true
21
+ disallow_untyped_decorators = true
22
+ disallow_untyped_defs = true
23
+ follow_imports = "silent"
24
+ ignore_missing_imports = true
25
+ no_implicit_optional = true
26
+ platform = "linux"
27
+ python_version = "3.11"
28
+ show_error_codes = true
29
+ strict_equality = true
30
+ warn_incomplete_stub = true
31
+ warn_redundant_casts = true
32
+ warn_unreachable = true
33
+ warn_unused_configs = true
34
+ warn_unused_ignores = true
35
+
36
+ [tool.poetry]
37
+ name = "liminal-sdk-python"
38
+ version = "2024.03.4"
39
+ description = "The Liminal SDK for Python"
40
+ readme = "README.md"
41
+ authors = ["Aaron Bach <ab@liminal.ai>"]
42
+ license = "Apache-2.0"
43
+ repository = "https://github.com/liminal-ai-security/liminal-sdk-python"
44
+ classifiers = [
45
+ "License :: OSI Approved :: MIT License",
46
+ "Programming Language :: Python",
47
+ "Programming Language :: Python :: 3",
48
+ "Programming Language :: Python :: 3.11",
49
+ "Programming Language :: Python :: 3.12",
50
+ "Programming Language :: Python :: Implementation :: CPython",
51
+ "Programming Language :: Python :: Implementation :: PyPy",
52
+ ]
53
+ packages = [
54
+ { include="liminal", from="." }
55
+ ]
56
+
57
+ [tool.poetry.dependencies]
58
+ httpx = "0.27.0"
59
+ msal = "1.27.0"
60
+ python = "^3.11.8"
61
+ mashumaro = "3.12"
62
+
63
+ [tool.poetry.group.dev.dependencies]
64
+ blacken-docs = "1.16.0"
65
+ codespell = "2.2.6"
66
+ coverage = {version = "7.4.4", extras = ["toml"]}
67
+ darglint = "1.8.1"
68
+ mypy = "1.9.0"
69
+ packaging = "==24.0"
70
+ pre-commit = "3.6.2"
71
+ pre-commit-hooks = "4.5.0"
72
+ pylint = "3.1.0"
73
+ pytest = "8.1.1"
74
+ pytest-asyncio = "0.23.5.post1"
75
+ pytest-cov = "4.1.0"
76
+ ruff = "0.3.2"
77
+
78
+ [tool.poetry.urls]
79
+ "Bug Tracker" = "https://github.com/liminal-ai-security/liminal-sdk-python/issues"
80
+ Changelog = "https://github.com/liminal-ai-security/liminal-sdk-python/releases"
81
+
82
+ [tool.pylint.BASIC]
83
+ class-const-naming-style = "any"
84
+ expected-line-ending-format = "LF"
85
+
86
+ [tool.pylint.DESIGN]
87
+ max-attributes = 20
88
+
89
+ [tool.pylint.FORMAT]
90
+ max-line-length = 88
91
+
92
+ [tool.pylint.MAIN]
93
+ py-version = "3.11"
94
+ ignore = [
95
+ "tests",
96
+ ]
97
+ # Use a conservative default here; 2 should speed up most setups and not hurt
98
+ # any too bad. Override on command line as appropriate.
99
+ jobs = 2
100
+ init-hook = """\
101
+ from pathlib import Path; \
102
+ import sys; \
103
+
104
+ from pylint.config import find_default_config_files; \
105
+
106
+ sys.path.append( \
107
+ str(Path(next(find_default_config_files())).parent.joinpath('pylint/plugins'))
108
+ ) \
109
+ """
110
+ load-plugins = [
111
+ "pylint.extensions.code_style",
112
+ "pylint.extensions.typing",
113
+ ]
114
+ persistent = false
115
+ fail-on = [
116
+ "I",
117
+ ]
118
+
119
+ [tool.pylint."MESSAGES CONTROL"]
120
+ # Reasons disabled:
121
+ # format - handled by ruff
122
+ # locally-disabled - it spams too much
123
+ # duplicate-code - unavoidable
124
+ # cyclic-import - doesn't test if both import on load
125
+ # abstract-class-little-used - prevents from setting right foundation
126
+ # unused-argument - generic callbacks and setup methods create a lot of warnings
127
+ # too-many-* - are not enforced for the sake of readability
128
+ # too-few-* - same as too-many-*
129
+ # abstract-method - with intro of async there are always methods missing
130
+ # inconsistent-return-statements - doesn't handle raise
131
+ # too-many-ancestors - it's too strict.
132
+ # wrong-import-order - isort guards this
133
+ # consider-using-f-string - str.format sometimes more readable
134
+ # ---
135
+ # Pylint CodeStyle plugin
136
+ # consider-using-namedtuple-or-dataclass - too opinionated
137
+ # consider-using-assignment-expr - decision to use := better left to devs
138
+ disable = [
139
+ "format",
140
+ "abstract-method",
141
+ "cyclic-import",
142
+ "duplicate-code",
143
+ "inconsistent-return-statements",
144
+ "locally-disabled",
145
+ "not-context-manager",
146
+ "too-few-public-methods",
147
+ "too-many-ancestors",
148
+ "too-many-arguments",
149
+ "too-many-instance-attributes",
150
+ "too-many-lines",
151
+ "too-many-locals",
152
+ "too-many-public-methods",
153
+ "too-many-boolean-expressions",
154
+ "wrong-import-order",
155
+ "consider-using-f-string",
156
+ "consider-using-namedtuple-or-dataclass",
157
+ "consider-using-assignment-expr",
158
+
159
+ # Handled by ruff
160
+ # Ref: <https://github.com/astral-sh/ruff/issues/970>
161
+ "await-outside-async", # PLE1142
162
+ "bad-str-strip-call", # PLE1310
163
+ "bad-string-format-type", # PLE1307
164
+ "bidirectional-unicode", # PLE2502
165
+ "broad-exception-caught", # W0718
166
+ "continue-in-finally", # PLE0116
167
+ "duplicate-bases", # PLE0241
168
+ "format-needs-mapping", # F502
169
+ "function-redefined", # F811
170
+ # Needed because ruff does not understand type of __all__ generated by a function
171
+ # "invalid-all-format", # PLE0605
172
+ "invalid-all-object", # PLE0604
173
+ "invalid-character-backspace", # PLE2510
174
+ "invalid-character-esc", # PLE2513
175
+ "invalid-character-nul", # PLE2514
176
+ "invalid-character-sub", # PLE2512
177
+ "invalid-character-zero-width-space", # PLE2515
178
+ "logging-too-few-args", # PLE1206
179
+ "logging-too-many-args", # PLE1205
180
+ "missing-format-string-key", # F524
181
+ "mixed-format-string", # F506
182
+ "no-method-argument", # N805
183
+ "no-self-argument", # N805
184
+ "nonexistent-operator", # B002
185
+ "nonlocal-without-binding", # PLE0117
186
+ "not-in-loop", # F701, F702
187
+ "notimplemented-raised", # F901
188
+ "return-in-init", # PLE0101
189
+ "return-outside-function", # F706
190
+ "syntax-error", # E999
191
+ "too-few-format-args", # F524
192
+ "too-many-format-args", # F522
193
+ "too-many-star-expressions", # F622
194
+ "truncated-format-string", # F501
195
+ "undefined-all-variable", # F822
196
+ "undefined-variable", # F821
197
+ "used-prior-global-declaration", # PLE0118
198
+ "yield-inside-async-function", # PLE1700
199
+ "yield-outside-function", # F704
200
+ "anomalous-backslash-in-string", # W605
201
+ "assert-on-string-literal", # PLW0129
202
+ "assert-on-tuple", # F631
203
+ "bad-format-string", # W1302, F
204
+ "bad-format-string-key", # W1300, F
205
+ "bare-except", # E722
206
+ "binary-op-exception", # PLW0711
207
+ "cell-var-from-loop", # B023
208
+ # "dangerous-default-value", # B006, ruff catches new occurrences, needs more work
209
+ "duplicate-except", # B014
210
+ "duplicate-key", # F601
211
+ "duplicate-string-formatting-argument", # F
212
+ "duplicate-value", # F
213
+ "eval-used", # S307
214
+ "exec-used", # S102
215
+ "expression-not-assigned", # B018
216
+ "f-string-without-interpolation", # F541
217
+ "forgotten-debug-statement", # T100
218
+ "format-string-without-interpolation", # F
219
+ # "global-statement", # PLW0603, ruff catches new occurrences, needs more work
220
+ "global-variable-not-assigned", # PLW0602
221
+ "implicit-str-concat", # ISC001
222
+ "import-self", # PLW0406
223
+ "inconsistent-quotes", # Q000
224
+ "invalid-envvar-default", # PLW1508
225
+ "keyword-arg-before-vararg", # B026
226
+ "logging-format-interpolation", # G
227
+ "logging-fstring-interpolation", # G
228
+ "logging-not-lazy", # G
229
+ "misplaced-future", # F404
230
+ "named-expr-without-context", # PLW0131
231
+ "nested-min-max", # PLW3301
232
+ "pointless-statement", # B018
233
+ "raise-missing-from", # B904
234
+ # "redefined-builtin", # A001, ruff is way more stricter, needs work
235
+ "try-except-raise", # TRY302
236
+ "unused-argument", # ARG001, we don't use it
237
+ "unused-format-string-argument", #F507
238
+ "unused-format-string-key", # F504
239
+ "unused-import", # F401
240
+ "unused-variable", # F841
241
+ "useless-else-on-loop", # PLW0120
242
+ "wildcard-import", # F403
243
+ "bad-classmethod-argument", # N804
244
+ "consider-iterating-dictionary", # SIM118
245
+ "empty-docstring", # D419
246
+ "invalid-name", # N815
247
+ "line-too-long", # E501, disabled globally
248
+ "missing-class-docstring", # D101
249
+ "missing-final-newline", # W292
250
+ "missing-function-docstring", # D103
251
+ "missing-module-docstring", # D100
252
+ "multiple-imports", #E401
253
+ "singleton-comparison", # E711, E712
254
+ "subprocess-run-check", # PLW1510
255
+ "superfluous-parens", # UP034
256
+ "ungrouped-imports", # I001
257
+ "unidiomatic-typecheck", # E721
258
+ "unnecessary-direct-lambda-call", # PLC3002
259
+ "unnecessary-lambda-assignment", # PLC3001
260
+ "unnecessary-pass", # PIE790
261
+ "unneeded-not", # SIM208
262
+ "useless-import-alias", # PLC0414
263
+ "wrong-import-order", # I001
264
+ "wrong-import-position", # E402
265
+ "comparison-of-constants", # PLR0133
266
+ "comparison-with-itself", # PLR0124
267
+ "consider-alternative-union-syntax", # UP007
268
+ "consider-merging-isinstance", # PLR1701
269
+ "consider-using-alias", # UP006
270
+ "consider-using-dict-comprehension", # C402
271
+ "consider-using-generator", # C417
272
+ "consider-using-get", # SIM401
273
+ "consider-using-set-comprehension", # C401
274
+ "consider-using-sys-exit", # PLR1722
275
+ "consider-using-ternary", # SIM108
276
+ "literal-comparison", # F632
277
+ "property-with-parameters", # PLR0206
278
+ "super-with-arguments", # UP008
279
+ "too-many-branches", # PLR0912
280
+ "too-many-return-statements", # PLR0911
281
+ "too-many-statements", # PLR0915
282
+ "trailing-comma-tuple", # COM818
283
+ "unnecessary-comprehension", # C416
284
+ "use-a-generator", # C417
285
+ "use-dict-literal", # C406
286
+ "use-list-literal", # C405
287
+ "useless-object-inheritance", # UP004
288
+ "useless-return", # PLR1711
289
+ # "no-self-use", # PLR6301 # Optional plugin, not enabled
290
+
291
+ # Handled by mypy
292
+ # Ref: <https://github.com/antonagestam/pylint-mypy-overlap>
293
+ "abstract-class-instantiated",
294
+ "arguments-differ",
295
+ "assigning-non-slot",
296
+ "assignment-from-no-return",
297
+ "assignment-from-none",
298
+ "bad-exception-cause",
299
+ "bad-format-character",
300
+ "bad-reversed-sequence",
301
+ "bad-super-call",
302
+ "bad-thread-instantiation",
303
+ "catching-non-exception",
304
+ "comparison-with-callable",
305
+ "deprecated-class",
306
+ "dict-iter-missing-items",
307
+ "format-combined-specification",
308
+ "global-variable-undefined",
309
+ "import-error",
310
+ "inconsistent-mro",
311
+ "inherit-non-class",
312
+ "init-is-generator",
313
+ "invalid-class-object",
314
+ "invalid-enum-extension",
315
+ "invalid-envvar-value",
316
+ "invalid-format-returned",
317
+ "invalid-hash-returned",
318
+ "invalid-metaclass",
319
+ "invalid-overridden-method",
320
+ "invalid-repr-returned",
321
+ "invalid-sequence-index",
322
+ "invalid-slice-index",
323
+ "invalid-slots-object",
324
+ "invalid-slots",
325
+ "invalid-star-assignment-target",
326
+ "invalid-str-returned",
327
+ "invalid-unary-operand-type",
328
+ "invalid-unicode-codec",
329
+ "isinstance-second-argument-not-valid-type",
330
+ "method-hidden",
331
+ "misplaced-format-function",
332
+ "missing-format-argument-key",
333
+ "missing-format-attribute",
334
+ "missing-kwoa",
335
+ "no-member",
336
+ "no-value-for-parameter",
337
+ "non-iterator-returned",
338
+ "non-str-assignment-to-dunder-name",
339
+ "nonlocal-and-global",
340
+ "not-a-mapping",
341
+ "not-an-iterable",
342
+ "not-async-context-manager",
343
+ "not-callable",
344
+ "not-context-manager",
345
+ "overridden-final-method",
346
+ "raising-bad-type",
347
+ "raising-non-exception",
348
+ "redundant-keyword-arg",
349
+ "relative-beyond-top-level",
350
+ "self-cls-assignment",
351
+ "signature-differs",
352
+ "star-needs-assignment-target",
353
+ "subclassed-final-class",
354
+ "super-without-brackets",
355
+ "too-many-function-args",
356
+ "typevar-double-variance",
357
+ "typevar-name-mismatch",
358
+ "unbalanced-dict-unpacking",
359
+ "unbalanced-tuple-unpacking",
360
+ "unexpected-keyword-arg",
361
+ "unhashable-member",
362
+ "unpacking-non-sequence",
363
+ "unsubscriptable-object",
364
+ "unsupported-assignment-operation",
365
+ "unsupported-binary-operation",
366
+ "unsupported-delete-operation",
367
+ "unsupported-membership-test",
368
+ "used-before-assignment",
369
+ "using-final-decorator-in-unsupported-version",
370
+ "wrong-exception-operation",
371
+ ]
372
+ enable = [
373
+ #"useless-suppression", # temporarily every now and then to clean them up
374
+ "use-symbolic-message-instead",
375
+ ]
376
+
377
+ [tool.pylint.TYPING]
378
+ runtime-typing = false
379
+
380
+ [tool.pylint.CODE_STYLE]
381
+ max-line-length-suggestions = 72
382
+
383
+ [tool.ruff.lint]
384
+ select = [
385
+ "ALL"
386
+ ]
387
+
388
+ ignore = [
389
+ "ANN101", # Missing type annotation for self
390
+ "ANN401", # Dynamically type expressions are disallowed in **kwargs
391
+ "D202", # No blank lines allowed after function docstring
392
+ "D203", # 1 blank line required before class docstring
393
+ "D213", # Multi-line docstring summary should start at the second line
394
+ "D406", # Section name should end with a newline
395
+ "D407", # Section name underlining
396
+ "E501", # line too long
397
+ "E731", # do not assign a lambda expression, use a def
398
+ "PLC1901", # {existing} can be simplified to {replacement} as an empty string is falsey; too many false positives
399
+ "PLR0911", # Too many return statements ({returns} > {max_returns})
400
+ "PLR0912", # Too many branches ({branches} > {max_branches})
401
+ "PLR0913", # Too many arguments to function call ({c_args} > {max_args})
402
+ "PLR0915", # Too many statements ({statements} > {max_statements})
403
+ "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
404
+ "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target
405
+ "SIM102", # Use a single if statement instead of nested if statements
406
+ "SIM108", # Use ternary operator {contents} instead of if-else-block
407
+ "SIM115", # Use context handler for opening files
408
+ "TCH", # flake8-type-checking
409
+ "UP006", # keep type annotation style as is
410
+ "UP007", # keep type annotation style as is
411
+ "PT012", # `pytest.raises()` block should contain a single simple statement
412
+
413
+ # May conflict with the formatter: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
414
+ "COM812",
415
+ "COM819",
416
+ "D206",
417
+ "D300",
418
+ "E111",
419
+ "E114",
420
+ "E117",
421
+ "ISC001",
422
+ "Q",
423
+ "W191",
424
+ ]
425
+
426
+ [tool.ruff.lint.isort]
427
+ force-sort-within-sections = true
428
+ known-first-party = [
429
+ "liminal",
430
+ "tests",
431
+ ]
432
+ combine-as-imports = true
433
+ split-on-trailing-comma = false
434
+
435
+ [tool.ruff.lint.per-file-ignores]
436
+ # Allow for main entry & scripts to write to stdout
437
+ "tests/*" = [
438
+ "ARG001", # Tests ofen have unused arguments
439
+ "FBT001", # Test fixtures may be boolean values
440
+ "S101", # Assertions are fine in tests
441
+ ]
@@ -1,5 +0,0 @@
1
- """Define package constants."""
2
-
3
- import logging
4
-
5
- LOGGER = logging.getLogger(__package__)
@@ -1,119 +0,0 @@
1
- [build-system]
2
- requires = [ "poetry-core==1.9.0",]
3
- build-backend = "poetry.core.masonry.api"
4
-
5
- [tool.mypy]
6
- check_untyped_defs = true
7
- disallow_incomplete_defs = true
8
- disallow_subclassing_any = true
9
- disallow_untyped_calls = true
10
- disallow_untyped_decorators = true
11
- disallow_untyped_defs = true
12
- follow_imports = "silent"
13
- ignore_missing_imports = true
14
- no_implicit_optional = true
15
- platform = "linux"
16
- python_version = "3.11"
17
- show_error_codes = true
18
- strict_equality = true
19
- warn_incomplete_stub = true
20
- warn_redundant_casts = true
21
- warn_unreachable = true
22
- warn_unused_configs = true
23
- warn_unused_ignores = true
24
-
25
- [tool.poetry]
26
- name = "liminal-sdk-python"
27
- version = "2024.03.3"
28
- description = "The Liminal SDK for Python"
29
- readme = "README.md"
30
- authors = [ "Aaron Bach <ab@liminal.ai>",]
31
- license = "Apache-2.0"
32
- repository = "https://github.com/liminal-ai-security/liminal-sdk-python"
33
- classifiers = [ "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy",]
34
-
35
- [[tool.poetry.packages]]
36
- include = "liminal"
37
- from = "."
38
-
39
- [tool.vulture]
40
- min_confidence = 80
41
- paths = [ "liminal", "tests",]
42
- verbose = false
43
-
44
- [tool.coverage.report]
45
- exclude_lines = [ "TYPE_CHECKING", "raise NotImplementedError",]
46
- fail_under = 100
47
- show_missing = true
48
-
49
- [tool.coverage.run]
50
- source = [ "liminal",]
51
-
52
- [tool.poetry.dependencies]
53
- httpx = "0.27.0"
54
- msal = "1.27.0"
55
- python = "^3.11.8"
56
- mashumaro = "3.12"
57
-
58
- [tool.poetry.urls]
59
- "Bug Tracker" = "https://github.com/liminal-ai-security/liminal-sdk-python/issues"
60
- Changelog = "https://github.com/liminal-ai-security/liminal-sdk-python/releases"
61
-
62
- [tool.pylint.BASIC]
63
- expected-line-ending-format = "LF"
64
-
65
- [tool.pylint.DESIGN]
66
- max-attributes = 20
67
-
68
- [tool.pylint.FORMAT]
69
- max-line-length = 88
70
-
71
- [tool.pylint.MAIN]
72
- fail-on = [ "I",]
73
- py-version = "3.12"
74
- ignore = [ "tests",]
75
- jobs = 2
76
- load-plugins = [ "pylint.extensions.code_style", "pylint.extensions.typing",]
77
-
78
- [tool.pylint."MESSAGES CONTROL"]
79
- disable = [ "format", "abstract-method", "cyclic-import", "duplicate-code", "inconsistent-return-statements", "locally-disabled", "not-context-manager", "too-few-public-methods", "too-many-ancestors", "too-many-arguments", "too-many-instance-attributes", "too-many-lines", "too-many-locals", "too-many-public-methods", "too-many-boolean-expressions", "wrong-import-order", "consider-using-f-string", "consider-using-namedtuple-or-dataclass", "consider-using-assignment-expr", "await-outside-async", "bad-str-strip-call", "bad-string-format-type", "bidirectional-unicode", "continue-in-finally", "duplicate-bases", "format-needs-mapping", "function-redefined", "invalid-all-object", "invalid-character-backspace", "invalid-character-esc", "invalid-character-nul", "invalid-character-sub", "invalid-character-zero-width-space", "logging-too-few-args", "logging-too-many-args", "missing-format-string-key", "mixed-format-string", "no-method-argument", "no-self-argument", "nonexistent-operator", "nonlocal-without-binding", "not-in-loop", "notimplemented-raised", "return-in-init", "return-outside-function", "syntax-error", "too-few-format-args", "too-many-format-args", "too-many-star-expressions", "truncated-format-string", "undefined-all-variable", "undefined-variable", "used-prior-global-declaration", "yield-inside-async-function", "yield-outside-function", "anomalous-backslash-in-string", "assert-on-string-literal", "assert-on-tuple", "bad-format-string", "bad-format-string-key", "bare-except", "binary-op-exception", "cell-var-from-loop", "duplicate-except", "duplicate-key", "duplicate-string-formatting-argument", "duplicate-value", "eval-used", "exec-used", "f-string-without-interpolation", "forgotten-debug-statement", "format-string-without-interpolation", "global-variable-not-assigned", "implicit-str-concat", "import-self", "inconsistent-quotes", "invalid-envvar-default", "keyword-arg-before-vararg", "logging-format-interpolation", "logging-fstring-interpolation", "logging-not-lazy", "misplaced-future", "named-expr-without-context", "nested-min-max", "raise-missing-from", "try-except-raise", "unused-argument", "unused-format-string-argument", "unused-format-string-key", "unused-import", "unused-variable", "useless-else-on-loop", "wildcard-import", "bad-classmethod-argument", "consider-iterating-dictionary", "empty-docstring", "invalid-name", "line-too-long", "missing-class-docstring", "missing-final-newline", "missing-function-docstring", "missing-module-docstring", "multiple-imports", "singleton-comparison", "subprocess-run-check", "superfluous-parens", "ungrouped-imports", "unidiomatic-typecheck", "unnecessary-direct-lambda-call", "unnecessary-lambda-assignment", "unnecessary-pass", "unneeded-not", "useless-import-alias", "wrong-import-order", "wrong-import-position", "comparison-of-constants", "comparison-with-itself", "consider-alternative-union-syntax", "consider-merging-isinstance", "consider-using-alias", "consider-using-dict-comprehension", "consider-using-generator", "consider-using-get", "consider-using-set-comprehension", "consider-using-sys-exit", "consider-using-ternary", "literal-comparison", "property-with-parameters", "super-with-arguments", "too-many-branches", "too-many-return-statements", "too-many-statements", "trailing-comma-tuple", "unnecessary-comprehension", "use-a-generator", "use-dict-literal", "use-list-literal", "useless-object-inheritance", "useless-return", "abstract-class-instantiated", "arguments-differ", "assigning-non-slot", "assignment-from-no-return", "assignment-from-none", "bad-exception-cause", "bad-format-character", "bad-reversed-sequence", "bad-super-call", "bad-thread-instantiation", "catching-non-exception", "comparison-with-callable", "deprecated-class", "dict-iter-missing-items", "format-combined-specification", "global-variable-undefined", "import-error", "inconsistent-mro", "inherit-non-class", "init-is-generator", "invalid-class-object", "invalid-enum-extension", "invalid-envvar-value", "invalid-format-returned", "invalid-hash-returned", "invalid-metaclass", "invalid-overridden-method", "invalid-repr-returned", "invalid-sequence-index", "invalid-slice-index", "invalid-slots-object", "invalid-slots", "invalid-star-assignment-target", "invalid-str-returned", "invalid-unary-operand-type", "invalid-unicode-codec", "isinstance-second-argument-not-valid-type", "method-hidden", "misplaced-format-function", "missing-format-argument-key", "missing-format-attribute", "missing-kwoa", "no-member", "no-value-for-parameter", "non-iterator-returned", "non-str-assignment-to-dunder-name", "nonlocal-and-global", "not-a-mapping", "not-an-iterable", "not-async-context-manager", "not-callable", "not-context-manager", "overridden-final-method", "raising-bad-type", "raising-non-exception", "redundant-keyword-arg", "relative-beyond-top-level", "self-cls-assignment", "signature-differs", "star-needs-assignment-target", "subclassed-final-class", "super-without-brackets", "too-many-function-args", "typevar-double-variance", "typevar-name-mismatch", "unbalanced-dict-unpacking", "unbalanced-tuple-unpacking", "unexpected-keyword-arg", "unhashable-member", "unpacking-non-sequence", "unsubscriptable-object", "unsupported-assignment-operation", "unsupported-binary-operation", "unsupported-delete-operation", "unsupported-membership-test", "used-before-assignment", "using-final-decorator-in-unsupported-version", "wrong-exception-operation",]
80
- enable = [ "use-symbolic-message-instead",]
81
-
82
- [tool.pylint.TYPING]
83
- runtime-typing = false
84
-
85
- [tool.pylint.CODE_STYLE]
86
- max-line-length-suggestions = 72
87
-
88
- [tool.pylint.REPORTS]
89
- score = false
90
-
91
- [tool.ruff.lint]
92
- select = [ "B002", "B005", "B007", "B014", "B015", "B023", "B026", "B032", "B904", "C", "COM818", "D", "DTZ003", "DTZ004", "E", "F", "G", "I", "ISC", "ICN001", "N804", "N805", "N815", "PERF", "PGH004", "PIE804", "PIE790", "PIE794", "PIE807", "PIE810", "PLC0414", "PLC", "PLE", "PLR", "PLW", "Q000", "RUF005", "RUF006", "S102", "S103", "S108", "S306", "S307", "S313", "S314", "S315", "S316", "S317", "S318", "S319", "S320", "S601", "S602", "S604", "S608", "S609", "SIM", "T100", "T20", "TID251", "TRY004", "TRY302", "UP", "W",]
93
- ignore = [ "D202", "D203", "D213", "D406", "D407", "E501", "E731", "PLC0208", "PLR0911", "PLR0912", "PLR0913", "PLR0915", "PLR2004", "PLW2901", "SIM102", "SIM108", "SIM115", "UP006", "UP007", "UP038", "W191", "E111", "E114", "E117", "D206", "D300", "Q000", "Q001", "Q002", "Q003", "COM812", "COM819", "ISC001", "PLE0605",]
94
-
95
- [tool.ruff.lint.isort]
96
- force-sort-within-sections = true
97
- known-first-party = [ "liminal",]
98
- combine-as-imports = true
99
- split-on-trailing-comma = false
100
-
101
- [tool.poetry.group.dev.dependencies]
102
- blacken-docs = "1.16.0"
103
- codespell = "2.2.6"
104
- darglint = "1.8.1"
105
- mypy = "1.9.0"
106
- packaging = "==24.0"
107
- pre-commit = "3.6.2"
108
- pre-commit-hooks = "4.5.0"
109
- pylint = "3.1.0"
110
- pytest = "8.1.1"
111
- pytest-asyncio = "0.23.5.post1"
112
- pytest-cov = "4.1.0"
113
- pyupgrade = "3.15.1"
114
- ruff = "0.3.2"
115
- vulture = "2.11"
116
-
117
- [tool.poetry.group.dev.dependencies.coverage]
118
- version = "7.4.4"
119
- extras = [ "toml",]