pytest-clerk 4.0.3__tar.gz → 4.0.5__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.
- {pytest_clerk-4.0.3 → pytest_clerk-4.0.5}/PKG-INFO +1 -1
- {pytest_clerk-4.0.3 → pytest_clerk-4.0.5}/pyproject.toml +3 -3
- {pytest_clerk-4.0.3 → pytest_clerk-4.0.5}/pytest_clerk/clerk.py +38 -36
- {pytest_clerk-4.0.3 → pytest_clerk-4.0.5}/LICENSE +0 -0
- {pytest_clerk-4.0.3 → pytest_clerk-4.0.5}/README.md +0 -0
- {pytest_clerk-4.0.3 → pytest_clerk-4.0.5}/pytest_clerk/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pytest-clerk"
|
|
3
|
-
version = "4.0.
|
|
3
|
+
version = "4.0.5"
|
|
4
4
|
description = "A set of pytest fixtures to help with integration testing with Clerk."
|
|
5
5
|
license = "MIT"
|
|
6
6
|
readme = "README.md"
|
|
@@ -28,8 +28,8 @@ email = "ryan.causey@munipal.io"
|
|
|
28
28
|
|
|
29
29
|
[tool.poetry.group.dev.dependencies]
|
|
30
30
|
prospector = "^1.10.2"
|
|
31
|
-
black = "^
|
|
32
|
-
isort = "^
|
|
31
|
+
black = "^25.0.0"
|
|
32
|
+
isort = "^6.0.0"
|
|
33
33
|
pre-commit = "^4.0.0"
|
|
34
34
|
|
|
35
35
|
[project.entry-points."pytest11"]
|
|
@@ -7,15 +7,7 @@ import httpx
|
|
|
7
7
|
import pytest
|
|
8
8
|
from decouple import UndefinedValueError, config
|
|
9
9
|
from limits import RateLimitItemPerSecond, storage, strategies
|
|
10
|
-
from tenacity import retry,
|
|
11
|
-
|
|
12
|
-
retryable_status_codes = (
|
|
13
|
-
httpx.codes.TOO_MANY_REQUESTS,
|
|
14
|
-
httpx.codes.INTERNAL_SERVER_ERROR,
|
|
15
|
-
httpx.codes.BAD_GATEWAY,
|
|
16
|
-
httpx.codes.SERVICE_UNAVAILABLE,
|
|
17
|
-
httpx.codes.GATEWAY_TIMEOUT,
|
|
18
|
-
)
|
|
10
|
+
from tenacity import retry, stop_after_attempt, wait_random_exponential
|
|
19
11
|
|
|
20
12
|
logger = logging.getLogger(__name__)
|
|
21
13
|
|
|
@@ -177,16 +169,6 @@ class ClerkRateLimiter:
|
|
|
177
169
|
sleep(1)
|
|
178
170
|
|
|
179
171
|
|
|
180
|
-
def retry_predicate(exception):
|
|
181
|
-
"""Return whether to retry. This depends on getting an exception with a response
|
|
182
|
-
object, and that response object having one of the status codes that we can retry.
|
|
183
|
-
"""
|
|
184
|
-
return (
|
|
185
|
-
hasattr(exception, "response")
|
|
186
|
-
and exception.response.status_code in retryable_status_codes
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
|
|
190
172
|
@pytest.fixture(scope="session")
|
|
191
173
|
def clerk_rate_limiter():
|
|
192
174
|
"""Return an instance of the Clerk rate limiter for use with HTTPX request hooks."""
|
|
@@ -234,6 +216,7 @@ def clerk_backend_httpx_client(clerk_secret_key, clerk_rate_limiter):
|
|
|
234
216
|
headers={"Authorization": f"Bearer {clerk_secret_key}"},
|
|
235
217
|
base_url="https://api.clerk.com/v1",
|
|
236
218
|
event_hooks={"request": [clerk_rate_limiter.rate_limit_hook]},
|
|
219
|
+
timeout=10,
|
|
237
220
|
)
|
|
238
221
|
|
|
239
222
|
yield client
|
|
@@ -268,7 +251,7 @@ def clerk_frontend_httpx_client(clerk_frontend_api_url, clerk_rate_limiter):
|
|
|
268
251
|
set via environment variables or in a .env file. This URL can be found under
|
|
269
252
|
Developers -> API Keys -> Show API URLs.
|
|
270
253
|
"""
|
|
271
|
-
with httpx.Client(base_url=f"{clerk_frontend_api_url}/v1") as client:
|
|
254
|
+
with httpx.Client(base_url=f"{clerk_frontend_api_url}/v1", timeout=10) as client:
|
|
272
255
|
result = client.post(url="/dev_browser")
|
|
273
256
|
|
|
274
257
|
result.raise_for_status()
|
|
@@ -277,6 +260,7 @@ def clerk_frontend_httpx_client(clerk_frontend_api_url, clerk_rate_limiter):
|
|
|
277
260
|
params={"__dev_session": result.json()["token"]},
|
|
278
261
|
base_url=f"{clerk_frontend_api_url}/v1",
|
|
279
262
|
event_hooks={"request": [clerk_rate_limiter.rate_limit_hook]},
|
|
263
|
+
timeout=10,
|
|
280
264
|
)
|
|
281
265
|
|
|
282
266
|
yield client
|
|
@@ -294,8 +278,9 @@ def clerk_delete_org(clerk_backend_httpx_client):
|
|
|
294
278
|
"""
|
|
295
279
|
|
|
296
280
|
@retry(
|
|
297
|
-
|
|
281
|
+
stop=stop_after_attempt(10),
|
|
298
282
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
283
|
+
reraise=True,
|
|
299
284
|
)
|
|
300
285
|
def _inner(org_id, **kwargs):
|
|
301
286
|
"""Delete the org with the given org ID. Any additional kwargs are passed
|
|
@@ -306,9 +291,14 @@ def clerk_delete_org(clerk_backend_httpx_client):
|
|
|
306
291
|
The API documentation for this call can be found below:
|
|
307
292
|
https://clerk.com/docs/reference/backend-api/tag/Organizations#operation/DeleteOrganization
|
|
308
293
|
"""
|
|
309
|
-
|
|
294
|
+
result = clerk_backend_httpx_client.delete(
|
|
310
295
|
url=f"/organizations/{org_id}", **kwargs
|
|
311
296
|
)
|
|
297
|
+
# Ignore 404 errors indicating it was already deleted. Raise other errors.
|
|
298
|
+
if result.status_code != httpx.codes.NOT_FOUND:
|
|
299
|
+
result.raise_for_status()
|
|
300
|
+
|
|
301
|
+
return result
|
|
312
302
|
|
|
313
303
|
return _inner
|
|
314
304
|
|
|
@@ -324,8 +314,9 @@ def clerk_create_org(clerk_backend_httpx_client, clerk_delete_org):
|
|
|
324
314
|
orgs_to_delete = []
|
|
325
315
|
|
|
326
316
|
@retry(
|
|
327
|
-
|
|
317
|
+
stop=stop_after_attempt(10),
|
|
328
318
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
319
|
+
reraise=True,
|
|
329
320
|
)
|
|
330
321
|
def _inner(organization_data, **kwargs):
|
|
331
322
|
"""This function creates an Organization with the provided organization_data,
|
|
@@ -337,8 +328,6 @@ def clerk_create_org(clerk_backend_httpx_client, clerk_delete_org):
|
|
|
337
328
|
The API documentation for this call can be found below:
|
|
338
329
|
https://clerk.com/docs/reference/backend-api/tag/Organizations#operation/CreateOrganization
|
|
339
330
|
"""
|
|
340
|
-
nonlocal orgs_to_delete
|
|
341
|
-
|
|
342
331
|
result = clerk_backend_httpx_client.post(
|
|
343
332
|
url="/organizations", json=organization_data, **kwargs
|
|
344
333
|
)
|
|
@@ -365,8 +354,9 @@ def clerk_update_org(clerk_backend_httpx_client):
|
|
|
365
354
|
"""
|
|
366
355
|
|
|
367
356
|
@retry(
|
|
368
|
-
|
|
357
|
+
stop=stop_after_attempt(10),
|
|
369
358
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
359
|
+
reraise=True,
|
|
370
360
|
)
|
|
371
361
|
def _inner(org_id_or_slug, organization_data, **kwargs):
|
|
372
362
|
"""This function attempts to update an organization with the provided
|
|
@@ -397,8 +387,9 @@ def clerk_get_org(clerk_backend_httpx_client):
|
|
|
397
387
|
"""
|
|
398
388
|
|
|
399
389
|
@retry(
|
|
400
|
-
|
|
390
|
+
stop=stop_after_attempt(10),
|
|
401
391
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
392
|
+
reraise=True,
|
|
402
393
|
)
|
|
403
394
|
def _inner(org_id_or_slug, **kwargs):
|
|
404
395
|
"""This function attempts to find and return the org with the given ID or slug.
|
|
@@ -428,8 +419,9 @@ def clerk_delete_user(clerk_backend_httpx_client):
|
|
|
428
419
|
"""
|
|
429
420
|
|
|
430
421
|
@retry(
|
|
431
|
-
|
|
422
|
+
stop=stop_after_attempt(10),
|
|
432
423
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
424
|
+
reraise=True,
|
|
433
425
|
)
|
|
434
426
|
def _inner(user_id, **kwargs):
|
|
435
427
|
"""Delete the user with the given user ID. All additional kwargs are passed
|
|
@@ -440,7 +432,12 @@ def clerk_delete_user(clerk_backend_httpx_client):
|
|
|
440
432
|
The API documentation for this call can be found below:
|
|
441
433
|
https://clerk.com/docs/reference/backend-api/tag/Users#operation/DeleteUser
|
|
442
434
|
"""
|
|
443
|
-
|
|
435
|
+
result = clerk_backend_httpx_client.delete(url=f"/users/{user_id}", **kwargs)
|
|
436
|
+
# Ignore 404 errors indicating it was already deleted. Raise other errors.
|
|
437
|
+
if result.status_code != httpx.codes.NOT_FOUND:
|
|
438
|
+
result.raise_for_status()
|
|
439
|
+
|
|
440
|
+
return result
|
|
444
441
|
|
|
445
442
|
return _inner
|
|
446
443
|
|
|
@@ -456,8 +453,9 @@ def clerk_create_user(clerk_backend_httpx_client, clerk_delete_user):
|
|
|
456
453
|
users_to_delete = []
|
|
457
454
|
|
|
458
455
|
@retry(
|
|
459
|
-
|
|
456
|
+
stop=stop_after_attempt(10),
|
|
460
457
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
458
|
+
reraise=True,
|
|
461
459
|
)
|
|
462
460
|
def _inner(user_data, **kwargs):
|
|
463
461
|
"""This function uses user_data to create a User with the backend API, and
|
|
@@ -469,7 +467,6 @@ def clerk_create_user(clerk_backend_httpx_client, clerk_delete_user):
|
|
|
469
467
|
The API documentation for this call can be found below:
|
|
470
468
|
https://clerk.com/docs/reference/backend-api/tag/Users#operation/CreateUser
|
|
471
469
|
"""
|
|
472
|
-
nonlocal users_to_delete
|
|
473
470
|
result = clerk_backend_httpx_client.post(url="/users", json=user_data, **kwargs)
|
|
474
471
|
result.raise_for_status()
|
|
475
472
|
result = result.json()
|
|
@@ -493,8 +490,9 @@ def clerk_add_org_member(clerk_backend_httpx_client):
|
|
|
493
490
|
"""
|
|
494
491
|
|
|
495
492
|
@retry(
|
|
496
|
-
|
|
493
|
+
stop=stop_after_attempt(10),
|
|
497
494
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
495
|
+
reraise=True,
|
|
498
496
|
)
|
|
499
497
|
def _inner(org_id, user_id, role, **kwargs):
|
|
500
498
|
"""Add's the provided user ID to the provided org ID with the provided role. All
|
|
@@ -527,8 +525,9 @@ def clerk_sign_user_in(clerk_frontend_httpx_client):
|
|
|
527
525
|
"""
|
|
528
526
|
|
|
529
527
|
@retry(
|
|
530
|
-
|
|
528
|
+
stop=stop_after_attempt(10),
|
|
531
529
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
530
|
+
reraise=True,
|
|
532
531
|
)
|
|
533
532
|
def _inner(email, password, **kwargs):
|
|
534
533
|
"""Attempts to sign in the user using the provided email and password, and then
|
|
@@ -565,8 +564,9 @@ def clerk_touch_user_session(clerk_frontend_httpx_client):
|
|
|
565
564
|
"""
|
|
566
565
|
|
|
567
566
|
@retry(
|
|
568
|
-
|
|
567
|
+
stop=stop_after_attempt(10),
|
|
569
568
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
569
|
+
reraise=True,
|
|
570
570
|
)
|
|
571
571
|
def _inner(session_id, session_data=None, **kwargs):
|
|
572
572
|
"""Given a Clerk user session ID and any optional session_data, touch the
|
|
@@ -626,8 +626,9 @@ def clerk_get_user_session_token(clerk_frontend_httpx_client):
|
|
|
626
626
|
"""
|
|
627
627
|
|
|
628
628
|
@retry(
|
|
629
|
-
|
|
629
|
+
stop=stop_after_attempt(10),
|
|
630
630
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
631
|
+
reraise=True,
|
|
631
632
|
)
|
|
632
633
|
def _inner(session_id, **kwargs):
|
|
633
634
|
"""Retrieves a currently valid session token for the user tied to the provided
|
|
@@ -659,8 +660,9 @@ def clerk_end_user_session(clerk_frontend_httpx_client):
|
|
|
659
660
|
"""
|
|
660
661
|
|
|
661
662
|
@retry(
|
|
662
|
-
|
|
663
|
+
stop=stop_after_attempt(10),
|
|
663
664
|
wait=wait_random_exponential(multiplier=0.5, max=60),
|
|
665
|
+
reraise=True,
|
|
664
666
|
)
|
|
665
667
|
def _inner(session_id, **kwargs):
|
|
666
668
|
"""Given a Clerk user session ID, ends that session. This passes through any
|
|
File without changes
|
|
File without changes
|
|
File without changes
|