fastapi-startkit 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/PKG-INFO +2 -2
  2. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/application.py +24 -1
  3. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/configuration/Configuration.py +1 -1
  4. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/configuration/providers/ConfigurationProvider.py +0 -3
  5. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Facade.py +6 -0
  6. fastapi_startkit-0.1.2/fastapi_startkit/logging/ChannelFactory.py +20 -0
  7. fastapi_startkit-0.1.2/fastapi_startkit/logging/Logger.py +2 -0
  8. fastapi_startkit-0.1.2/fastapi_startkit/logging/__init__.py +1 -0
  9. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/BaseChannel.py +60 -0
  10. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/DailyChannel.py +17 -0
  11. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/MultiBaseChannel.py +64 -0
  12. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/SingleChannel.py +14 -0
  13. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/SlackChannel.py +19 -0
  14. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/StackChannel.py +30 -0
  15. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/SyslogChannel.py +14 -0
  16. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/TerminalChannel.py +14 -0
  17. fastapi_startkit-0.1.2/fastapi_startkit/logging/channels/__init__.py +8 -0
  18. fastapi_startkit-0.1.2/fastapi_startkit/logging/configs/logging.py +46 -0
  19. fastapi_startkit-0.1.2/fastapi_startkit/logging/drivers/BaseDriver.py +25 -0
  20. fastapi_startkit-0.1.2/fastapi_startkit/logging/drivers/LogSingleDriver.py +84 -0
  21. fastapi_startkit-0.1.2/fastapi_startkit/logging/drivers/LogSlackDriver.py +94 -0
  22. fastapi_startkit-0.1.2/fastapi_startkit/logging/drivers/LogSyslogDriver.py +48 -0
  23. fastapi_startkit-0.1.2/fastapi_startkit/logging/drivers/LogTerminalDriver.py +60 -0
  24. fastapi_startkit-0.1.2/fastapi_startkit/logging/drivers/__init__.py +5 -0
  25. fastapi_startkit-0.1.2/fastapi_startkit/logging/factory.py +15 -0
  26. fastapi_startkit-0.1.2/fastapi_startkit/logging/listeners.py +15 -0
  27. fastapi_startkit-0.1.2/fastapi_startkit/logging/managers/LoggingManager.py +11 -0
  28. fastapi_startkit-0.1.2/fastapi_startkit/logging/managers/__init__.py +1 -0
  29. fastapi_startkit-0.1.2/fastapi_startkit/logging/providers/LoggingProvider.py +25 -0
  30. fastapi_startkit-0.1.2/fastapi_startkit/logging/providers/__init__.py +1 -0
  31. fastapi_startkit-0.1.2/fastapi_startkit/providers/__init__.py +3 -0
  32. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/pyproject.toml +2 -2
  33. fastapi_startkit-0.1.0/fastapi_startkit/providers/ConfigurationProvider.py +0 -13
  34. fastapi_startkit-0.1.0/fastapi_startkit/providers/__init__.py +0 -4
  35. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/__init__.py +0 -0
  36. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/configuration/__init__.py +0 -0
  37. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/configuration/helpers.py +0 -0
  38. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/configuration/providers/__init__.py +0 -0
  39. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/container/__init__.py +0 -0
  40. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/container/container.py +0 -0
  41. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/environment/environment.py +0 -0
  42. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/DD.py +0 -0
  43. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/ExceptionHandler.py +0 -0
  44. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/__init__.py +0 -0
  45. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/exceptionite/__init__.py +0 -0
  46. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/exceptionite/blocks.py +0 -0
  47. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/exceptionite/controllers.py +0 -0
  48. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/exceptionite/solutions.py +0 -0
  49. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/exceptionite/tabs.py +0 -0
  50. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/exceptions.py +0 -0
  51. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/handlers/DumpExceptionHandler.py +0 -0
  52. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/handlers/HttpExceptionHandler.py +0 -0
  53. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/exceptions/handlers/ModelNotFoundHandler.py +0 -0
  54. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Auth.py +0 -0
  55. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Auth.pyi +0 -0
  56. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Broadcast.py +0 -0
  57. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Cache.py +0 -0
  58. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Config.py +0 -0
  59. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Config.pyi +0 -0
  60. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Dump.py +0 -0
  61. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Dump.pyi +0 -0
  62. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Gate.py +0 -0
  63. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Gate.pyi +0 -0
  64. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Hash.py +0 -0
  65. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Hash.pyi +0 -0
  66. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Loader.py +0 -0
  67. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Loader.pyi +0 -0
  68. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Mail.py +0 -0
  69. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Mail.pyi +0 -0
  70. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Notification.py +0 -0
  71. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Notification.pyi +0 -0
  72. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Queue.py +0 -0
  73. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Queue.pyi +0 -0
  74. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/RateLimiter.py +0 -0
  75. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/RateLimiter.pyi +0 -0
  76. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Request.py +0 -0
  77. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Request.pyi +0 -0
  78. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Response.py +0 -0
  79. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Response.pyi +0 -0
  80. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Session.py +0 -0
  81. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Session.pyi +0 -0
  82. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Storage.py +0 -0
  83. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Storage.pyi +0 -0
  84. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Url.py +0 -0
  85. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/Url.pyi +0 -0
  86. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/View.py +0 -0
  87. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/View.pyi +0 -0
  88. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/facades/__init__.py +0 -0
  89. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/loader/Loader.py +0 -0
  90. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/loader/__init__.py +0 -0
  91. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/providers/Provider.py +0 -0
  92. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/__init__.py +0 -0
  93. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/collections.py +0 -0
  94. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/console.py +0 -0
  95. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/data/mime.types +0 -0
  96. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/filesystem.py +0 -0
  97. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/http.py +0 -0
  98. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/location.py +0 -0
  99. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/str.py +0 -0
  100. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/structures.py +0 -0
  101. {fastapi_startkit-0.1.0 → fastapi_startkit-0.1.2}/fastapi_startkit/utils/time.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-startkit
