dcicutils 7.4.2__tar.gz → 7.4.2.1b0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dcicutils might be problematic. Click here for more details.

Files changed (51) hide show
  1. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/PKG-INFO +1 -1
  2. dcicutils-7.4.2.1b0/dcicutils/project_utils.py +257 -0
  3. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/pyproject.toml +1 -1
  4. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/setup.py +1 -1
  5. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/LICENSE.txt +0 -0
  6. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/README.rst +0 -0
  7. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/__init__.py +0 -0
  8. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/base.py +0 -0
  9. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/beanstalk_utils.py +0 -0
  10. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/cloudformation_utils.py +0 -0
  11. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/codebuild_utils.py +0 -0
  12. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/command_utils.py +0 -0
  13. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/common.py +0 -0
  14. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/creds_utils.py +0 -0
  15. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/data_utils.py +0 -0
  16. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/deployment_utils.py +0 -0
  17. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/diff_utils.py +0 -0
  18. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/docker_utils.py +0 -0
  19. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/ecr_scripts.py +0 -0
  20. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/ecr_utils.py +0 -0
  21. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/ecs_utils.py +0 -0
  22. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/env_base.py +0 -0
  23. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/env_manager.py +0 -0
  24. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/env_scripts.py +0 -0
  25. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/env_utils.py +0 -0
  26. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/env_utils_legacy.py +0 -0
  27. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/es_utils.py +0 -0
  28. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/exceptions.py +0 -0
  29. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/ff_mocks.py +0 -0
  30. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/ff_utils.py +0 -0
  31. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/function_cache_decorator.py +0 -0
  32. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/glacier_utils.py +0 -0
  33. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/jh_utils.py +0 -0
  34. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/kibana/dashboards.json +0 -0
  35. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/kibana/readme.md +0 -0
  36. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/lang_utils.py +0 -0
  37. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/log_utils.py +0 -0
  38. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/misc_utils.py +0 -0
  39. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/obfuscation_utils.py +0 -0
  40. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/opensearch_utils.py +0 -0
  41. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/qa_checkers.py +0 -0
  42. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/qa_utils.py +0 -0
  43. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/redis_tools.py +0 -0
  44. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/redis_utils.py +0 -0
  45. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/s3_utils.py +0 -0
  46. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/scripts/publish_to_pypi.py +0 -0
  47. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/secrets_utils.py +0 -0
  48. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/snapshot_utils.py +0 -0
  49. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/ssl_certificate_utils.py +0 -0
  50. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/task_utils.py +0 -0
  51. {dcicutils-7.4.2 → dcicutils-7.4.2.1b0}/dcicutils/trace_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcicutils
3
- Version: 7.4.2
3
+ Version: 7.4.2.1b0
4
4
  Summary: Utility package for interacting with the 4DN Data Portal and other 4DN resources
5
5
  Home-page: https://github.com/4dn-dcic/utils
6
6
  License: MIT
