diff --git a/poetry.lock b/poetry.lock index 2ad1cc662..03015f1d1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "ansible-runner" version = "2.3.6" description = "\"Consistent Ansible Python API and CLI with container and process isolation runtime capabilities\"" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -23,7 +22,6 @@ six = "*" name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" -category = "dev" optional = false python-versions = "*" files = [ @@ -35,7 +33,6 @@ files = [ name = "asgiref" version = "3.6.0" description = "ASGI specs, helper code, and adapters" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -50,7 +47,6 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "asttokens" version = "2.4.1" description = "Annotate AST trees with source code positions" -category = "dev" optional = false python-versions = "*" files = [ @@ -69,7 +65,6 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] name = "async-timeout" version = "4.0.2" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -81,7 +76,6 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -100,7 +94,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "autobahn" version = "24.4.2" description = "WebSocket client & server library, WAMP real-time framework" -category = "main" optional = false python-versions = ">=3.9" files = [] @@ -134,7 +127,6 @@ resolved_reference = "f38f16ba28fa253dee951068cc729089c88d857d" name = "automat" version = "22.10.0" description = "Self-service finite-state machines for the programmer on the go." -category = "main" optional = false python-versions = "*" files = [ @@ -153,7 +145,6 @@ visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"] name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -201,7 +192,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "cachetools" version = "3.1.1" description = "Extensible memoizing collections and decorators" -category = "main" optional = false python-versions = "*" files = [ @@ -213,7 +203,6 @@ files = [ name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -225,7 +214,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -302,7 +290,6 @@ pycparser = "*" name = "channels" version = "4.0.0" description = "Brings async, event-driven capabilities to Django 3.2 and up." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -323,7 +310,6 @@ tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", " name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -408,7 +394,6 @@ files = [ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -423,7 +408,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -435,7 +419,6 @@ files = [ name = "constantly" version = "15.1.0" description = "Symbolic constants in Python" -category = "main" optional = false python-versions = "*" files = [ @@ -447,7 +430,6 @@ files = [ name = "coverage" version = "7.3.0" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -512,7 +494,6 @@ toml = ["tomli"] name = "croniter" version = "1.3.14" description = "croniter provides iteration for datetime object with cron like format" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -527,7 +508,6 @@ python-dateutil = "*" name = "cryptography" version = "42.0.5" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -582,7 +562,6 @@ test-randomorder = ["pytest-randomly"] name = "daphne" version = "4.0.0" description = "Django ASGI (HTTP/WebSocket) server" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -602,7 +581,6 @@ tests = ["django", "hypothesis", "pytest", "pytest-asyncio"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -614,7 +592,6 @@ files = [ name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -626,7 +603,6 @@ files = [ name = "distro" version = "1.9.0" description = "Distro - an OS platform information API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -638,7 +614,6 @@ files = [ name = "django" version = "4.2.7" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -659,7 +634,6 @@ bcrypt = ["bcrypt"] name = "django-ansible-base" version = "2024.9.12.0.dev4+ga44d6bf" description = "A Django app used by ansible services" -category = "main" optional = false python-versions = ">=3.9" files = [] @@ -696,7 +670,6 @@ resolved_reference = "a44d6bfab27ffb33a2bd04604b0cb88c7dd7762d" name = "django-crum" version = "0.7.9" description = "Django middleware to capture current request and user." -category = "main" optional = false python-versions = "*" files = [ @@ -711,7 +684,6 @@ django = ">=1.8" name = "django-filter" version = "23.5" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -726,7 +698,6 @@ Django = ">=3.2" name = "django-redis" version = "5.4.0" description = "Full featured redis cache backend for Django." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -745,7 +716,6 @@ hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] name = "django-rq" version = "2.8.0" description = "An app that provides django integration for RQ (Redis Queue)" -category = "main" optional = false python-versions = "*" files = [ @@ -766,7 +736,6 @@ testing = ["mock (>=2.0.0)"] name = "django-split-settings" version = "1.2.0" description = "Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -778,7 +747,6 @@ files = [ name = "djangorestframework" version = "3.15.1" description = "Web APIs for Django, made easy." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -793,7 +761,6 @@ django = ">=3.0" name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -805,7 +772,6 @@ files = [ name = "drf-spectacular" version = "0.26.5" description = "Sane and flexible OpenAPI 3 schema generation for Django REST framework" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -829,7 +795,6 @@ sidecar = ["drf-spectacular-sidecar"] name = "dynaconf" version = "3.2.4" description = "The dynamic configurator for your Python Project" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -851,7 +816,6 @@ yaml = ["ruamel.yaml"] name = "ecdsa" version = "0.19.0" description = "ECDSA cryptographic signature library (pure python)" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.6" files = [ @@ -870,7 +834,6 @@ gmpy2 = ["gmpy2"] name = "eradicate" version = "2.2.0" description = "Removes commented-out code." -category = "dev" optional = false python-versions = "*" files = [ @@ -882,7 +845,6 @@ files = [ name = "executing" version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -897,7 +859,6 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth name = "flake8" version = "5.0.4" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -914,7 +875,6 @@ pyflakes = ">=2.5.0,<2.6.0" name = "flake8-broken-line" version = "0.6.0" description = "Flake8 plugin to forbid backslashes for line breaks" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -929,7 +889,6 @@ flake8 = ">=3.5,<6" name = "flake8-bugbear" version = "23.3.12" description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -948,7 +907,6 @@ dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", name = "flake8-comprehensions" version = "3.12.0" description = "A flake8 plugin to help you write better list/set/dict comprehensions." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -963,7 +921,6 @@ flake8 = ">=3.0,<3.2.0 || >3.2.0" name = "flake8-debugger" version = "4.1.2" description = "ipdb/pdb statement checker plugin for flake8" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -979,7 +936,6 @@ pycodestyle = "*" name = "flake8-docstrings" version = "1.7.0" description = "Extension for flake8 which uses pydocstyle to check docstrings" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -995,7 +951,6 @@ pydocstyle = ">=2.1" name = "flake8-eradicate" version = "1.4.0" description = "Flake8 plugin to find commented out code" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -1012,7 +967,6 @@ flake8 = ">=3.5,<6" name = "flake8-print" version = "5.0.0" description = "print statement checker plugin for flake8" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1028,7 +982,6 @@ pycodestyle = "*" name = "flake8-string-format" version = "0.3.0" description = "string format checker, plugin for flake8" -category = "dev" optional = false python-versions = "*" files = [ @@ -1043,7 +996,6 @@ flake8 = "*" name = "google-auth" version = "2.17.3" description = "Google Authentication Library" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" files = [ @@ -1068,7 +1020,6 @@ requests = ["requests (>=2.20.0,<3.0.0dev)"] name = "httpie" version = "3.2.3" description = "HTTPie: modern, user-friendly command-line HTTP client for the API era." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1096,7 +1047,6 @@ test = ["pytest", "pytest-httpbin (>=0.0.6)", "pytest-mock", "responses", "werkz name = "hyperlink" version = "21.0.0" description = "A featureful, immutable, and correct URL for Python." -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1111,7 +1061,6 @@ idna = ">=2.5" name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1123,7 +1072,6 @@ files = [ name = "incremental" version = "22.10.0" description = "\"A small library that versions your Python projects.\"" -category = "main" optional = false python-versions = "*" files = [ @@ -1139,7 +1087,6 @@ scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1151,7 +1098,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1163,7 +1109,6 @@ files = [ name = "insights-analytics-collector" version = "0.3.2" description = "Collector Package for Insights for AAP" -category = "main" optional = false python-versions = "*" files = [ @@ -1179,7 +1124,6 @@ requests = "*" name = "ipython" version = "8.17.2" description = "IPython: Productive Interactive Computing" -category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1216,7 +1160,6 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pa name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -1234,7 +1177,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "jedi" version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1254,7 +1196,6 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.1.3" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1272,7 +1213,6 @@ i18n = ["Babel (>=2.7)"] name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1292,7 +1232,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "kubernetes" version = "26.1.0" description = "Kubernetes python client" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1310,7 +1249,7 @@ requests-oauthlib = "*" setuptools = ">=21.0.0" six = ">=1.9.0" urllib3 = ">=1.24.2" -websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.0 || >=0.43.0" +websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" [package.extras] adal = ["adal (>=1.0.2)"] @@ -1319,7 +1258,6 @@ adal = ["adal (>=1.0.2)"] name = "lockfile" version = "0.12.2" description = "Platform-independent file locking module" -category = "main" optional = false python-versions = "*" files = [ @@ -1331,7 +1269,6 @@ files = [ name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1356,7 +1293,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1426,7 +1362,6 @@ files = [ name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1441,7 +1376,6 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1453,7 +1387,6 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1465,7 +1398,6 @@ files = [ name = "multidict" version = "6.0.5" description = "multidict implementation" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1565,7 +1497,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1577,7 +1508,6 @@ files = [ name = "oauthlib" version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1594,7 +1524,6 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1606,7 +1535,6 @@ files = [ name = "parso" version = "0.8.3" description = "A Python Parser" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1622,7 +1550,6 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1634,7 +1561,6 @@ files = [ name = "pep8-naming" version = "0.13.3" description = "Check PEP-8 naming conventions, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1649,7 +1575,6 @@ flake8 = ">=5.0.0" name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = false python-versions = "*" files = [ @@ -1664,7 +1589,6 @@ ptyprocess = ">=0.5" name = "pip" version = "24.2" description = "The PyPA recommended tool for installing Python packages." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1676,7 +1600,6 @@ files = [ name = "platformdirs" version = "3.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1692,7 +1615,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest- name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1708,7 +1630,6 @@ testing = ["pytest", "pytest-benchmark"] name = "podman" version = "4.9.0" description = "Bindings for Podman RESTful API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1728,7 +1649,6 @@ progress-bar = ["rich (>=12.5.1)"] name = "prompt-toolkit" version = "3.0.41" description = "Library for building powerful interactive command lines in Python" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -1743,7 +1663,6 @@ wcwidth = "*" name = "psycopg" version = "3.2.1" description = "PostgreSQL database adapter for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1767,7 +1686,6 @@ test = ["anyio (>=4.0)", "mypy (>=1.6)", "pproxy (>=2.7)", "pytest (>=6.2.5)", " name = "psycopg-binary" version = "3.2.1" description = "PostgreSQL database adapter for Python -- C optimisation distribution" -category = "main" optional = true python-versions = ">=3.8" files = [ @@ -1830,7 +1748,6 @@ files = [ name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -1842,7 +1759,6 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" -category = "dev" optional = false python-versions = "*" files = [ @@ -1857,7 +1773,6 @@ tests = ["pytest"] name = "pyasn1" version = "0.5.0" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -1869,7 +1784,6 @@ files = [ name = "pyasn1-modules" version = "0.3.0" description = "A collection of ASN.1-based protocols modules" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -1884,7 +1798,6 @@ pyasn1 = ">=0.4.6,<0.6.0" name = "pycodestyle" version = "2.9.1" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1896,7 +1809,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1908,7 +1820,6 @@ files = [ name = "pydantic" version = "1.10.7" description = "Data validation and settings management using python type hints" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1961,7 +1872,6 @@ email = ["email-validator (>=1.0.3)"] name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1979,7 +1889,6 @@ toml = ["tomli (>=1.2.3)"] name = "pyflakes" version = "2.5.0" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1991,7 +1900,6 @@ files = [ name = "pygments" version = "2.17.1" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2007,7 +1915,6 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pyjwt" version = "2.8.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2028,7 +1935,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pyopenssl" version = "24.1.0" description = "Python wrapper module around the OpenSSL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2047,7 +1953,6 @@ test = ["pretend", "pytest (>=3.0.1)", "pytest-rerunfailures"] name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2084,7 +1989,6 @@ files = [ name = "pysocks" version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2097,7 +2001,6 @@ files = [ name = "pytest" version = "7.3.1" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2118,7 +2021,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.21.0" description = "Pytest support for asyncio" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2137,7 +2039,6 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2156,7 +2057,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-django" version = "4.5.2" description = "A Django plugin for pytest." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2175,7 +2075,6 @@ testing = ["Django", "django-configurations (>=2.0)"] name = "pytest-lazy-fixture" version = "0.6.3" description = "It helps to use fixtures in pytest.mark.parametrize" -category = "dev" optional = false python-versions = "*" files = [ @@ -2190,7 +2089,6 @@ pytest = ">=3.2.5" name = "python-daemon" version = "3.0.1" description = "Library to implement a well-behaved Unix daemon process." -category = "main" optional = false python-versions = ">=3" files = [ @@ -2211,7 +2109,6 @@ test = ["coverage", "docutils", "testscenarios (>=0.4)", "testtools"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2226,7 +2123,6 @@ six = ">=1.5" name = "python-gnupg" version = "0.5.2" description = "A wrapper for the Gnu Privacy Guard (GPG or GnuPG)" -category = "main" optional = false python-versions = "*" files = [ @@ -2238,7 +2134,6 @@ files = [ name = "pyxdg" version = "0.28" description = "PyXDG contains implementations of freedesktop.org standards in python." -category = "main" optional = false python-versions = "*" files = [ @@ -2250,7 +2145,6 @@ files = [ name = "pyyaml" version = "6.0.2" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2313,7 +2207,6 @@ files = [ name = "redis" version = "4.5.4" description = "Python client for Redis database and key-value store" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2332,7 +2225,6 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2355,7 +2247,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-mock" version = "1.12.1" description = "Mock out responses from the requests package" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2373,7 +2264,6 @@ fixture = ["fixtures"] name = "requests-oauthlib" version = "1.3.1" description = "OAuthlib authentication support for Requests." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2392,7 +2282,6 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2407,7 +2296,6 @@ requests = ">=2.0.1,<3.0.0" name = "rich" version = "13.8.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -2426,7 +2314,6 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "rq" version = "1.13.0" description = "RQ is a simple, lightweight, library for creating background jobs, and processing them." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2442,7 +2329,6 @@ redis = ">=3.5.0" name = "rq-scheduler" version = "0.10.0" description = "Provides job scheduling capabilities to RQ (Redis Queue)" -category = "main" optional = false python-versions = "*" files = [ @@ -2458,7 +2344,6 @@ rq = ">=0.13" name = "rsa" version = "4.9" description = "Pure-Python RSA implementation" -category = "main" optional = false python-versions = ">=3.6,<4" files = [ @@ -2473,7 +2358,6 @@ pyasn1 = ">=0.1.3" name = "ruff" version = "0.0.262" description = "An extremely fast Python linter, written in Rust." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2500,7 +2384,6 @@ files = [ name = "service-identity" version = "21.1.0" description = "Service identity verification for pyOpenSSL & cryptography." -category = "main" optional = false python-versions = "*" files = [ @@ -2525,7 +2408,6 @@ tests = ["coverage[toml] (>=5.0.2)", "pytest"] name = "setuptools" version = "67.7.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2542,7 +2424,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2554,7 +2435,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -2566,7 +2446,6 @@ files = [ name = "sqlparse" version = "0.4.4" description = "A non-validating SQL parser." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2583,7 +2462,6 @@ test = ["pytest", "pytest-cov"] name = "stack-data" version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "dev" optional = false python-versions = "*" files = [ @@ -2603,7 +2481,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "traitlets" version = "5.13.0" description = "Traitlets Python configuration system" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2619,7 +2496,6 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0, name = "twisted" version = "22.10.0" description = "An asynchronous networking framework written in Python" -category = "main" optional = false python-versions = ">=3.7.1" files = [ @@ -2661,7 +2537,6 @@ windows-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0. name = "twisted-iocpsupport" version = "1.0.3" description = "An extension for use in the twisted I/O Completion Ports reactor." -category = "main" optional = false python-versions = "*" files = [ @@ -2687,7 +2562,6 @@ files = [ name = "txaio" version = "23.1.1" description = "Compatibility API between asyncio/Twisted/Trollius" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2704,7 +2578,6 @@ twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2716,7 +2589,6 @@ files = [ name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ @@ -2728,7 +2600,6 @@ files = [ name = "uritemplate" version = "4.1.1" description = "Implementation of RFC 6570 URI Templates" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2740,7 +2611,6 @@ files = [ name = "urllib3" version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -2757,7 +2627,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "wcwidth" version = "0.2.10" description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" optional = false python-versions = "*" files = [ @@ -2769,7 +2638,6 @@ files = [ name = "websocket-client" version = "1.5.1" description = "WebSocket client for Python with low level API options" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2786,7 +2654,6 @@ test = ["websockets"] name = "xxhash" version = "3.4.1" description = "Python binding for xxHash" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2904,7 +2771,6 @@ files = [ name = "zope-interface" version = "6.0" description = "Interfaces for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ diff --git a/src/aap_eda/analytics/analytics_collectors.py b/src/aap_eda/analytics/analytics_collectors.py index 01e75198f..d89e21a3f 100644 --- a/src/aap_eda/analytics/analytics_collectors.py +++ b/src/aap_eda/analytics/analytics_collectors.py @@ -65,6 +65,9 @@ def audit_actions_table( ): audit_actions = _get_audit_action_qs(since, until) + if not bool(audit_actions): + return + audit_action_query = ( f"COPY ({audit_actions.query}) TO STDOUT WITH CSV HEADER" ) @@ -82,7 +85,12 @@ def audit_events_table( since: datetime, full_path: str, until: datetime, **kwargs ): audit_actions = _get_audit_action_qs(since, until) + if not bool(audit_actions): + return + audit_event_query = _get_audit_event_query(audit_actions) + if not bool(audit_event_query): + return return _copy_table("audit_events", audit_event_query, full_path) @@ -97,6 +105,9 @@ def audit_rules_table( since: datetime, full_path: str, until: datetime, **kwargs ): audit_rules = _get_audit_rule_qs(since, until) + if not bool(audit_rules): + return + audit_rule_query = f"COPY ({audit_rules.query}) TO STDOUT WITH CSV HEADER" return _copy_table("audit_rules", audit_rule_query, full_path) @@ -221,9 +232,13 @@ def teams_table(since: datetime, full_path: str, until: datetime, **kwargs): return _copy_table("teams", query, full_path) -def _datetime_format(timestamp: datetime) -> str: +def _datetime_format(dt: datetime) -> str: """Convert datetime object to string.""" - iso_format = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f%z") + if dt.microsecond == 0: + iso_format = dt.strftime("%Y-%m-%d %H:%M:%S%z") + else: + iso_format = dt.strftime("%Y-%m-%d %H:%M:%S.%f%z") + return iso_format[:-2] + ":" + iso_format[-2:] @@ -246,6 +261,7 @@ def _get_query( Q(created_at__gt=since, created_at__lte=until) | Q(modified_at__gt=since, modified_at__lte=until) ).order_by("id") + query = ( str(qs.query) .replace(_datetime_format(since), f"'{since.isoformat()}'") @@ -260,6 +276,9 @@ def _get_audit_event_query(actions: list[models.AuditAction]): for action in actions: events |= action.audit_events.all() + if not bool(events): + return + query = str(events.distinct().query) for action in actions: @@ -285,7 +304,7 @@ def _get_audit_rule_qs(since: datetime, until: datetime): ) if len(activation_instance_ids) == 0: - return [] + return models.RulebookProcess.objects.none() if len(activation_instance_ids) == 1: audit_rules = models.AuditRule.objects.filter( @@ -304,7 +323,7 @@ def _get_audit_action_qs(since: datetime, until: datetime): audit_rule_ids = audit_rules.values_list("id").distinct() if len(audit_rule_ids) == 0: - return [] + return models.AuditRule.objects.none() if len(audit_rule_ids) == 1: audit_actions = models.AuditAction.objects.filter( diff --git a/src/aap_eda/analytics/collector.py b/src/aap_eda/analytics/collector.py index 3545df621..f7696cfd8 100644 --- a/src/aap_eda/analytics/collector.py +++ b/src/aap_eda/analytics/collector.py @@ -1,12 +1,13 @@ import json +from datetime import datetime -from django.conf import settings from django.core.serializers.json import DjangoJSONEncoder from django.db import connection from insights_analytics_collector import Collector from aap_eda.analytics.package import Package from aap_eda.analytics.utils import datetime_hook +from aap_eda.conf.settings import application_settings class AnalyticsCollector(Collector): @@ -18,11 +19,8 @@ def db_connection(): def _package_class(): return Package - def get_last_gathering(self): - return self._last_gathering() - def _is_shipping_configured(self): - if not settings.INSIGHTS_TRACKING_STATE: + if not application_settings.INSIGHTS_TRACKING_STATE: self.logger.warning( "Insights for Event Driven Ansible is not enabled." ) @@ -35,26 +33,38 @@ def _is_valid_license(self): return True def _last_gathering(self): - return settings.AUTOMATION_ANALYTICS_LAST_GATHER + self.logger.info( + "Last gather: " + f"{application_settings.AUTOMATION_ANALYTICS_LAST_GATHER}" + ) + + return ( + datetime.fromisoformat( + application_settings.AUTOMATION_ANALYTICS_LAST_GATHER + ) + if bool(application_settings.AUTOMATION_ANALYTICS_LAST_GATHER) + else None + ) def _load_last_gathered_entries(self): - last_entries = settings.AUTOMATION_ANALYTICS_LAST_ENTRIES + last_entries = application_settings.AUTOMATION_ANALYTICS_LAST_ENTRIES + last_entries = last_entries.replace("'", '"') + self.logger.info(f"Last collect entries: {last_entries}") - return json.loads( - last_entries.value - if last_entries and last_entries.value - else "{}", # noqa: P103 - object_hook=datetime_hook, - ) + return json.loads(last_entries, object_hook=datetime_hook) def _save_last_gathered_entries(self, last_gathered_entries): - self.logger.info(f"Save last_entries: {last_gathered_entries}") - - settings.AUTOMATION_ANALYTICS_LAST_ENTRIES = json.dumps( + application_settings.AUTOMATION_ANALYTICS_LAST_ENTRIES = json.dumps( last_gathered_entries, cls=DjangoJSONEncoder ) + self.logger.info( + "Save last_entries: " + f"{application_settings.AUTOMATION_ANALYTICS_LAST_ENTRIES}" + ) def _save_last_gather(self): self.logger.info(f"Save last_gather: {self.gather_until}") - settings.AUTOMATION_ANALYTICS_LAST_GATHER = self.gather_until + application_settings.AUTOMATION_ANALYTICS_LAST_GATHER = ( + self.gather_until.isoformat() + ) diff --git a/src/aap_eda/analytics/package.py b/src/aap_eda/analytics/package.py index d69ce09b8..965670c91 100644 --- a/src/aap_eda/analytics/package.py +++ b/src/aap_eda/analytics/package.py @@ -1,9 +1,20 @@ -import logging - +# Copyright 2024 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from django.conf import settings from insights_analytics_collector import Package as InsightsAnalyticsPackage -logger = logging.getLogger(__name__) +from aap_eda.conf import application_settings class Package(InsightsAnalyticsPackage): @@ -15,16 +26,16 @@ def _tarname_base(self): return f'eda-analytics-{timestamp.strftime("%Y-%m-%d-%H%M%S%z")}' def get_ingress_url(self): - return settings.AUTOMATION_ANALYTICS_URL + return application_settings.AUTOMATION_ANALYTICS_URL def shipping_auth_mode(self): return settings.AUTOMATION_AUTH_METHOD def _get_rh_user(self): - return settings.REDHAT_USERNAME + return application_settings.REDHAT_USERNAME def _get_rh_password(self): - return settings.REDHAT_PASSWORD + return application_settings.REDHAT_PASSWORD def _get_http_request_headers(self): return { diff --git a/src/aap_eda/conf/registry.py b/src/aap_eda/conf/registry.py index e9b3b7032..30e41d217 100644 --- a/src/aap_eda/conf/registry.py +++ b/src/aap_eda/conf/registry.py @@ -84,8 +84,7 @@ class RegistryData(object): ), RegistryData( name="AUTOMATION_ANALYTICS_LAST_ENTRIES", - type=dict, - default={}, + default="{}", # noqa P103 ), RegistryData( name="AUTOMATION_ANALYTICS_GATHER_INTERVAL", diff --git a/src/aap_eda/core/management/commands/gather_analytics.py b/src/aap_eda/core/management/commands/gather_analytics.py index d55b8f7d1..ad46c579d 100644 --- a/src/aap_eda/core/management/commands/gather_analytics.py +++ b/src/aap_eda/core/management/commands/gather_analytics.py @@ -60,6 +60,7 @@ def handle(self, *args, **options): since = parser.parse(opt_since) if opt_since else None if since and since.tzinfo is None: since = since.replace(tzinfo=timezone.utc) + until = parser.parse(opt_until) if opt_until else None if until and until.tzinfo is None: until = until.replace(tzinfo=timezone.utc) diff --git a/tests/integration/analytics/test_analytics_collectors.py b/tests/integration/analytics/test_analytics_collectors.py index 67a54c32e..c86e76192 100644 --- a/tests/integration/analytics/test_analytics_collectors.py +++ b/tests/integration/analytics/test_analytics_collectors.py @@ -25,9 +25,16 @@ from aap_eda.analytics import analytics_collectors as collectors from aap_eda.analytics.collector import AnalyticsCollector +from aap_eda.conf import settings_registry from aap_eda.core import models +@pytest.fixture(autouse=True) +def register() -> None: + settings_registry.persist_registry_data() + return None + + @pytest.mark.django_db def test_internal_infra_files(): collector = AnalyticsCollector( @@ -140,6 +147,7 @@ def test_activations_table_collector(default_activation: models.Activation): assert lines[0][3] == default_activation.description +@pytest.mark.django_db def assert_audit_rules(expected_audit_rules): time_start = now() - timedelta(hours=9) @@ -209,6 +217,7 @@ def test_multiple_audit_action_table_collector( assert_audit_events([audit_event_1, audit_event_2]) +@pytest.mark.django_db def assert_audit_actions(expected_audit_actions): time_start = now() - timedelta(hours=9) @@ -238,6 +247,7 @@ def assert_audit_actions(expected_audit_actions): ) +@pytest.mark.django_db def assert_audit_events(expected_audit_events): time_start = now() - timedelta(hours=9) diff --git a/tests/unit/test_application_settings.py b/tests/unit/test_application_settings.py index cae27881f..3001f0956 100644 --- a/tests/unit/test_application_settings.py +++ b/tests/unit/test_application_settings.py @@ -15,7 +15,7 @@ import pytest from aap_eda.conf import application_settings, settings_registry -from aap_eda.conf.registry import InvalidKeyError, InvalidValueError +from aap_eda.conf.registry import InvalidKeyError @pytest.fixture(autouse=True) @@ -43,16 +43,6 @@ def test_read_only_application_setting(): application_settings.INSIGHTS_CERT_PATH = "path" -@pytest.mark.django_db -def test_application_setting_bad_type(): - assert ( - settings_registry.get_setting_type("AUTOMATION_ANALYTICS_LAST_ENTRIES") - == dict - ) - with pytest.raises(InvalidValueError): - application_settings.AUTOMATION_ANALYTICS_LAST_ENTRIES = 1 - - @pytest.mark.django_db def test_list_keys(): assert len(settings_registry.get_registered_settings()) == 10