3
- Version: 0.1.0
4
- Summary: Core Masonite components (Container, Config, Loader)
3
+ Version: 0.1.2
4
+ Summary: Fastapi_Startkit components
5
5
  Author: Bedram Tamang
6
6
  Author-email: tmgbedu@gmail.com
7
7
  Requires-Python: >=3.12,<4.0
@@ -1,24 +1,34 @@
1
- from dotenv import load_dotenv
1
+ import os
2
+
2
3
  from fastapi import FastAPI
4
+
3
5
  from .container import Container
4
6
  from .environment.environment import LoadEnvironment
7
+ from .facades import Facade
5
8
 
6
9
 
7
10
  class Application(Container):
8
11
  def __init__(self, base_path: str = None, providers=None):
9
12
  self.base_path: str = base_path
10
13
  self.providers = providers if providers else []
14
+
15
+ Facade.application = self
11
16
 
12
17
  self.load_environment()
18
+ self.configure_paths()
13
19
  self.register_providers()
14
20
 
15
21
  self.fastapi = FastAPI()
16
22
  self.load_providers()
17
23
 
18
24
  def register_providers(self):
25
+ providers = []
19
26
  for provider_class in self.providers:
20
27
  provider = provider_class(self)
21
28
  provider.register()
29
+ providers.append(provider)
30
+
31
+ self.providers = providers
22
32
  return self
23
33
 
24
34
  def load_providers(self):
@@ -38,3 +48,16 @@ class Application(Container):
38
48
 
39
49
  def load_environment(self):
40
50
  LoadEnvironment(base_path=self.base_path)
51
+
52
+ def configure_paths(self):
53
+ self.bind('config.location', os.path.join(self.base_path, "config"))
54
+
55
+ def use_config_path(self, path: str = None):
56
+ self.bind('config.location', path)
57
+
58
+ return self
59
+
60
+ def use_storage_path(self, path: str = None):
61
+ self.bind('storage.location', path)
62
+
63
+ return self
@@ -1,4 +1,4 @@
1
- from fastapi_startkit_foundation.loader import Loader
1
+ from fastapi_startkit.loader import Loader
2
2
  from ..utils.structures import data
3
3
  from ..exceptions import InvalidConfigurationLocation, InvalidConfigurationSetup
4
4
 
@@ -4,9 +4,6 @@ from ..Configuration import Configuration
4
4
 
5
5
 
6
6
  class ConfigurationProvider(Provider):
7
- def __init__(self, application):
8
- self.application = application
9
-
10
7
  def register(self):
11
8
  config = Configuration(self.application)
12
9
  config.load()
@@ -1,5 +1,11 @@
1
1
  class Facade(type):
2
+
3
+ application = None
4
+
2
5
  def __getattr__(self, attribute, *args, **kwargs):
6
+ if self.application:
7
+ return getattr(self.application.make(self.key), attribute)
8
+
3
9
  from wsgi import application
4
10
 
5
11
  return getattr(application.make(self.key), attribute)
