dtlpy 1.115.44__py3-none-any.whl → 1.117.6__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.
- dtlpy/__init__.py +491 -491
- dtlpy/__version__.py +1 -1
- dtlpy/assets/__init__.py +26 -26
- dtlpy/assets/code_server/config.yaml +2 -2
- dtlpy/assets/code_server/installation.sh +24 -24
- dtlpy/assets/code_server/launch.json +13 -13
- dtlpy/assets/code_server/settings.json +2 -2
- dtlpy/assets/main.py +53 -53
- dtlpy/assets/main_partial.py +18 -18
- dtlpy/assets/mock.json +11 -11
- dtlpy/assets/model_adapter.py +83 -83
- dtlpy/assets/package.json +61 -61
- dtlpy/assets/package_catalog.json +29 -29
- dtlpy/assets/package_gitignore +307 -307
- dtlpy/assets/service_runners/__init__.py +33 -33
- dtlpy/assets/service_runners/converter.py +96 -96
- dtlpy/assets/service_runners/multi_method.py +49 -49
- dtlpy/assets/service_runners/multi_method_annotation.py +54 -54
- dtlpy/assets/service_runners/multi_method_dataset.py +55 -55
- dtlpy/assets/service_runners/multi_method_item.py +52 -52
- dtlpy/assets/service_runners/multi_method_json.py +52 -52
- dtlpy/assets/service_runners/single_method.py +37 -37
- dtlpy/assets/service_runners/single_method_annotation.py +43 -43
- dtlpy/assets/service_runners/single_method_dataset.py +43 -43
- dtlpy/assets/service_runners/single_method_item.py +41 -41
- dtlpy/assets/service_runners/single_method_json.py +42 -42
- dtlpy/assets/service_runners/single_method_multi_input.py +45 -45
- dtlpy/assets/voc_annotation_template.xml +23 -23
- dtlpy/caches/base_cache.py +32 -32
- dtlpy/caches/cache.py +473 -473
- dtlpy/caches/dl_cache.py +201 -201
- dtlpy/caches/filesystem_cache.py +89 -89
- dtlpy/caches/redis_cache.py +84 -84
- dtlpy/dlp/__init__.py +20 -20
- dtlpy/dlp/cli_utilities.py +367 -367
- dtlpy/dlp/command_executor.py +764 -764
- dtlpy/dlp/dlp +1 -1
- dtlpy/dlp/dlp.bat +1 -1
- dtlpy/dlp/dlp.py +128 -128
- dtlpy/dlp/parser.py +651 -651
- dtlpy/entities/__init__.py +83 -83
- dtlpy/entities/analytic.py +347 -347
- dtlpy/entities/annotation.py +1879 -1879
- dtlpy/entities/annotation_collection.py +699 -699
- dtlpy/entities/annotation_definitions/__init__.py +20 -20
- dtlpy/entities/annotation_definitions/base_annotation_definition.py +100 -100
- dtlpy/entities/annotation_definitions/box.py +195 -195
- dtlpy/entities/annotation_definitions/classification.py +67 -67
- dtlpy/entities/annotation_definitions/comparison.py +72 -72
- dtlpy/entities/annotation_definitions/cube.py +204 -204
- dtlpy/entities/annotation_definitions/cube_3d.py +149 -149
- dtlpy/entities/annotation_definitions/description.py +32 -32
- dtlpy/entities/annotation_definitions/ellipse.py +124 -124
- dtlpy/entities/annotation_definitions/free_text.py +62 -62
- dtlpy/entities/annotation_definitions/gis.py +69 -69
- dtlpy/entities/annotation_definitions/note.py +139 -139
- dtlpy/entities/annotation_definitions/point.py +117 -117
- dtlpy/entities/annotation_definitions/polygon.py +182 -182
- dtlpy/entities/annotation_definitions/polyline.py +111 -111
- dtlpy/entities/annotation_definitions/pose.py +92 -92
- dtlpy/entities/annotation_definitions/ref_image.py +86 -86
- dtlpy/entities/annotation_definitions/segmentation.py +240 -240
- dtlpy/entities/annotation_definitions/subtitle.py +34 -34
- dtlpy/entities/annotation_definitions/text.py +85 -85
- dtlpy/entities/annotation_definitions/undefined_annotation.py +74 -74
- dtlpy/entities/app.py +220 -220
- dtlpy/entities/app_module.py +107 -107
- dtlpy/entities/artifact.py +174 -174
- dtlpy/entities/assignment.py +399 -399
- dtlpy/entities/base_entity.py +214 -214
- dtlpy/entities/bot.py +113 -113
- dtlpy/entities/codebase.py +292 -292
- dtlpy/entities/collection.py +38 -38
- dtlpy/entities/command.py +169 -169
- dtlpy/entities/compute.py +449 -449
- dtlpy/entities/dataset.py +1299 -1299
- dtlpy/entities/directory_tree.py +44 -44
- dtlpy/entities/dpk.py +470 -470
- dtlpy/entities/driver.py +235 -235
- dtlpy/entities/execution.py +397 -397
- dtlpy/entities/feature.py +124 -124
- dtlpy/entities/feature_set.py +152 -145
- dtlpy/entities/filters.py +798 -798
- dtlpy/entities/gis_item.py +107 -107
- dtlpy/entities/integration.py +184 -184
- dtlpy/entities/item.py +975 -959
- dtlpy/entities/label.py +123 -123
- dtlpy/entities/links.py +85 -85
- dtlpy/entities/message.py +175 -175
- dtlpy/entities/model.py +684 -684
- dtlpy/entities/node.py +1005 -1005
- dtlpy/entities/ontology.py +810 -803
- dtlpy/entities/organization.py +287 -287
- dtlpy/entities/package.py +657 -657
- dtlpy/entities/package_defaults.py +5 -5
- dtlpy/entities/package_function.py +185 -185
- dtlpy/entities/package_module.py +113 -113
- dtlpy/entities/package_slot.py +118 -118
- dtlpy/entities/paged_entities.py +299 -299
- dtlpy/entities/pipeline.py +624 -624
- dtlpy/entities/pipeline_execution.py +279 -279
- dtlpy/entities/project.py +394 -394
- dtlpy/entities/prompt_item.py +505 -505
- dtlpy/entities/recipe.py +301 -301
- dtlpy/entities/reflect_dict.py +102 -102
- dtlpy/entities/resource_execution.py +138 -138
- dtlpy/entities/service.py +974 -963
- dtlpy/entities/service_driver.py +117 -117
- dtlpy/entities/setting.py +294 -294
- dtlpy/entities/task.py +495 -495
- dtlpy/entities/time_series.py +143 -143
- dtlpy/entities/trigger.py +426 -426
- dtlpy/entities/user.py +118 -118
- dtlpy/entities/webhook.py +124 -124
- dtlpy/examples/__init__.py +19 -19
- dtlpy/examples/add_labels.py +135 -135
- dtlpy/examples/add_metadata_to_item.py +21 -21
- dtlpy/examples/annotate_items_using_model.py +65 -65
- dtlpy/examples/annotate_video_using_model_and_tracker.py +75 -75
- dtlpy/examples/annotations_convert_to_voc.py +9 -9
- dtlpy/examples/annotations_convert_to_yolo.py +9 -9
- dtlpy/examples/convert_annotation_types.py +51 -51
- dtlpy/examples/converter.py +143 -143
- dtlpy/examples/copy_annotations.py +22 -22
- dtlpy/examples/copy_folder.py +31 -31
- dtlpy/examples/create_annotations.py +51 -51
- dtlpy/examples/create_video_annotations.py +83 -83
- dtlpy/examples/delete_annotations.py +26 -26
- dtlpy/examples/filters.py +113 -113
- dtlpy/examples/move_item.py +23 -23
- dtlpy/examples/play_video_annotation.py +13 -13
- dtlpy/examples/show_item_and_mask.py +53 -53
- dtlpy/examples/triggers.py +49 -49
- dtlpy/examples/upload_batch_of_items.py +20 -20
- dtlpy/examples/upload_items_and_custom_format_annotations.py +55 -55
- dtlpy/examples/upload_items_with_modalities.py +43 -43
- dtlpy/examples/upload_segmentation_annotations_from_mask_image.py +44 -44
- dtlpy/examples/upload_yolo_format_annotations.py +70 -70
- dtlpy/exceptions.py +125 -125
- dtlpy/miscellaneous/__init__.py +20 -20
- dtlpy/miscellaneous/dict_differ.py +95 -95
- dtlpy/miscellaneous/git_utils.py +217 -217
- dtlpy/miscellaneous/json_utils.py +14 -14
- dtlpy/miscellaneous/list_print.py +105 -105
- dtlpy/miscellaneous/zipping.py +130 -130
- dtlpy/ml/__init__.py +20 -20
- dtlpy/ml/base_feature_extractor_adapter.py +27 -27
- dtlpy/ml/base_model_adapter.py +1287 -1230
- dtlpy/ml/metrics.py +461 -461
- dtlpy/ml/predictions_utils.py +274 -274
- dtlpy/ml/summary_writer.py +57 -57
- dtlpy/ml/train_utils.py +60 -60
- dtlpy/new_instance.py +252 -252
- dtlpy/repositories/__init__.py +56 -56
- dtlpy/repositories/analytics.py +85 -85
- dtlpy/repositories/annotations.py +916 -916
- dtlpy/repositories/apps.py +383 -383
- dtlpy/repositories/artifacts.py +452 -452
- dtlpy/repositories/assignments.py +599 -599
- dtlpy/repositories/bots.py +213 -213
- dtlpy/repositories/codebases.py +559 -559
- dtlpy/repositories/collections.py +332 -332
- dtlpy/repositories/commands.py +152 -152
- dtlpy/repositories/compositions.py +61 -61
- dtlpy/repositories/computes.py +439 -439
- dtlpy/repositories/datasets.py +1585 -1504
- dtlpy/repositories/downloader.py +1157 -923
- dtlpy/repositories/dpks.py +433 -433
- dtlpy/repositories/drivers.py +482 -482
- dtlpy/repositories/executions.py +815 -815
- dtlpy/repositories/feature_sets.py +256 -226
- dtlpy/repositories/features.py +255 -255
- dtlpy/repositories/integrations.py +484 -484
- dtlpy/repositories/items.py +912 -912
- dtlpy/repositories/messages.py +94 -94
- dtlpy/repositories/models.py +1000 -1000
- dtlpy/repositories/nodes.py +80 -80
- dtlpy/repositories/ontologies.py +511 -511
- dtlpy/repositories/organizations.py +525 -525
- dtlpy/repositories/packages.py +1941 -1941
- dtlpy/repositories/pipeline_executions.py +451 -451
- dtlpy/repositories/pipelines.py +640 -640
- dtlpy/repositories/projects.py +539 -539
- dtlpy/repositories/recipes.py +429 -399
- dtlpy/repositories/resource_executions.py +137 -137
- dtlpy/repositories/schema.py +120 -120
- dtlpy/repositories/service_drivers.py +213 -213
- dtlpy/repositories/services.py +1704 -1704
- dtlpy/repositories/settings.py +339 -339
- dtlpy/repositories/tasks.py +1477 -1477
- dtlpy/repositories/times_series.py +278 -278
- dtlpy/repositories/triggers.py +536 -536
- dtlpy/repositories/upload_element.py +257 -257
- dtlpy/repositories/uploader.py +661 -661
- dtlpy/repositories/webhooks.py +249 -249
- dtlpy/services/__init__.py +22 -22
- dtlpy/services/aihttp_retry.py +131 -131
- dtlpy/services/api_client.py +1786 -1785
- dtlpy/services/api_reference.py +40 -40
- dtlpy/services/async_utils.py +133 -133
- dtlpy/services/calls_counter.py +44 -44
- dtlpy/services/check_sdk.py +68 -68
- dtlpy/services/cookie.py +115 -115
- dtlpy/services/create_logger.py +156 -156
- dtlpy/services/events.py +84 -84
- dtlpy/services/logins.py +235 -235
- dtlpy/services/reporter.py +256 -256
- dtlpy/services/service_defaults.py +91 -91
- dtlpy/utilities/__init__.py +20 -20
- dtlpy/utilities/annotations/__init__.py +16 -16
- dtlpy/utilities/annotations/annotation_converters.py +269 -269
- dtlpy/utilities/base_package_runner.py +285 -264
- dtlpy/utilities/converter.py +1650 -1650
- dtlpy/utilities/dataset_generators/__init__.py +1 -1
- dtlpy/utilities/dataset_generators/dataset_generator.py +670 -670
- dtlpy/utilities/dataset_generators/dataset_generator_tensorflow.py +23 -23
- dtlpy/utilities/dataset_generators/dataset_generator_torch.py +21 -21
- dtlpy/utilities/local_development/__init__.py +1 -1
- dtlpy/utilities/local_development/local_session.py +179 -179
- dtlpy/utilities/reports/__init__.py +2 -2
- dtlpy/utilities/reports/figures.py +343 -343
- dtlpy/utilities/reports/report.py +71 -71
- dtlpy/utilities/videos/__init__.py +17 -17
- dtlpy/utilities/videos/video_player.py +598 -598
- dtlpy/utilities/videos/videos.py +470 -470
- {dtlpy-1.115.44.data → dtlpy-1.117.6.data}/scripts/dlp +1 -1
- dtlpy-1.117.6.data/scripts/dlp.bat +2 -0
- {dtlpy-1.115.44.data → dtlpy-1.117.6.data}/scripts/dlp.py +128 -128
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/METADATA +186 -186
- dtlpy-1.117.6.dist-info/RECORD +239 -0
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/WHEEL +1 -1
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/licenses/LICENSE +200 -200
- tests/features/environment.py +551 -551
- dtlpy/assets/__pycache__/__init__.cpython-310.pyc +0 -0
- dtlpy-1.115.44.data/scripts/dlp.bat +0 -2
- dtlpy-1.115.44.dist-info/RECORD +0 -240
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/entry_points.txt +0 -0
- {dtlpy-1.115.44.dist-info → dtlpy-1.117.6.dist-info}/top_level.txt +0 -0
dtlpy/miscellaneous/git_utils.py
CHANGED
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
import subprocess
|
|
2
|
-
import logging
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
logger = logging.getLogger(name='dtlpy')
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class GitUtils:
|
|
9
|
-
"""
|
|
10
|
-
Performs git related methods
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
@staticmethod
|
|
14
|
-
def git_included(path):
|
|
15
|
-
"""
|
|
16
|
-
Get only included git repo files based on .gitignore file
|
|
17
|
-
|
|
18
|
-
:param path: directory - str
|
|
19
|
-
:return: list()
|
|
20
|
-
"""
|
|
21
|
-
included_files = list()
|
|
22
|
-
|
|
23
|
-
try:
|
|
24
|
-
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), 'ls-files'],
|
|
25
|
-
stdout=subprocess.PIPE,
|
|
26
|
-
stderr=subprocess.PIPE)
|
|
27
|
-
output, err = p.communicate()
|
|
28
|
-
string_output = str(output, 'utf-8')
|
|
29
|
-
included_files = string_output.split('\n')
|
|
30
|
-
except Exception:
|
|
31
|
-
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
32
|
-
# include all files
|
|
33
|
-
for r, d, f in os.walk(path):
|
|
34
|
-
for folder in d:
|
|
35
|
-
included_files.append(os.path.join(r, folder))
|
|
36
|
-
|
|
37
|
-
return included_files
|
|
38
|
-
|
|
39
|
-
@staticmethod
|
|
40
|
-
def is_git_repo(path):
|
|
41
|
-
"""
|
|
42
|
-
Check if directory is a git repo
|
|
43
|
-
|
|
44
|
-
:param path: directory - str
|
|
45
|
-
:return: True/False
|
|
46
|
-
"""
|
|
47
|
-
try:
|
|
48
|
-
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), '--work-tree', path, 'status'],
|
|
49
|
-
stdout=subprocess.PIPE,
|
|
50
|
-
stderr=subprocess.PIPE)
|
|
51
|
-
output, err = p.communicate()
|
|
52
|
-
if p.returncode != 0 and 'not a git repository' in str(err):
|
|
53
|
-
response = False
|
|
54
|
-
elif p.returncode == 0 and 'On branch' in str(output):
|
|
55
|
-
response = True
|
|
56
|
-
else:
|
|
57
|
-
response = False
|
|
58
|
-
except Exception:
|
|
59
|
-
response = False
|
|
60
|
-
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
61
|
-
return response
|
|
62
|
-
|
|
63
|
-
@staticmethod
|
|
64
|
-
def git_status(path):
|
|
65
|
-
"""
|
|
66
|
-
Get git repository git status
|
|
67
|
-
|
|
68
|
-
:param path: directory - str
|
|
69
|
-
:return: String
|
|
70
|
-
"""
|
|
71
|
-
status = dict()
|
|
72
|
-
try:
|
|
73
|
-
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), '--work-tree', path, 'status'],
|
|
74
|
-
stdout=subprocess.PIPE,
|
|
75
|
-
stderr=subprocess.PIPE)
|
|
76
|
-
output, err = p.communicate()
|
|
77
|
-
output_lines = str(output, 'utf-8').splitlines()
|
|
78
|
-
branch = output_lines[0].replace('On branch ', '').strip()
|
|
79
|
-
|
|
80
|
-
logs = GitUtils.git_log(path)
|
|
81
|
-
status = {'branch': branch,
|
|
82
|
-
'commit_id': logs[0]['commit'],
|
|
83
|
-
'commit_author': logs[0]['Author'],
|
|
84
|
-
'commit_message': logs[0]['message']}
|
|
85
|
-
except Exception:
|
|
86
|
-
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
87
|
-
|
|
88
|
-
return status
|
|
89
|
-
|
|
90
|
-
@staticmethod
|
|
91
|
-
def git_url(path):
|
|
92
|
-
"""
|
|
93
|
-
Get git remote url
|
|
94
|
-
|
|
95
|
-
:param path: directory - str
|
|
96
|
-
:return: String
|
|
97
|
-
"""
|
|
98
|
-
url = ''
|
|
99
|
-
try:
|
|
100
|
-
p = subprocess.Popen(
|
|
101
|
-
['git', '--git-dir', os.path.join(path, '.git'), 'config', '--get', 'remote.origin.url'],
|
|
102
|
-
stdout=subprocess.PIPE,
|
|
103
|
-
stderr=subprocess.PIPE)
|
|
104
|
-
output, err = p.communicate()
|
|
105
|
-
url = str(output, 'utf-8').splitlines()[0]
|
|
106
|
-
|
|
107
|
-
except Exception:
|
|
108
|
-
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
109
|
-
|
|
110
|
-
return url
|
|
111
|
-
|
|
112
|
-
@staticmethod
|
|
113
|
-
def git_log(path):
|
|
114
|
-
"""
|
|
115
|
-
Get git repository git log
|
|
116
|
-
|
|
117
|
-
:param path: directory - str
|
|
118
|
-
:return: log as list()
|
|
119
|
-
"""
|
|
120
|
-
log = list()
|
|
121
|
-
try:
|
|
122
|
-
log_limit = 100
|
|
123
|
-
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), '--work-tree', path, 'log'],
|
|
124
|
-
stdout=subprocess.PIPE,
|
|
125
|
-
stderr=subprocess.PIPE)
|
|
126
|
-
output, err = p.communicate()
|
|
127
|
-
string_output = str(output, 'utf-8').split('\ncommit')
|
|
128
|
-
for output in string_output:
|
|
129
|
-
output = output.split('\n')
|
|
130
|
-
if output[0].startswith('commit'):
|
|
131
|
-
output[0] = output[0].replace('commit', '')
|
|
132
|
-
log_line = {
|
|
133
|
-
'commit': output[0].strip(),
|
|
134
|
-
'Author': output[1].replace('Author:', '').strip(),
|
|
135
|
-
'Date': output[2].replace('Date:', '').strip(),
|
|
136
|
-
'message': output[4].strip(),
|
|
137
|
-
}
|
|
138
|
-
log.append(log_line)
|
|
139
|
-
log = log[0:log_limit]
|
|
140
|
-
except Exception:
|
|
141
|
-
logging.warning('Error getting git log for git repository in: {}'.format(path))
|
|
142
|
-
|
|
143
|
-
return log
|
|
144
|
-
|
|
145
|
-
@staticmethod
|
|
146
|
-
def git_clone(path, git_url, **kwargs):
|
|
147
|
-
"""
|
|
148
|
-
Clone git repo to local path
|
|
149
|
-
:param path: `str` local path to clone to
|
|
150
|
-
:param git_url: `str` git url to clone from
|
|
151
|
-
:return `bool` for successful clone
|
|
152
|
-
"""
|
|
153
|
-
cmd = ''
|
|
154
|
-
if not os.path.isdir(path):
|
|
155
|
-
os.makedirs(path)
|
|
156
|
-
try:
|
|
157
|
-
username = kwargs.get('username')
|
|
158
|
-
password = kwargs.get('password')
|
|
159
|
-
if username is not None and password is not None:
|
|
160
|
-
if git_url.startswith('https://'):
|
|
161
|
-
git_url = git_url.replace('https://', 'https://{}:{}@'.format(username, password))
|
|
162
|
-
elif git_url.startswith('http://'):
|
|
163
|
-
git_url = git_url.replace('http://', 'http://{}:{}@'.format(username, password))
|
|
164
|
-
else:
|
|
165
|
-
git_url = 'https://{}:{}@{}'.format(username, password, git_url)
|
|
166
|
-
tag = kwargs.get('tag')
|
|
167
|
-
branch = kwargs.get('branch')
|
|
168
|
-
if tag is not None:
|
|
169
|
-
branch_cmd = ['--branch', tag]
|
|
170
|
-
elif branch is not None:
|
|
171
|
-
branch_cmd = ['--branch', branch]
|
|
172
|
-
else:
|
|
173
|
-
branch_cmd = []
|
|
174
|
-
|
|
175
|
-
cmd = ['git', 'clone'] + branch_cmd + [git_url, path]
|
|
176
|
-
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
177
|
-
output, err = [std.decode() for std in p.communicate()]
|
|
178
|
-
exit_code = p.returncode
|
|
179
|
-
response = not exit_code
|
|
180
|
-
if exit_code:
|
|
181
|
-
logging.error('Error executing: {ps1} $ {cmd}\n{err}'.format(ps1=path, cmd=' '.join(cmd), err=err))
|
|
182
|
-
except Exception:
|
|
183
|
-
response = False
|
|
184
|
-
logging.exception('Error cloning git with cmd: {}'.format(cmd))
|
|
185
|
-
return response
|
|
186
|
-
|
|
187
|
-
@staticmethod
|
|
188
|
-
def git_command(path, cmd, show=False):
|
|
189
|
-
"""
|
|
190
|
-
Execute command for a local git repo in path
|
|
191
|
-
:param path: `str` local path for the git repo
|
|
192
|
-
:param cmd: `str` or `list` of `str` specifying the command to run
|
|
193
|
-
:param show: `bool` if True, prints the stdout of the process (default=False)
|
|
194
|
-
:return: `bool` if command was successful or not
|
|
195
|
-
"""
|
|
196
|
-
prev_dir = os.getcwd()
|
|
197
|
-
if isinstance(cmd, str):
|
|
198
|
-
cmd = cmd.split()
|
|
199
|
-
|
|
200
|
-
try:
|
|
201
|
-
os.chdir(path)
|
|
202
|
-
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
203
|
-
output, err = p.communicate()
|
|
204
|
-
output, err = output.decode(), err.decode()
|
|
205
|
-
exit_code = p.returncode
|
|
206
|
-
response = not exit_code
|
|
207
|
-
# Print the process stdout / stderr
|
|
208
|
-
if show:
|
|
209
|
-
print(output)
|
|
210
|
-
if exit_code:
|
|
211
|
-
logging.error('Error executing: {ps1} $ {cmd}\n{err}'.format(ps1=path, cmd=' '.join(cmd), err=err))
|
|
212
|
-
except Exception:
|
|
213
|
-
response = False
|
|
214
|
-
logging.critical('Error executing: {ps1} $ {cmd}'.format(ps1=path, cmd=' '.join(cmd)))
|
|
215
|
-
finally:
|
|
216
|
-
os.chdir(prev_dir)
|
|
217
|
-
return response
|
|
1
|
+
import subprocess
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(name='dtlpy')
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GitUtils:
|
|
9
|
+
"""
|
|
10
|
+
Performs git related methods
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def git_included(path):
|
|
15
|
+
"""
|
|
16
|
+
Get only included git repo files based on .gitignore file
|
|
17
|
+
|
|
18
|
+
:param path: directory - str
|
|
19
|
+
:return: list()
|
|
20
|
+
"""
|
|
21
|
+
included_files = list()
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), 'ls-files'],
|
|
25
|
+
stdout=subprocess.PIPE,
|
|
26
|
+
stderr=subprocess.PIPE)
|
|
27
|
+
output, err = p.communicate()
|
|
28
|
+
string_output = str(output, 'utf-8')
|
|
29
|
+
included_files = string_output.split('\n')
|
|
30
|
+
except Exception:
|
|
31
|
+
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
32
|
+
# include all files
|
|
33
|
+
for r, d, f in os.walk(path):
|
|
34
|
+
for folder in d:
|
|
35
|
+
included_files.append(os.path.join(r, folder))
|
|
36
|
+
|
|
37
|
+
return included_files
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def is_git_repo(path):
|
|
41
|
+
"""
|
|
42
|
+
Check if directory is a git repo
|
|
43
|
+
|
|
44
|
+
:param path: directory - str
|
|
45
|
+
:return: True/False
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), '--work-tree', path, 'status'],
|
|
49
|
+
stdout=subprocess.PIPE,
|
|
50
|
+
stderr=subprocess.PIPE)
|
|
51
|
+
output, err = p.communicate()
|
|
52
|
+
if p.returncode != 0 and 'not a git repository' in str(err):
|
|
53
|
+
response = False
|
|
54
|
+
elif p.returncode == 0 and 'On branch' in str(output):
|
|
55
|
+
response = True
|
|
56
|
+
else:
|
|
57
|
+
response = False
|
|
58
|
+
except Exception:
|
|
59
|
+
response = False
|
|
60
|
+
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
61
|
+
return response
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def git_status(path):
|
|
65
|
+
"""
|
|
66
|
+
Get git repository git status
|
|
67
|
+
|
|
68
|
+
:param path: directory - str
|
|
69
|
+
:return: String
|
|
70
|
+
"""
|
|
71
|
+
status = dict()
|
|
72
|
+
try:
|
|
73
|
+
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), '--work-tree', path, 'status'],
|
|
74
|
+
stdout=subprocess.PIPE,
|
|
75
|
+
stderr=subprocess.PIPE)
|
|
76
|
+
output, err = p.communicate()
|
|
77
|
+
output_lines = str(output, 'utf-8').splitlines()
|
|
78
|
+
branch = output_lines[0].replace('On branch ', '').strip()
|
|
79
|
+
|
|
80
|
+
logs = GitUtils.git_log(path)
|
|
81
|
+
status = {'branch': branch,
|
|
82
|
+
'commit_id': logs[0]['commit'],
|
|
83
|
+
'commit_author': logs[0]['Author'],
|
|
84
|
+
'commit_message': logs[0]['message']}
|
|
85
|
+
except Exception:
|
|
86
|
+
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
87
|
+
|
|
88
|
+
return status
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def git_url(path):
|
|
92
|
+
"""
|
|
93
|
+
Get git remote url
|
|
94
|
+
|
|
95
|
+
:param path: directory - str
|
|
96
|
+
:return: String
|
|
97
|
+
"""
|
|
98
|
+
url = ''
|
|
99
|
+
try:
|
|
100
|
+
p = subprocess.Popen(
|
|
101
|
+
['git', '--git-dir', os.path.join(path, '.git'), 'config', '--get', 'remote.origin.url'],
|
|
102
|
+
stdout=subprocess.PIPE,
|
|
103
|
+
stderr=subprocess.PIPE)
|
|
104
|
+
output, err = p.communicate()
|
|
105
|
+
url = str(output, 'utf-8').splitlines()[0]
|
|
106
|
+
|
|
107
|
+
except Exception:
|
|
108
|
+
logging.warning('Error getting git info for git repository in: {}'.format(path))
|
|
109
|
+
|
|
110
|
+
return url
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def git_log(path):
|
|
114
|
+
"""
|
|
115
|
+
Get git repository git log
|
|
116
|
+
|
|
117
|
+
:param path: directory - str
|
|
118
|
+
:return: log as list()
|
|
119
|
+
"""
|
|
120
|
+
log = list()
|
|
121
|
+
try:
|
|
122
|
+
log_limit = 100
|
|
123
|
+
p = subprocess.Popen(['git', '--git-dir', os.path.join(path, '.git'), '--work-tree', path, 'log'],
|
|
124
|
+
stdout=subprocess.PIPE,
|
|
125
|
+
stderr=subprocess.PIPE)
|
|
126
|
+
output, err = p.communicate()
|
|
127
|
+
string_output = str(output, 'utf-8').split('\ncommit')
|
|
128
|
+
for output in string_output:
|
|
129
|
+
output = output.split('\n')
|
|
130
|
+
if output[0].startswith('commit'):
|
|
131
|
+
output[0] = output[0].replace('commit', '')
|
|
132
|
+
log_line = {
|
|
133
|
+
'commit': output[0].strip(),
|
|
134
|
+
'Author': output[1].replace('Author:', '').strip(),
|
|
135
|
+
'Date': output[2].replace('Date:', '').strip(),
|
|
136
|
+
'message': output[4].strip(),
|
|
137
|
+
}
|
|
138
|
+
log.append(log_line)
|
|
139
|
+
log = log[0:log_limit]
|
|
140
|
+
except Exception:
|
|
141
|
+
logging.warning('Error getting git log for git repository in: {}'.format(path))
|
|
142
|
+
|
|
143
|
+
return log
|
|
144
|
+
|
|
145
|
+
@staticmethod
|
|
146
|
+
def git_clone(path, git_url, **kwargs):
|
|
147
|
+
"""
|
|
148
|
+
Clone git repo to local path
|
|
149
|
+
:param path: `str` local path to clone to
|
|
150
|
+
:param git_url: `str` git url to clone from
|
|
151
|
+
:return `bool` for successful clone
|
|
152
|
+
"""
|
|
153
|
+
cmd = ''
|
|
154
|
+
if not os.path.isdir(path):
|
|
155
|
+
os.makedirs(path)
|
|
156
|
+
try:
|
|
157
|
+
username = kwargs.get('username')
|
|
158
|
+
password = kwargs.get('password')
|
|
159
|
+
if username is not None and password is not None:
|
|
160
|
+
if git_url.startswith('https://'):
|
|
161
|
+
git_url = git_url.replace('https://', 'https://{}:{}@'.format(username, password))
|
|
162
|
+
elif git_url.startswith('http://'):
|
|
163
|
+
git_url = git_url.replace('http://', 'http://{}:{}@'.format(username, password))
|
|
164
|
+
else:
|
|
165
|
+
git_url = 'https://{}:{}@{}'.format(username, password, git_url)
|
|
166
|
+
tag = kwargs.get('tag')
|
|
167
|
+
branch = kwargs.get('branch')
|
|
168
|
+
if tag is not None:
|
|
169
|
+
branch_cmd = ['--branch', tag]
|
|
170
|
+
elif branch is not None:
|
|
171
|
+
branch_cmd = ['--branch', branch]
|
|
172
|
+
else:
|
|
173
|
+
branch_cmd = []
|
|
174
|
+
|
|
175
|
+
cmd = ['git', 'clone'] + branch_cmd + [git_url, path]
|
|
176
|
+
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
177
|
+
output, err = [std.decode() for std in p.communicate()]
|
|
178
|
+
exit_code = p.returncode
|
|
179
|
+
response = not exit_code
|
|
180
|
+
if exit_code:
|
|
181
|
+
logging.error('Error executing: {ps1} $ {cmd}\n{err}'.format(ps1=path, cmd=' '.join(cmd), err=err))
|
|
182
|
+
except Exception:
|
|
183
|
+
response = False
|
|
184
|
+
logging.exception('Error cloning git with cmd: {}'.format(cmd))
|
|
185
|
+
return response
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def git_command(path, cmd, show=False):
|
|
189
|
+
"""
|
|
190
|
+
Execute command for a local git repo in path
|
|
191
|
+
:param path: `str` local path for the git repo
|
|
192
|
+
:param cmd: `str` or `list` of `str` specifying the command to run
|
|
193
|
+
:param show: `bool` if True, prints the stdout of the process (default=False)
|
|
194
|
+
:return: `bool` if command was successful or not
|
|
195
|
+
"""
|
|
196
|
+
prev_dir = os.getcwd()
|
|
197
|
+
if isinstance(cmd, str):
|
|
198
|
+
cmd = cmd.split()
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
os.chdir(path)
|
|
202
|
+
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
203
|
+
output, err = p.communicate()
|
|
204
|
+
output, err = output.decode(), err.decode()
|
|
205
|
+
exit_code = p.returncode
|
|
206
|
+
response = not exit_code
|
|
207
|
+
# Print the process stdout / stderr
|
|
208
|
+
if show:
|
|
209
|
+
print(output)
|
|
210
|
+
if exit_code:
|
|
211
|
+
logging.error('Error executing: {ps1} $ {cmd}\n{err}'.format(ps1=path, cmd=' '.join(cmd), err=err))
|
|
212
|
+
except Exception:
|
|
213
|
+
response = False
|
|
214
|
+
logging.critical('Error executing: {ps1} $ {cmd}'.format(ps1=path, cmd=' '.join(cmd)))
|
|
215
|
+
finally:
|
|
216
|
+
os.chdir(prev_dir)
|
|
217
|
+
return response
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
class JsonUtils:
|
|
2
|
-
@staticmethod
|
|
3
|
-
def get_if_absent(value, default=None):
|
|
4
|
-
if value is None:
|
|
5
|
-
if default is None:
|
|
6
|
-
value_type = type(value)
|
|
7
|
-
if value_type == dict:
|
|
8
|
-
default = {}
|
|
9
|
-
elif value_type == list:
|
|
10
|
-
default = []
|
|
11
|
-
else:
|
|
12
|
-
default = ''
|
|
13
|
-
value = default
|
|
14
|
-
return value
|
|
1
|
+
class JsonUtils:
|
|
2
|
+
@staticmethod
|
|
3
|
+
def get_if_absent(value, default=None):
|
|
4
|
+
if value is None:
|
|
5
|
+
if default is None:
|
|
6
|
+
value_type = type(value)
|
|
7
|
+
if value_type == dict:
|
|
8
|
+
default = {}
|
|
9
|
+
elif value_type == list:
|
|
10
|
+
default = []
|
|
11
|
+
else:
|
|
12
|
+
default = ''
|
|
13
|
+
value = default
|
|
14
|
+
return value
|