36 Commits

Author SHA1 Message Date
dffa3de1ec Merge pull request '2021.11' (#50) from 2021.11 into master
Reviewed-on: #50
2021-11-30 12:03:03 +01:00
403837901b Added logic to simulate uninstall command 2021-11-30 11:55:11 +01:00
0de725c907 Added logic to simulate install command 2021-11-30 11:51:45 +01:00
e811e08c52 Changed version of cli 2021-11-30 11:22:02 +01:00
6518ae7516 Changed version of query 2021-11-30 11:21:19 +01:00
95b5f99f1f Changed core version 2021-11-30 11:20:15 +01:00
de22e79b71 Removed console from db connection 2021-11-30 11:15:41 +01:00
127c67e566 Improved imports 2021-11-30 11:14:40 +01:00
3523dbd5c5 Improved typing 2021-11-30 11:12:13 +01:00
b526a07e19 Added demo for SQL Support 2021-11-30 11:10:36 +01:00
d9f10edbb7 [WIP] Added native mysql support 2021-11-29 20:55:43 +01:00
7616cd4c69 Changed version 2021-11-29 17:49:10 +01:00
afe75f6848 Fixed custom scripts 2021-11-29 17:47:44 +01:00
c0e2db8281 Build new CLI version 2021-11-29 09:30:46 +01:00
3727af11c4 Minor bugfixes with custom scripts 2021-11-29 09:30:10 +01:00
450295cfcf Build new version 2021-11-29 09:22:33 +01:00
457bce8aa9 Minor bugfixes 2021-11-29 09:21:55 +01:00
0f81497ea3 Changed version 2021-11-24 17:48:39 +01:00
fa7ee800e1 Fixed cpl start reading full path 2021-11-24 17:48:19 +01:00
56b7452e55 Changed version 2021-11-23 19:02:15 +01:00
9d73566453 Fixed custom command handling 2021-11-23 19:01:00 +01:00
28ba0c174a Changed version 2021-11-22 20:54:07 +01:00
5d0444bcc0 Fixed type problems with ordered List 2021-11-22 20:52:10 +01:00
40876005d5 Changed vs code settings 2021-11-22 20:49:39 +01:00
ac6d941822 Improved gitignore 2021-11-19 09:16:11 +01:00
113b365a47 Removed outdating line 2021-11-15 01:16:37 +01:00
2f785536e1 Improved path handling for new projects 2021-11-15 01:03:50 +01:00
9ab4013b4b Fixed async handling for new command 2021-11-15 00:20:39 +01:00
b3b04f03ce Merge pull request '2021.10.2' (#48) from 2021.10.2 into master
Reviewed-on: #48
Closed #47
2021-11-14 12:56:41 +01:00
57040f85f0 Changed versions 2021-11-14 12:53:09 +01:00
589ef4fd4c Added logic to generate new projects with async 2021-11-14 12:32:11 +01:00
4b829cc484 Added logic to handle async applicationBase 2021-11-14 12:16:50 +01:00
98e343a108 Added logic to handle scoped services 2021-11-14 11:56:42 +01:00
7749d5a789 Moved tests to src & added add scoped logic 2021-11-14 10:04:32 +01:00
c3b48bfa41 Changed version 2021-11-14 09:55:27 +01:00
470e7ab2f4 Changed versions to new scheme 2021-11-14 09:52:07 +01:00
188 changed files with 1630 additions and 709 deletions

1
.gitignore vendored
View File

@@ -133,3 +133,4 @@ dmypy.json
# IDE
.idea/
PythonImportHelper-v2-Completion.json

15
.vscode/launch.json vendored
View File

@@ -41,6 +41,10 @@
"cwd": "${workspaceFolder}/src/tests/custom/database/src",
"program": "main.py",
"console": "integratedTerminal",
"env": {
"PYTHON_ENVIRONMENT": "development",
"PYTHONPATH": "${workspaceFolder}/src/:$PYTHONPATH"
}
},
{
"name": "CLI",
@@ -197,7 +201,11 @@
"args": [
"install",
"discord.py",
]
],
"env": {
"GISMO_ENVIRONMENT": "development",
"PYTHONPATH": "${workspaceFolder}/src/:$PYTHONPATH"
}
},
{
"name": "CLI: install local",
@@ -256,7 +264,10 @@
"console": "integratedTerminal",
"args": [
"start",
]
],
"env": {
"PYTHONPATH": "${workspaceFolder}/src/:${workspaceFolder}/src/cpl_cli/"
}
},
{
"name": "CLI: uninstall discord.py",

25
.vscode/settings.json vendored
View File

@@ -1,26 +1,23 @@
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#fbed80",
"activityBar.activeBorder": "#06b9a5",
"activityBar.background": "#fbed80",
"activityBar.activeBackground": "#93e6fc",
"activityBar.activeBorder": "#fa45d4",
"activityBar.background": "#93e6fc",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#06b9a5",
"activityBarBadge.background": "#fa45d4",
"activityBarBadge.foreground": "#15202b",
"editorGroup.border": "#fbed80",
"panel.border": "#fbed80",
"sash.hoverBorder": "#fbed80",
"sideBar.border": "#fbed80",
"statusBar.background": "#f9e64f",
"sash.hoverBorder": "#93e6fc",
"statusBar.background": "#61dafb",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#f7df1e",
"statusBarItem.remoteBackground": "#f9e64f",
"statusBarItem.hoverBackground": "#2fcefa",
"statusBarItem.remoteBackground": "#61dafb",
"statusBarItem.remoteForeground": "#15202b",
"titleBar.activeBackground": "#f9e64f",
"titleBar.activeBackground": "#61dafb",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#f9e64f99",
"titleBar.inactiveBackground": "#61dafb99",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.color": "#f9e64f",
"peacock.color": "#61dafb",
"python.pythonPath": "cpl-env/bin/python3.9",
}

View File

