From c4373e08b772832dcebee62cc6a6387b9bc00813 Mon Sep 17 00:00:00 2001 From: shacharl Date: Mon, 19 May 2025 19:33:54 +0300 Subject: [PATCH 1/6] Refactor imports: replace wildcard aapi imports with explicit module imports --- src/aapi/__init__.py | 2 +- src/aapi/action.py | 2 +- src/aapi/addevents.py | 3 +- src/aapi/basefolder.py | 17 ++++++++++- src/aapi/businessfield.py | 2 +- src/aapi/businessparameter.py | 3 +- src/aapi/calendar.py | 4 ++- src/aapi/calendarfields.py | 3 +- src/aapi/calendarkey.py | 3 +- src/aapi/captureoutput.py | 2 +- src/aapi/condition.py | 2 +- src/aapi/config.py | 3 +- src/aapi/connectionprofile.py | 7 +++-- src/aapi/ctbruledata.py | 2 +- src/aapi/date.py | 2 +- src/aapi/definitionitemdetails.py | 2 +- src/aapi/deleteevents.py | 3 +- src/aapi/disallowedoptions.py | 2 +- src/aapi/do.py | 2 +- src/aapi/donotify.py | 3 +- src/aapi/driver.py | 2 +- src/aapi/endpoint.py | 3 +- src/aapi/event.py | 2 +- src/aapi/extractrule.py | 2 +- src/aapi/filetransfer.py | 2 +- src/aapi/filetransfergroup.py | 2 +- src/aapi/{flow_.py => flow.py} | 4 +-- src/aapi/folderclientdata.py | 2 +- src/aapi/folderjobbase.py | 13 ++++++-- src/aapi/hostfiletransfer.py | 3 +- src/aapi/hostmapping.py | 3 +- src/aapi/if_.py | 4 +-- src/aapi/ifbase.py | 5 ++-- src/aapi/ifcollection.py | 4 ++- src/aapi/ifrerun.py | 2 +- src/aapi/internalrule.py | 4 +-- src/aapi/iteminfo.py | 2 +- src/aapi/job.py | 14 ++++++++- src/aapi/jobsfilter.py | 2 +- src/aapi/jobtag.py | 2 +- src/aapi/mail.py | 2 +- src/aapi/notify.py | 2 +- src/aapi/on.py | 2 +- src/aapi/output.py | 2 +- src/aapi/package.py | 2 +- src/aapi/packageparams.py | 2 +- src/aapi/period.py | 3 +- src/aapi/possibleoptions.py | 2 +- src/aapi/propertycondition.py | 2 +- src/aapi/rbcdetails.py | 2 +- src/aapi/remedy.py | 2 +- src/aapi/resource.py | 2 +- src/aapi/resourcepools.py | 2 +- src/aapi/run.py | 2 +- src/aapi/runningjobs.py | 2 +- src/aapi/set_.py | 2 +- src/aapi/sitestandard.py | 4 ++- src/aapi/sitestandarddata.py | 2 +- src/aapi/sitestandardoperatorvalueoptions.py | 2 +- src/aapi/sitestandardpolicy.py | 3 +- src/aapi/sitestandardpolicydata.py | 2 +- src/aapi/sitestandardpossiblevalue.py | 2 +- src/aapi/sitestandardrestriction.py | 4 ++- src/aapi/steprange.py | 3 +- src/aapi/tag.py | 3 +- src/aapi/time.py | 3 +- src/aapi/variable.py | 3 +- src/aapi/waitforevents.py | 3 +- src/aapi/workloadflat.py | 2 +- src/aapi/workloadpolicy.py | 5 +++- src/aapi/wpperiod.py | 2 +- src/aapi/year.py | 2 +- src/ctm_python_client/core/workflow.py | 31 +++++++++++++++----- 73 files changed, 168 insertions(+), 87 deletions(-) rename src/aapi/{flow_.py => flow.py} (87%) diff --git a/src/aapi/__init__.py b/src/aapi/__init__.py index 6d7a195..e7d88c5 100644 --- a/src/aapi/__init__.py +++ b/src/aapi/__init__.py @@ -11,7 +11,7 @@ from aapi.deleteevents import DeleteEvents from aapi.do import Do from aapi.event import Event, EventAdd, EventDelete, EventIn, EventOut, EventOutAdd, EventOutDelete -from aapi.flow_ import Flow_ +from aapi.flow import Flow from aapi.basefolder import SimpleFolder, Folder from aapi.folderclientdata import FolderClientData from aapi.businessfield import BusinessField diff --git a/src/aapi/action.py b/src/aapi/action.py index 42f4992..69f0d7b 100644 --- a/src/aapi/action.py +++ b/src/aapi/action.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/addevents.py b/src/aapi/addevents.py index 6c95717..91ca4cc 100644 --- a/src/aapi/addevents.py +++ b/src/aapi/addevents.py @@ -5,8 +5,9 @@ import enum import random import string -from aapi import * +from aapi.bases import AAPIObject +from aapi.event import EventOutAdd @attrs.define class AddEvents(AAPIObject): diff --git a/src/aapi/basefolder.py b/src/aapi/basefolder.py index 3b07350..71af80a 100644 --- a/src/aapi/basefolder.py +++ b/src/aapi/basefolder.py @@ -3,8 +3,23 @@ import attrs import typing import enum -from aapi import * +import typing +import attrs +from aapi.addevents import AddEvents +from aapi.bases import AAPIJob, AAPIObject +from aapi.calendar import CalendarRuleBased +from aapi.deleteevents import DeleteEvents +from aapi.event import Event +from aapi.folderclientdata import FolderClientData +from aapi.folderjobbase import SubFolder +from aapi.ifbase import IfBase +from aapi.job import Job +from aapi.notify import Notify +from aapi.resource import ResourceLock +from aapi.tag import TagGlobal +from aapi.waitforevents import WaitForEvents +from aapi.flow import Flow @attrs.define class SimpleFolder(AAPIObject): diff --git a/src/aapi/businessfield.py b/src/aapi/businessfield.py index 7bffef5..9ee9c9d 100644 --- a/src/aapi/businessfield.py +++ b/src/aapi/businessfield.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/businessparameter.py b/src/aapi/businessparameter.py index d9f1944..7f05d2a 100644 --- a/src/aapi/businessparameter.py +++ b/src/aapi/businessparameter.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.sitestandardpossiblevalue import SiteStandardPossibleValue @attrs.define diff --git a/src/aapi/calendar.py b/src/aapi/calendar.py index c2bab95..e09cecd 100644 --- a/src/aapi/calendar.py +++ b/src/aapi/calendar.py @@ -3,7 +3,9 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.period import Period +from aapi.year import Year @attrs.define class Calendar(AAPIObject): diff --git a/src/aapi/calendarfields.py b/src/aapi/calendarfields.py index 9d611ed..25a9c8b 100644 --- a/src/aapi/calendarfields.py +++ b/src/aapi/calendarfields.py @@ -3,8 +3,7 @@ import attrs import typing import enum -from aapi import * - +from aapi.bases import AAPIObject @attrs.define class CalendarFields(AAPIObject): diff --git a/src/aapi/calendarkey.py b/src/aapi/calendarkey.py index 36f11b6..a8368b0 100644 --- a/src/aapi/calendarkey.py +++ b/src/aapi/calendarkey.py @@ -3,8 +3,7 @@ import attrs import typing import enum -from aapi import * - +from aapi.bases import AAPIObject @attrs.define class CalendarKey(AAPIObject): diff --git a/src/aapi/captureoutput.py b/src/aapi/captureoutput.py index 9fb81c8..04a36f6 100644 --- a/src/aapi/captureoutput.py +++ b/src/aapi/captureoutput.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/condition.py b/src/aapi/condition.py index cc3206a..def5589 100644 --- a/src/aapi/condition.py +++ b/src/aapi/condition.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/config.py b/src/aapi/config.py index 8119430..19bee14 100644 --- a/src/aapi/config.py +++ b/src/aapi/config.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/connectionprofile.py b/src/aapi/connectionprofile.py index ef5d9c3..362da29 100644 --- a/src/aapi/connectionprofile.py +++ b/src/aapi/connectionprofile.py @@ -3,8 +3,11 @@ import attrs import typing import enum -from aapi import * - +from importlib.resources import Package +from aapi.bases import AAPIObject +from aapi.endpoint import EndpointDestFtp, EndpointDestFtps, EndpointDestLocal, EndpointDestSftp, EndpointSrcFtp, EndpointSrcFtps, EndpointSrcLocal, EndpointSrcSftp +from aapi.extractrule import ExtractRule +from aapi.packageparams import PackageParams @attrs.define class ConnectionProfile(AAPIObject): diff --git a/src/aapi/ctbruledata.py b/src/aapi/ctbruledata.py index a99e05e..9d23fb1 100644 --- a/src/aapi/ctbruledata.py +++ b/src/aapi/ctbruledata.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/date.py b/src/aapi/date.py index c063a45..1730fc2 100644 --- a/src/aapi/date.py +++ b/src/aapi/date.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/definitionitemdetails.py b/src/aapi/definitionitemdetails.py index a2b9982..98dd640 100644 --- a/src/aapi/definitionitemdetails.py +++ b/src/aapi/definitionitemdetails.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/deleteevents.py b/src/aapi/deleteevents.py index b2c20f0..c804355 100644 --- a/src/aapi/deleteevents.py +++ b/src/aapi/deleteevents.py @@ -5,7 +5,8 @@ import enum import random import string -from aapi import * +from aapi.bases import AAPIObject +from aapi.event import EventOutDelete @attrs.define diff --git a/src/aapi/disallowedoptions.py b/src/aapi/disallowedoptions.py index 5843fb1..cc21542 100644 --- a/src/aapi/disallowedoptions.py +++ b/src/aapi/disallowedoptions.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/do.py b/src/aapi/do.py index e0e639b..1c4c825 100644 --- a/src/aapi/do.py +++ b/src/aapi/do.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/donotify.py b/src/aapi/donotify.py index 291a0f4..6c1371c 100644 --- a/src/aapi/donotify.py +++ b/src/aapi/donotify.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/driver.py b/src/aapi/driver.py index af24abf..98b2ca3 100644 --- a/src/aapi/driver.py +++ b/src/aapi/driver.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/endpoint.py b/src/aapi/endpoint.py index 2a130c7..3ef5180 100644 --- a/src/aapi/endpoint.py +++ b/src/aapi/endpoint.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.packageparams import PackageParams @attrs.define diff --git a/src/aapi/event.py b/src/aapi/event.py index 939344e..e1d549a 100644 --- a/src/aapi/event.py +++ b/src/aapi/event.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/extractrule.py b/src/aapi/extractrule.py index 5749499..f2d5d32 100644 --- a/src/aapi/extractrule.py +++ b/src/aapi/extractrule.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/filetransfer.py b/src/aapi/filetransfer.py index 6dea887..f9c2379 100644 --- a/src/aapi/filetransfer.py +++ b/src/aapi/filetransfer.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/filetransfergroup.py b/src/aapi/filetransfergroup.py index 1beabf9..7ba817a 100644 --- a/src/aapi/filetransfergroup.py +++ b/src/aapi/filetransfergroup.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/flow_.py b/src/aapi/flow.py similarity index 87% rename from src/aapi/flow_.py rename to src/aapi/flow.py index 58b7db4..e756040 100644 --- a/src/aapi/flow_.py +++ b/src/aapi/flow.py @@ -3,11 +3,11 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define -class Flow_(AAPIObject): +class Flow(AAPIObject): _type: str = attrs.field(init=False, default='Flow', metadata={ '_aapi_repr_': 'Type', '_type_aapi_': 'Flow'}) diff --git a/src/aapi/folderclientdata.py b/src/aapi/folderclientdata.py index 06509f2..a2ec1cb 100644 --- a/src/aapi/folderclientdata.py +++ b/src/aapi/folderclientdata.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/folderjobbase.py b/src/aapi/folderjobbase.py index 4c7978b..78fd86b 100644 --- a/src/aapi/folderjobbase.py +++ b/src/aapi/folderjobbase.py @@ -3,8 +3,17 @@ import attrs import typing import enum -from aapi import * - +from aapi.bases import AAPIJob, AAPIObject +from aapi.addevents import AddEvents +from aapi.deleteevents import DeleteEvents +from aapi.ifbase import IfBase +from aapi.job import Job +from aapi.jobtag import JobTag +from aapi.notify import Notify +from aapi.resource import ResourceLock +from aapi.tag import Tag, TagFolder +from aapi.waitforevents import WaitForEvents +from aapi.flow import Flow @attrs.define class FolderJobBase(AAPIObject): diff --git a/src/aapi/hostfiletransfer.py b/src/aapi/hostfiletransfer.py index 9b10ae2..3e7795b 100644 --- a/src/aapi/hostfiletransfer.py +++ b/src/aapi/hostfiletransfer.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/hostmapping.py b/src/aapi/hostmapping.py index 047b3a7..cbe90fb 100644 --- a/src/aapi/hostmapping.py +++ b/src/aapi/hostmapping.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/if_.py b/src/aapi/if_.py index 03693b6..2302a4c 100644 --- a/src/aapi/if_.py +++ b/src/aapi/if_.py @@ -3,8 +3,8 @@ import attrs import typing import enum -from aapi import * - +from aapi.bases import AAPIObject +from ast import If @attrs.define class IfZOS(If): diff --git a/src/aapi/ifbase.py b/src/aapi/ifbase.py index 1fd0c30..56f91ae 100644 --- a/src/aapi/ifbase.py +++ b/src/aapi/ifbase.py @@ -4,8 +4,9 @@ import typing import attrs - -from aapi import * +from aapi.on import On +from aapi.bases import AAPIObject +from aapi.do import Do @attrs.define diff --git a/src/aapi/ifcollection.py b/src/aapi/ifcollection.py index a15a60d..0d24d5c 100644 --- a/src/aapi/ifcollection.py +++ b/src/aapi/ifcollection.py @@ -3,8 +3,10 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.do import Do +from aapi.if_ import IfZOS @attrs.define class IfCollection(AAPIObject): diff --git a/src/aapi/ifrerun.py b/src/aapi/ifrerun.py index 897cce0..8dbc18b 100644 --- a/src/aapi/ifrerun.py +++ b/src/aapi/ifrerun.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/internalrule.py b/src/aapi/internalrule.py index 3bc18c7..6fac919 100644 --- a/src/aapi/internalrule.py +++ b/src/aapi/internalrule.py @@ -3,8 +3,8 @@ import attrs import typing import enum -from aapi import * - +from aapi.bases import AAPIObject +from aapi.sitestandardpossiblevalue import SiteStandardPossibleValue @attrs.define class InternalRule(AAPIObject): diff --git a/src/aapi/iteminfo.py b/src/aapi/iteminfo.py index 1aaa8dc..af2754f 100644 --- a/src/aapi/iteminfo.py +++ b/src/aapi/iteminfo.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/job.py b/src/aapi/job.py index bd0960d..a05e3ab 100644 --- a/src/aapi/job.py +++ b/src/aapi/job.py @@ -1,9 +1,21 @@ from __future__ import annotations +from asyncio import Condition, Event import attrs import typing import enum -from aapi import * +from aapi.addevents import AddEvents +from aapi.bases import AAPIJob, AAPIObject +from aapi.captureoutput import ActionCaptureOutput +from aapi.deleteevents import DeleteEvents +from aapi.filetransfer import FileTransfer +from aapi.ifbase import IfBase +from aapi.ifcollection import IfCollection +from aapi.jobtag import JobTag +from aapi.notify import Notify +from aapi.resource import Resource +from aapi.steprange import StepRange +from aapi.waitforevents import WaitForEvents @attrs.define diff --git a/src/aapi/jobsfilter.py b/src/aapi/jobsfilter.py index db2d6f2..41a37df 100644 --- a/src/aapi/jobsfilter.py +++ b/src/aapi/jobsfilter.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/jobtag.py b/src/aapi/jobtag.py index 1f1fddf..1c9154d 100644 --- a/src/aapi/jobtag.py +++ b/src/aapi/jobtag.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/mail.py b/src/aapi/mail.py index e3047eb..b963c29 100644 --- a/src/aapi/mail.py +++ b/src/aapi/mail.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/notify.py b/src/aapi/notify.py index 8678643..36903e1 100644 --- a/src/aapi/notify.py +++ b/src/aapi/notify.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/on.py b/src/aapi/on.py index 31049dd..4ff3ff1 100644 --- a/src/aapi/on.py +++ b/src/aapi/on.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/output.py b/src/aapi/output.py index c7141ac..c31f202 100644 --- a/src/aapi/output.py +++ b/src/aapi/output.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/package.py b/src/aapi/package.py index 24c066d..18a026c 100644 --- a/src/aapi/package.py +++ b/src/aapi/package.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/packageparams.py b/src/aapi/packageparams.py index b3508fc..4be2aef 100644 --- a/src/aapi/packageparams.py +++ b/src/aapi/packageparams.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/period.py b/src/aapi/period.py index 54edacf..5ca6a43 100644 --- a/src/aapi/period.py +++ b/src/aapi/period.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.year import Year @attrs.define diff --git a/src/aapi/possibleoptions.py b/src/aapi/possibleoptions.py index 40aee61..7daff04 100644 --- a/src/aapi/possibleoptions.py +++ b/src/aapi/possibleoptions.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/propertycondition.py b/src/aapi/propertycondition.py index ad5a09e..884137f 100644 --- a/src/aapi/propertycondition.py +++ b/src/aapi/propertycondition.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/rbcdetails.py b/src/aapi/rbcdetails.py index b966e70..87711be 100644 --- a/src/aapi/rbcdetails.py +++ b/src/aapi/rbcdetails.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/remedy.py b/src/aapi/remedy.py index ff24e51..dac0a8c 100644 --- a/src/aapi/remedy.py +++ b/src/aapi/remedy.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/resource.py b/src/aapi/resource.py index 117eff9..1b8c524 100644 --- a/src/aapi/resource.py +++ b/src/aapi/resource.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/resourcepools.py b/src/aapi/resourcepools.py index 8e677ee..24361d8 100644 --- a/src/aapi/resourcepools.py +++ b/src/aapi/resourcepools.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/run.py b/src/aapi/run.py index be20725..6506260 100644 --- a/src/aapi/run.py +++ b/src/aapi/run.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/runningjobs.py b/src/aapi/runningjobs.py index 0d99b23..092e9bc 100644 --- a/src/aapi/runningjobs.py +++ b/src/aapi/runningjobs.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/set_.py b/src/aapi/set_.py index bf80689..65a4135 100644 --- a/src/aapi/set_.py +++ b/src/aapi/set_.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/sitestandard.py b/src/aapi/sitestandard.py index 10c2d39..e6954e9 100644 --- a/src/aapi/sitestandard.py +++ b/src/aapi/sitestandard.py @@ -3,8 +3,10 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.businessparameter import BusinessParameter +from aapi.internalrule import InternalRule @attrs.define class SiteStandard(AAPIObject): diff --git a/src/aapi/sitestandarddata.py b/src/aapi/sitestandarddata.py index d7565c7..fc2bcfa 100644 --- a/src/aapi/sitestandarddata.py +++ b/src/aapi/sitestandarddata.py @@ -3,8 +3,8 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define class SiteStandardData(AAPIObject): diff --git a/src/aapi/sitestandardoperatorvalueoptions.py b/src/aapi/sitestandardoperatorvalueoptions.py index fc650dd..72e50a9 100644 --- a/src/aapi/sitestandardoperatorvalueoptions.py +++ b/src/aapi/sitestandardoperatorvalueoptions.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/sitestandardpolicy.py b/src/aapi/sitestandardpolicy.py index 4b782b4..4720852 100644 --- a/src/aapi/sitestandardpolicy.py +++ b/src/aapi/sitestandardpolicy.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.businessfield import BusinessField @attrs.define diff --git a/src/aapi/sitestandardpolicydata.py b/src/aapi/sitestandardpolicydata.py index 67ebf3e..eb6ecfc 100644 --- a/src/aapi/sitestandardpolicydata.py +++ b/src/aapi/sitestandardpolicydata.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/sitestandardpossiblevalue.py b/src/aapi/sitestandardpossiblevalue.py index c50d581..4edbe29 100644 --- a/src/aapi/sitestandardpossiblevalue.py +++ b/src/aapi/sitestandardpossiblevalue.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/sitestandardrestriction.py b/src/aapi/sitestandardrestriction.py index 34fc77b..f84c3e9 100644 --- a/src/aapi/sitestandardrestriction.py +++ b/src/aapi/sitestandardrestriction.py @@ -3,7 +3,9 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject +from aapi.sitestandardoperatorvalueoptions import SiteStandardOperatorValueOptions @attrs.define diff --git a/src/aapi/steprange.py b/src/aapi/steprange.py index 7fab272..e07bec5 100644 --- a/src/aapi/steprange.py +++ b/src/aapi/steprange.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/tag.py b/src/aapi/tag.py index 5d6d3b2..aa51738 100644 --- a/src/aapi/tag.py +++ b/src/aapi/tag.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/time.py b/src/aapi/time.py index 76bebf9..d751a31 100644 --- a/src/aapi/time.py +++ b/src/aapi/time.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/variable.py b/src/aapi/variable.py index 38c95a7..9e8182e 100644 --- a/src/aapi/variable.py +++ b/src/aapi/variable.py @@ -3,7 +3,8 @@ import attrs import typing import enum -from aapi import * + +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/waitforevents.py b/src/aapi/waitforevents.py index b498240..acc2f45 100644 --- a/src/aapi/waitforevents.py +++ b/src/aapi/waitforevents.py @@ -5,7 +5,8 @@ import enum import random import string -from aapi import * +from aapi.bases import AAPIObject +from aapi.event import EventIn @attrs.define diff --git a/src/aapi/workloadflat.py b/src/aapi/workloadflat.py index 9365b2b..9aeceb4 100644 --- a/src/aapi/workloadflat.py +++ b/src/aapi/workloadflat.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/workloadpolicy.py b/src/aapi/workloadpolicy.py index 40a6b95..5b6611f 100644 --- a/src/aapi/workloadpolicy.py +++ b/src/aapi/workloadpolicy.py @@ -3,7 +3,10 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject +from aapi.hostmapping import HostMapping +from aapi.resourcepools import ResourcePools +from aapi.runningjobs import RunningJobs @attrs.define diff --git a/src/aapi/wpperiod.py b/src/aapi/wpperiod.py index 3f8e775..9e60fa5 100644 --- a/src/aapi/wpperiod.py +++ b/src/aapi/wpperiod.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/aapi/year.py b/src/aapi/year.py index 3332934..c5ab453 100644 --- a/src/aapi/year.py +++ b/src/aapi/year.py @@ -3,7 +3,7 @@ import attrs import typing import enum -from aapi import * +from aapi.bases import AAPIObject @attrs.define diff --git a/src/ctm_python_client/core/workflow.py b/src/ctm_python_client/core/workflow.py index 67a1768..de6c5f7 100644 --- a/src/ctm_python_client/core/workflow.py +++ b/src/ctm_python_client/core/workflow.py @@ -1,17 +1,34 @@ import abc -import typing -import attrs +import ast +import collections +import copy import json import pathlib import random import tempfile -import collections -import copy +import typing +import attrs -from aapi import * -from ctm_python_client.core.comm import AAPIClientResponse, AbstractAAPIClient, Environment, EnvironmentMode, OnPremAAPIClient, SaasAAPIClient, sanitize_output -from ctm_python_client.core.monitoring import RunMonitor +from ctm_python_client.core.comm import ( + AAPIClientResponse, + AbstractAAPIClient, + Environment, + EnvironmentMode, + OnPremAAPIClient, + SaasAAPIClient, + sanitize_output, +) +from ctm_python_client.core.monitoring import RunMonitor +from aapi.addevents import AddEvents +from aapi.basefolder import Folder, SimpleFolder +from aapi.bases import AAPIJob, AAPIObject +from aapi.connectionprofile import ConnectionProfile +from aapi.deleteevents import DeleteEvents +from aapi.event import EventIn, EventOutAdd, EventOutDelete +from aapi.folderjobbase import SubFolder +from aapi.job import Job +from aapi.waitforevents import WaitForEvents __all__ = ['AbstractWorkflow', 'WorkflowDefaults', 'BaseWorkflow', 'Workflow'] From e21005b21d8485fbe95928ac81edbbad9022d1d4 Mon Sep 17 00:00:00 2001 From: shacharl Date: Mon, 19 May 2025 19:49:42 +0300 Subject: [PATCH 2/6] feat: add useArrayFormat support to get_deployed_folders_new_with_http_info --- src/clients/ctm_api_client/api/deploy_api.py | 6 ++++-- src/clients/ctm_saas_client/api/deploy_api.py | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/clients/ctm_api_client/api/deploy_api.py b/src/clients/ctm_api_client/api/deploy_api.py index ba6c4ad..eee9ef3 100644 --- a/src/clients/ctm_api_client/api/deploy_api.py +++ b/src/clients/ctm_api_client/api/deploy_api.py @@ -1660,7 +1660,7 @@ def get_deployed_folders_new_with_http_info(self, **kwargs): # noqa: E501 returns the request thread. """ - all_params = ["format", "folder", "ctm", "server"] # noqa: E501 + all_params = ["format", "folder", "ctm", "server", "useArrayFormat"] # noqa: E501 all_params.append("async_req") all_params.append("_return_http_data_only") all_params.append("_preload_content") @@ -1689,7 +1689,9 @@ def get_deployed_folders_new_with_http_info(self, **kwargs): # noqa: E501 query_params.append(("ctm", params["ctm"])) # noqa: E501 if "server" in params: query_params.append(("server", params["server"])) # noqa: E501 - + if "useArrayFormat" in params: + query_params.append(("useArrayFormat", params["useArrayFormat"])) # noqa: E501 + header_params = {} form_params = [] diff --git a/src/clients/ctm_saas_client/api/deploy_api.py b/src/clients/ctm_saas_client/api/deploy_api.py index 3037a42..6c79f64 100644 --- a/src/clients/ctm_saas_client/api/deploy_api.py +++ b/src/clients/ctm_saas_client/api/deploy_api.py @@ -1341,7 +1341,7 @@ def get_deployed_folders_new_with_http_info(self, **kwargs): # noqa: E501 returns the request thread. """ - all_params = ['format', 'folder', 'ctm', 'server'] # noqa: E501 + all_params = ['format', 'folder', 'ctm', 'server', 'useArrayFormat'] # noqa: E501 all_params.append('async_req') all_params.append('_return_http_data_only') all_params.append('_preload_content') @@ -1370,6 +1370,8 @@ def get_deployed_folders_new_with_http_info(self, **kwargs): # noqa: E501 query_params.append(('ctm', params['ctm'])) # noqa: E501 if 'server' in params: query_params.append(('server', params['server'])) # noqa: E501 + if "useArrayFormat" in params: + query_params.append(('useArrayFormat', params['useArrayFormat'])) # noqa: E501 header_params = {} From 73b52b0a1469ace4b60019f8a4338977a066f775 Mon Sep 17 00:00:00 2001 From: shacharl Date: Mon, 19 May 2025 20:50:28 +0300 Subject: [PATCH 3/6] feat: add dynamic deserialization mechanism using cattrs for @attrs-based AAPI models - Automatically discovers all @attrs classes in the aapi module - Registers structure hooks per class to enable nested and dynamic deserialization - Builds and uses a shared JOB_TYPE_MAP for resolving job subclasses from _type - Introduces a shared Converter instance for consistent usage --- src/aapi/__init__.py | 11 ++- src/aapi/utils/converter/__init__.py | 26 +++++++ src/aapi/utils/converter/discovery.py | 67 +++++++++++++++++ src/aapi/utils/converter/job_type_registry.py | 64 ++++++++++++++++ src/aapi/utils/converter/registry.py | 73 +++++++++++++++++++ src/aapi/utils/converter/shared_converter.py | 5 ++ 6 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 src/aapi/utils/converter/__init__.py create mode 100644 src/aapi/utils/converter/discovery.py create mode 100644 src/aapi/utils/converter/job_type_registry.py create mode 100644 src/aapi/utils/converter/registry.py create mode 100644 src/aapi/utils/converter/shared_converter.py diff --git a/src/aapi/__init__.py b/src/aapi/__init__.py index e7d88c5..b0bb088 100644 --- a/src/aapi/__init__.py +++ b/src/aapi/__init__.py @@ -76,4 +76,13 @@ from aapi.integration_factory.jobs import * -from aapi.integration_factory.connection_profiles import * \ No newline at end of file +from aapi.integration_factory.connection_profiles import * + +# Initialize and configure the shared Converter instance for the entire project. +# This will ensure that custom deserialization (structure hooks) is available globally. +# from aapi.utils.converter import converter + +from aapi.utils.converter import initialize_converter + +# Initialize the global converter hooks +initialize_converter() \ No newline at end of file diff --git a/src/aapi/utils/converter/__init__.py b/src/aapi/utils/converter/__init__.py new file mode 100644 index 0000000..06692a2 --- /dev/null +++ b/src/aapi/utils/converter/__init__.py @@ -0,0 +1,26 @@ +from aapi.utils.converter.shared_converter import converter +from aapi.utils.converter.discovery import discover_attrs_classes +from aapi.utils.converter.registry import register_structure_hooks +from aapi.utils.converter.job_type_registry import build_job_type_map +import sys + +# Shared job type map initialized after converter setup +JOB_TYPE_MAP = None + +def initialize_converter(): + """ + Initializes the shared converter by: + 1. Discovering all @attrs classes in the aapi module. + 2. Registering structure hooks for each class. + 3. Building a job type mapping for runtime type resolution. + """ + global JOB_TYPE_MAP + + # Discover all classes decorated with @attr.s within the aapi module + all_attrs_classes = discover_attrs_classes(sys.modules["aapi"]) + + # Register structure hooks for each discovered @attrs class + register_structure_hooks(converter, all_attrs_classes) + + # Build the mapping from _type to Job subclass for dynamic resolution + JOB_TYPE_MAP = build_job_type_map() \ No newline at end of file diff --git a/src/aapi/utils/converter/discovery.py b/src/aapi/utils/converter/discovery.py new file mode 100644 index 0000000..31e4e48 --- /dev/null +++ b/src/aapi/utils/converter/discovery.py @@ -0,0 +1,67 @@ +import importlib +import inspect +import pkgutil +import sys +from types import ModuleType +import attrs + +def is_attrs_class(cls): + """ + Check if a class is an `@attrs` class defined in the 'aapi' package. + """ + return ( + inspect.isclass(cls) # Is it a class? + and attrs.has(cls) # Is it an `@attrs` class? + and cls.__module__.startswith("aapi") # Belongs to the 'aapi' package? + ) + +def import_all_submodules(package: ModuleType): + """ + Dynamically import all submodules in the given package. + This ensures all classes (even deeply nested) are loaded into sys.modules. + """ + for _, module_name, _ in pkgutil.walk_packages(package.__path__, package.__name__ + "."): + try: + importlib.import_module(module_name) + except Exception: + pass # Skip modules that fail to import (optional: log if needed) + +def collect_attrs_classes(cls, seen): + """ + Recursively collect all nested `@attrs` classes starting from a given class. + Args: + cls: A class to inspect. + seen: A set to store already-discovered classes and avoid duplicates. + This walks inside inner classes (e.g., Job.RerunLimit) to register everything. + """ + if cls in seen or not is_attrs_class(cls): + return + seen.add(cls) + + # Inspect all members of the class — looking for nested `@attrs` classes + for name, member in inspect.getmembers(cls): + if inspect.isclass(member) and attrs.has(member): + collect_attrs_classes(member, seen) + +def discover_attrs_classes(package: ModuleType): + """ + Discover all `@attrs` classes (including nested ones) in a package. + Args: + package: The root module (e.g., `import aapi; discover_attrs_classes(aapi)`) + Returns: + A list of all discovered `@attrs` classes. + """ + import_all_submodules(package) # Make sure all submodules are imported + seen = set() # Use a set to avoid duplicates + + for module in list(sys.modules.values()): + if not isinstance(module, ModuleType): + continue + if not getattr(module, "__name__", "").startswith("aapi"): + continue + + # For every class in this module, collect it and its nested @attrs classes + for _, obj in inspect.getmembers(module, inspect.isclass): + collect_attrs_classes(obj, seen) + + return list(seen) \ No newline at end of file diff --git a/src/aapi/utils/converter/job_type_registry.py b/src/aapi/utils/converter/job_type_registry.py new file mode 100644 index 0000000..6555391 --- /dev/null +++ b/src/aapi/utils/converter/job_type_registry.py @@ -0,0 +1,64 @@ +import inspect +import sys +from aapi import Job + +def build_job_type_map(): + import types + + def extract_type_from_field(cls): + """ + Try to extract the default value of the '_type' field from the attrs definition, + without needing to instantiate the class. + """ + import attr + for field in attr.fields(cls): + if field.name == "_type": + return field.default + return None + + job_map = {} + + for module in list(sys.modules.values()): + if not isinstance(module, types.ModuleType): + continue + if not getattr(module, "__name__", "").startswith("aapi"): + continue + + for name, cls in inspect.getmembers(module, inspect.isclass): + if not issubclass(cls, Job) or cls is Job: + continue + + # --- NEW: Try static extraction via attr field default --- + job_type_field = extract_type_from_field(cls) + if isinstance(job_type_field, str): + job_map[job_type_field] = cls + continue # Don't fall back to instantiation if already resolved + + # --- OLD fallback: Try to instantiate --- + try: + instance = cls(object_name="dummy") + job_type = getattr(instance, "_type", None) + + if isinstance(job_type, str): + job_map[job_type] = cls + else: + pass + except Exception as e: + pass + + return job_map + + + +def resolve_type(obj: dict, type_map: dict, label: str = "type"): + """ + Resolves the appropriate subclass using the provided type hint ("Type" or "_type") + from the input dictionary. Raises if no match is found in the type_map. + """ + type_hint = obj.get("Type") or obj.get("_type") + + cls = type_map.get(type_hint) + if cls is None: + raise ValueError(f"Unknown {label}: {type_hint}") + + return cls \ No newline at end of file diff --git a/src/aapi/utils/converter/registry.py b/src/aapi/utils/converter/registry.py new file mode 100644 index 0000000..3519d03 --- /dev/null +++ b/src/aapi/utils/converter/registry.py @@ -0,0 +1,73 @@ +import attr +from cattrs import Converter +from aapi.utils.converter.job_type_registry import resolve_type + +def make_structure_hook(cls, converter: Converter): + """ + Generates a structure hook for the given @attrs class. + This hook transforms raw JSON-like dicts into properly typed instances, + supporting dynamic type resolution for nested fields. + """ + def hook(data, _): + from aapi.utils.converter import JOB_TYPE_MAP + + # Create field mapping from JSON keys to attribute names + field_map = { + f.metadata.get("_aapi_repr_", f.name): f.name + for f in attr.fields(cls) + } + + init_fields = {f.name for f in attr.fields(cls) if f.init} + type_map_ = {f.name: f.type for f in attr.fields(cls)} + + kwargs = {} + + # Iterate over the input data, mapping it to constructor kwargs + for json_key, field_name in field_map.items(): + if json_key not in data or field_name not in init_fields: + continue + + value = data[json_key] + field_type = type_map_.get(field_name) + + try: + # Handle nested object (dict) deserialization + if isinstance(value, dict) and attr.has(field_type): + try: + resolved_cls = resolve_type(value, JOB_TYPE_MAP, label="Type") + except Exception: + resolved_cls = field_type + kwargs[field_name] = converter.structure(value, resolved_cls) + + # Handle lists of nested objects + elif isinstance(value, list) and hasattr(field_type, '__args__'): + item_type = field_type.__args__[0] + if attr.has(item_type): + structured_list = [] + for item in value: + try: + resolved_cls = resolve_type(item, JOB_TYPE_MAP, label="Type") + except Exception: + resolved_cls = item_type + structured_list.append(converter.structure(item, resolved_cls)) + kwargs[field_name] = structured_list + else: + kwargs[field_name] = value # fallback for plain lists + + else: + kwargs[field_name] = value # assign simple fields as-is + + except Exception: + kwargs[field_name] = value # fallback on failure to deserialize + + return cls(**kwargs) + + return hook + +def register_structure_hooks(converter: Converter, classes: list): + """ + Registers structure hooks for a list of @attrs classes with the given converter. + These hooks allow for dynamic construction of instances from raw dict data. + """ + for cls in classes: + converter.register_structure_hook(cls, make_structure_hook(cls, converter)) \ No newline at end of file diff --git a/src/aapi/utils/converter/shared_converter.py b/src/aapi/utils/converter/shared_converter.py new file mode 100644 index 0000000..805bc9b --- /dev/null +++ b/src/aapi/utils/converter/shared_converter.py @@ -0,0 +1,5 @@ +from cattrs import Converter + +# Shared instance of the cattrs converter +# Used across the application for structuring and unstructuring data +converter = Converter() \ No newline at end of file From 0098ca0ddf795dbd7bef65e00218fd2554d6ddbe Mon Sep 17 00:00:00 2001 From: shacharl Date: Tue, 20 May 2025 15:13:31 +0300 Subject: [PATCH 4/6] feat: add get_jobs method to wrap AAPI deploy jobs::get into Workflow --- src/aapi/basefolder.py | 2 +- src/aapi/utils/converter/registry.py | 2 +- src/ctm_python_client/core/workflow.py | 50 ++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/aapi/basefolder.py b/src/aapi/basefolder.py index 71af80a..0484167 100644 --- a/src/aapi/basefolder.py +++ b/src/aapi/basefolder.py @@ -43,7 +43,7 @@ class OrderMethod(enum.Enum): business_fields: typing.List[typing.Dict[str,str]] = attrs.field( kw_only=True, metadata={'_aapi_repr_': 'BusinessFields'}, factory=list) job_list: typing.List[Job] = attrs.field(kw_only=True, factory=list, metadata={ - '_abstract_aapi_container_': True}) + '_abstract_aapi_container_': True, '_aapi_alias_': 'Jobs'}) flow_list: typing.List[Flow] = attrs.field(kw_only=True, factory=list, metadata={ '_abstract_aapi_container_': True}) folder_client_data_list: typing.List[FolderClientData] = attrs.field( diff --git a/src/aapi/utils/converter/registry.py b/src/aapi/utils/converter/registry.py index 3519d03..03d539d 100644 --- a/src/aapi/utils/converter/registry.py +++ b/src/aapi/utils/converter/registry.py @@ -13,7 +13,7 @@ def hook(data, _): # Create field mapping from JSON keys to attribute names field_map = { - f.metadata.get("_aapi_repr_", f.name): f.name + f.metadata.get("_aapi_repr_", f.metadata.get("_aapi_alias_", f.name)): f.name for f in attr.fields(cls) } diff --git a/src/ctm_python_client/core/workflow.py b/src/ctm_python_client/core/workflow.py index de6c5f7..924f7d4 100644 --- a/src/ctm_python_client/core/workflow.py +++ b/src/ctm_python_client/core/workflow.py @@ -29,6 +29,8 @@ from aapi.folderjobbase import SubFolder from aapi.job import Job from aapi.waitforevents import WaitForEvents +from aapi.utils.converter.shared_converter import converter + __all__ = ['AbstractWorkflow', 'WorkflowDefaults', 'BaseWorkflow', 'Workflow'] @@ -467,3 +469,51 @@ def run_on_demand(self, skip_login: bool = False, file_path: str = None, delete_ finally: if delete_afterwards: fpath.unlink() + + def get_jobs(environment: Environment, server: str = "*", folder: str = "*") -> "Workflow": + """ + Retrieve a Workflow instance based on deployed folders and jobs matching server and folder patterns. + :param environment: Control-M environment to fetch from + :param server: Control-M server name (supports wildcards) + :param folder: Folder name pattern (supports wildcards) + :return: Populated Workflow instance or None if error occurs + """ + try: + + # Select the appropriate AAPI client + client = ( + SaasAAPIClient(environment.endpoint, environment.credentials) + if environment.mode == EnvironmentMode.SAAS + else OnPremAAPIClient(environment.endpoint, environment.credentials) + ) + + client.authenticate() + + # Query the deployed folders and jobs + raw_response = client.deploy_api.get_deployed_folders_new( + server=server, + folder=folder, + format="json", + useArrayFormat=True + ) + + # Parse the raw response safely into a Python dictionary + folders_data = ast.literal_eval(raw_response) + + # Initialize an empty workflow with default settings + workflow = Workflow(environment, WorkflowDefaults(run_as='default_user')) + + # Convert each folder dict into a Folder instance and add to the workflow + for folder_name, folder_dict in folders_data.items(): + folder_dict.setdefault("object_name", folder_name) + + for job in folder_dict.get("Jobs", []): + job.setdefault("object_name", job.get("Name")) + + folder_instance = converter.structure(folder_dict, Folder) + workflow.add(folder_instance) + + return workflow + + except Exception as error: + raise RuntimeError(f"Failed to retrieve job definitions: {error}") From d82d48684d3b6da6b33d2c67a7f81f67d415901c Mon Sep 17 00:00:00 2001 From: shacharl Date: Wed, 21 May 2025 12:28:34 +0300 Subject: [PATCH 5/6] add init file --- src/aapi/utils/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/aapi/utils/__init__.py diff --git a/src/aapi/utils/__init__.py b/src/aapi/utils/__init__.py new file mode 100644 index 0000000..e69de29 From ad193cce9f59488a0af0ff08e24832e0aad9b8b6 Mon Sep 17 00:00:00 2001 From: shacharl Date: Wed, 21 May 2025 12:33:45 +0300 Subject: [PATCH 6/6] test: add cattrs to test requirements --- requirements_test.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index 2778f3c..d99b797 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -2,4 +2,5 @@ pytest keyring coverage -graphviz \ No newline at end of file +graphviz +cattrs \ No newline at end of file