@@ -0,0 +1,257 @@
1
+ import os
2
+ import toml
3
+
4
+ from pkg_resources import resource_filename
5
+ from typing import Optional
6
+ from .env_utils import EnvUtils
7
+ from .misc_utils import classproperty
8
+
9
+
10
+ def project_filename(filename):
11
+ # TODO: In fact we should do this based on the working dir so that when this is imported to another repo,
12
+ # it gets the inserts out of that repo's tests, not our own.
13
+ return resource_filename(Project.PACKAGE_NAME, filename)
14
+
15
+
16
+ class ProjectRegistry:
17
+
18
+ SHOW_HERALD_WHEN_INITIALIZED = True
19
+
20
+ REGISTERED_PROJECTS = {}
21
+
22
+ # All of these might never be other than None so be careful when accessing them.
23
+ APPLICATION_PROJECT_HOME = None
24
+ PYPROJECT_TOML_FILE = None
25
+ PYPROJECT_TOML = None
26
+ POETRY_DATA = None
27
+ # This is expected to ultimately be set properly.
28
+ _PYPROJECT_NAME = None
29
+
30
+ @classproperty
31
+ def PYPROJECT_NAME(cls) -> str: # noQA - PyCharm thinks this should be 'self'
32
+ if cls._PYPROJECT_NAME is None:
33
+ cls.initialize_pyproject_name()
34
+ result: Optional[str] = cls._PYPROJECT_NAME
35
+ if result is None:
36
+ raise ValueError(f"ProjectRegistry.PROJECT_NAME not initialized properly.")
37
+ return result
38
+
39
+ @classmethod
40
+ def initialize_pyproject_name(cls, project_home=None, pyproject_toml_file=None):
41
+ if cls._PYPROJECT_NAME is None:
42
+ # This isn't the home of snovault, but the home of the snovault-based application.
43
+ # So in CGAP, for example, this would want to be the home of the CGAP application.
44
+ # If not set, it will be assumed that the current working directory is that.
45
+ if not project_home:
46
+ project_home = os.environ.get("APPLICATION_PROJECT_HOME", os.path.abspath(os.curdir))
47
+ cls.APPLICATION_PROJECT_HOME = project_home
48
+ if not pyproject_toml_file:
49
+ expected_pyproject_toml_file = os.path.join(project_home, "pyproject.toml")
50
+ pyproject_toml_file = (expected_pyproject_toml_file
51
+ if os.path.exists(expected_pyproject_toml_file)
52
+ else None)
53
+ cls.PYPROJECT_TOML_FILE = pyproject_toml_file
54
+ cls.PYPROJECT_TOML = pyproject_toml = (toml.load(cls.PYPROJECT_TOML_FILE)
55
+ if cls.PYPROJECT_TOML_FILE
56
+ else None)
57
+ cls.POETRY_DATA = (pyproject_toml['tool']['poetry']
58
+ if pyproject_toml
59
+ else None)
60
+
61
+ declared_pyproject_name = os.environ.get("APPLICATION_PYPROJECT_NAME")
62
+ inferred_pyproject_name = cls.POETRY_DATA['name'] if cls.POETRY_DATA else None
63
+ if (declared_pyproject_name and inferred_pyproject_name
64
+ and declared_pyproject_name != inferred_pyproject_name):
65
+ raise RuntimeError(f"APPLICATION_PYPROJECT_NAME={declared_pyproject_name!r},"
66
+ f" but {pyproject_toml_file} says it should be {inferred_pyproject_name!r}")
67
+
68
+ cls._PYPROJECT_NAME = declared_pyproject_name or inferred_pyproject_name
69
+
70
+ @classmethod
71
+ def register(cls, name):
72
+ """
73
+ Registers a class to be used based on the name in the top of pyproject.toml.
74
+ Note that this means that cgap-portal and fourfront will both register as 'encoded',
75
+ as in:
76
+
77
+ @Project.register('encoded')
78
+ class FourfrontProject(EncodedCoreProject):
79
+ PRETTY_NAME = "Fourfront"
80
+
81
+ Since fourfront and cgap-portal don't occupy the same space, no confusion should result.
82
+ """
83
+ def _wrap_class(the_class):
84
+ the_class_name = the_class.__name__
85
+ if not issubclass(the_class, Project):
86
+ raise ValueError(f"The class {the_class_name} must inherit from Project.")
87
+ lower_registry_name = name.lower()
88
+ for x in ['cgap-portal', 'fourfront', 'smaht']:
89
+ if x in lower_registry_name:
90
+ # It's an easy error to make, but the name of the project from which we're gaining foothold
91
+ # in pyproject.toml is 'encoded', not 'cgap-portal', etc., so the name 'encoded' will be
92
+ # needed for bootstrapping. So it should look like
93
+ # -kmp 15-May-2023
94
+ raise ValueError(f"Please use ProjectRegistry.register('encoded'),"
95
+ f" not ProjectRegistry.register({name!r})."
96
+ f" This registration is just for bootstrapping."
97
+ f" The class can still be {the_class_name}.")
98
+ cls.REGISTERED_PROJECTS[name] = the_class
99
+ return the_class
100
+ return _wrap_class
101
+
102
+ @classmethod
103
+ def _lookup(cls, name):
104
+ """
105
+ Returns the project object with the given name.
106
+
107
+ :param name: a string name that was used in a ProjectRegistry.register decorator
108
+
109
+ NOTE: There is no need for this function to be called outside of this class except for testing.
110
+ Really only one of these should be instantiated per running application, and that's
111
+ done automatically by this class.
112
+ """
113
+ project_class = cls.REGISTERED_PROJECTS.get(name)
114
+ return project_class
115
+
116
+ @classmethod
117
+ def _make_project(cls):
118
+ """
119
+ Creates and returns an instantiated project object for the current project.
120
+
121
+ The project to use can be specified by setting the environment variable APPLICATION_PROJECT_HOME
122
+ to a particular directory that contains the pyproject.toml file to use.
123
+ If no such variable is set, the current working directory is used.
124
+
125
+ NOTE: There is no need for this function to be called outside of this class except for testing.
126
+ Really only one of these should be instantiated per running application, and that's
127
+ done automatically by this class.
128
+ """
129
+ project_class = cls._lookup(cls.PYPROJECT_NAME)
130
+ assert issubclass(project_class, Project)
131
+ project: Project = project_class()
132
+ return project # instantiate and return
133
+
134
+ _app_project = None
135
+ _initialized = False
136
+
137
+ @classmethod
138
+ def initialize(cls):
139
+ if cls._initialized:
140
+ raise RuntimeError(f"{cls.__name__}.initialize() was called more than once.")
141
+ cls._app_project = cls._make_project()
142
+ cls._initalized = True
143
+ if cls.SHOW_HERALD_WHEN_INITIALIZED:
144
+ cls.show_herald()
145
+ app_project: Project = cls.app_project
146
+ return app_project # It's initialized now, so we use the proper interface
147
+
148
+ @classmethod
149
+ def show_herald(cls):
150
+ app_project = cls.app_project_maker()
151
+
152
+ print("=" * 80)
153
+ print(f"APPLICATION_PROJECT_HOME == {cls.APPLICATION_PROJECT_HOME!r}")
154
+ print(f"PYPROJECT_TOML_FILE == {cls.PYPROJECT_TOML_FILE!r}")
155
+ print(f"PYPROJECT_NAME == {cls.PYPROJECT_NAME!r}")
156
+ the_app_project = Project.app_project
157
+ the_app_project_class = the_app_project.__class__
158
+ the_app_project_class_name = the_app_project_class.__name__
159
+ assert (Project.app_project
160
+ == app_project()
161
+ == the_app_project_class.app_project
162
+ == the_app_project.app_project), (
163
+ "Project consistency check failed."
164
+ )
165
+ print(f"{the_app_project_class_name}.app_project == Project.app_project == app_project() == {app_project()!r}")
166
+ print(f"app_project().NAME == {app_project().NAME!r}")
167
+ print(f"app_project().PRETTY_NAME == {app_project().PRETTY_NAME!r}")
168
+ print(f"app_project().PACKAGE_NAME == {app_project().PACKAGE_NAME!r}")
169
+ print(f"app_project().APP_NAME == {app_project().APP_NAME!r}")
170
+ print(f"app_project().APP_PRETTY_NAME == {app_project().APP_PRETTY_NAME!r}")
171
+ print("=" * 80)
172
+
173
+ @classproperty
174
+ def app_project(cls): # noQA - PyCharm thinks we should use 'self'
175
+ """
176
+ Once the project is initialized, ProjectRegistry.app_project returns the application object
177
+ that should be used to dispatch project-dependent behavior.
178
+ """
179
+ if cls._app_project is None:
180
+ # You need to put a call to
181
+ raise RuntimeError(f"Attempt to access {cls.__name__}.project before .initialize() called.")
182
+ return cls._app_project
183
+
184
+ @classmethod
185
+ def app_project_maker(cls):
186
+
187
+ def app_project(initialize=False, initialization_options: Optional[dict] = None):
188
+ if initialize:
189
+ Project.initialize_app_project(**(initialization_options or {}))
190
+ return ProjectRegistry.app_project
191
+
192
+ return app_project
193
+
194
+
195
+ class Project:
196
+ """
197
+ A class that should be a superclass of all classes registered using ProjectRegistry.register
198
+
199
+ All such classes have these names:
200
+ .NAME - The name of the project in pyproject.toml
201
+ .PACKAGE_NAME - The pypi name of the project, useful for pkg_resources, for example.
202
+ .PRETTY_NAME - The pretty name of the package name
203
+ .APP_NAME - The ame of the project application (see dcicutils.common and the orchestrated app in EnvUtils)
204
+ .APP_PRETTY_NAME - The pretty name of the project application.
205
+
206
+ Some sample usess of pre-defined attributes of a Project that may help motivate the choice of attribute names:
207
+
208
+ registered |
209
+ name | NAME | PACKAGE_NAME | PRETTY NAME | APP_NAME | APP_PRETTY_NAME
210
+ -------------+--------------+----------------+--------------+-----------+----------------
211
+ snovault | dcicsnovault | snovault | Snovault | snovault | Snovault
212
+ encoded-core | encoded-core | encoded-core | Encoded Core | core | Core
213
+ encoded | cgap-portal | cgap-portal | CGAP Portal | cgap | CGAP
214
+ encoded | fourfront | fourfront | Fourfront | fourfront | Fourfront
215
+ encoded | smaht-portal | smaht-portal | SMaHT Portal | smaht | SMaHT
216
+
217
+ The registered name is the one used with the ProjectRegistry.register() decorator.
218
+ """
219
+
220
+ NAME = 'project'
221
+
222
+ @classmethod
223
+ def _prettify(cls, name):
224
+ return name.title().replace("Cgap", "CGAP").replace("Smaht", "SMaHT").replace("-", " ")
225
+
226
+ @classproperty
227
+ def PACKAGE_NAME(cls): # noQA - PyCharm wants the variable name to be self
228
+ return cls.NAME.replace('dcic', '')
229
+
230
+ @classproperty
231
+ def PRETTY_NAME(cls): # noQA - PyCharm wants the variable name to be self
232
+ return cls._prettify(cls.PACKAGE_NAME)
233
+
234
+ @classproperty
235
+ def APP_NAME(cls): # noQA - PyCharm wants the variable name to be self
236
+ return cls.PACKAGE_NAME.replace('-portal', '').replace('encoded-', '')
237
+
238
+ @classproperty
239
+ def APP_PRETTY_NAME(cls): # noQA - PyCharm wants the variable name to be self
240
+ return cls._prettify(cls.APP_NAME)
241
+
242
+ @classproperty
243
+ def app_project(cls): # noQA - PyCharm wants the variable name to be self
244
+ """
245
+ Project.app_project returns the actual instantiated project for app-specific behavior,
246
+ which might be of this class or one of its subclasses.
247
+
248
+ This access will fail if the project has not been initialized.
249
+ """
250
+ return ProjectRegistry.app_project
251
+
252
+ @classmethod
253
+ def initialize_app_project(cls, initialize_env_utils=True):
254
+ if initialize_env_utils:
255
+ EnvUtils.init()
256
+ project: Project = ProjectRegistry.initialize()
257
+ return project
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "dcicutils"
3
- version = "7.4.2"
3
+ version = "7.4.2.1b0" # to become 7.5.0
4
4
  description = "Utility package for interacting with the 4DN Data Portal and other 4DN resources"