@@ -1,16 +1,16 @@
#!/bin/bash
if [ $1 == "-prod" ]; then
twine upload -r pip.sh-edraft.de ../dist/sh_cpl-cli/publish/setup/*
twine upload -r pip.sh-edraft.de ../dist/sh_cpl-core/publish/setup/*
twine upload -r pip.sh-edraft.de ../dist/sh_cpl-query/publish/setup/*
twine upload -r pip.sh-edraft.de dist/sh_cpl-cli/publish/setup/*
twine upload -r pip.sh-edraft.de dist/sh_cpl-core/publish/setup/*
twine upload -r pip.sh-edraft.de dist/sh_cpl-query/publish/setup/*
elif [ $1 == "-prod" ]; then
twine upload -r pip-exp.sh-edraft.de ../dist/sh_cpl-cli/publish/setup/*
twine upload -r pip-exp.sh-edraft.de ../dist/sh_cpl-core/publish/setup/*
twine upload -r pip-.sh-edraft.de ../dist/sh_cpl-query/publish/setup/*
twine upload -r pip-exp.sh-edraft.de dist/sh_cpl-cli/publish/setup/*
twine upload -r pip-exp.sh-edraft.de dist/sh_cpl-core/publish/setup/*
twine upload -r pip-.sh-edraft.de dist/sh_cpl-query/publish/setup/*
else
twine upload -r pip-dev.sh-edraft.de ../dist/sh_cpl-cli/publish/setup/*
twine upload -r pip-dev.sh-edraft.de ../dist/sh_cpl-core/publish/setup/*
twine upload -r pip-dev.sh-edraft.de ../dist/sh_cpl-query/publish/setup/*
twine upload -r pip-dev.sh-edraft.de dist/sh_cpl-cli/publish/setup/*
twine upload -r pip-dev.sh-edraft.de dist/sh_cpl-core/publish/setup/*
twine upload -r pip-dev.sh-edraft.de dist/sh_cpl-query/publish/setup/*
fi

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -29,4 +29,4 @@ from .main import main
from .startup import Startup
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.build'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.generate'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console.source'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console.source.name'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -5,29 +5,51 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC
class ApplicationTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'application.py'
self._path = path
self._value = textwrap.dedent("""\
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
self._use_async = use_async
if self._use_async:
self._value = textwrap.dedent("""\
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')
""")
async def configure(self):
pass
async def main(self):
Console.write_line('Hello World')
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')
""")
@property
def name(self) -> str:

View File

@@ -6,7 +6,7 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC
class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
@@ -15,22 +15,44 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
import_pkg = f'{name}.'
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
from {import_pkg}startup import Startup
def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent(f"""\
import asyncio
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
from {import_pkg}startup import Startup
async def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app: Application = await app_builder.build_async()
await app.run_async()
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
from {import_pkg}startup import Startup
def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
@@ -47,7 +69,7 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
class MainWithApplicationBaseTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
@@ -56,20 +78,40 @@ class MainWithApplicationBaseTemplate(TemplateFileABC):
import_pkg = f'{name}.'
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent(f"""\
import asyncio
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
async def main():
app_builder = ApplicationBuilder(Application)
app: Application = await app_builder.build_async()
await app.run_async()
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
@@ -86,7 +128,7 @@ class MainWithApplicationBaseTemplate(TemplateFileABC):
class MainWithoutApplicationBaseTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
@@ -95,17 +137,33 @@ class MainWithoutApplicationBaseTemplate(TemplateFileABC):
import_pkg = f'{name}.'
self._value = textwrap.dedent("""\
from cpl_core.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent("""\
import asyncio
from cpl_core.console import Console
async def main():
Console.write_line('Hello World')
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
@@ -122,7 +180,7 @@ class MainWithoutApplicationBaseTemplate(TemplateFileABC):
class MainWithDependencyInjection(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
name = String.convert_to_snake_case(name)
@@ -131,31 +189,61 @@ class MainWithDependencyInjection(TemplateFileABC):
import_pkg = f'{name}.'
self._value = textwrap.dedent("""\
from cpl_core.configuration import Configuration, ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent("""\
import asyncio
from cpl_core.configuration import Configuration, ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC
async def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
async def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
async def main():
config = await configure_configuration()
provider = await configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.configuration import Configuration, ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:

View File

@@ -5,29 +5,51 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC
class StartupTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'startup.py'
self._path = path
self._value = textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
self._use_async = use_async
if self._use_async:
self._value = textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
async def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
async def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
@property
def name(self) -> str:

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console.source.tests'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library.source'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library.source.name'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -5,29 +5,50 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC
class ApplicationTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'application.py'
self._path = path
self._value = textwrap.dedent("""\
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
if use_async:
self._value = textwrap.dedent("""\
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')
""")
async def configure(self):
pass
async def main(self):
Console.write_line('Hello World')
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
def configure(self):
pass
def main(self):
Console.write_line('Hello World')
""")
@property
def name(self) -> str:

View File

@@ -5,7 +5,7 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC
class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'main.py'
@@ -15,22 +15,44 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
if name == '':
import_pkg = ''
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
from {import_pkg}startup import Startup
def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent(f"""\
import asyncio
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
from {import_pkg}startup import Startup
async def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app: Application = await app_builder.build_async()
await app.run_async()
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
from {import_pkg}startup import Startup
def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
@@ -47,7 +69,7 @@ class MainWithApplicationHostAndStartupTemplate(TemplateFileABC):
class MainWithApplicationBaseTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'main.py'
@@ -57,20 +79,40 @@ class MainWithApplicationBaseTemplate(TemplateFileABC):
if name == '':
import_pkg = ''
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent(f"""\
import asyncio
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
async def main():
app_builder = ApplicationBuilder(Application)
app: Application = await app_builder.build_async()
await app.run_async()
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent(f"""\
from cpl_core.application import ApplicationBuilder
from {import_pkg}application import Application
def main():
app_builder = ApplicationBuilder(Application)
app_builder.build().run()
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
@@ -87,23 +129,39 @@ class MainWithApplicationBaseTemplate(TemplateFileABC):
class MainWithoutApplicationBaseTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'main.py'
self._path = path
self._value = textwrap.dedent("""\
from cpl_core.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent("""\
import asyncio
from cpl_core.console import Console
async def main():
Console.write_line('Hello World')
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.console import Console
def main():
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:
@@ -120,37 +178,67 @@ class MainWithoutApplicationBaseTemplate(TemplateFileABC):
class MainWithDependencyInjection(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'main.py'
self._path = path
self._value = textwrap.dedent("""\
from cpl_core.configuration import Configuration, ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
if use_async:
self._value = textwrap.dedent("""\
import asyncio
from cpl_core.configuration import Configuration, ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC
async def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
async def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
async def main():
config = await configure_configuration()
provider = await configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
ml = asyncio.get_event_loop()
ml.run_until_complete(main())
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.configuration import Configuration, ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC
def configure_configuration() -> ConfigurationABC:
config = Configuration()
return config
def configure_services(config: ConfigurationABC) -> ServiceProviderABC:
services = ServiceCollection(config)
return services.build_service_provider()
def main():
config = configure_configuration()
provider = configure_services(config)
Console.write_line('Hello World')
if __name__ == '__main__':
main()
""")
@property
def name(self) -> str:

View File

@@ -5,29 +5,50 @@ from cpl_cli._templates.template_file_abc import TemplateFileABC
class StartupTemplate(TemplateFileABC):
def __init__(self, name: str, path: str):
def __init__(self, name: str, path: str, use_async: bool):
TemplateFileABC.__init__(self)
self._name = 'startup.py'
self._path = path
self._value = textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
if use_async:
self._value = textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
async def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
async def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
else:
self._value = textwrap.dedent("""\
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()
""")
@property
def name(self) -> str:

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library.source.tests'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.publish'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.command'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -28,4 +28,4 @@ from .publish_service import PublishService
from .version_service import VersionService
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -30,10 +30,6 @@ class CustomScriptService(CommandABC):
if script == cmd:
command = self._workspace.scripts[script]
try:
run_command = []
for word in command.split(' '):
run_command.append(word)
subprocess.run(run_command)
subprocess.run(command, shell=True if os.name == 'posix' else None)
except Exception as e:
Console.error(str(e))

View File

@@ -2,20 +2,21 @@ import json
import os
import subprocess
import textwrap
import time
from packaging import version
from cpl_core.configuration.configuration_abc import ConfigurationABC
from cpl_core.console.console import Console
from cpl_core.console.foreground_color_enum import ForegroundColorEnum
from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC
from cpl_core.utils.pip import Pip
from cpl_cli.cli_settings import CLISettings
from cpl_cli.command_abc import CommandABC
from cpl_cli.configuration.build_settings import BuildSettings
from cpl_cli.configuration.project_settings import ProjectSettings
from cpl_cli.configuration.settings_helper import SettingsHelper
from cpl_cli.error import Error
from cpl_core.configuration.configuration_abc import ConfigurationABC
from cpl_core.console.console import Console
from cpl_core.console.foreground_color_enum import ForegroundColorEnum
from cpl_core.environment.application_environment_abc import \
ApplicationEnvironmentABC
from cpl_core.utils.pip import Pip
from packaging import version
class InstallService(CommandABC):
@@ -37,6 +38,9 @@ class InstallService(CommandABC):
self._build_settings = build_settings
self._project_settings = project_settings
self._cli_settings = cli_settings
self._is_simulating = False
self._is_virtual = False
self._project_file = f'{self._config.get_configuration("ProjectName")}.json'
@@ -49,6 +53,9 @@ class InstallService(CommandABC):
Arguments:
package The package to install
""")
def _wait(self, t: int, *args, source: str = None, stdout=None, stderr=None):
time.sleep(t)
def _install_project(self):
"""
@@ -64,11 +71,12 @@ class InstallService(CommandABC):
Error.error(f'Found invalid dependencies in {self._project_file}.')
return
Pip.set_executable(self._project_settings.python_executable)
if not self._is_virtual:
Pip.set_executable(self._project_settings.python_executable)
for dependency in self._project_settings.dependencies:
Console.spinner(
f'Installing: {dependency}',
Pip.install, dependency,
Pip.install if not self._is_virtual else self._wait, dependency if not self._is_virtual else 2,
source=self._cli_settings.pip_path if 'sh_cpl' in dependency else None,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
@@ -76,7 +84,8 @@ class InstallService(CommandABC):
spinner_foreground_color=ForegroundColorEnum.cyan
)
Pip.reset_executable()
if not self._is_virtual:
Pip.reset_executable()
def _install_package(self, package: str):
"""
@@ -85,7 +94,8 @@ class InstallService(CommandABC):
:return:
"""
is_already_in_project = False
Pip.set_executable(self._project_settings.python_executable)
if not self._is_virtual:
Pip.set_executable(self._project_settings.python_executable)
if self._project_settings is None or self._build_settings is None:
Error.error('The command requires to be run in an CPL project, but a project could not be found.')
@@ -129,15 +139,18 @@ class InstallService(CommandABC):
Console.spinner(
f'Installing: {package}',
Pip.install, package,
Pip.install if not self._is_virtual else self._wait, package if not self._is_virtual else 2,
source=self._cli_settings.pip_path if 'sh_cpl' in package else None,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
text_foreground_color=ForegroundColorEnum.green,
spinner_foreground_color=ForegroundColorEnum.cyan
)
new_package = Pip.get_package(name)
Console.write_line(new_package)
if self._is_virtual:
new_package = name
else:
new_package = Pip.get_package(name)
if new_package is None \
or '==' in package and \
version.parse(package.split('==')[1]) != version.parse(new_package.split('==')[1]):
@@ -159,14 +172,15 @@ class InstallService(CommandABC):
self._project_settings.dependencies.append(new_name)
config = {
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._env.working_directory, self._project_file), 'w') as project_file:
project_file.write(json.dumps(config, indent=2))
project_file.close()
if not self._is_simulating:
config = {
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._env.working_directory, self._project_file), 'w') as project_file:
project_file.write(json.dumps(config, indent=2))
project_file.close()
Pip.reset_executable()
@@ -176,6 +190,16 @@ class InstallService(CommandABC):
:param args:
:return:
"""
if '--virtual' in args:
self._is_virtual = True
args.remove('--virtual')
Console.write_line('Running in virtual mode:')
if '--simulate' in args:
self._is_virtual = True
args.remove('--simulate')
Console.write_line('Running in simulation mode:')
if len(args) == 0:
self._install_project()
else:

View File

@@ -46,6 +46,7 @@ class NewService(CommandABC):
self._use_application_api: bool = False
self._use_startup: bool = False
self._use_service_providing: bool = False
self._use_async: bool = False
@property
def help_message(self) -> str:
@@ -97,7 +98,7 @@ class NewService(CommandABC):
ProjectSettingsNameEnum.license_name.value: '',
ProjectSettingsNameEnum.license_description.value: '',
ProjectSettingsNameEnum.dependencies.value: [
f'sh_cpl>={version.parse(cpl_core.__version__)}'
f'sh_cpl-core>={version.parse(cpl_core.__version__)}'
],
ProjectSettingsNameEnum.python_version.value: f'>={sys.version.split(" ")[0]}',
ProjectSettingsNameEnum.python_path.value: {
@@ -177,6 +178,10 @@ class NewService(CommandABC):
result = Console.read('Do you want to use service providing? (y/n) ')
if result.lower() == 'y':
self._use_service_providing = True
result = Console.read('Do you want to use async? (y/n) ')
if result.lower() == 'y':
self._use_async = True
Console.set_foreground_color(ForegroundColorEnum.default)
@@ -202,6 +207,7 @@ class NewService(CommandABC):
self._use_application_api,
self._use_startup,
self._use_service_providing,
self._use_async,
self._project.name,
self._project_json,
self._workspace
@@ -231,6 +237,7 @@ class NewService(CommandABC):
self._use_application_api,
self._use_startup,
self._use_service_providing,
self._use_async,
self._project.name,
self._project_json,
self._workspace

View File

@@ -57,7 +57,8 @@ class RemoveService(CommandABC):
ws_dict = {
WorkspaceSettings.__name__: {
WorkspaceSettingsNameEnum.default_project.value: self._workspace.default_project,
WorkspaceSettingsNameEnum.projects.value: self._workspace.projects
WorkspaceSettingsNameEnum.projects.value: self._workspace.projects,
WorkspaceSettingsNameEnum.scripts.value: self._workspace.scripts
}
}

View File

@@ -2,6 +2,7 @@ import json
import os
import subprocess
import textwrap
import time
from cpl_core.configuration.configuration_abc import ConfigurationABC
from cpl_core.console.console import Console
@@ -31,6 +32,9 @@ class UninstallService(CommandABC):
self._env = env
self._build_settings = build_settings
self._project_settings = project_settings
self._is_simulating = False
self._is_virtual = False
@property
def help_message(self) -> str:
@@ -41,6 +45,9 @@ class UninstallService(CommandABC):
Arguments:
package The package to uninstall
""")
def _wait(self, t: int, *args, source: str = None, stdout=None, stderr=None):
time.sleep(t)
def run(self, args: list[str]):
"""
@@ -52,13 +59,28 @@ class UninstallService(CommandABC):
Console.error(f'Expected package')
Console.error(f'Usage: cpl uninstall <package>')
return
if '--virtual' in args:
self._is_virtual = True
args.remove('--virtual')
Console.write_line('Running in virtual mode:')
if '--simulate' in args:
self._is_virtual = True
args.remove('--simulate')
Console.write_line('Running in simulation mode:')
Pip.set_executable(self._project_settings.python_executable)
if not self._is_virtual:
Pip.set_executable(self._project_settings.python_executable)
package = args[0]
is_in_dependencies = False
pip_package = Pip.get_package(package)
if not self._is_virtual:
pip_package = Pip.get_package(package)
else:
pip_package = package
for dependency in self._project_settings.dependencies:
if package in dependency:
@@ -74,7 +96,7 @@ class UninstallService(CommandABC):
Console.spinner(
f'Uninstalling: {package}',
Pip.uninstall, package,
Pip.uninstall if not self._is_virtual else self._wait, package if not self._is_virtual else 2,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
text_foreground_color=ForegroundColorEnum.green,
@@ -83,13 +105,15 @@ class UninstallService(CommandABC):
if package in self._project_settings.dependencies:
self._project_settings.dependencies.remove(package)
config = {
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._env.working_directory, f'{self._config.get_configuration("ProjectName")}.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2))
project_file.close()
if not self._is_simulating:
config = {
ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings),
BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings)
}
with open(os.path.join(self._env.working_directory, f'{self._config.get_configuration("ProjectName")}.json'), 'w') as project_file:
project_file.write(json.dumps(config, indent=2))
project_file.close()
Console.write_line(f'Removed {package}')
Pip.reset_executable()
if not self._is_virtual:
Pip.reset_executable()

View File

@@ -52,7 +52,11 @@ class VersionService(CommandABC):
]
packages = []
for modname in cpl_packages:
module = pkgutil.find_loader(modname).load_module(modname)
module = pkgutil.find_loader(modname)
if module is None:
break
module = module.load_module(modname)
if '__version__' in dir(module):
packages.append([f'{modname}', module.__version__])

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.configuration'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -30,4 +30,4 @@ from .workspace_settings import WorkspaceSettings
from .workspace_settings_name_enum import WorkspaceSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -3,8 +3,8 @@
"Name": "sh_cpl-cli",
"Version": {
"Major": "2021",
"Minor": "10",
"Micro": "0.post2"
"Minor": "11",
"Micro": "0"
},
"Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de",
@@ -16,7 +16,7 @@
"LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [
"sh_cpl-core>=2021.10.0.post1"
"sh_cpl-core>=2021.10.0"
],
"PythonVersion": ">=3.8",
"PythonPath": {},

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.live_server'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -41,7 +41,7 @@ class LiveServerService(FileSystemEventHandler):
:return:
"""
self._observer = Observer()
self._observer.schedule(self, path=self._src_dir, recursive=True)
self._observer.schedule(self, path=os.path.abspath(os.path.join(self._src_dir, '../')), recursive=True)
self._observer.start()
def _restart(self):

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_cli.publish'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -24,4 +24,4 @@ from .publisher_abc import PublisherABC
from .publisher_service import PublisherService
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_cli.source_creator'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -39,12 +39,12 @@ class ConsoleBuilder:
project_json.close()
@classmethod
def _create_workspace(cls, path: str, project_name, projects: dict):
def _create_workspace(cls, path: str, project_name, projects: dict, scripts: dict):
ws_dict = {
WorkspaceSettings.__name__: {
WorkspaceSettingsNameEnum.default_project.value: project_name,
WorkspaceSettingsNameEnum.projects.value: projects,
WorkspaceSettingsNameEnum.scripts.value: {}
WorkspaceSettingsNameEnum.scripts.value: scripts
}
}
@@ -59,19 +59,24 @@ class ConsoleBuilder:
@classmethod
def build(cls, project_path: str, use_application_api: bool, use_startup: bool, use_service_providing: bool,
project_name: str, project_settings: dict, workspace: Optional[WorkspaceSettings]):
use_async: bool, project_name: str, project_settings: dict, workspace: Optional[WorkspaceSettings]):
"""
Builds the console project files
:param project_path:
:param use_application_api:
:param use_startup:
:param use_service_providing:
:param use_async:
:param project_name:
:param project_settings:
:param workspace:
:return:
"""
project_name_snake = String.convert_to_snake_case(project_name)
pj_name = project_name
if '/' in pj_name:
pj_name = pj_name.split('/')[len(pj_name.split('/')) - 1]
project_name_snake = String.convert_to_snake_case(pj_name)
if workspace is None:
templates: list[TemplateFileABC] = [
@@ -79,7 +84,8 @@ class ConsoleBuilder:
ReadmeTemplate(),
TestsInitTemplate(),
AppsettingsTemplate(),
MainInitTemplate(project_name, os.path.join('src/', project_name_snake))
MainInitTemplate(project_name, os.path.join(
'src/', project_name_snake))
]
else:
project_path = os.path.join(
@@ -88,8 +94,6 @@ class ConsoleBuilder:
)
templates: list[TemplateFileABC] = [
LicenseTemplate(),
ReadmeTemplate(),
AppsettingsTemplate(),
MainInitTemplate('', '')
]
@@ -103,36 +107,62 @@ class ConsoleBuilder:
src_rel_path = os.path.join('src/', src_name)
if use_application_api:
templates.append(ApplicationTemplate(src_name, src_rel_path))
templates.append(ApplicationTemplate(
src_name, src_rel_path, use_async))
if use_startup:
templates.append(StartupTemplate(src_name, src_rel_path))
templates.append(MainWithApplicationHostAndStartupTemplate(src_name, src_rel_path))
templates.append(StartupTemplate(
src_name, src_rel_path, use_async))
templates.append(MainWithApplicationHostAndStartupTemplate(
src_name, src_rel_path, use_async))
else:
templates.append(MainWithApplicationBaseTemplate(src_name, src_rel_path))
templates.append(MainWithApplicationBaseTemplate(
src_name, src_rel_path, use_async))
else:
if use_service_providing:
templates.append(MainWithDependencyInjection(src_name, src_rel_path))
templates.append(MainWithDependencyInjection(
src_name, src_rel_path, use_async))
else:
templates.append(MainWithoutApplicationBaseTemplate(src_name, src_rel_path))
templates.append(MainWithoutApplicationBaseTemplate(
src_name, src_rel_path, use_async))
if '/' in project_name:
old_pj_name = project_name
parts = project_name.split('/')
project_name = parts[len(parts) - 1]
src_rel_path = old_pj_name.split(project_name)[0]
proj_name = project_name
if src_rel_path.endswith('/'):
src_rel_path = src_rel_path[:len(src_rel_path) - 1]
if src_rel_path != '':
proj_name = f'{src_rel_path}/{project_name}'
if workspace is not None:
proj_name = project_name_snake
project_file_path = f'{project_name_snake}/{project_name}.json'
if src_rel_path != '':
project_file_path = f'{src_rel_path}/{project_name_snake}/{project_name}.json'
else:
project_file_path = f'{project_name_snake}/{project_name}.json'
if workspace is None:
src_path = f'src/{project_name_snake}'
workspace_file_path = f'{proj_name}/cpl-workspace.json'
project_file_rel_path = f'{src_path}/{project_name}.json'
project_file_path = f'{proj_name}/{src_path}/{project_name}.json'
cls._create_workspace(workspace_file_path, project_name, {
project_name: project_file_rel_path
})
cls._create_workspace(
workspace_file_path,
project_name,
{
project_name: project_file_rel_path
},
{}
)
else:
workspace.projects[project_name] = f'src/{project_file_path}'
cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects)
cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects, workspace.scripts)
Console.spinner(
f'Creating {project_file_path}',

View File

@@ -39,12 +39,12 @@ class LibraryBuilder:
project_json.close()
@classmethod
def _create_workspace(cls, path: str, project_name, projects: dict):
def _create_workspace(cls, path: str, project_name, projects: dict, scripts: dict):
ws_dict = {
WorkspaceSettings.__name__: {
WorkspaceSettingsNameEnum.default_project.value: project_name,
WorkspaceSettingsNameEnum.projects.value: projects,
WorkspaceSettingsNameEnum.scripts.value: {}
WorkspaceSettingsNameEnum.scripts.value: scripts,
}
}
@@ -59,7 +59,7 @@ class LibraryBuilder:
@classmethod
def build(cls, project_path: str, use_application_api: bool, use_startup: bool,
use_service_providing: bool, project_name: str, project_settings: dict,
use_async: bool, use_service_providing: bool, project_name: str, project_settings: dict,
workspace: Optional[WorkspaceSettings]):
"""
Builds the library project files
@@ -67,19 +67,25 @@ class LibraryBuilder:
:param use_application_api:
:param use_startup:
:param use_service_providing:
:param use_async:
:param project_name:
:param project_settings:
:param workspace:
:return:
"""
project_name_snake = String.convert_to_snake_case(project_name)
pj_name = project_name
if '/' in pj_name:
pj_name = pj_name.split('/')[len(pj_name.split('/')) - 1]
project_name_snake = String.convert_to_snake_case(pj_name)
if workspace is None:
templates: list[TemplateFileABC] = [
LicenseTemplate(),
ReadmeTemplate(),
TestsInitTemplate(),
NameInitTemplate(project_name, os.path.join('src/', project_name_snake)),
NameInitTemplate(project_name, os.path.join(
'src/', project_name_snake)),
AppsettingsTemplate()
]
else:
@@ -104,36 +110,62 @@ class LibraryBuilder:
src_rel_path = os.path.join('src/', src_name)
if use_application_api:
templates.append(ApplicationTemplate(src_name, src_rel_path))
templates.append(ApplicationTemplate(
src_name, src_rel_path, use_async))
if use_startup:
templates.append(StartupTemplate(src_name, src_rel_path))
templates.append(MainWithApplicationHostAndStartupTemplate(src_name, src_rel_path))
templates.append(StartupTemplate(
src_name, src_rel_path, use_async))
templates.append(MainWithApplicationHostAndStartupTemplate(
src_name, src_rel_path, use_async))
else:
templates.append(MainWithApplicationBaseTemplate(src_name, src_rel_path))
templates.append(MainWithApplicationBaseTemplate(
src_name, src_rel_path, use_async))
else:
if use_service_providing:
templates.append(MainWithDependencyInjection(src_name, src_rel_path))
templates.append(MainWithDependencyInjection(
src_name, src_rel_path, use_async))
else:
templates.append(MainWithoutApplicationBaseTemplate(src_name, src_rel_path))
templates.append(MainWithoutApplicationBaseTemplate(
src_name, src_rel_path, use_async))
if '/' in project_name:
old_pj_name = project_name
parts = project_name.split('/')
project_name = parts[len(parts) - 1]
src_rel_path = old_pj_name.split(project_name)[0]
proj_name = project_name
if src_rel_path.endswith('/'):
src_rel_path = src_rel_path[:len(src_rel_path) - 1]
if src_rel_path != '':
proj_name = f'{src_rel_path}/{project_name}'
if workspace is not None:
proj_name = project_name_snake
project_file_path = f'{project_name_snake}/{project_name}.json'
if src_rel_path != '':
project_file_path = f'{src_rel_path}/{project_name_snake}/{project_name}.json'
else:
project_file_path = f'{project_name_snake}/{project_name}.json'
if workspace is None:
src_path = f'src/{project_name_snake}'
workspace_file_path = f'{proj_name}/cpl-workspace.json'
project_file_rel_path = f'{src_path}/{project_name}.json'
project_file_path = f'{proj_name}/{src_path}/{project_name}.json'
cls._create_workspace(workspace_file_path, project_name, {
project_name: project_file_rel_path
})
cls._create_workspace(
workspace_file_path,
project_name,
{
project_name: project_file_rel_path
},
{}
)
else:
workspace.projects[project_name] = f'src/{project_file_path}'
cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects)
cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects, workspace.scripts)
Console.spinner(
f'Creating {project_file_path}',

View File

@@ -55,7 +55,10 @@ class Startup(StartupABC):
ConsoleArgument('', 'help', ['h', 'H'], ' ', is_value_token_optional=True)
)
configuration.add_console_argument(
ConsoleArgument('', 'install', ['i', 'I'], ' ', is_value_token_optional=True)
ConsoleArgument('', 'install', ['i', 'I'], ' ', is_value_token_optional=True, console_arguments= [
ConsoleArgument('', '--virtual', ['--v', '--V'], ''),
ConsoleArgument('', '--simulate', ['--s', '--S'], ''),
])
)
configuration.add_console_argument(ConsoleArgument('', 'new', ['n', 'N'], '', console_arguments=[
ConsoleArgument('', 'console', ['c', 'C'], ' '),

View File

@@ -1,14 +0,0 @@
from sqlalchemy import Column, Integer, String
from cpl_core.database import DatabaseModel
class CityModel(DatabaseModel):
__tablename__ = 'Cities'
Id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
Name = Column(String(64), nullable=False)
ZIP = Column(String(5), nullable=False)
def __init__(self, name: str, zip_code: str):
self.Name = name
self.ZIP = zip_code

View File

@@ -1,18 +0,0 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from cpl_core.database import DatabaseModel
from .city_model import CityModel
class UserModel(DatabaseModel):
__tablename__ = 'Users'
Id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
Name = Column(String(64), nullable=False)
City_Id = Column(Integer, ForeignKey('Cities.Id'), nullable=False)
City = relationship("CityModel")
def __init__(self, name: str, city: CityModel):
self.Name = name
self.City_Id = city.Id
self.City = city

View File

@@ -1,29 +0,0 @@
from cpl_core.database.context import DatabaseContextABC
from .city_model import CityModel
from .user_model import UserModel
from .user_repo_abc import UserRepoABC
class UserRepo(UserRepoABC):
def __init__(self, db_context: DatabaseContextABC):
UserRepoABC.__init__(self)
self._session = db_context.session
self._user_query = db_context.session.query(UserModel)
def create(self): pass
def add_test_user(self):
city = CityModel('Haren', '49733')
city2 = CityModel('Meppen', '49716')
self._session.add(city2)
user = UserModel('TestUser', city)
self._session.add(user)
self._session.commit()
def get_users(self) -> list[UserModel]:
return self._session.query(UserModel).all()
def get_cities(self) -> list[CityModel]:
return self._session.query(CityModel).all()

View File

@@ -1,39 +0,0 @@
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.database import DatabaseSettings
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.logging import LoggerABC, Logger
from model.db_context import DBContext
from model.user_repo import UserRepo
from model.user_repo_abc import UserRepoABC
class Startup(StartupABC):
def __init__(self, config: ConfigurationABC, services: ServiceCollectionABC):
StartupABC.__init__(self)
self._configuration = config
self._environment = self._configuration.environment
self._services = services
def configure_configuration(self) -> ConfigurationABC:
self._configuration.add_environment_variables('PYTHON_')
self._configuration.add_environment_variables('CPL_')
self._configuration.add_console_arguments()
self._configuration.add_json_file(f'appsettings.json')
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.environment_name}.json')
self._configuration.add_json_file(f'appsettings.{self._configuration.environment.host_name}.json', optional=True)
return self._configuration
def configure_services(self) -> ServiceProviderABC:
# Create and connect to database
db_settings: DatabaseSettings = self._configuration.get_configuration(DatabaseSettings)
self._services.add_db_context(DBContext, db_settings)
self._services.add_singleton(UserRepoABC, UserRepo)
self._services.add_singleton(LoggerABC, Logger)
return self._services.build_service_provider()

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_core'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.application'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -26,4 +26,4 @@ from .application_builder_abc import ApplicationBuilderABC
from .startup_abc import StartupABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -34,6 +34,17 @@ class ApplicationABC(ABC):
self.main()
except KeyboardInterrupt:
Console.close()
async def run_async(self):
r"""Entry point
Called by custom Application.main
"""
try:
await self.configure()
await self.main()
except KeyboardInterrupt:
Console.close()
@abstractmethod
def configure(self):

View File

@@ -1,4 +1,3 @@
import types
from typing import Type, Optional, Callable
from cpl_core.application.application_abc import ApplicationABC
@@ -6,7 +5,6 @@ from cpl_core.application.application_builder_abc import ApplicationBuilderABC
from cpl_core.application.application_extension_abc import ApplicationExtensionABC
from cpl_core.application.startup_abc import StartupABC
from cpl_core.configuration.configuration import Configuration
from cpl_core.console import Console
from cpl_core.dependency_injection.service_collection import ServiceCollection
@@ -50,3 +48,17 @@ class ApplicationBuilder(ApplicationBuilderABC):
extension.run(config, services)
return self._app(config, services)
async def build_async(self) -> ApplicationABC:
if self._startup is not None:
await self._startup.configure_configuration(self._configuration, self._environment)
await self._startup.configure_services(self._services, self._environment)
config = self._configuration
services = self._services.build_service_provider()
for ex in self._extensions:
extension = ex()
await extension.run(config, services)
return self._app(config, services)

View File

@@ -23,6 +23,17 @@ class ApplicationBuilderABC(ABC):
"""
pass
@abstractmethod
async def use_startup(self, startup: Type[StartupABC]):
r"""Sets the custom startup class to use async
Parameter
---------
startup: Type[:class:`cpl_core.application.startup_abc.StartupABC`]
Startup class to use
"""
pass
@abstractmethod
def build(self) -> ApplicationABC:
r"""Creates custom application object
@@ -32,3 +43,13 @@ class ApplicationBuilderABC(ABC):
Object of :class:`cpl_core.application.application_abc.ApplicationABC`
"""
pass
@abstractmethod
async def build_async(self) -> ApplicationABC:
r"""Creates custom application object async
Returns
-------
Object of :class:`cpl_core.application.application_abc.ApplicationABC`
"""
pass

View File

@@ -11,3 +11,6 @@ class ApplicationExtensionABC(ABC):
@abstractmethod
def run(self, config: ConfigurationABC, services: ServiceProviderABC): pass
@abstractmethod
async def run(self, config: ConfigurationABC, services: ServiceProviderABC): pass

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.configuration'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -27,4 +27,4 @@ from .configuration_variable_name_enum import ConfigurationVariableNameEnum
from .console_argument import ConsoleArgument
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.console'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -27,4 +27,4 @@ from .foreground_color_enum import ForegroundColorEnum
from .spinner_thread import SpinnerThread
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -3,8 +3,8 @@
"Name": "sh_cpl-core",
"Version": {
"Major": "2021",
"Minor": "10",
"Micro": "0.post1"
"Minor": "11",
"Micro": "0"
},
"Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de",
@@ -19,15 +19,14 @@
"colorama==0.4.4",
"mysql-connector==2.2.9",
"psutil==5.8.0",
"packaging==20.9",
"packaging==21.3",
"pyfiglet==0.8.post1",
"pynput==1.7.3",
"SQLAlchemy==1.4.7",
"setuptools==56.0.0",
"pynput==1.7.5",
"setuptools==59.4.0",
"tabulate==0.8.9",
"termcolor==1.1.0",
"watchdog==2.0.2",
"wheel==0.36.2"
"watchdog==2.1.6",
"wheel==0.37.0"
],
"PythonVersion": ">=3.8",
"PythonPath": {},

View File

@@ -15,14 +15,14 @@ __title__ = 'cpl_core.database'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
from .database_model import DatabaseModel
from .database_settings import DatabaseSettings
from .database_settings_name_enum import DatabaseSettingsNameEnum
from .database_settings import DatabaseSettings
from .table_abc import TableABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.database.connection'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -24,4 +24,4 @@ from .database_connection import DatabaseConnection
from .database_connection_abc import DatabaseConnectionABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -1,64 +1,52 @@
from typing import Optional
from sqlalchemy import engine, create_engine
from sqlalchemy.orm import Session, sessionmaker
from cpl_core.console.console import Console
from cpl_core.console.foreground_color_enum import ForegroundColorEnum
from cpl_core.database.connection.database_connection_abc import DatabaseConnectionABC
import mysql.connector as sql
from cpl_core.database.connection.database_connection_abc import \
DatabaseConnectionABC
from cpl_core.database.database_settings import DatabaseSettings
from cpl_core.utils.credential_manager import CredentialManager
from mysql.connector.abstracts import MySQLConnectionAbstract
from mysql.connector.cursor import MySQLCursorBuffered
class DatabaseConnection(DatabaseConnectionABC):
r"""Representation of the database connection
Parameter
---------
database_settings: :class:`cpl_core.database.database_settings.DatabaseSettings`
"""
def __init__(self, database_settings: DatabaseSettings):
def __init__(self):
DatabaseConnectionABC.__init__(self)
self._db_settings = database_settings
self._engine: Optional[engine] = None
self._session: Optional[Session] = None
self._credentials: Optional[str] = None
self._database: Optional[MySQLConnectionAbstract] = None
self._cursor: Optional[MySQLCursorBuffered] = None
@property
def engine(self) -> engine:
return self._engine
def server(self) -> MySQLConnectionAbstract:
return self._database
@property
def session(self) -> Session:
return self._session
def cursor(self) -> MySQLCursorBuffered:
return self._cursor
def connect(self, connection_string: str):
try:
self._engine = create_engine(connection_string)
if self._db_settings.auth_plugin is not None:
self._engine = create_engine(connection_string, connect_args={'auth_plugin': self._db_settings.auth_plugin})
if self._db_settings.encoding is not None:
self._engine.encoding = self._db_settings.encoding
if self._db_settings.case_sensitive is not None:
self._engine.case_sensitive = self._db_settings.case_sensitive
if self._db_settings.echo is not None:
self._engine.echo = self._db_settings.echo
self._engine.connect()
db_session = sessionmaker(bind=self._engine)
self._session = db_session()
Console.set_foreground_color(ForegroundColorEnum.green)
Console.write_line(f'[{__name__}] Connected to database')
Console.set_foreground_color(ForegroundColorEnum.default)
except Exception as e:
Console.set_foreground_color(ForegroundColorEnum.red)
Console.write_line(f'[{__name__}] Database connection failed -> {e}')
Console.set_foreground_color(ForegroundColorEnum.default)
exit()
def connect(self, database_settings: DatabaseSettings):
connection = sql.connect(
host=database_settings.host,
user=database_settings.user,
passwd=CredentialManager.decrypt(database_settings.password),
charset=database_settings.charset,
use_unicode=database_settings.use_unicode,
buffered=database_settings.buffered,
auth_plugin=database_settings.auth_plugin
)
connection.cursor().execute(
f'CREATE DATABASE IF NOT EXISTS `{database_settings.database}`;')
self._database = sql.connect(
host=database_settings.host,
user=database_settings.user,
passwd=CredentialManager.decrypt(database_settings.password),
db=database_settings.database,
charset=database_settings.charset,
use_unicode=database_settings.use_unicode,
buffered=database_settings.buffered,
auth_plugin=database_settings.auth_plugin
)
self._cursor = self._database.cursor()

View File

@@ -1,7 +1,8 @@
from abc import abstractmethod, ABC
from abc import ABC, abstractmethod
from sqlalchemy import engine
from sqlalchemy.orm import Session
from cpl_core.database.database_settings import DatabaseSettings
from mysql.connector.abstracts import MySQLConnectionAbstract
from mysql.connector.cursor import MySQLCursorBuffered
class DatabaseConnectionABC(ABC):
@@ -12,14 +13,14 @@ class DatabaseConnectionABC(ABC):
@property
@abstractmethod
def engine(self) -> engine: pass
def server(self) -> MySQLConnectionAbstract: pass
@property
@abstractmethod
def session(self) -> Session: pass
def cursor(self) -> MySQLCursorBuffered: pass
@abstractmethod
def connect(self, connection_string: str):
def connect(self, database_settings: DatabaseSettings):
r"""Connects to a database by connection string
Parameter

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.database.context'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -24,4 +24,4 @@ from .database_context import DatabaseContext
from .database_context_abc import DatabaseContextABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -1,13 +1,13 @@
from sqlalchemy import engine, Table
from sqlalchemy.orm import Session
from cpl_core.console.console import Console
from cpl_core.console.foreground_color_enum import ForegroundColorEnum
from typing import Optional
from cpl_core.database.connection.database_connection import DatabaseConnection
from cpl_core.database.connection.database_connection_abc import DatabaseConnectionABC
from cpl_core.database.connection.database_connection_abc import \
DatabaseConnectionABC
from cpl_core.database.context.database_context_abc import DatabaseContextABC
from cpl_core.database.database_settings import DatabaseSettings
from cpl_core.database.database_model import DatabaseModel
from cpl_core.database.table_abc import TableABC
from mysql.connector.cursor import MySQLCursorBuffered
class DatabaseContext(DatabaseContextABC):
@@ -19,38 +19,23 @@ class DatabaseContext(DatabaseContextABC):
"""
def __init__(self, database_settings: DatabaseSettings):
DatabaseContextABC.__init__(self)
DatabaseContextABC.__init__(self, database_settings)
self._db: DatabaseConnectionABC = DatabaseConnection(database_settings)
self._tables: list[Table] = []
self._db: DatabaseConnectionABC = DatabaseConnection()
self._tables: list[TableABC] = TableABC.__subclasses__()
@property
def engine(self) -> engine:
return self._db.engine
@property
def session(self) -> Session:
return self._db.session
def connect(self, connection_string: str):
self._db.connect(connection_string)
self._create_tables()
def cursor(self) -> MySQLCursorBuffered:
return self._db.cursor
def connect(self, database_settings: DatabaseSettings):
self._db.connect(database_settings)
for table in self._tables:
self._db.cursor.execute(table.get_create_string())
def save_changes(self):
self._db.session.commit()
def _create_tables(self):
try:
for subclass in DatabaseModel.__subclasses__():
self._tables.append(subclass.__table__)
DatabaseModel.metadata.drop_all(self._db.engine, self._tables)
DatabaseModel.metadata.create_all(self._db.engine, self._tables, checkfirst=True)
Console.set_foreground_color(ForegroundColorEnum.green)
Console.write_line(f'[{__name__}] Created tables')
Console.set_foreground_color(ForegroundColorEnum.default)
except Exception as e:
Console.set_foreground_color(ForegroundColorEnum.red)
Console.write_line(f'[{__name__}] Creating tables failed -> {e}')
Console.set_foreground_color(ForegroundColorEnum.default)
exit()
self._db.server.commit()
def select(self, statement: str) -> list[tuple]:
self._db.cursor.execute(statement)
return self._db.cursor.fetchall()

View File

@@ -1,7 +1,7 @@
from abc import abstractmethod, ABC
from abc import ABC, abstractmethod
from sqlalchemy import engine
from sqlalchemy.orm import Session
from cpl_core.database.database_settings import DatabaseSettings
from mysql.connector.cursor import MySQLCursorBuffered
class DatabaseContextABC(ABC):
@@ -12,29 +12,34 @@ class DatabaseContextABC(ABC):
pass
@property
def cursor(self) -> MySQLCursorBuffered:
return self._cursor
@abstractmethod
def engine(self) -> engine: pass
@property
@abstractmethod
def session(self) -> Session: pass
@abstractmethod
def connect(self, connection_string: str):
r"""Connects to a database by connection string
def connect(self, database_settings: DatabaseSettings):
r"""Connects to a database by connection settings
Parameter
---------
connection_string: :class:`str`
Database connection string, see: https://docs.sqlalchemy.org/en/14/core/engines.html
database_settings :class:`cpl_core.database.database_settings.DatabaseSettings`
"""
pass
@abstractmethod
def save_changes(self):
r"""Saves changes of the database"""
pass
@abstractmethod
def _create_tables(self):
r"""Create all tables for application from database model"""
def select(self, statement: str) -> list[tuple]:
r"""Runs SQL Statements
Parameter
---------
statement: :class:`str`
Returns
-------
list: Fetched list of selected elements
"""
pass

View File

@@ -1,3 +0,0 @@
from sqlalchemy.ext.declarative import declarative_base
DatabaseModel: declarative_base = declarative_base()

View File

@@ -13,61 +13,47 @@ class DatabaseSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._host: Optional[str] = None
self._user: Optional[str] = None
self._password: Optional[str] = None
self._databse: Optional[str] = None
self._charset: Optional[str] = None
self._use_unicode: Optional[bool] = None
self._buffered: Optional[bool] = None
self._auth_plugin: Optional[str] = None
self._connection_string: Optional[str] = None
self._credentials: Optional[str] = None
self._encoding: Optional[str] = None
self._case_sensitive: Optional[bool] = None
self._echo: Optional[bool] = None
@property
def auth_plugin(self) -> str:
def host(self) -> Optional[str]:
return self._host
@property
def user(self) -> Optional[str]:
return self._user
@property
def password(self) -> Optional[str]:
return self._password
@property
def database(self) -> Optional[str]:
return self._databse
@property
def charset(self) -> Optional[str]:
return self._charset
@property
def use_unicode(self) -> Optional[bool]:
return self._use_unicode
@property
def buffered(self) -> Optional[bool]:
return self._buffered
@property
def auth_plugin(self) -> Optional[str]:
return self._auth_plugin
@auth_plugin.setter
def auth_plugin(self, auth_plugin: str):
self._auth_plugin = auth_plugin
@property
def connection_string(self) -> str:
return self._connection_string
@connection_string.setter
def connection_string(self, connection_string: str):
self._connection_string = connection_string
@property
def credentials(self) -> str:
return self._credentials
@credentials.setter
def credentials(self, credentials: str):
self._credentials = credentials
@property
def encoding(self) -> str:
return self._encoding
@encoding.setter
def encoding(self, encoding: str) -> None:
self._encoding = encoding
@property
def case_sensitive(self) -> bool:
return self._case_sensitive
@case_sensitive.setter
def case_sensitive(self, case_sensitive: bool) -> None:
self._case_sensitive = case_sensitive
@property
def echo(self) -> bool:
return self._echo
@echo.setter
def echo(self, echo: bool) -> None:
self._echo = echo
def from_dict(self, settings: dict):
r"""Sets attributes from given dict
@@ -76,20 +62,22 @@ class DatabaseSettings(ConfigurationModelABC):
settings: :class:`dict`
"""
try:
self._connection_string = settings[DatabaseSettingsNameEnum.connection_string.value]
self._credentials = settings[DatabaseSettingsNameEnum.credentials.value]
self._host = settings[DatabaseSettingsNameEnum.host.value]
self._user = settings[DatabaseSettingsNameEnum.user.value]
self._password = settings[DatabaseSettingsNameEnum.password.value]
self._databse = settings[DatabaseSettingsNameEnum.database.value]
if DatabaseSettingsNameEnum.charset.value in settings:
self._charset = settings[DatabaseSettingsNameEnum.charset.value]
if DatabaseSettingsNameEnum.buffered.value in settings:
self._use_unicode = bool(settings[DatabaseSettingsNameEnum.use_unicode.value])
if DatabaseSettingsNameEnum.buffered.value in settings:
self._buffered = bool(settings[DatabaseSettingsNameEnum.buffered.value])
if DatabaseSettingsNameEnum.auth_plugin.value in settings:
self._auth_plugin = settings[DatabaseSettingsNameEnum.auth_plugin.value]
if DatabaseSettingsNameEnum.encoding.value in settings:
self._encoding = settings[DatabaseSettingsNameEnum.encoding.value]
if DatabaseSettingsNameEnum.case_sensitive.value in settings:
self._case_sensitive = bool(settings[DatabaseSettingsNameEnum.case_sensitive.value])
if DatabaseSettingsNameEnum.echo.value in settings:
self._echo = bool(settings[DatabaseSettingsNameEnum.echo.value])
except Exception as e:
Console.set_foreground_color(ForegroundColorEnum.red)
Console.write_line(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')

View File

@@ -3,9 +3,11 @@ from enum import Enum
class DatabaseSettingsNameEnum(Enum):
connection_string = 'ConnectionString'
credentials = 'Credentials'
encoding = 'Encoding'
case_sensitive = 'CaseSensitive'
echo = 'Echo'
host = 'Host'
user = 'User'
password = 'Password'
database = 'Database'
charset = 'Charset'
use_unicode = 'UseUnicode'
buffered = 'Buffered'
auth_plugin = 'AuthPlugin'

View File

@@ -0,0 +1,35 @@
from abc import ABC, abstractmethod
from datetime import datetime
from typing import Optional
class TableABC(ABC):
@abstractmethod
def __init__(self):
self._created_at: Optional[datetime] = None
self._modified_at: Optional[datetime] = None
@property
def CreatedAt(self) -> datetime:
return self._created_at
@property
def LastModifiedAt(self) -> datetime:
return self._modified_at
@staticmethod
@abstractmethod
def get_create_string() -> str: pass
@property
@abstractmethod
def insert_string(self) -> str: pass
@property
@abstractmethod
def udpate_string(self) -> str: pass
@property
@abstractmethod
def delete_string(self) -> str: pass

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.dependency_injection'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -28,4 +28,4 @@ from .service_provider import ServiceProvider
from .service_provider_abc import ServiceProviderABC
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -0,0 +1,18 @@
from cpl_core.console.console import Console
from cpl_core.dependency_injection.scope_abc import ScopeABC
from cpl_core.dependency_injection.service_provider_abc import ServiceProviderABC
class Scope(ScopeABC):
def __init__(self, service_provider: ServiceProviderABC):
self._service_provider = service_provider
self._service_provider.set_scope(self)
@property
def service_provider(self) -> ServiceProviderABC:
return self._service_provider
def dispose(self):
self._service_provider = None

View File

@@ -0,0 +1,24 @@
from abc import ABC, abstractmethod
class ScopeABC(ABC):
r"""ABC for the class :class:`cpl_core.dependency_injection.scope.Scope`"""
def __init__(self):
pass
@property
@abstractmethod
def service_provider(self):
r"""Returns to service provider of scope
Returns
-------
Object of type :class:`cpl_core.dependency_injection.service_provider_abc.ServiceProviderABC`
"""
pass
@abstractmethod
def dispose():
r"""Sets service_provider to None
"""
pass

View File

@@ -0,0 +1,19 @@
from cpl_core.dependency_injection.scope import Scope
from cpl_core.dependency_injection.scope_abc import ScopeABC
from cpl_core.dependency_injection.service_provider_abc import ServiceProviderABC
class ScopeBuilder:
r"""Class to build :class:`cpl_core.dependency_injection.scope.Scope`"""
def __init__(self, service_provider: ServiceProviderABC) -> None:
self._service_provider = service_provider
def build(self) -> ScopeABC:
r"""Returns scope
Returns
-------
Object of type :class:`cpl_core.dependency_injection.scope.Scope`
"""
return Scope(self._service_provider)

View File

@@ -40,7 +40,7 @@ class ServiceCollection(ServiceCollectionABC):
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
self._database_context = db_context_type(db_settings)
self._database_context.connect(CredentialManager.build_string(db_settings.connection_string, db_settings.credentials))
self._database_context.connect(db_settings)
def add_logging(self):
self.add_singleton(LoggerABC, Logger)
@@ -59,9 +59,13 @@ class ServiceCollection(ServiceCollectionABC):
self._add_descriptor(impl, ServiceLifetimeEnum.singleton)
def add_scoped(self, service_type: Type, service: Callable = None):
raise Exception('Not implemented')
if service is not None:
self._add_descriptor(service, ServiceLifetimeEnum.scoped)
else:
self._add_descriptor(service_type, ServiceLifetimeEnum.scoped)
def add_transient(self, service_type: Union[type], service: Union[type] = None):
def add_transient(self, service_type: type, service: type = None):
if service is not None:
self._add_descriptor(service, ServiceLifetimeEnum.transient)
else:

View File

@@ -15,15 +15,13 @@ class ServiceCollectionABC(ABC):
pass
@abstractmethod
def add_db_context(self, db_context: Type[DatabaseContextABC], db_settings: DatabaseSettings):
def add_db_context(self, db_context: Type[DatabaseContextABC]):
r"""Adds database context
Parameter
---------
db_context: Type[:class:`cpl_core.database.context.database_context_abc.DatabaseContextABC`]
Database context
db_settings: :class:`cpl_core.database.database_settings.DatabaseSettings`
Database settings
"""
pass

View File

@@ -4,5 +4,5 @@ from enum import Enum
class ServiceLifetimeEnum(Enum):
singleton = 0
scoped = 1 # not supported yet
scoped = 1
transient = 2

View File

@@ -1,10 +1,13 @@
from collections import Callable
import copy
from inspect import signature, Parameter
from typing import Optional
from cpl_core.configuration.configuration_abc import ConfigurationABC
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl_core.database.context.database_context_abc import DatabaseContextABC
from cpl_core.dependency_injection.scope_abc import ScopeABC
from cpl_core.dependency_injection.scope_builder import ScopeBuilder
from cpl_core.dependency_injection.service_provider_abc import ServiceProviderABC
from cpl_core.dependency_injection.service_descriptor import ServiceDescriptor
from cpl_core.dependency_injection.service_lifetime_enum import ServiceLifetimeEnum
@@ -30,8 +33,9 @@ class ServiceProvider(ServiceProviderABC):
self._service_descriptors: list[ServiceDescriptor] = service_descriptors
self._configuration: ConfigurationABC = config
self._database_context = db_context
self._scope: Optional[ScopeABC] = None
def _find_service(self, service_type: type) -> [ServiceDescriptor]:
def _find_service(self, service_type: type) -> ServiceDescriptor:
for descriptor in self._service_descriptors:
if descriptor.service_type == service_type or issubclass(descriptor.service_type, service_type):
return descriptor
@@ -84,6 +88,13 @@ class ServiceProvider(ServiceProviderABC):
params.append(self._get_service(parameter))
return service_type(*params)
def set_scope(self, scope: ScopeABC):
self._scope = scope
def create_scope(self) -> ScopeABC:
sb = ScopeBuilder(ServiceProvider(copy.deepcopy(self._service_descriptors), self._configuration, self._database_context))
return sb.build()
def get_service(self, service_type: type) -> Optional[Callable[object]]:
result = self._find_service(service_type)
@@ -95,7 +106,7 @@ class ServiceProvider(ServiceProviderABC):
return result.implementation
implementation = self.build_service(service_type)
if result.lifetime == ServiceLifetimeEnum.singleton:
if result.lifetime == ServiceLifetimeEnum.singleton or result.lifetime == ServiceLifetimeEnum.scoped and self._scope is not None:
result.implementation = implementation
return implementation

View File

@@ -2,6 +2,8 @@ from abc import abstractmethod, ABC
from collections import Callable
from typing import Type, Optional
from cpl_core.dependency_injection.scope_abc import ScopeABC
class ServiceProviderABC(ABC):
r"""ABC for the class :class:`cpl_core.dependency_injection.service_provider.ServiceProvider`"""
@@ -24,6 +26,27 @@ class ServiceProviderABC(ABC):
Object of the given type
"""
pass
@abstractmethod
def set_scope(self, scope: ScopeABC):
r"""Sets the scope of service provider
Parameter
---------
scope :class:`cpl_core.dependency_injection.scope.Scope`
Service scope
"""
pass
@abstractmethod
def create_scope(self) -> ScopeABC:
r"""Creates a service scope
Returns
-------
Object of type :class:`cpl_core.dependency_injection.scope.Scope`
"""
pass
@abstractmethod
def get_service(self, instance_type: Type) -> Optional[Callable[object]]:

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.environment'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -25,4 +25,4 @@ from .environment_name_enum import EnvironmentNameEnum
from .application_environment import ApplicationEnvironment
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.logging'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -27,4 +27,4 @@ from .logging_settings import LoggingSettings
from .logging_settings_name_enum import LoggingSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.mailing'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -27,4 +27,4 @@ from .email_client_settings import EMailClientSettings
from .email_client_settings_name_enum import EMailClientSettingsNameEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.time'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -24,4 +24,4 @@ from .time_format_settings import TimeFormatSettings
from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_core.utils'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post1'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -25,4 +25,4 @@ from .string import String
from .pip import Pip
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post1')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_query'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -15,11 +15,11 @@ __title__ = 'cpl_query._query'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
# imports:
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -6,7 +6,7 @@ from cpl_query.extension.ordered_iterable_abc import OrderedIterableABC
def order_by_query(_list: IterableABC, _func: Callable) -> OrderedIterableABC:
result = OrderedIterableABC(_func)
result = OrderedIterableABC(_list.type, _func)
_list.sort(key=_func)
result.extend(_list)
return result
@@ -19,7 +19,7 @@ def order_by_descending_query(_list: IterableABC, _func: Callable) -> OrderedIte
if _func is None:
raise ArgumentNoneException(ExceptionArgument.func)
result = OrderedIterableABC(_func)
result = OrderedIterableABC(_list.type, _func)
_list.sort(key=_func, reverse=True)
result.extend(_list)
return result

View File

@@ -3,8 +3,8 @@
"Name": "sh_cpl-query",
"Version": {
"Major": "2021",
"Minor": "10",
"Micro": "0.post2"
"Minor": "11",
"Micro": "0"
},
"Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de",
@@ -16,9 +16,9 @@
"LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [
"sh_cpl-core>=2021.10.0"
"sh_cpl-core>=2021.11.0"
],
"PythonVersion": ">=3.9.2",
"PythonVersion": ">=3.8",
"PythonPath": {},
"Classifiers": []
},

View File

@@ -15,7 +15,7 @@ __title__ = 'cpl_query.extension'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de'
__version__ = '2021.10.0.post2'
__version__ = '2021.11.0'
from collections import namedtuple
@@ -27,4 +27,4 @@ from .ordered_iterable_abc import OrderedIterableABC
from .ordered_iterable import OrderedIterable
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='2021', minor='10', micro='0.post2')
version_info = VersionInfo(major='2021', minor='11', micro='0')

View File

@@ -75,13 +75,13 @@ class Iterable(IterableABC):
def order_by(self, func: Callable) -> OrderedIterableABC:
res = order_by_query(self, func)
from cpl_query._extension.ordered_iterable import OrderedIterable
from cpl_query.extension.ordered_iterable import OrderedIterable
res.__class__ = OrderedIterable
return res
def order_by_descending(self, func: Callable) -> OrderedIterableABC:
res = order_by_descending_query(self, func)
from cpl_query._extension.ordered_iterable import OrderedIterable
from cpl_query.extension.ordered_iterable import OrderedIterable
res.__class__ = OrderedIterable
return res

View File

@@ -9,9 +9,9 @@ class OrderedIterable(Iterable, OrderedIterableABC):
r"""Implementation of :class: `cpl_query.extension.Iterable` `cpl_query.extension.OrderedIterableABC`
"""
def __init__(self):
Iterable.__init__(self)
OrderedIterableABC.__init__(self)
def __init__(self, _t: type = None):
Iterable.__init__(self, _t)
OrderedIterableABC.__init__(self, _t)
def then_by(self, _func: Callable) -> OrderedIterableABC:
self._funcs.append(_func)

View File

@@ -7,8 +7,8 @@ from cpl_query.extension.iterable_abc import IterableABC
class OrderedIterableABC(IterableABC):
@abstractmethod
def __init__(self, _func: Callable = None):
IterableABC.__init__(self)
def __init__(self, _t: type, _func: Callable = None):
IterableABC.__init__(self, _t)
self._funcs: list[Callable] = []
if _func is not None:
self._funcs.append(_func)

View File

@@ -0,0 +1,9 @@
{
"WorkspaceSettings": {
"DefaultProject": "async",
"Projects": {
"async": "src/async/async.json"
},
"Scripts": {}
}
}

View File

@@ -0,0 +1,16 @@
from cpl_core.application import ApplicationABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.console import Console
from cpl_core.dependency_injection import ServiceProviderABC
class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services)
async def configure(self):
pass
async def main(self):
Console.write_line('Hello World')

View File

@@ -0,0 +1,43 @@
{
"ProjectSettings": {
"Name": "async",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl>=2021.10.0.post1"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"ProjectType": "console",
"SourcePath": "",
"OutputPath": "../../dist",
"Main": "async.main",
"EntryPoint": "async",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {},
"ProjectReferences": []
}
}

View File

@@ -0,0 +1,17 @@
import asyncio
from cpl_core.application import ApplicationBuilder
from application import Application
from startup import Startup
async def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app = await app_builder.build_async()
await app.run_async()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

View File

@@ -0,0 +1,16 @@
from cpl_core.application import StartupABC
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC, ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironment
class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
async def configure_configuration(self, configuration: ConfigurationABC, environment: ApplicationEnvironment) -> ConfigurationABC:
return configuration
async def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC:
return services.build_service_provider()

Some files were not shown because too many files have changed in this diff Show More