@@ -0,0 +1,20 @@
1
+ from .channels import SingleChannel, DailyChannel, SlackChannel, StackChannel, SyslogChannel, TerminalChannel
2
+
3
+ class ChannelFactory:
4
+
5
+ channels = {
6
+ 'single': SingleChannel,
7
+ 'daily': DailyChannel,
8
+ 'slack': SlackChannel,
9
+ 'stack': StackChannel,
10
+ 'syslog': SyslogChannel,
11
+ 'terminal': TerminalChannel
12
+ }
13
+
14
+ @classmethod
15
+ def make(cls, channel):
16
+ return cls.channels.get(channel)
17
+
18
+ @classmethod
19
+ def register(cls, channel_dictionary):
20
+ cls.channels.update(channel_dictionary)
@@ -0,0 +1,2 @@
1
+ class Logger:
2
+ pass
@@ -0,0 +1 @@
1
+ from .Logger import Logger
@@ -0,0 +1,60 @@
1
+ import pendulum
2
+ from fastapi_startkit.facades import Config
3
+
4
+ class BaseChannel:
5
+
6
+ def get_time(self):
7
+
8
+ return pendulum.now().in_tz(Config.get('logging.channels.timezone', 'UTC'))
9
+
10
+ def emergency(self, message, *args, **kwargs):
11
+ if not self.driver.should_run('emergency', self.max_level):
12
+ return
13
+
14
+ return self.driver.emergency(message, *args, **kwargs)
15
+
16
+ def alert(self, message, *args, **kwargs):
17
+ if not self.driver.should_run('alert', self.max_level):
18
+ return
19
+
20
+ return self.driver.alert(message, *args, **kwargs)
21
+
22
+ def critical(self, message, *args, **kwargs):
23
+ if not self.driver.should_run('critical', self.max_level):
24
+ return
25
+
26
+ return self.driver.critical(message, *args, **kwargs)
27
+
28
+ def error(self, message, *args, **kwargs):
29
+ if not self.driver.should_run('error', self.max_level):
30
+ return
31
+
32
+ return self.driver.error(message, *args, **kwargs)
33
+
34
+ def warning(self, message, *args, **kwargs):
35
+ if not self.driver.should_run('warning', self.max_level):
36
+ return
37
+
38
+ return self.driver.warning(message, *args, **kwargs)
39
+
40
+ def notice(self, message, *args, **kwargs):
41
+ if not self.driver.should_run('notice', self.max_level):
42
+ return
43
+
44
+ return self.driver.notice(message, *args, **kwargs)
45
+
46
+ def info(self, message, *args, **kwargs):
47
+ if not self.driver.should_run('info', self.max_level):
48
+ return
49
+
50
+ return self.driver.info(message, *args, **kwargs)
51
+
52
+ def debug(self, message, *args, **kwargs):
53
+ if not self.driver.should_run('debug', self.max_level):
54
+ return
55
+
56
+ return self.driver.debug(message, *args, **kwargs)
57
+
58
+ def channel(self, channel):
59
+ from ..ChannelFactory import ChannelFactory
60
+ return ChannelFactory().make(channel)()
@@ -0,0 +1,17 @@
1
+ from ..factory import DriverFactory
2
+ from fastapi_startkit.facades import Config
3
+ from fastapi_startkit.utils.filesystem import make_directory
4
+ import os
5
+ from .BaseChannel import BaseChannel
6
+
7
+ class DailyChannel(BaseChannel):
8
+
9
+ def __init__(self, driver=None, path=None):
10
+ path = path or Config.get('logging.channels.daily.path')
11
+ path = os.path.join(path, self.get_time().to_date_string() + '.log')
12
+ self.max_level = Config.get('logging.channels.daily.level')
13
+ make_directory(path)
14
+ self.driver = DriverFactory.make(driver or Config.get('logging.channels.daily.driver'))(path=path, max_level=self.max_level)
15
+
16
+ def debug(self, message, *args, **kwargs):
17
+ return self.driver.debug(message, *args, **kwargs)
@@ -0,0 +1,64 @@
1
+ import pendulum
2
+ from fastapi_startkit.facades import Config
3
+
4
+ class MultiBaseChannel:
5
+
6
+ def get_time(self):
7
+ return pendulum.now().in_tz(Config.get('logging.channels.timezone', 'UTC'))
8
+
9
+ def emergency(self, message, *args, **kwargs):
10
+ for channel in self.channels:
11
+ if not channel.driver.should_run('emergency', channel.max_level):
12
+ continue
13
+
14
+ channel.driver.emergency(message, *args, **kwargs)
15
+
16
+ def alert(self, message, *args, **kwargs):
17
+ for channel in self.channels:
18
+ if not channel.driver.should_run('alert', channel.max_level):
19
+ continue
20
+
21
+ channel.driver.alert(message, *args, **kwargs)
22
+
23
+ def critical(self, message, *args, **kwargs):
24
+ for channel in self.channels:
25
+ if not channel.driver.should_run('critical', channel.max_level):
26
+ continue
27
+
28
+ channel.driver.critical(message, *args, **kwargs)
29
+
30
+ def error(self, message, *args, **kwargs):
31
+ for channel in self.channels:
32
+ if not channel.driver.should_run('error', channel.max_level):
33
+ continue
34
+
35
+ channel.driver.error(message, *args, **kwargs)
36
+
37
+ def warning(self, message, *args, **kwargs):
38
+ for channel in self.channels:
39
+ if not channel.driver.should_run('warning', channel.max_level):
40
+ continue
41
+
42
+ channel.driver.warning(message, *args, **kwargs)
43
+
44
+ def notice(self, message, *args, **kwargs):
45
+ for channel in self.channels:
46
+ if not channel.driver.should_run('notice', channel.max_level):
47
+ continue
48
+
49
+ channel.driver.notice(message, *args, **kwargs)
50
+
51
+ def info(self, message, *args, **kwargs):
52
+ for channel in self.channels:
53
+ if not channel.driver.should_run('info', channel.max_level):
54
+ continue
55
+
56
+ channel.driver.info(message, *args, **kwargs)
57
+
58
+ def debug(self, message, *args, **kwargs):
59
+ for channel in self.channels:
60
+ if not channel.driver.should_run('debug', channel.max_level):
61
+ continue
62
+
63
+ channel.driver.debug(message, *args, **kwargs)
64
+
@@ -0,0 +1,14 @@
1
+ from ..factory import DriverFactory
2
+ from fastapi_startkit.facades import Config
3
+ from fastapi_startkit.utils.filesystem import make_directory
4
+ import os
5
+ import pendulum
6
+ from .BaseChannel import BaseChannel
7
+
8
+
9
+ class SingleChannel(BaseChannel):
10
+ def __init__(self, driver=None, path=None):
11
+ path = path or Config.get('logging.channels.single.path')
12
+ make_directory(path)
13
+ self.max_level = Config.get('logging.channels.single.level')
14
+ self.driver = DriverFactory.make(driver or Config.get('logging.channels.single.driver'))(path=path, max_level=self.max_level)
@@ -0,0 +1,19 @@
1
+
2
+ from ..factory import DriverFactory
3
+ from fastapi_startkit.facades import Config
4
+ import os
5
+ import pendulum
6
+ from .BaseChannel import BaseChannel
7
+
8
+ class SlackChannel(BaseChannel):
9
+
10
+ def __init__(self, driver=None, path=None):
11
+ token = Config.get('logging.channels.slack.token')
12
+ channel = Config.get('logging.channels.slack.channel')
13
+ emoji = Config.get('logging.channels.slack.emoji')
14
+ username = Config.get('logging.channels.slack.username')
15
+ self.max_level = Config.get('logging.channels.slack.level')
16
+ self.driver = DriverFactory.make(driver or Config.get('logging.channels.slack.driver'))(emoji=emoji, username=username, token=token, channel=channel)
17
+
18
+ def debug(self, message, *args, **kwargs):
19
+ return self.driver.debug(message, *args, **kwargs)
@@ -0,0 +1,30 @@
1
+ from ..factory import DriverFactory
2
+ from fastapi_startkit.facades import Config
3
+ import os
4
+ import pendulum
5
+ from .MultiBaseChannel import MultiBaseChannel
6
+
7
+ class StackChannel(MultiBaseChannel):
8
+
9
+ def __init__(self, channels=[]):
10
+ channels = channels or Config.get('logging.channels.stack.channels')
11
+ from ..ChannelFactory import ChannelFactory
12
+ self.channels = []
13
+ for channel in channels:
14
+ channel = ChannelFactory.make(channel)()
15
+ self.channels.append(channel)
16
+
17
+ def debug(self, message, *args, **kwargs):
18
+ for channel in self.channels:
19
+ if not channel.driver.should_run('debug', channel.max_level):
20
+ continue
21
+
22
+ channel.driver.debug(message, *args, **kwargs)
23
+
24
+ def notice(self, message, *args, **kwargs):
25
+ for channel in self.channels:
26
+ if not channel.driver.should_run('notice', channel.max_level):
27
+ continue
28
+
29
+ channel.driver.notice(message, *args, **kwargs)
30
+
@@ -0,0 +1,14 @@
1
+ from ..factory import DriverFactory
2
+ from fastapi_startkit.facades import Config
3
+ from fastapi_startkit.utils.filesystem import make_directory
4
+ import os
5
+ import pendulum
6
+ from .BaseChannel import BaseChannel
7
+
8
+ class SyslogChannel(BaseChannel):
9
+
10
+ def __init__(self, driver=None, path=None):
11
+ path = path or Config.get('logging.channels.syslog.path')
12
+ make_directory(path)
13
+ self.max_level = Config.get('logging.channels.syslog.level')
14
+ self.driver = DriverFactory.make(driver or Config.get('logging.channels.syslog.driver'))(path=path, max_level=self.max_level)
@@ -0,0 +1,14 @@
1
+ import os
2
+
3
+ import pendulum
4
+ from fastapi_startkit.facades import Config
5
+
6
+ from ..factory import DriverFactory
7
+ from ..channels.BaseChannel import BaseChannel
8
+
9
+
10
+ class TerminalChannel(BaseChannel):
11
+
12
+ def __init__(self, driver=None, path=None):
13
+ self.max_level = Config.get('logging.channels.terminal.level', 'debug')
14
+ self.driver = DriverFactory.make(driver or Config.get('logging.channels.terminal.driver'))(path=path, max_level=self.max_level)
@@ -0,0 +1,8 @@
1
+ from .SingleChannel import SingleChannel
2
+ from .TerminalChannel import TerminalChannel
3
+ from .DailyChannel import DailyChannel
4
+ from .SlackChannel import SlackChannel
5
+ from .SyslogChannel import SyslogChannel
6
+ from .StackChannel import StackChannel
7
+ from .BaseChannel import BaseChannel
8
+ from .MultiBaseChannel import MultiBaseChannel
@@ -0,0 +1,46 @@
1
+ """ Logging Settings """
2
+
3
+ import os
4
+ from fastapi_startkit.environment.environment import env
5
+
6
+ """Default Channel
7
+ """
8
+
9
+ DEFAULT=env('LOG_CHANNEL', 'single')
10
+
11
+ """Channels
12
+ """
13
+ CHANNELS = {
14
+ 'timezone': env('LOG_TIMEZONE', 'UTC'),
15
+ 'single': {
16
+ 'driver': 'single',
17
+ 'level': 'debug',
18
+ 'path': 'storage/logs/single.log'
19
+ },
20
+ 'stack': {
21
+ 'driver': 'stack',
22
+ 'channels': ['single', 'daily', 'slack', 'terminal']
23
+ },
24
+ 'daily': {
25
+ 'driver': 'daily',
26
+ 'level': 'debug',
27
+ 'path': 'storage/logs'
28
+ },
29
+ 'terminal': {
30
+ 'driver': 'terminal',
31
+ 'level': 'info',
32
+ },
33
+ 'slack': {
34
+ 'driver': 'slack',
35
+ 'channel': '#bot',
36
+ 'emoji': ':warning:',
37
+ 'username': 'Logging Bot',
38
+ 'token': env('SLACK_TOKEN', None),
39
+ 'level': 'debug'
40
+ },
41
+ 'syslog': {
42
+ 'driver': 'syslog',
43
+ 'path': '/var/run/syslog',
44
+ 'level': 'debug'
45
+ }
46
+ }
@@ -0,0 +1,25 @@
1
+ import pendulum
2
+ from fastapi_startkit.facades import Config
3
+
4
+ class BaseDriver:
5
+
6
+ levels = [
7
+ 'emergency',
8
+ 'alert',
9
+ 'critical',
10
+ 'error',
11
+ 'warning',
12
+ 'notice',
13
+ 'info',
14
+ 'debug',
15
+ ]
16
+
17
+ def get_time(self):
18
+ return pendulum.now().in_tz(Config.get('logging.channels.timezone', 'UTC'))
19
+
20
+ def should_run(self, level, max_level):
21
+ if not max_level:
22
+ return True
23
+
24
+ return self.levels.index(level) <= self.levels.index(max_level)
25
+
@@ -0,0 +1,84 @@
1
+ import logging
2
+ import os
3
+ from .BaseDriver import BaseDriver
4
+
5
+ class LogSingleDriver(BaseDriver):
6
+
7
+ def __init__(self, *args, **kwargs):
8
+ self.max_level = kwargs.get('max_level')
9
+ self.path = kwargs.get('path')
10
+ self.log = logging.getLogger('root')
11
+
12
+ handler = logging.FileHandler(self.path, 'a')
13
+ formatter = logging.Formatter('{} - %(levelname)s - %(message)s'.format(self.get_time().to_datetime_string()))
14
+
15
+ handler.setFormatter(formatter)
16
+ self.log.addHandler(handler)
17
+
18
+ def change_format(self, changed_format):
19
+ for hdlr in self.log.handlers[:]: # remove all old handlers
20
+ self.log.removeHandler(hdlr)
21
+
22
+ handler = logging.FileHandler(self.path, 'a')
23
+ formatter = logging.Formatter(changed_format)
24
+
25
+ handler.setFormatter(formatter)
26
+
27
+ self.log.addHandler(handler)
28
+
29
+ def emergency(self, message, *args, **kwargs):
30
+ self.log.setLevel(logging.CRITICAL)
31
+ self.change_format('{} - {} - %(message)s'.format(
32
+ self.get_time().to_datetime_string(),
33
+ 'EMERGENCY'))
34
+ return self.log.critical(message)
35
+
36
+ def alert(self, message, *args, **kwargs):
37
+ self.log.setLevel(logging.CRITICAL)
38
+ self.change_format('{} - {} - %(message)s'.format(
39
+ self.get_time().to_datetime_string(),
40
+ 'ALERT'))
41
+ return self.log.critical(message)
42
+
43
+ def critical(self, message, *args, **kwargs):
44
+ self.log.setLevel(logging.CRITICAL)
45
+ self.change_format('{} - {} - %(message)s'.format(
46
+ self.get_time().to_datetime_string(),
47
+ 'CRITICAL'))
48
+ return self.log.critical(message)
49
+
50
+ def error(self, message, *args, **kwargs):
51
+ self.log.setLevel(logging.ERROR)
52
+ self.change_format('{} - {} - %(message)s'.format(
53
+ self.get_time().to_datetime_string(),
54
+ 'ERROR'))
55
+ return self.log.error(message)
56
+
57
+ def warning(self, message, *args, **kwargs):
58
+ self.log.setLevel(logging.WARNING)
59
+ self.change_format('{} - {} - %(message)s'.format(
60
+ self.get_time().to_datetime_string(),
61
+ 'WARNING'))
62
+ return self.log.warning(message)
63
+
64
+ def notice(self, message, *args, **kwargs):
65
+ self.log.setLevel(logging.INFO)
66
+ self.change_format('{} - {} - %(message)s'.format(
67
+ self.get_time().to_datetime_string(),
68
+ 'NOTICE'))
69
+ return self.log.info(message)
70
+
71
+ def info(self, message, *args, **kwargs):
72
+ self.log.setLevel(logging.INFO)
73
+ self.change_format('{} - {} - %(message)s'.format(
74
+ self.get_time().to_datetime_string(),
75
+ 'INFO'))
76
+ return self.log.info(message)
77
+
78
+ def debug(self, message, *args, **kwargs):
79
+ self.log.setLevel(logging.DEBUG)
80
+ self.change_format('{} - {} - %(message)s'.format(
81
+ self.get_time().to_datetime_string(),
82
+ 'DEBUG'))
83
+ return self.log.debug(message)
84
+
@@ -0,0 +1,94 @@
1
+ import os
2
+ from .BaseDriver import BaseDriver
3
+ import requests
4
+
5
+ class LogSlackDriver(BaseDriver):
6
+
7
+ def __init__(self, *args, **kwargs):
8
+ self.slack_url = 'https://slack.com/api/chat.postMessage'
9
+ self.token = kwargs.get('token')
10
+ self.channel = kwargs.get('channel')
11
+ self.emoji = kwargs.get('emoji', ':warning:')
12
+ self.username = kwargs.get('username')
13
+
14
+ def emergency(self, message, *args, **kwargs):
15
+ self.send(
16
+ self.get_format(message, 'EMERGENCY')
17
+ )
18
+
19
+ def alert(self, message, *args, **kwargs):
20
+ self.send(
21
+ self.get_format(message, 'ALERT')
22
+ )
23
+
24
+ def critical(self, message, *args, **kwargs):
25
+ self.send(
26
+ self.get_format(message, 'CRITICAL')
27
+ )
28
+
29
+ def error(self, message, *args, **kwargs):
30
+ self.send(
31
+ self.get_format(message, 'ERROR')
32
+ )
33
+
34
+ def warning(self, message, *args, **kwargs):
35
+ self.send(
36
+ self.get_format(message, 'WARNING')
37
+ )
38
+
39
+ def notice(self, message, *args, **kwargs):
40
+ self.send(
41
+ self.get_format(message, 'NOTICE')
42
+ )
43
+
44
+ def info(self, message, *args, **kwargs):
45
+ self.send(
46
+ self.get_format(message, 'INFO')
47
+ )
48
+
49
+ def debug(self, message, *args, **kwargs):
50
+ self.send(
51
+ self.get_format(message, 'DEBUG')
52
+ )
53
+
54
+ def get_format(self, message, level):
55
+ return "{time} - {level} - {message}".format(
56
+ time=self.get_time().to_datetime_string(),
57
+ message=message,
58
+ level=level
59
+ )
60
+
61
+ def send(self, message):
62
+ requests.post(self.slack_url, {
63
+ 'token': self.token,
64
+ 'channel': self.find_channel(self.channel),
65
+ 'text': message,
66
+ 'username': self.username,
67
+ 'icon_emoji': self.emoji,
68
+ 'as_user': False,
69
+ 'reply_broadcast': True,
70
+ 'unfurl_links': True,
71
+ 'unfurl_media': True,
72
+ })
73
+
74
+ def find_channel(self, name):
75
+ """Calls the Slack API to find the channel name.
76
+ This is so we do not have to specify the channel ID's. Slack requires channel ID's
77
+ to be used.
78
+ Arguments:
79
+ name {string} -- The channel name to find.
80
+ Raises:
81
+ SlackChannelNotFound -- Thrown if the channel name is not found.
82
+ Returns:
83
+ self
84
+ """
85
+ response = requests.post('https://slack.com/api/channels.list', {
86
+ 'token': self.token
87
+ })
88
+
89
+ for channel in response.json()['channels']:
90
+ if channel['name'] == name.split('#')[1]:
91
+ return channel['id']
92
+
93
+ raise SlackChannelNotFound(
94
+ 'Could not find the {} channel'.format(name))
@@ -0,0 +1,48 @@
1
+ from .BaseDriver import BaseDriver
2
+ import logging
3
+ import logging.handlers
4
+
5
+ class LogSyslogDriver(BaseDriver):
6
+
7
+ def __init__(self, *args, **kwargs):
8
+ self.log = logging.getLogger('root')
9
+ path = kwargs.get('path')
10
+
11
+ handler = logging.handlers.SysLogHandler(address = path)
12
+
13
+ formatter = logging.Formatter('{} - %(levelname)s - %(message)s'.format(self.get_time().to_datetime_string()))
14
+ handler.setFormatter(formatter)
15
+
16
+ self.log.addHandler(handler)
17
+
18
+ def emergency(self, message):
19
+ self.log.setLevel(logging.CRITICAL)
20
+ return self.log.critical(message)
21
+
22
+ def alert(self, message):
23
+ self.log.setLevel(logging.CRITICAL)
24
+ return self.log.critical(message)
25
+
26
+ def critical(self, message):
27
+ self.log.setLevel(logging.CRITICAL)
28
+ return self.log.critical(message)
29
+
30
+ def error(self, message):
31
+ self.log.setLevel(logging.ERROR)
32
+ return self.log.error(message)
33
+
34
+ def warning(self, message):
35
+ self.log.setLevel(logging.WARNING)
36
+ return self.log.warning(message)
37
+
38
+ def notice(self, message):
39
+ self.log.setLevel(logging.NOTICE)
40
+ return self.log.info(message)
41
+
42
+ def info(self, message):
43
+ self.log.setLevel(logging.INFO)
44
+ return self.log.info(message)
45
+
46
+ def debug(self, message):
47
+ self.log.setLevel(logging.DEBUG)
48
+ return self.log.debug(message)
@@ -0,0 +1,60 @@
1
+ # from logging import Logger
2
+ import os
3
+
4
+ from fastapi_startkit.facades import Config
5
+ from fastapi_startkit.utils.console import HasColoredOutput
6
+
7
+ from .BaseDriver import BaseDriver
8
+
9
+
10
+ class LogTerminalDriver(BaseDriver, HasColoredOutput):
11
+
12
+ def __init__(self, *args, **kwargs):
13
+ pass
14
+
15
+ def emergency(self, message):
16
+ super().warning(
17
+ self.get_format(message, 'EMERGENCY')
18
+ )
19
+
20
+ def alert(self, message):
21
+ super().warning(
22
+ self.get_format(message, 'ALERT')
23
+ )
24
+
25
+ def critical(self, message):
26
+ super().warning(
27
+ self.get_format(message, 'CRITICAL')
28
+ )
29
+
30
+ def error(self, message):
31
+ super().warning(
32
+ self.get_format(message, 'ERROR')
33
+ )
34
+
35
+ def warning(self, message):
36
+ super().warning(
37
+ self.get_format(message, 'WARNING')
38
+ )
39
+
40
+ def notice(self, message):
41
+ super().warning(
42
+ self.get_format(message, 'NOTICE')
43
+ )
44
+
45
+ def info(self, message):
46
+ super().warning(
47
+ self.get_format(message, 'INFO')
48
+ )
49
+
50
+ def debug(self, message):
51
+ super().warning(
52
+ self.get_format(message, 'DEBUG')
53
+ )
54
+
55
+ def get_format(self, message, level):
56
+ return '{time} - {level} - {message}'.format(
57
+ time=self.get_time().to_datetime_string(),
58
+ level=level,
59
+ message=message
60
+ )
@@ -0,0 +1,5 @@
1
+ from .LogSingleDriver import LogSingleDriver
2
+ from .LogTerminalDriver import LogTerminalDriver
3
+ from .LogSlackDriver import LogSlackDriver
4
+ from .LogSyslogDriver import LogSyslogDriver
5
+ from .BaseDriver import BaseDriver
@@ -0,0 +1,15 @@
1
+ from .drivers import LogSingleDriver, LogTerminalDriver, LogSlackDriver, LogSyslogDriver
2
+ class DriverFactory:
3
+
4
+ drivers = {
5
+ 'single': LogSingleDriver,
6
+ 'daily': LogSingleDriver,
7
+ 'slack': LogSlackDriver,
8
+ 'syslog': LogSyslogDriver,
9
+ 'terminal': LogTerminalDriver
10
+ }
11
+
12
+ @classmethod
13
+ def make(cls, driver):
14
+ return cls.drivers.get(driver)
15
+
@@ -0,0 +1,15 @@
1
+ from .Logger import Logger
2
+
3
+ class LoggerExceptionListener:
4
+
5
+ listens = ['*']
6
+
7
+ def __init__(self, logger: Logger):
8
+ self.logger = logger
9
+
10
+ def handle(self, exception, file, line):
11
+ self.logger.error("{} in {} on line {}".format(
12
+ exception.__class__.__name__,
13
+ file,
14
+ line
15
+ ))
@@ -0,0 +1,11 @@
1
+ class LoggingManager:
2
+
3
+ # config = 'LoggingConfig'
4
+ # driver_prefix = 'Logging'
5
+
6
+ def __init__(self, channel_factory=None, driver_factory=None):
7
+ self.channel_factory = channel_factory
8
+ self.driver_factory = driver_factory
9
+
10
+ def channel(self, channel):
11
+ return self.channel_factory.make(channel)()
@@ -0,0 +1 @@
1
+ from .LoggingManager import LoggingManager
@@ -0,0 +1,25 @@
1
+ from fastapi_startkit.providers import Provider
2
+
3
+ from ..ChannelFactory import ChannelFactory
4
+ from ..Logger import Logger
5
+ from ..factory import DriverFactory
6
+ from ..listeners import LoggerExceptionListener
7
+ from ..managers import LoggingManager
8
+
9
+
10
+ class LoggingProvider(Provider):
11
+ def register(self):
12
+ self.application.bind('LogChannelFactory', ChannelFactory)
13
+ self.application.bind('LogDriverFactory', DriverFactory)
14
+ self.application.bind('LoggingManager', LoggingManager(ChannelFactory, DriverFactory))
15
+ self.application.simple(LoggerExceptionListener)
16
+
17
+ def boot(self):
18
+ config = self.application.make('config')
19
+ if not config.get('logging.default'):
20
+ return
21
+ logger = self.application.make('LoggingManager')
22
+ channel = logger.channel(config.get('logging.default'))
23
+
24
+ self.application.bind('logger', channel)
25
+ self.application.swap(Logger, channel)
@@ -0,0 +1 @@
1
+ from .LoggingProvider import LoggingProvider
@@ -0,0 +1,3 @@
1
+ from .Provider import Provider
2
+
3
+ __all__ = ["Provider"]
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "fastapi-startkit"
3
- version = "0.1.0"
4
- description = "Core Masonite components (Container, Config, Loader)"
3
+ version = "0.1.2"
4
+ description = "Fastapi_Startkit components"
5
5
  authors = [
6
6
  {name = "Bedram Tamang", email = "tmgbedu@gmail.com"}
7
7
  ]
@@ -1,13 +0,0 @@
1
- from .Provider import Provider
2
- from ..configuration import Configuration
3
- import os
4
-
5
- class ConfigurationProvider(Provider):
6
- def register(self):
7
- self.application.bind('config.location', os.path.join(self.application.base_path, "config"))
8
- configuration = Configuration(self.application)
9
- configuration.load()
10
- self.application.bind("config", configuration)
11
-
12
- def boot(self):
13
- pass
@@ -1,4 +0,0 @@
1
- from .Provider import Provider
2
- from .ConfigurationProvider import ConfigurationProvider
3
-
4
- __all__ = ["Provider", "ConfigurationProvider"]