Name | t-desktop JSON |
Version |
0.0.19
JSON |
| download |
home_page | https://www.thoughtful.ai/ |
Summary | t-desktop is a Python library that provides common methods for desktop automation, simplifyingtasks like window management, keyboard, and mouse control. |
upload_time | 2025-01-15 16:04:25 |
maintainer | None |
docs_url | None |
author | Thoughtful |
requires_python | >=3.9 |
license | None |
keywords |
t_desktop
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
======================
t-desktop
======================
This Python library provides functionality for interacting with desktop
applications via UI automation on Windows OS using ``pywinauto``. It
includes methods to manage application lifecycles, interact with UI
elements, and handle alerts.
--------------
Classes
-------
``DesktopApp``
~~~~~~~~~~~~~~
The main class, ``DesktopApp``, is an abstract base class designed to
manage desktop applications, providing methods to start, connect, and
interact with app elements.
--------------
Class Documentation
-------------------
Initialization
.. code:: python
DesktopApp(app_path: str)
Initializes the desktop application instance.
- **Parameters**
- ``app_path`` (``str``): Path to the application executable.
--------------
Methods
-------
``dialog`` (property)
~~~~~~~~~~~~~~~~~~~~~
The main point of interaction with the App Window.
**Returns**: - ``WindowSpecification``: The top-level window of the
application.
--------------
``connect_to_app``
~~~~~~~~~~~~~~~~~~
Connect to the application.
.. code:: python
def connect_to_app(app_path: str = None, title: str = None, timeout: int = None, **kwargs) -> Application
- **Parameters**
- ``app_path`` (``str``, optional): Location of the application.
- ``title`` (``str``, optional): Window title.
- ``timeout`` (``int``, optional): Max wait time for connection.
- **Returns**:
- ``Application``: Connected application object.
--------------
``start_app``
~~~~~~~~~~~~~
Starts the application.
.. code:: python
def start_app(app_path: str, app_folder: str, sleep_seconds: int = 2) -> None
- **Parameters**
- ``app_path`` (``str``): Application path.
- ``app_folder`` (``str``): Application folder.
- ``sleep_seconds`` (``int``): Pause time after startup.
--------------
``close_alerts``
~~~~~~~~~~~~~~~~
Closes application alerts.
.. code:: python
def close_alerts(expected_window_title: str, max_attempts: int = 3, sleep_seconds: int = 1, ignored_titles: list[str] = []) -> None
- **Parameters**
- ``expected_window_title`` (``str``): Title of the expected window.
- ``max_attempts`` (``int``): Max attempts to check for the window.
- ``sleep_seconds`` (``int``): Time between attempts.
- ``ignored_titles`` (``list[str]``): Titles to ignore.
- **Raises**:
- ``ElementNotFoundError``: If the expected window is not visible.
--------------
``get_element``
~~~~~~~~~~~~~~~
Retrieves a UI element.
.. code:: python
def get_element(control_type: str, title: str | None = None, auto_id: str | None = None, dialog: WindowSpecification = None, **kwargs) -> WindowSpecification
- **Parameters**
- ``control_type`` (``str``): Control type of the element.
- ``title`` (``str``, optional): Title of the element.
- ``auto_id`` (``str``, optional): Automation ID.
- **Returns**:
- ``WindowSpecification``: Matching UI element.
--------------
``invoke_button``
~~~~~~~~~~~~~~~~~
Invokes a button.
.. code:: python
def invoke_button(auto_id: str = None, title: str = None, dialog: WindowSpecification | None = None, **kwargs) -> None
- **Parameters**
- ``auto_id`` (``str``, optional): Automation ID of the button.
- ``title`` (``str``, optional): Title of the button.
--------------
``set_input_text``
~~~~~~~~~~~~~~~~~~
Sets text in an input field.
.. code:: python
def set_input_text(text: str, auto_id: str = None, title: str = None, dialog: WindowSpecification | None = None) -> None
- **Parameters**
- ``text`` (``str``): Text to set.
- ``auto_id`` (``str``, optional): ID of the input field.
- ``title`` (``str``, optional): Title of the input field.
--------------
``mouse_click_element``
~~~~~~~~~~~~~~~~~~~~~~~
Performs a mouse click on a specified element.
.. code:: python
def mouse_click_element(element: WindowSpecification, button: str = "left", offset_x: int = 0, offset_y: int = 0) -> None
- **Parameters**
- ``element`` (``WindowSpecification``): Element to click.
- ``button`` (``str``): Mouse button.
- ``offset_x`` (``int``): Horizontal offset.
- ``offset_y`` (``int``): Vertical offset.
--------------
``mouse_double_click_element``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Performs a mouse double-click on a specified element.
.. code:: python
def mouse_double_click_element(element: WindowSpecification, button: str = "left", set_focus: bool = False) -> None
- **Parameters**
- ``element`` (``WindowSpecification``): Element to double-click.
- ``button`` (``str``): Mouse button.
- ``set_focus`` (``bool``): Set focus before clicking.
--------------
``select_dropdown_item``
~~~~~~~~~~~~~~~~~~~~~~~~
Selects an item from a dropdown.
.. code:: python
def select_dropdown_item(auto_id: str, dropdown_item: str) -> None
- **Parameters**
- ``auto_id`` (``str``): Dropdown ID.
- ``dropdown_item`` (``str``): Dropdown item to select.
--------------
``wait_to_disappear``
~~~~~~~~~~~~~~~~~~~~~
Waits for an element to disappear.
.. code:: python
def wait_to_disappear(control_type: str, auto_id: str = None, title: str = None, max_attempts: int = 3, timeout: int = 1) -> None
- **Parameters**
- ``control_type`` (``str``): Element control type.
- ``auto_id`` (``str``, optional): Element ID.
- ``title`` (``str``, optional): Element title.
- **Raises**:
- ``AssertionError``: If the element is still present after all
attempts.
Here’s the documentation for the new methods and the ``dialog``
attribute:
--------------
``click_input``
~~~~~~~~~~~~~~~
Click element based on provided kwargs.
.. code:: python
def click_input(
self,
control_type: str,
auto_id: str | None = None,
title: str | None = None,
dialog: WindowSpecification | None = None,
**kwargs,
) -> None
**Args**: - ``control_type`` (str): The control type of the element
(required). - ``auto_id`` (str, optional): The automation ID of the
button. Defaults to None. - ``title`` (str, optional): The title of the
button. Defaults to None. - ``dialog`` (WindowSpecification, optional):
The dialog to operate on. Defaults to self.dialog. - ``**kwargs``:
Additional keyword arguments for identifying a child window element.
--------------
``right_click_empty_space``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Right clicks in the blank space after a list of elements.
.. code:: python
def right_click_empty_space(self, element: WindowSpecification, sleep_seconds: int = 2) -> None
**Args**: - ``element`` (WindowSpecification): The element to operate
on. - ``sleep_seconds`` (int): Time to sleep after right-clicking to
allow the dropdown to appear.
--------------
``get_element_coordinates``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieves the coordinates of an element.
.. code:: python
def get_element_coordinates(element: WindowSpecification) -> tuple
**Args**: - ``element`` (WindowSpecification): The element whose
coordinates are retrieved.
**Returns**: - ``tuple``: The coordinates of the element.
**Raises**: - ``AssertionError``: If the coordinates cannot be
retrieved.
--------------
``wait_until_element_visible``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Waits for an element to become visible in the dialog window.
.. code:: python
def wait_until_element_visible(
self, control_type: str, title: str = None, auto_id: str = None, timeout: int = 5
) -> bool
**Args**: - ``control_type`` (str): The control type of the element
(required). - ``title`` (str, optional): The title of the element.
Defaults to None. - ``auto_id`` (str, optional): The automation ID of
the element. Defaults to None. - ``timeout`` (int, optional): The
maximum wait time for the element to become visible. Defaults to 5
seconds.
**Raises**: - ``ValueError``: If neither ‘title’ nor ‘auto_id’ is
provided. - ``TimeoutError``: If the element does not become visible
within the timeout.
**Returns**: - ``bool``: True if the element becomes visible within the
allowed time.
--------------
``kill_app``
~~~~~~~~~~~~
Closes the app if it remains open after the session ends.
.. code:: python
def kill_app(self, process: str, app_path: str) -> None
**Args**: - ``process`` (str): The name of the application process. -
``app_path`` (str): The path of the application executable.
**Raises**: - ``UsernameNotFoundError``: If the username is missing.
--------------
``get_app_session_if_running``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns the current session ID if the app is running.
.. code:: python
def get_app_session_if_running(self, app_path: str) -> str | None
**Args**: - ``app_path`` (str): The system path of the application
executable.
**Returns**: - ``None | str``: None if the app is not running, otherwise
the tasklist output.
**Raises**: - ``UsernameNotFoundError``: If the username is missing.
--------------
Utilities
---------
``relogin_and_retry_if_pywin_error``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Decorator to relogin and retry a function if a specified PyWin error
occurs.
**Args**: - ``retries`` (int): Number of times to retry the function.
Defaults to 3. - ``delay`` (int): Delay in seconds between retries.
Defaults to 1.
**Returns**: - ``Callable``: The decorated function with retry and
relogin logic.
**Raises**: - ``LoginMethodNotFoundError``: If the ``login`` method is
not defined or not callable on the class.
--------------
``retry_if_pywin_error``
~~~~~~~~~~~~~~~~~~~~~~~~
Decorator for retrying a function in Apps derived classes if specified
exceptions are encountered.
**Args**: - ``retries`` (int): Number of times to retry the function.
Defaults to 3. - ``delay`` (int): Delay in seconds between retries.
Defaults to 1. - ``close_modal`` (bool): Whether to attempt closing
modal dialogs on error. Defaults to False. - ``exceptions``
(tuple[Type[BaseException], …]): Additional exceptions to catch and
retry on.
**Returns**: - ``Callable``: The decorated function with retry logic for
specified exceptions.
**Raises**: - The last caught exception if all retry attempts fail.
--------------
``capture_screenshot_if_pywin_error``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Decorator to capture a screenshot if specified exceptions occur during
the execution of a function.
**Args**: - ``func`` (Callable, optional): The function being decorated.
- ``exceptions_to_include`` (List[Type[Exception]], optional): List of
exceptions to trigger screenshot capture. Defaults to a predefined list.
- ``output`` (str): Directory path where screenshots will be saved.
Defaults to ``CONFIG.DIRECTORIES.SCREENSHOTS``.
**Returns**: - ``Callable``: The decorated function that captures a
screenshot upon specific errors.
**Raises**: - The original exception that triggered the screenshot
capture if a failure occurs.
Raw data
{
"_id": null,
"home_page": "https://www.thoughtful.ai/",
"name": "t-desktop",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "t_desktop",
"author": "Thoughtful",
"author_email": "support@thoughtful.ai",
"download_url": "https://files.pythonhosted.org/packages/74/3d/1bc0f1cd6db39a06a45b7f964a15776e6ae03d4da6e715560cf2c5a3d2d4/t_desktop-0.0.19.tar.gz",
"platform": null,
"description": "======================\nt-desktop\n======================\n\nThis Python library provides functionality for interacting with desktop\napplications via UI automation on Windows OS using ``pywinauto``. It\nincludes methods to manage application lifecycles, interact with UI\nelements, and handle alerts.\n\n--------------\n\nClasses\n-------\n\n``DesktopApp``\n~~~~~~~~~~~~~~\n\nThe main class, ``DesktopApp``, is an abstract base class designed to\nmanage desktop applications, providing methods to start, connect, and\ninteract with app elements.\n\n--------------\n\nClass Documentation\n-------------------\n\nInitialization\n\n.. code:: python\n\n DesktopApp(app_path: str)\n\nInitializes the desktop application instance.\n\n- **Parameters**\n\n - ``app_path`` (``str``): Path to the application executable.\n\n--------------\n\nMethods\n-------\n\n``dialog`` (property)\n~~~~~~~~~~~~~~~~~~~~~\n\nThe main point of interaction with the App Window.\n\n**Returns**: - ``WindowSpecification``: The top-level window of the\napplication.\n\n--------------\n\n``connect_to_app``\n~~~~~~~~~~~~~~~~~~\n\nConnect to the application.\n\n.. code:: python\n\n def connect_to_app(app_path: str = None, title: str = None, timeout: int = None, **kwargs) -> Application\n\n- **Parameters**\n\n - ``app_path`` (``str``, optional): Location of the application.\n - ``title`` (``str``, optional): Window title.\n - ``timeout`` (``int``, optional): Max wait time for connection.\n\n- **Returns**:\n\n - ``Application``: Connected application object.\n\n--------------\n\n``start_app``\n~~~~~~~~~~~~~\n\nStarts the application.\n\n.. code:: python\n\n def start_app(app_path: str, app_folder: str, sleep_seconds: int = 2) -> None\n\n- **Parameters**\n\n - ``app_path`` (``str``): Application path.\n - ``app_folder`` (``str``): Application folder.\n - ``sleep_seconds`` (``int``): Pause time after startup.\n\n--------------\n\n``close_alerts``\n~~~~~~~~~~~~~~~~\n\nCloses application alerts.\n\n.. code:: python\n\n def close_alerts(expected_window_title: str, max_attempts: int = 3, sleep_seconds: int = 1, ignored_titles: list[str] = []) -> None\n\n- **Parameters**\n\n - ``expected_window_title`` (``str``): Title of the expected window.\n - ``max_attempts`` (``int``): Max attempts to check for the window.\n - ``sleep_seconds`` (``int``): Time between attempts.\n - ``ignored_titles`` (``list[str]``): Titles to ignore.\n\n- **Raises**:\n\n - ``ElementNotFoundError``: If the expected window is not visible.\n\n--------------\n\n``get_element``\n~~~~~~~~~~~~~~~\n\nRetrieves a UI element.\n\n.. code:: python\n\n def get_element(control_type: str, title: str | None = None, auto_id: str | None = None, dialog: WindowSpecification = None, **kwargs) -> WindowSpecification\n\n- **Parameters**\n\n - ``control_type`` (``str``): Control type of the element.\n - ``title`` (``str``, optional): Title of the element.\n - ``auto_id`` (``str``, optional): Automation ID.\n\n- **Returns**:\n\n - ``WindowSpecification``: Matching UI element.\n\n--------------\n\n``invoke_button``\n~~~~~~~~~~~~~~~~~\n\nInvokes a button.\n\n.. code:: python\n\n def invoke_button(auto_id: str = None, title: str = None, dialog: WindowSpecification | None = None, **kwargs) -> None\n\n- **Parameters**\n\n - ``auto_id`` (``str``, optional): Automation ID of the button.\n - ``title`` (``str``, optional): Title of the button.\n\n--------------\n\n``set_input_text``\n~~~~~~~~~~~~~~~~~~\n\nSets text in an input field.\n\n.. code:: python\n\n def set_input_text(text: str, auto_id: str = None, title: str = None, dialog: WindowSpecification | None = None) -> None\n\n- **Parameters**\n\n - ``text`` (``str``): Text to set.\n - ``auto_id`` (``str``, optional): ID of the input field.\n - ``title`` (``str``, optional): Title of the input field.\n\n--------------\n\n``mouse_click_element``\n~~~~~~~~~~~~~~~~~~~~~~~\n\nPerforms a mouse click on a specified element.\n\n.. code:: python\n\n def mouse_click_element(element: WindowSpecification, button: str = \"left\", offset_x: int = 0, offset_y: int = 0) -> None\n\n- **Parameters**\n\n - ``element`` (``WindowSpecification``): Element to click.\n - ``button`` (``str``): Mouse button.\n - ``offset_x`` (``int``): Horizontal offset.\n - ``offset_y`` (``int``): Vertical offset.\n\n--------------\n\n``mouse_double_click_element``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nPerforms a mouse double-click on a specified element.\n\n.. code:: python\n\n def mouse_double_click_element(element: WindowSpecification, button: str = \"left\", set_focus: bool = False) -> None\n\n- **Parameters**\n\n - ``element`` (``WindowSpecification``): Element to double-click.\n - ``button`` (``str``): Mouse button.\n - ``set_focus`` (``bool``): Set focus before clicking.\n\n--------------\n\n``select_dropdown_item``\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nSelects an item from a dropdown.\n\n.. code:: python\n\n def select_dropdown_item(auto_id: str, dropdown_item: str) -> None\n\n- **Parameters**\n\n - ``auto_id`` (``str``): Dropdown ID.\n - ``dropdown_item`` (``str``): Dropdown item to select.\n\n--------------\n\n``wait_to_disappear``\n~~~~~~~~~~~~~~~~~~~~~\n\nWaits for an element to disappear.\n\n.. code:: python\n\n def wait_to_disappear(control_type: str, auto_id: str = None, title: str = None, max_attempts: int = 3, timeout: int = 1) -> None\n\n- **Parameters**\n\n - ``control_type`` (``str``): Element control type.\n - ``auto_id`` (``str``, optional): Element ID.\n - ``title`` (``str``, optional): Element title.\n\n- **Raises**:\n\n - ``AssertionError``: If the element is still present after all\n attempts.\n\nHere\u2019s the documentation for the new methods and the ``dialog``\nattribute:\n\n--------------\n\n``click_input``\n~~~~~~~~~~~~~~~\n\nClick element based on provided kwargs.\n\n.. code:: python\n\n def click_input(\n self,\n control_type: str,\n auto_id: str | None = None,\n title: str | None = None,\n dialog: WindowSpecification | None = None,\n **kwargs,\n ) -> None\n\n**Args**: - ``control_type`` (str): The control type of the element\n(required). - ``auto_id`` (str, optional): The automation ID of the\nbutton. Defaults to None. - ``title`` (str, optional): The title of the\nbutton. Defaults to None. - ``dialog`` (WindowSpecification, optional):\nThe dialog to operate on. Defaults to self.dialog. - ``**kwargs``:\nAdditional keyword arguments for identifying a child window element.\n\n--------------\n\n``right_click_empty_space``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nRight clicks in the blank space after a list of elements.\n\n.. code:: python\n\n def right_click_empty_space(self, element: WindowSpecification, sleep_seconds: int = 2) -> None\n\n**Args**: - ``element`` (WindowSpecification): The element to operate\non. - ``sleep_seconds`` (int): Time to sleep after right-clicking to\nallow the dropdown to appear.\n\n--------------\n\n``get_element_coordinates``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nRetrieves the coordinates of an element.\n\n.. code:: python\n\n def get_element_coordinates(element: WindowSpecification) -> tuple\n\n**Args**: - ``element`` (WindowSpecification): The element whose\ncoordinates are retrieved.\n\n**Returns**: - ``tuple``: The coordinates of the element.\n\n**Raises**: - ``AssertionError``: If the coordinates cannot be\nretrieved.\n\n--------------\n\n``wait_until_element_visible``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWaits for an element to become visible in the dialog window.\n\n.. code:: python\n\n def wait_until_element_visible(\n self, control_type: str, title: str = None, auto_id: str = None, timeout: int = 5\n ) -> bool\n\n**Args**: - ``control_type`` (str): The control type of the element\n(required). - ``title`` (str, optional): The title of the element.\nDefaults to None. - ``auto_id`` (str, optional): The automation ID of\nthe element. Defaults to None. - ``timeout`` (int, optional): The\nmaximum wait time for the element to become visible. Defaults to 5\nseconds.\n\n**Raises**: - ``ValueError``: If neither \u2018title\u2019 nor \u2018auto_id\u2019 is\nprovided. - ``TimeoutError``: If the element does not become visible\nwithin the timeout.\n\n**Returns**: - ``bool``: True if the element becomes visible within the\nallowed time.\n\n--------------\n\n``kill_app``\n~~~~~~~~~~~~\n\nCloses the app if it remains open after the session ends.\n\n.. code:: python\n\n def kill_app(self, process: str, app_path: str) -> None\n\n**Args**: - ``process`` (str): The name of the application process. -\n``app_path`` (str): The path of the application executable.\n\n**Raises**: - ``UsernameNotFoundError``: If the username is missing.\n\n--------------\n\n``get_app_session_if_running``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nReturns the current session ID if the app is running.\n\n.. code:: python\n\n def get_app_session_if_running(self, app_path: str) -> str | None\n\n**Args**: - ``app_path`` (str): The system path of the application\nexecutable.\n\n**Returns**: - ``None | str``: None if the app is not running, otherwise\nthe tasklist output.\n\n**Raises**: - ``UsernameNotFoundError``: If the username is missing.\n\n--------------\n\nUtilities\n---------\n\n``relogin_and_retry_if_pywin_error``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDecorator to relogin and retry a function if a specified PyWin error\noccurs.\n\n**Args**: - ``retries`` (int): Number of times to retry the function.\nDefaults to 3. - ``delay`` (int): Delay in seconds between retries.\nDefaults to 1.\n\n**Returns**: - ``Callable``: The decorated function with retry and\nrelogin logic.\n\n**Raises**: - ``LoginMethodNotFoundError``: If the ``login`` method is\nnot defined or not callable on the class.\n\n--------------\n\n``retry_if_pywin_error``\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nDecorator for retrying a function in Apps derived classes if specified\nexceptions are encountered.\n\n**Args**: - ``retries`` (int): Number of times to retry the function.\nDefaults to 3. - ``delay`` (int): Delay in seconds between retries.\nDefaults to 1. - ``close_modal`` (bool): Whether to attempt closing\nmodal dialogs on error. Defaults to False. - ``exceptions``\n(tuple[Type[BaseException], \u2026]): Additional exceptions to catch and\nretry on.\n\n**Returns**: - ``Callable``: The decorated function with retry logic for\nspecified exceptions.\n\n**Raises**: - The last caught exception if all retry attempts fail.\n\n--------------\n\n``capture_screenshot_if_pywin_error``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDecorator to capture a screenshot if specified exceptions occur during\nthe execution of a function.\n\n**Args**: - ``func`` (Callable, optional): The function being decorated.\n- ``exceptions_to_include`` (List[Type[Exception]], optional): List of\nexceptions to trigger screenshot capture. Defaults to a predefined list.\n- ``output`` (str): Directory path where screenshots will be saved.\nDefaults to ``CONFIG.DIRECTORIES.SCREENSHOTS``.\n\n**Returns**: - ``Callable``: The decorated function that captures a\nscreenshot upon specific errors.\n\n**Raises**: - The original exception that triggered the screenshot\ncapture if a failure occurs.\n",
"bugtrack_url": null,
"license": null,
"summary": "t-desktop is a Python library that provides common methods for desktop automation, simplifyingtasks like window management, keyboard, and mouse control.",
"version": "0.0.19",
"project_urls": {
"Homepage": "https://www.thoughtful.ai/"
},
"split_keywords": [
"t_desktop"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "743d1bc0f1cd6db39a06a45b7f964a15776e6ae03d4da6e715560cf2c5a3d2d4",
"md5": "195bb72d961ca62c33f63e56ca588e97",
"sha256": "d6e74512cc871421c6b7b7e9f182916554e94d0da1c4d03ca95d4ab6a2a3eba2"
},
"downloads": -1,
"filename": "t_desktop-0.0.19.tar.gz",
"has_sig": false,
"md5_digest": "195bb72d961ca62c33f63e56ca588e97",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 30883,
"upload_time": "2025-01-15T16:04:25",
"upload_time_iso_8601": "2025-01-15T16:04:25.204615Z",
"url": "https://files.pythonhosted.org/packages/74/3d/1bc0f1cd6db39a06a45b7f964a15776e6ae03d4da6e715560cf2c5a3d2d4/t_desktop-0.0.19.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-15 16:04:25",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "t-desktop"
}