5
5
  authors = ["4DN-DCIC Team <support@4dnucleome.org>"]
6
6
  license = "MIT"
@@ -38,7 +38,7 @@ entry_points = \
38
38
 
39
39
  setup_kwargs = {
40
40
  'name': 'dcicutils',
41
- 'version': '7.4.2',
41
+ 'version': '7.4.2.1b0',
42
42
  'description': 'Utility package for interacting with the 4DN Data Portal and other 4DN resources',
43
43
  'long_description': '=====\nutils\n=====\n\nCheck out our full documentation `here <https://dcic-utils.readthedocs.io/en/latest/>`_\n\nThis repository contains various utility modules shared amongst several projects in the 4DN-DCIC. It is meant to be used internally by the DCIC team and externally as a Python API to `Fourfront <https://data.4dnucleome.org>`_\\ , the 4DN data portal.\n\npip installable as the ``dcicutils`` package with: ``pip install dcicutils``\n\nSee `this document <https://dcic-utils.readthedocs.io/en/latest/getting_started.html>`_ for tips on getting started. `Go here <https://dcic-utils.readthedocs.io/en/latest/examples.html>`_ for examples of some of the most useful functions.\n\n\n.. image:: https://travis-ci.org/4dn-dcic/utils.svg?branch=master\n :target: https://travis-ci.org/4dn-dcic/utils\n :alt: Build Status\n\n\n.. image:: https://coveralls.io/repos/github/4dn-dcic/utils/badge.svg?branch=master\n :target: https://coveralls.io/github/4dn-dcic/utils?branch=master\n :alt: Coverage\n\n.. image:: https://readthedocs.org/projects/dcic-utils/badge/?version=latest\n :target: https://dcic-utils.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n',
44
44
  'author': '4DN-DCIC Team',
File without changes
File without changes