algokit-utils 2.4.0b1__py3-none-any.whl → 3.0.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of algokit-utils might be problematic. Click here for more details.
- algokit_utils/__init__.py +23 -181
- algokit_utils/_debugging.py +89 -45
- algokit_utils/_legacy_v2/__init__.py +177 -0
- algokit_utils/{_ensure_funded.py → _legacy_v2/_ensure_funded.py} +19 -18
- algokit_utils/{_transfer.py → _legacy_v2/_transfer.py} +24 -23
- algokit_utils/_legacy_v2/account.py +203 -0
- algokit_utils/_legacy_v2/application_client.py +1471 -0
- algokit_utils/_legacy_v2/application_specification.py +21 -0
- algokit_utils/_legacy_v2/asset.py +168 -0
- algokit_utils/_legacy_v2/common.py +28 -0
- algokit_utils/_legacy_v2/deploy.py +822 -0
- algokit_utils/_legacy_v2/logic_error.py +14 -0
- algokit_utils/{models.py → _legacy_v2/models.py} +16 -45
- algokit_utils/_legacy_v2/network_clients.py +140 -0
- algokit_utils/account.py +12 -183
- algokit_utils/accounts/__init__.py +2 -0
- algokit_utils/accounts/account_manager.py +909 -0
- algokit_utils/accounts/kmd_account_manager.py +159 -0
- algokit_utils/algorand.py +265 -0
- algokit_utils/application_client.py +9 -1447
- algokit_utils/application_specification.py +39 -197
- algokit_utils/applications/__init__.py +7 -0
- algokit_utils/applications/abi.py +276 -0
- algokit_utils/applications/app_client.py +2056 -0
- algokit_utils/applications/app_deployer.py +600 -0
- algokit_utils/applications/app_factory.py +826 -0
- algokit_utils/applications/app_manager.py +470 -0
- algokit_utils/applications/app_spec/__init__.py +2 -0
- algokit_utils/applications/app_spec/arc32.py +207 -0
- algokit_utils/applications/app_spec/arc56.py +1023 -0
- algokit_utils/applications/enums.py +40 -0
- algokit_utils/asset.py +32 -168
- algokit_utils/assets/__init__.py +1 -0
- algokit_utils/assets/asset_manager.py +320 -0
- algokit_utils/beta/_utils.py +36 -0
- algokit_utils/beta/account_manager.py +4 -195
- algokit_utils/beta/algorand_client.py +4 -314
- algokit_utils/beta/client_manager.py +5 -74
- algokit_utils/beta/composer.py +5 -712
- algokit_utils/clients/__init__.py +2 -0
- algokit_utils/clients/client_manager.py +656 -0
- algokit_utils/clients/dispenser_api_client.py +192 -0
- algokit_utils/common.py +8 -26
- algokit_utils/config.py +71 -18
- algokit_utils/deploy.py +7 -894
- algokit_utils/dispenser_api.py +8 -176
- algokit_utils/errors/__init__.py +1 -0
- algokit_utils/errors/logic_error.py +121 -0
- algokit_utils/logic_error.py +7 -82
- algokit_utils/models/__init__.py +8 -0
- algokit_utils/models/account.py +193 -0
- algokit_utils/models/amount.py +198 -0
- algokit_utils/models/application.py +61 -0
- algokit_utils/models/network.py +25 -0
- algokit_utils/models/simulate.py +11 -0
- algokit_utils/models/state.py +59 -0
- algokit_utils/models/transaction.py +100 -0
- algokit_utils/network_clients.py +7 -128
- algokit_utils/protocols/__init__.py +2 -0
- algokit_utils/protocols/account.py +22 -0
- algokit_utils/protocols/typed_clients.py +108 -0
- algokit_utils/transactions/__init__.py +3 -0
- algokit_utils/transactions/transaction_composer.py +2293 -0
- algokit_utils/transactions/transaction_creator.py +156 -0
- algokit_utils/transactions/transaction_sender.py +574 -0
- {algokit_utils-2.4.0b1.dist-info → algokit_utils-3.0.0b2.dist-info}/METADATA +11 -7
- algokit_utils-3.0.0b2.dist-info/RECORD +70 -0
- {algokit_utils-2.4.0b1.dist-info → algokit_utils-3.0.0b2.dist-info}/WHEEL +1 -1
- algokit_utils-2.4.0b1.dist-info/RECORD +0 -24
- {algokit_utils-2.4.0b1.dist-info → algokit_utils-3.0.0b2.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import enum
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
import httpx
|
|
7
|
+
|
|
8
|
+
from algokit_utils.config import config
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"DISPENSER_ACCESS_TOKEN_KEY",
|
|
12
|
+
"DISPENSER_ASSETS",
|
|
13
|
+
"DISPENSER_REQUEST_TIMEOUT",
|
|
14
|
+
"DispenserApiConfig",
|
|
15
|
+
"DispenserAsset",
|
|
16
|
+
"DispenserAssetName",
|
|
17
|
+
"DispenserFundResponse",
|
|
18
|
+
"DispenserLimitResponse",
|
|
19
|
+
"TestNetDispenserApiClient",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = config.logger
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DispenserApiConfig:
|
|
27
|
+
BASE_URL = "https://api.dispenser.algorandfoundation.tools"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DispenserAssetName(enum.IntEnum):
|
|
31
|
+
ALGO = 0
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class DispenserAsset:
|
|
36
|
+
asset_id: int
|
|
37
|
+
decimals: int
|
|
38
|
+
description: str
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class DispenserFundResponse:
|
|
43
|
+
tx_id: str
|
|
44
|
+
amount: int
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class DispenserLimitResponse:
|
|
49
|
+
amount: int
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
DISPENSER_ASSETS = {
|
|
53
|
+
DispenserAssetName.ALGO: DispenserAsset(
|
|
54
|
+
asset_id=0,
|
|
55
|
+
decimals=6,
|
|
56
|
+
description="Algo",
|
|
57
|
+
),
|
|
58
|
+
}
|
|
59
|
+
DISPENSER_REQUEST_TIMEOUT = 15
|
|
60
|
+
DISPENSER_ACCESS_TOKEN_KEY = "ALGOKIT_DISPENSER_ACCESS_TOKEN"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TestNetDispenserApiClient:
|
|
64
|
+
"""
|
|
65
|
+
Client for interacting with the [AlgoKit TestNet Dispenser API](https://github.com/algorandfoundation/algokit/blob/main/docs/testnet_api.md).
|
|
66
|
+
To get started create a new access token via `algokit dispenser login --ci`
|
|
67
|
+
and pass it to the client constructor as `auth_token`.
|
|
68
|
+
Alternatively set the access token as environment variable `ALGOKIT_DISPENSER_ACCESS_TOKEN`,
|
|
69
|
+
and it will be auto loaded. If both are set, the constructor argument takes precedence.
|
|
70
|
+
|
|
71
|
+
Default request timeout is 15 seconds. Modify by passing `request_timeout` to the constructor.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
auth_token: str
|
|
75
|
+
request_timeout = DISPENSER_REQUEST_TIMEOUT
|
|
76
|
+
|
|
77
|
+
def __init__(self, auth_token: str | None = None, request_timeout: int = DISPENSER_REQUEST_TIMEOUT):
|
|
78
|
+
auth_token_from_env = os.getenv(DISPENSER_ACCESS_TOKEN_KEY)
|
|
79
|
+
|
|
80
|
+
if auth_token:
|
|
81
|
+
self.auth_token = auth_token
|
|
82
|
+
elif auth_token_from_env:
|
|
83
|
+
self.auth_token = auth_token_from_env
|
|
84
|
+
else:
|
|
85
|
+
raise Exception(
|
|
86
|
+
f"Can't init AlgoKit TestNet Dispenser API client "
|
|
87
|
+
f"because neither environment variable {DISPENSER_ACCESS_TOKEN_KEY} or "
|
|
88
|
+
"the auth_token were provided."
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
self.request_timeout = request_timeout
|
|
92
|
+
|
|
93
|
+
def _process_dispenser_request(
|
|
94
|
+
self, *, auth_token: str, url_suffix: str, data: dict | None = None, method: str = "POST"
|
|
95
|
+
) -> httpx.Response:
|
|
96
|
+
"""
|
|
97
|
+
Generalized method to process http requests to dispenser API
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
headers = {"Authorization": f"Bearer {(auth_token)}"}
|
|
101
|
+
|
|
102
|
+
# Set request arguments
|
|
103
|
+
request_args = {
|
|
104
|
+
"url": f"{DispenserApiConfig.BASE_URL}/{url_suffix}",
|
|
105
|
+
"headers": headers,
|
|
106
|
+
"timeout": self.request_timeout,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if method.upper() != "GET" and data is not None:
|
|
110
|
+
request_args["json"] = data
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
response: httpx.Response = getattr(httpx, method.lower())(**request_args)
|
|
114
|
+
response.raise_for_status()
|
|
115
|
+
return response
|
|
116
|
+
|
|
117
|
+
except httpx.HTTPStatusError as err:
|
|
118
|
+
error_message = f"Error processing dispenser API request: {err.response.status_code}"
|
|
119
|
+
error_response = None
|
|
120
|
+
with contextlib.suppress(Exception):
|
|
121
|
+
error_response = err.response.json()
|
|
122
|
+
|
|
123
|
+
if error_response and error_response.get("code"):
|
|
124
|
+
error_message = error_response.get("code")
|
|
125
|
+
|
|
126
|
+
elif err.response.status_code == httpx.codes.BAD_REQUEST:
|
|
127
|
+
error_message = err.response.json()["message"]
|
|
128
|
+
|
|
129
|
+
raise Exception(error_message) from err
|
|
130
|
+
|
|
131
|
+
except Exception as err:
|
|
132
|
+
error_message = "Error processing dispenser API request"
|
|
133
|
+
logger.debug(f"{error_message}: {err}", exc_info=True)
|
|
134
|
+
raise err
|
|
135
|
+
|
|
136
|
+
def fund(self, address: str, amount: int, asset_id: int) -> DispenserFundResponse:
|
|
137
|
+
"""
|
|
138
|
+
Fund an account with Algos from the dispenser API
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
response = self._process_dispenser_request(
|
|
143
|
+
auth_token=self.auth_token,
|
|
144
|
+
url_suffix=f"fund/{asset_id}",
|
|
145
|
+
data={"receiver": address, "amount": amount, "assetID": asset_id},
|
|
146
|
+
method="POST",
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
content = response.json()
|
|
150
|
+
return DispenserFundResponse(tx_id=content["txID"], amount=content["amount"])
|
|
151
|
+
|
|
152
|
+
except Exception as err:
|
|
153
|
+
logger.exception(f"Error funding account {address}: {err}")
|
|
154
|
+
raise err
|
|
155
|
+
|
|
156
|
+
def refund(self, refund_txn_id: str) -> None:
|
|
157
|
+
"""
|
|
158
|
+
Register a refund for a transaction with the dispenser API
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
self._process_dispenser_request(
|
|
163
|
+
auth_token=self.auth_token,
|
|
164
|
+
url_suffix="refund",
|
|
165
|
+
data={"refundTransactionID": refund_txn_id},
|
|
166
|
+
method="POST",
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
except Exception as err:
|
|
170
|
+
logger.exception(f"Error issuing refund for txn_id {refund_txn_id}: {err}")
|
|
171
|
+
raise err
|
|
172
|
+
|
|
173
|
+
def get_limit(
|
|
174
|
+
self,
|
|
175
|
+
address: str,
|
|
176
|
+
) -> DispenserLimitResponse:
|
|
177
|
+
"""
|
|
178
|
+
Get current limit for an account with Algos from the dispenser API
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
try:
|
|
182
|
+
response = self._process_dispenser_request(
|
|
183
|
+
auth_token=self.auth_token,
|
|
184
|
+
url_suffix=f"fund/{DISPENSER_ASSETS[DispenserAssetName.ALGO].asset_id}/limit",
|
|
185
|
+
method="GET",
|
|
186
|
+
)
|
|
187
|
+
content = response.json()
|
|
188
|
+
|
|
189
|
+
return DispenserLimitResponse(amount=content["amount"])
|
|
190
|
+
except Exception as err:
|
|
191
|
+
logger.exception(f"Error setting limit for account {address}: {err}")
|
|
192
|
+
raise err
|
algokit_utils/common.py
CHANGED
|
@@ -1,28 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
This module contains common classes and methods that are reused in more than one file.
|
|
3
|
-
"""
|
|
1
|
+
import warnings
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
warnings.warn(
|
|
4
|
+
"The legacy v2 common module is deprecated and will be removed in a future version. "
|
|
5
|
+
"Refer to `CompiledTeal` class from `algokit_utils` instead.",
|
|
6
|
+
DeprecationWarning,
|
|
7
|
+
stacklevel=2,
|
|
8
|
+
)
|
|
7
9
|
|
|
8
|
-
from
|
|
9
|
-
|
|
10
|
-
from algokit_utils import deploy
|
|
11
|
-
|
|
12
|
-
if typing.TYPE_CHECKING:
|
|
13
|
-
from algosdk.v2client.algod import AlgodClient
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Program:
|
|
17
|
-
"""A compiled TEAL program"""
|
|
18
|
-
|
|
19
|
-
def __init__(self, program: str, client: "AlgodClient"):
|
|
20
|
-
"""
|
|
21
|
-
Fully compile the program source to binary and generate a
|
|
22
|
-
source map for matching pc to line number
|
|
23
|
-
"""
|
|
24
|
-
self.teal = program
|
|
25
|
-
result: dict = client.compile(deploy.strip_comments(self.teal), source_map=True)
|
|
26
|
-
self.raw_binary = base64.b64decode(result["result"])
|
|
27
|
-
self.binary_hash: str = result["hash"]
|
|
28
|
-
self.source_map = SourceMap(result["sourcemap"])
|
|
10
|
+
from algokit_utils._legacy_v2.common import * # noqa: F403, E402
|
algokit_utils/config.py
CHANGED
|
@@ -2,14 +2,57 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
logger = logging.getLogger(__name__)
|
|
5
|
+
from typing import Any
|
|
7
6
|
|
|
8
7
|
# Environment variable to override the project root
|
|
9
8
|
ALGOKIT_PROJECT_ROOT = os.getenv("ALGOKIT_PROJECT_ROOT")
|
|
10
9
|
ALGOKIT_CONFIG_FILENAME = ".algokit.toml"
|
|
11
10
|
|
|
12
11
|
|
|
12
|
+
class AlgoKitLogger:
|
|
13
|
+
def __init__(self) -> None:
|
|
14
|
+
self._logger = logging.getLogger("algokit")
|
|
15
|
+
self._setup_logger()
|
|
16
|
+
|
|
17
|
+
def _setup_logger(self) -> None:
|
|
18
|
+
formatter = logging.Formatter("%(levelname)s: %(message)s")
|
|
19
|
+
handler = logging.StreamHandler()
|
|
20
|
+
handler.setFormatter(formatter)
|
|
21
|
+
self._logger.addHandler(handler)
|
|
22
|
+
self._logger.setLevel(logging.INFO)
|
|
23
|
+
|
|
24
|
+
def _get_logger(self, *, suppress_log: bool = False) -> logging.Logger:
|
|
25
|
+
if suppress_log:
|
|
26
|
+
null_logger = logging.getLogger("null")
|
|
27
|
+
null_logger.addHandler(logging.NullHandler())
|
|
28
|
+
return null_logger
|
|
29
|
+
return self._logger
|
|
30
|
+
|
|
31
|
+
def error(self, message: str, *args: Any, suppress_log: bool = False, **kwargs: Any) -> None:
|
|
32
|
+
"""Log an error message, optionally suppressing output"""
|
|
33
|
+
self._get_logger(suppress_log=suppress_log).error(message, *args, **kwargs)
|
|
34
|
+
|
|
35
|
+
def exception(self, message: str, *args: Any, suppress_log: bool = False, **kwargs: Any) -> None:
|
|
36
|
+
"""Log an exception message, optionally suppressing output"""
|
|
37
|
+
self._get_logger(suppress_log=suppress_log).exception(message, *args, **kwargs)
|
|
38
|
+
|
|
39
|
+
def warning(self, message: str, *args: Any, suppress_log: bool = False, **kwargs: Any) -> None:
|
|
40
|
+
"""Log a warning message, optionally suppressing output"""
|
|
41
|
+
self._get_logger(suppress_log=suppress_log).warning(message, *args, **kwargs)
|
|
42
|
+
|
|
43
|
+
def info(self, message: str, *args: Any, suppress_log: bool = False, **kwargs: Any) -> None:
|
|
44
|
+
"""Log an info message, optionally suppressing output"""
|
|
45
|
+
self._get_logger(suppress_log=suppress_log).info(message, *args, **kwargs)
|
|
46
|
+
|
|
47
|
+
def debug(self, message: str, *args: Any, suppress_log: bool = False, **kwargs: Any) -> None:
|
|
48
|
+
"""Log a debug message, optionally suppressing output"""
|
|
49
|
+
self._get_logger(suppress_log=suppress_log).debug(message, *args, **kwargs)
|
|
50
|
+
|
|
51
|
+
def verbose(self, message: str, *args: Any, suppress_log: bool = False, **kwargs: Any) -> None:
|
|
52
|
+
"""Log a verbose message (maps to debug), optionally suppressing output"""
|
|
53
|
+
self._get_logger(suppress_log=suppress_log).debug(message, *args, **kwargs)
|
|
54
|
+
|
|
55
|
+
|
|
13
56
|
class UpdatableConfig:
|
|
14
57
|
"""Class to manage and update configuration settings for the AlgoKit project.
|
|
15
58
|
|
|
@@ -19,26 +62,33 @@ class UpdatableConfig:
|
|
|
19
62
|
trace_all (bool): Indicates whether to trace all operations.
|
|
20
63
|
trace_buffer_size_mb (int): The size of the trace buffer in megabytes.
|
|
21
64
|
max_search_depth (int): The maximum depth to search for a specific file.
|
|
65
|
+
populate_app_call_resources (bool): Indicates whether to populate app call resources.
|
|
22
66
|
"""
|
|
23
67
|
|
|
24
68
|
def __init__(self) -> None:
|
|
69
|
+
self._logger = AlgoKitLogger()
|
|
25
70
|
self._debug: bool = False
|
|
26
71
|
self._project_root: Path | None = None
|
|
27
72
|
self._trace_all: bool = False
|
|
28
73
|
self._trace_buffer_size_mb: int | float = 256 # megabytes
|
|
29
74
|
self._max_search_depth: int = 10
|
|
75
|
+
self._populate_app_call_resources: bool = False
|
|
30
76
|
self._configure_project_root()
|
|
31
77
|
|
|
32
78
|
def _configure_project_root(self) -> None:
|
|
33
79
|
"""Configures the project root by searching for a specific file within a depth limit."""
|
|
34
80
|
current_path = Path(__file__).resolve()
|
|
35
81
|
for _ in range(self._max_search_depth):
|
|
36
|
-
logger.debug(f"Searching in: {current_path}")
|
|
82
|
+
self.logger.debug(f"Searching in: {current_path}")
|
|
37
83
|
if (current_path / ALGOKIT_CONFIG_FILENAME).exists():
|
|
38
84
|
self._project_root = current_path
|
|
39
85
|
break
|
|
40
86
|
current_path = current_path.parent
|
|
41
87
|
|
|
88
|
+
@property
|
|
89
|
+
def logger(self) -> AlgoKitLogger:
|
|
90
|
+
return self._logger
|
|
91
|
+
|
|
42
92
|
@property
|
|
43
93
|
def debug(self) -> bool:
|
|
44
94
|
"""Returns the debug status."""
|
|
@@ -59,6 +109,10 @@ class UpdatableConfig:
|
|
|
59
109
|
"""Returns the size of the trace buffer in megabytes."""
|
|
60
110
|
return self._trace_buffer_size_mb
|
|
61
111
|
|
|
112
|
+
@property
|
|
113
|
+
def populate_app_call_resource(self) -> bool:
|
|
114
|
+
return self._populate_app_call_resources
|
|
115
|
+
|
|
62
116
|
def with_debug(self, func: Callable[[], str | None]) -> None:
|
|
63
117
|
"""Executes a function with debug mode temporarily enabled."""
|
|
64
118
|
original_debug = self._debug
|
|
@@ -68,14 +122,15 @@ class UpdatableConfig:
|
|
|
68
122
|
finally:
|
|
69
123
|
self._debug = original_debug
|
|
70
124
|
|
|
71
|
-
def configure(
|
|
125
|
+
def configure(
|
|
72
126
|
self,
|
|
73
127
|
*,
|
|
74
|
-
debug: bool,
|
|
128
|
+
debug: bool | None = None,
|
|
75
129
|
project_root: Path | None = None,
|
|
76
130
|
trace_all: bool = False,
|
|
77
131
|
trace_buffer_size_mb: float = 256,
|
|
78
132
|
max_search_depth: int = 10,
|
|
133
|
+
populate_app_call_resources: bool = False,
|
|
79
134
|
) -> None:
|
|
80
135
|
"""
|
|
81
136
|
Configures various settings for the application.
|
|
@@ -85,28 +140,26 @@ class UpdatableConfig:
|
|
|
85
140
|
If you are executing the config from an algokit compliant project, you can simply call
|
|
86
141
|
`config.configure(debug=True)`.
|
|
87
142
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
trace_all (bool, optional): Indicates whether to trace all operations. Defaults to False. Which implies that
|
|
143
|
+
:param debug: Indicates whether debug mode is enabled.
|
|
144
|
+
:param project_root: The path to the project root directory. Defaults to None.
|
|
145
|
+
:param trace_all: Indicates whether to trace all operations. Defaults to False. Which implies that
|
|
92
146
|
only the operations that are failed will be traced by default.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
Returns:
|
|
97
|
-
None
|
|
147
|
+
:param trace_buffer_size_mb: The size of the trace buffer in megabytes. Defaults to 256
|
|
148
|
+
:param max_search_depth: The maximum depth to search for a specific file. Defaults to 10
|
|
149
|
+
:param populate_app_call_resources: Indicates whether to populate app call resources. Defaults to False
|
|
98
150
|
"""
|
|
99
151
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if project_root:
|
|
152
|
+
if debug is not None:
|
|
153
|
+
self._debug = debug
|
|
154
|
+
if project_root is not None:
|
|
103
155
|
self._project_root = project_root.resolve(strict=True)
|
|
104
|
-
elif debug and ALGOKIT_PROJECT_ROOT:
|
|
156
|
+
elif debug is not None and ALGOKIT_PROJECT_ROOT:
|
|
105
157
|
self._project_root = Path(ALGOKIT_PROJECT_ROOT).resolve(strict=True)
|
|
106
158
|
|
|
107
159
|
self._trace_all = trace_all
|
|
108
160
|
self._trace_buffer_size_mb = trace_buffer_size_mb
|
|
109
161
|
self._max_search_depth = max_search_depth
|
|
162
|
+
self._populate_app_call_resources = populate_app_call_resources
|
|
110
163
|
|
|
111
164
|
|
|
112
165
|
config = UpdatableConfig()
|