dataroom-client 1.0.1.post49.dev0__tar.gz → 1.0.1.post62.dev0__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.
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/PKG-INFO +1 -1
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/client.py +89 -130
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/pyproject.toml +1 -1
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/README.md +0 -0
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/__init__.py +0 -0
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/counter.py +0 -0
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/loader.py +0 -0
- {dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/print_utils.py +0 -0
{dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/client.py
RENAMED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import functools
|
|
3
|
+
import inspect
|
|
4
|
+
import threading
|
|
5
|
+
import atexit
|
|
2
6
|
from datetime import datetime
|
|
3
7
|
import json as json_module
|
|
4
8
|
import logging
|
|
@@ -1440,12 +1444,75 @@ class DataRoomClient:
|
|
|
1440
1444
|
)
|
|
1441
1445
|
|
|
1442
1446
|
|
|
1447
|
+
|
|
1448
|
+
class AsyncRunner:
|
|
1449
|
+
"""
|
|
1450
|
+
Manages a single, shared event loop in a background thread
|
|
1451
|
+
to run async functions from a synchronous context using classmethods.
|
|
1452
|
+
|
|
1453
|
+
The shutdown method is automatically registered to be called on exit.
|
|
1454
|
+
"""
|
|
1455
|
+
_loop: asyncio.AbstractEventLoop | None = None
|
|
1456
|
+
_thread: threading.Thread | None = None
|
|
1457
|
+
_lock = threading.Lock() # To ensure thread-safe initialization
|
|
1458
|
+
|
|
1459
|
+
@classmethod
|
|
1460
|
+
def _initialize(cls):
|
|
1461
|
+
"""Initializes the background event loop and thread if not already done."""
|
|
1462
|
+
with cls._lock:
|
|
1463
|
+
if cls._thread is not None:
|
|
1464
|
+
return
|
|
1465
|
+
|
|
1466
|
+
cls._loop = asyncio.new_event_loop()
|
|
1467
|
+
cls._thread = threading.Thread(
|
|
1468
|
+
target=cls._loop.run_forever,
|
|
1469
|
+
daemon=True,
|
|
1470
|
+
name="ClassAsyncRunnerThread"
|
|
1471
|
+
)
|
|
1472
|
+
cls._thread.start()
|
|
1473
|
+
# Register the shutdown method to be called when the program exits.
|
|
1474
|
+
# This is done here to ensure it's only registered once.
|
|
1475
|
+
atexit.register(cls.shutdown)
|
|
1476
|
+
logger.debug("Initialized ClassAsyncRunner background thread")
|
|
1477
|
+
|
|
1478
|
+
@classmethod
|
|
1479
|
+
def run(cls, coro):
|
|
1480
|
+
"""
|
|
1481
|
+
Runs a coroutine on the shared background event loop and returns the result.
|
|
1482
|
+
Initializes the loop on the first call.
|
|
1483
|
+
"""
|
|
1484
|
+
if cls._thread is None:
|
|
1485
|
+
cls._initialize()
|
|
1486
|
+
|
|
1487
|
+
future = asyncio.run_coroutine_threadsafe(coro, cls._loop)
|
|
1488
|
+
return future.result()
|
|
1489
|
+
|
|
1490
|
+
@classmethod
|
|
1491
|
+
def shutdown(cls):
|
|
1492
|
+
"""
|
|
1493
|
+
Cleanly stops the shared event loop.
|
|
1494
|
+
This is registered with atexit and called automatically.
|
|
1495
|
+
"""
|
|
1496
|
+
# The check for cls._loop is important because atexit might call this
|
|
1497
|
+
# even if the runner was never initialized.
|
|
1498
|
+
if cls._loop and cls._loop.is_running():
|
|
1499
|
+
logger.debug("Shutting down ClassAsyncRunner background thread...")
|
|
1500
|
+
cls._loop.call_soon_threadsafe(cls._loop.stop)
|
|
1501
|
+
# It's good practice to have a timeout on join
|
|
1502
|
+
cls._thread.join(timeout=5)
|
|
1503
|
+
cls._loop.close()
|
|
1504
|
+
logger.debug("ClassAsyncRunner has been shut down.")
|
|
1505
|
+
|
|
1506
|
+
cls._loop = None
|
|
1507
|
+
cls._thread = None
|
|
1508
|
+
|
|
1509
|
+
|
|
1443
1510
|
class DataRoomClientSync:
|
|
1444
1511
|
"""
|
|
1445
1512
|
The official client of the DataRoom API using synchronous method and requests.
|
|
1446
1513
|
"""
|
|
1447
1514
|
|
|
1448
|
-
def __init__(self, api_key=None, api_url=None):
|
|
1515
|
+
def __init__(self, api_key=None, api_url=None, timeout=120):
|
|
1449
1516
|
"""
|
|
1450
1517
|
@param api_key: API key for DataRoom API
|
|
1451
1518
|
@param api_url: URL of the DataRoom backend API
|
|
@@ -1457,140 +1524,32 @@ class DataRoomClientSync:
|
|
|
1457
1524
|
)
|
|
1458
1525
|
if not self.api_url:
|
|
1459
1526
|
raise DataRoomError("DataRoom api_url is not set")
|
|
1460
|
-
self._async_client = DataRoomClient(api_key=api_key, api_url=api_url)
|
|
1527
|
+
self._async_client = DataRoomClient(api_key=self.api_key, api_url=self.api_url, timeout=timeout)
|
|
1461
1528
|
|
|
1462
|
-
|
|
1529
|
+
def __getattr__(self, name):
|
|
1530
|
+
"""
|
|
1531
|
+
Dynamically create sync methods for all methods of the async client.
|
|
1532
|
+
"""
|
|
1533
|
+
attr = getattr(self._async_client, name)
|
|
1463
1534
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
try:
|
|
1467
|
-
# Check if there's an existing running event loop
|
|
1468
|
-
loop = asyncio.get_running_loop()
|
|
1469
|
-
except RuntimeError:
|
|
1470
|
-
# No running event loop, create a new one
|
|
1471
|
-
return asyncio.run(coro)
|
|
1472
|
-
else:
|
|
1473
|
-
# A running event loop exists, use run_until_complete
|
|
1474
|
-
return loop.run_until_complete(coro)
|
|
1535
|
+
if not callable(attr):
|
|
1536
|
+
return attr
|
|
1475
1537
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1538
|
+
@functools.wraps(attr)
|
|
1539
|
+
def sync_wrapper(*args, **kwargs):
|
|
1540
|
+
result = attr(*args, **kwargs)
|
|
1541
|
+
if inspect.isawaitable(result):
|
|
1542
|
+
return AsyncRunner.run(result)
|
|
1543
|
+
return result
|
|
1478
1544
|
|
|
1479
|
-
|
|
1480
|
-
return self._run_sync(
|
|
1481
|
-
self._async_client._make_paginated_request(*args, **kwargs)
|
|
1482
|
-
)
|
|
1545
|
+
return sync_wrapper
|
|
1483
1546
|
|
|
1484
|
-
|
|
1547
|
+
def __dir__(self) -> List[str]:
|
|
1548
|
+
"""
|
|
1549
|
+
Provide a list of attributes for introspection and autocompletion in tools like IPython.
|
|
1550
|
+
"""
|
|
1551
|
+
return sorted(list(set(super().__dir__()) | set(dir(self._async_client))))
|
|
1485
1552
|
|
|
1486
1553
|
@classmethod
|
|
1487
1554
|
def download_image_from_url(cls, *args, **kwargs) -> DataRoomFile:
|
|
1488
|
-
return
|
|
1489
|
-
|
|
1490
|
-
# -------------------- Image API methods --------------------
|
|
1491
|
-
|
|
1492
|
-
def get_images(self, *args, **kwargs):
|
|
1493
|
-
return self._run_sync(self._async_client.get_images(*args, **kwargs))
|
|
1494
|
-
|
|
1495
|
-
def get_images_iter(self, *args, **kwargs):
|
|
1496
|
-
return self._run_sync(self._async_client.get_images_iter(*args, **kwargs))
|
|
1497
|
-
|
|
1498
|
-
def get_random_images(self, *args, **kwargs):
|
|
1499
|
-
return self._run_sync(self._async_client.get_random_images(*args, **kwargs))
|
|
1500
|
-
|
|
1501
|
-
def count_images(self, *args, **kwargs):
|
|
1502
|
-
return self._run_sync(self._async_client.count_images(*args, **kwargs))
|
|
1503
|
-
|
|
1504
|
-
def get_image(self, *args, **kwargs):
|
|
1505
|
-
return self._run_sync(self._async_client.get_image(*args, **kwargs))
|
|
1506
|
-
|
|
1507
|
-
def create_image(self, *args, **kwargs):
|
|
1508
|
-
return self._run_sync(self._async_client.create_image(*args, **kwargs))
|
|
1509
|
-
|
|
1510
|
-
def create_images(self, *args, **kwargs):
|
|
1511
|
-
return self._run_sync(self._async_client.create_images(*args, **kwargs))
|
|
1512
|
-
|
|
1513
|
-
def delete_image(self, *args, **kwargs):
|
|
1514
|
-
return self._run_sync(self._async_client.delete_image(*args, **kwargs))
|
|
1515
|
-
|
|
1516
|
-
def get_image_audit_logs(self, *args, **kwargs):
|
|
1517
|
-
return self._run_sync(self._async_client.get_image_audit_logs(*args, **kwargs))
|
|
1518
|
-
|
|
1519
|
-
def get_image_similarity(self, *args, **kwargs):
|
|
1520
|
-
return self._run_sync(self._async_client.get_image_similarity(*args, **kwargs))
|
|
1521
|
-
|
|
1522
|
-
def get_related_images(self, *args, **kwargs):
|
|
1523
|
-
return self._run_sync(self._async_client.get_related_images(*args, **kwargs))
|
|
1524
|
-
|
|
1525
|
-
def get_similar_images(self, *args, **kwargs):
|
|
1526
|
-
return self._run_sync(self._async_client.get_similar_images(*args, **kwargs))
|
|
1527
|
-
|
|
1528
|
-
def set_image_latent(self, *args, **kwargs):
|
|
1529
|
-
return self._run_sync(self._async_client.set_image_latent(*args, **kwargs))
|
|
1530
|
-
|
|
1531
|
-
def delete_image_latent(self, *args, **kwargs):
|
|
1532
|
-
return self._run_sync(self._async_client.delete_image_latent(*args, **kwargs))
|
|
1533
|
-
|
|
1534
|
-
def update_image(self,*args, **kwargs):
|
|
1535
|
-
return self._run_sync(self._async_client.update_image(*args, **kwargs))
|
|
1536
|
-
|
|
1537
|
-
def update_images(self,*args, **kwargs):
|
|
1538
|
-
return self._run_sync(self._async_client.update_images(*args, **kwargs))
|
|
1539
|
-
|
|
1540
|
-
def add_image_attributes(self, *args, **kwargs):
|
|
1541
|
-
return self._run_sync(self._async_client.add_image_attributes(*args, **kwargs))
|
|
1542
|
-
|
|
1543
|
-
def add_image_attributes_in_bulk(self, *args, **kwargs):
|
|
1544
|
-
return self._run_sync(self._async_client.add_image_attributes_in_bulk(*args, **kwargs))
|
|
1545
|
-
|
|
1546
|
-
def set_image_coca_embedding(self, *args, **kwargs):
|
|
1547
|
-
return self._run_sync(self._async_client.set_image_coca_embedding(*args, **kwargs))
|
|
1548
|
-
|
|
1549
|
-
def aggregate_images(self, *args, **kwargs):
|
|
1550
|
-
return self._run_sync(self._async_client.aggregate_images(*args, **kwargs))
|
|
1551
|
-
|
|
1552
|
-
def bucket_images(self, *args, **kwargs):
|
|
1553
|
-
return self._run_sync(self._async_client.bucket_images(*args, **kwargs))
|
|
1554
|
-
|
|
1555
|
-
# -------------------- Tag API methods --------------------
|
|
1556
|
-
|
|
1557
|
-
def create_tag(self, *args, **kwargs):
|
|
1558
|
-
return self._run_sync(self._async_client.create_tag(*args, **kwargs))
|
|
1559
|
-
|
|
1560
|
-
def get_tag(self, *args, **kwargs):
|
|
1561
|
-
return self._run_sync(self._async_client.get_tag(*args, **kwargs))
|
|
1562
|
-
|
|
1563
|
-
def get_tags(self, *args, **kwargs):
|
|
1564
|
-
return self._run_sync(self._async_client.get_tags(*args, **kwargs))
|
|
1565
|
-
|
|
1566
|
-
def tag_images(self, *args, **kwargs):
|
|
1567
|
-
return self._run_sync(self._async_client.tag_images(*args, **kwargs))
|
|
1568
|
-
|
|
1569
|
-
# -------------------- Dataset API methods --------------------
|
|
1570
|
-
|
|
1571
|
-
def get_datasets(self, *args, **kwargs):
|
|
1572
|
-
return self._run_sync(self._async_client.get_datasets(*args, **kwargs))
|
|
1573
|
-
|
|
1574
|
-
def get_dataset(self, *args, **kwargs):
|
|
1575
|
-
return self._run_sync(self._async_client.get_dataset(*args, **kwargs))
|
|
1576
|
-
|
|
1577
|
-
def create_dataset(self, *args, **kwargs):
|
|
1578
|
-
return self._run_sync(self._async_client.create_dataset(*args, **kwargs))
|
|
1579
|
-
|
|
1580
|
-
def freeze_dataset(self, *args, **kwargs):
|
|
1581
|
-
return self._run_sync(self._async_client.freeze_dataset(*args, **kwargs))
|
|
1582
|
-
|
|
1583
|
-
def unfreeze_dataset(self, *args, **kwargs):
|
|
1584
|
-
return self._run_sync(self._async_client.unfreeze_dataset(*args, **kwargs))
|
|
1585
|
-
|
|
1586
|
-
def dataset_add_images(self, *args, **kwargs):
|
|
1587
|
-
return self._run_sync(self._async_client.dataset_add_images(*args, **kwargs))
|
|
1588
|
-
|
|
1589
|
-
def dataset_remove_images(self, *args, **kwargs):
|
|
1590
|
-
return self._run_sync(self._async_client.dataset_remove_images(*args, **kwargs))
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
for method_name in dir(DataRoomClient):
|
|
1594
|
-
if not method_name.startswith("_"):
|
|
1595
|
-
if not hasattr(DataRoomClientSync, method_name):
|
|
1596
|
-
logger.warning(f"Missing implementation: DataRoomClientSync.{method_name}")
|
|
1555
|
+
return AsyncRunner.run(DataRoomClient.download_image_from_url(*args, **kwargs))
|
|
File without changes
|
{dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/__init__.py
RENAMED
|
File without changes
|
{dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/counter.py
RENAMED
|
File without changes
|
{dataroom_client-1.0.1.post49.dev0 → dataroom_client-1.0.1.post62.dev0}/dataroom_client/loader.py
RENAMED
|
File without changes
|
|
File without changes
|