feat: add psagentai agent with deployment and configuration
Initial project setup including the main agent script, configuration files, profile JSON state, systemd service unit, startup script, deployment documentation, and Python dependencies. Includes .env, venv/, and __pycache__/ which should likely be excluded via .gitignore to avoid committing secrets and artifacts.
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
"""Top-level package for sniffio."""
|
||||
|
||||
__all__ = [
|
||||
"current_async_library",
|
||||
"AsyncLibraryNotFoundError",
|
||||
"current_async_library_cvar",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
from ._version import __version__
|
||||
|
||||
from ._impl import (
|
||||
current_async_library,
|
||||
AsyncLibraryNotFoundError,
|
||||
current_async_library_cvar,
|
||||
thread_local,
|
||||
)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
from contextvars import ContextVar
|
||||
from typing import Optional
|
||||
import sys
|
||||
import threading
|
||||
|
||||
current_async_library_cvar = ContextVar(
|
||||
"current_async_library_cvar", default=None
|
||||
) # type: ContextVar[Optional[str]]
|
||||
|
||||
|
||||
class _ThreadLocal(threading.local):
|
||||
# Since threading.local provides no explicit mechanism is for setting
|
||||
# a default for a value, a custom class with a class attribute is used
|
||||
# instead.
|
||||
name = None # type: Optional[str]
|
||||
|
||||
|
||||
thread_local = _ThreadLocal()
|
||||
|
||||
|
||||
class AsyncLibraryNotFoundError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def current_async_library() -> str:
|
||||
"""Detect which async library is currently running.
|
||||
|
||||
The following libraries are currently supported:
|
||||
|
||||
================ =========== ============================
|
||||
Library Requires Magic string
|
||||
================ =========== ============================
|
||||
**Trio** Trio v0.6+ ``"trio"``
|
||||
**Curio** - ``"curio"``
|
||||
**asyncio** ``"asyncio"``
|
||||
**Trio-asyncio** v0.8.2+ ``"trio"`` or ``"asyncio"``,
|
||||
depending on current mode
|
||||
================ =========== ============================
|
||||
|
||||
Returns:
|
||||
A string like ``"trio"``.
|
||||
|
||||
Raises:
|
||||
AsyncLibraryNotFoundError: if called from synchronous context,
|
||||
or if the current async library was not recognized.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
from sniffio import current_async_library
|
||||
|
||||
async def generic_sleep(seconds):
|
||||
library = current_async_library()
|
||||
if library == "trio":
|
||||
import trio
|
||||
await trio.sleep(seconds)
|
||||
elif library == "asyncio":
|
||||
import asyncio
|
||||
await asyncio.sleep(seconds)
|
||||
# ... and so on ...
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported library {library!r}")
|
||||
|
||||
"""
|
||||
value = thread_local.name
|
||||
if value is not None:
|
||||
return value
|
||||
|
||||
value = current_async_library_cvar.get()
|
||||
if value is not None:
|
||||
return value
|
||||
|
||||
# Need to sniff for asyncio
|
||||
if "asyncio" in sys.modules:
|
||||
import asyncio
|
||||
try:
|
||||
current_task = asyncio.current_task # type: ignore[attr-defined]
|
||||
except AttributeError:
|
||||
current_task = asyncio.Task.current_task # type: ignore[attr-defined]
|
||||
try:
|
||||
if current_task() is not None:
|
||||
return "asyncio"
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
# Sniff for curio (for now)
|
||||
if 'curio' in sys.modules:
|
||||
from curio.meta import curio_running
|
||||
if curio_running():
|
||||
return 'curio'
|
||||
|
||||
raise AsyncLibraryNotFoundError(
|
||||
"unknown async library, or not in async context"
|
||||
)
|
||||
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from .. import (
|
||||
current_async_library, AsyncLibraryNotFoundError,
|
||||
current_async_library_cvar, thread_local
|
||||
)
|
||||
|
||||
|
||||
def test_basics_cvar():
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
token = current_async_library_cvar.set("generic-lib")
|
||||
try:
|
||||
assert current_async_library() == "generic-lib"
|
||||
finally:
|
||||
current_async_library_cvar.reset(token)
|
||||
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
|
||||
def test_basics_tlocal():
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
old_name, thread_local.name = thread_local.name, "generic-lib"
|
||||
try:
|
||||
assert current_async_library() == "generic-lib"
|
||||
finally:
|
||||
thread_local.name = old_name
|
||||
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
|
||||
def test_asyncio():
|
||||
import asyncio
|
||||
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
ran = []
|
||||
|
||||
async def this_is_asyncio():
|
||||
assert current_async_library() == "asyncio"
|
||||
# Call it a second time to exercise the caching logic
|
||||
assert current_async_library() == "asyncio"
|
||||
ran.append(True)
|
||||
|
||||
asyncio.run(this_is_asyncio())
|
||||
assert ran == [True]
|
||||
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info >= (3, 12),
|
||||
reason=
|
||||
"curio broken on 3.12 (https://github.com/python-trio/sniffio/pull/42)",
|
||||
)
|
||||
def test_curio():
|
||||
import curio
|
||||
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
|
||||
ran = []
|
||||
|
||||
async def this_is_curio():
|
||||
assert current_async_library() == "curio"
|
||||
# Call it a second time to exercise the caching logic
|
||||
assert current_async_library() == "curio"
|
||||
ran.append(True)
|
||||
|
||||
curio.run(this_is_curio)
|
||||
assert ran == [True]
|
||||
|
||||
with pytest.raises(AsyncLibraryNotFoundError):
|
||||
current_async_library()
|
||||
@@ -0,0 +1,3 @@
|
||||
# This file is imported from __init__.py and exec'd from setup.py
|
||||
|
||||
__version__ = "1.3.1"
|
||||
Reference in New Issue
Block a user