-
Notifications
You must be signed in to change notification settings - Fork 4
Full refactoring. #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
8ce347f
Refactor bootstrapper base class and add sentry instrument. tests are…
insani7y 6916196
Add opentelemetry]
insani7y 8a95047
Continue implementing opentelemetry instrument
insani7y a980598
Continue implementing opentelemetry instrument
insani7y c4deff5
Continue implementing opentelemetry instrument
insani7y c66448e
Continue implementing opentelemetry instrument
insani7y 105acf1
Continue implementing opentelemetry instrument
insani7y b4304d2
Continue implementing opentelemetry instrument
insani7y d318c27
Add logging instrument
insani7y 9ce839c
Add logging instrument
insani7y fc1863b
Add logging instrument
insani7y 5a81e07
Add logging instrument
insani7y 70ecb38
Add prometheus instrument
insani7y 69b8659
Small interface improvments
insani7y 7e598a0
Small interface improvments
insani7y 6e7c76a
Add teardown to litestar bootstrapper
insani7y 61a2efc
Highly arguable decision
insani7y 954d2dd
Highly arguable decision
insani7y b4b4f8e
Separate instruments and bootstrapper
insani7y 305aff4
Make instrument box private
insani7y 9814971
Make use_instrument typed
insani7y 82ce504
Implement before and after hooks
insani7y dbdfcfb
Make is_ready a function
insani7y c4effbb
Make settings per framework
insani7y 2b3e603
Make settings per framework
insani7y 3eba74c
Add tests to some instruments
insani7y 33fc201
Add tests to some instruments
insani7y 7fb4f69
Add tests to some instruments
insani7y ad2f37b
Add tests to some instruments
insani7y f469d6c
Add tests to some instruments
insani7y 5a53da4
Trigger codecov
insani7y 40f161d
Try trigger codecov
insani7y 7286144
Try trigger codecov
insani7y b6e0495
Try trigger codecov
insani7y 80c4f71
Try trigger codecov
insani7y 11cbca0
Fix comments
insani7y 9b38a52
Fix comments
insani7y d090096
Add some helpers tests
insani7y a9e003a
Add some helpers tests
insani7y 98732dd
Small changes
insani7y c49365c
Added tests for everythin
insani7y 88a5436
Update packages
insani7y b8b4040
Start writing docs
insani7y 31080a6
Logo draft
1120db7
Logo update
6a8e04a
Merge branch 'main' into feature/full-refactor
insani7y File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,51 @@ | ||
# microbootstrap | ||
This package helps you create application with all necessary instruments already set up | ||
|
||
<img src="./logo.svg" width="300" /> | ||
- `sentry` | ||
- `prometheus` | ||
- `opentelemetry` | ||
- `logging` | ||
|
||
```python | ||
# settings.py | ||
from microbootstrap import LitestarSettings | ||
|
||
To be done... | ||
|
||
class YourSettings(LitestarSettings): | ||
# Your settings stored here | ||
|
||
|
||
settings = YourSettings() | ||
|
||
|
||
# application.py | ||
import litestar | ||
from microbootstrap.bootstrappers.litestar import LitestarBootstrapper | ||
|
||
from your_application.settings import settings | ||
|
||
# Litestar application with all instruments ready for use! | ||
application: litestar.Litestar = LitestarBootstrapper(settings).bootstrap() | ||
``` | ||
|
||
Interested? Let's jump right into it ⚡ | ||
|
||
## Installation | ||
|
||
You can install `microbootstrap` with extra for framework you need. | ||
|
||
poetry: | ||
|
||
```bash | ||
$ poetry add microbootstrap -E litestar | ||
# or | ||
$ poetry add microbootstrap -E fastapi | ||
``` | ||
|
||
pip: | ||
|
||
```bash | ||
$ pip install microbootsrap[litestar] | ||
# or | ||
$ pip install microbootsrap[fastapi] | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from microbootstrap.instruments.logging_instrument import LoggingConfig | ||
from microbootstrap.instruments.opentelemetry_instrument import OpentelemetryConfig | ||
from microbootstrap.instruments.prometheus_instrument import PrometheusConfig | ||
from microbootstrap.instruments.sentry_instrument import SentryConfig | ||
from microbootstrap.settings import LitestarSettings | ||
|
||
|
||
__all__ = ( | ||
"SentryConfig", | ||
"OpentelemetryConfig", | ||
"PrometheusConfig", | ||
"LoggingConfig", | ||
"LitestarBootstrapper", | ||
"LitestarSettings", | ||
) |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from __future__ import annotations | ||
import abc | ||
import typing | ||
|
||
import typing_extensions | ||
|
||
from microbootstrap.helpers import dataclass_to_dict_no_defaults, merge_dataclasses_configs, merge_dict_configs | ||
from microbootstrap.instruments.instrument_box import InstrumentBox | ||
from microbootstrap.settings import SettingsT | ||
|
||
|
||
if typing.TYPE_CHECKING: | ||
from _typeshed import DataclassInstance | ||
|
||
from microbootstrap.instruments.base import Instrument, InstrumentConfigT | ||
|
||
|
||
ApplicationT = typing.TypeVar("ApplicationT") | ||
DataclassT = typing.TypeVar("DataclassT", bound="DataclassInstance") | ||
|
||
|
||
class ApplicationBootstrapper(abc.ABC, typing.Generic[SettingsT, ApplicationT, DataclassT]): | ||
application_type: type[ApplicationT] | ||
application_config: DataclassT | ||
__instrument_box: InstrumentBox = InstrumentBox() | ||
|
||
def __init__(self, settings: SettingsT) -> None: | ||
self.settings = settings | ||
self.__instrument_box.initialize(self.settings) | ||
|
||
def configure_application( | ||
self: typing_extensions.Self, | ||
application_config: DataclassT, | ||
) -> typing_extensions.Self: | ||
self.application_config = merge_dataclasses_configs(self.application_config, application_config) | ||
return self | ||
|
||
def configure_instrument( | ||
self: typing_extensions.Self, | ||
instrument_config: InstrumentConfigT, | ||
) -> typing_extensions.Self: | ||
self.__instrument_box.configure_instrument(instrument_config) | ||
return self | ||
|
||
@classmethod | ||
def use_instrument( | ||
cls, | ||
) -> typing.Callable[ | ||
[type[Instrument[InstrumentConfigT]]], | ||
type[Instrument[InstrumentConfigT]], | ||
]: | ||
return cls.__instrument_box.extend_instruments | ||
|
||
def bootstrap(self: typing_extensions.Self) -> ApplicationT: | ||
resulting_application_config = dataclass_to_dict_no_defaults(self.application_config) | ||
for instrument in self.__instrument_box.instruments: | ||
resulting_application_config = merge_dict_configs( | ||
resulting_application_config, | ||
instrument.bootstrap(), | ||
) | ||
|
||
application = self.application_type( | ||
**merge_dict_configs(resulting_application_config, self.bootstrap_before()), | ||
) | ||
|
||
for instrument in self.__instrument_box.instruments: | ||
application = instrument.bootstrap_after(application) | ||
return self.bootstrap_after(application) | ||
|
||
def bootstrap_before(self: typing_extensions.Self) -> dict[str, typing.Any]: | ||
"""Add some framework-related parameters to final bootstrap result before application creation.""" | ||
return {} | ||
|
||
def bootstrap_after(self: typing_extensions.Self, application: ApplicationT) -> ApplicationT: | ||
"""Add some framework-related parameters to final bootstrap result after application creation.""" | ||
return application | ||
|
||
def teardown(self: typing_extensions.Self) -> None: | ||
for instrument in self.__instrument_box.instruments: | ||
instrument.teardown() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
from __future__ import annotations | ||
import typing | ||
|
||
import litestar | ||
import litestar.types | ||
import sentry_sdk | ||
import typing_extensions | ||
from litestar import status_codes | ||
from litestar.config.app import AppConfig as LitestarConfig | ||
from litestar.contrib.opentelemetry.config import OpenTelemetryConfig as LitestarOpentelemetryConfig | ||
from litestar.contrib.prometheus import PrometheusConfig as LitestarPrometheusConfig | ||
from litestar.contrib.prometheus import PrometheusController | ||
from litestar.exceptions.http_exceptions import HTTPException | ||
|
||
from microbootstrap.bootstrappers.base import ApplicationBootstrapper | ||
from microbootstrap.instruments.logging_instrument import LoggingInstrument | ||
from microbootstrap.instruments.opentelemetry_instrument import OpentelemetryInstrument | ||
from microbootstrap.instruments.prometheus_instrument import PrometheusInstrument | ||
from microbootstrap.instruments.sentry_instrument import SentryInstrument | ||
from microbootstrap.middlewares.litestar import build_litestar_logging_middleware | ||
from microbootstrap.settings import LitestarSettings | ||
|
||
|
||
class LitestarBootstrapper( | ||
ApplicationBootstrapper[LitestarSettings, litestar.Litestar, LitestarConfig], | ||
): | ||
application_config = LitestarConfig() | ||
application_type = litestar.Litestar | ||
|
||
def bootstrap_before(self: typing_extensions.Self) -> dict[str, typing.Any]: | ||
return {"debug": self.settings.service_debug, "on_shutdown": [self.teardown]} | ||
|
||
|
||
@LitestarBootstrapper.use_instrument() | ||
class LitestarSentryInstrument(SentryInstrument): | ||
@staticmethod | ||
async def sentry_exception_catcher_hook( | ||
exception: Exception, | ||
_request_scope: litestar.types.Scope, | ||
) -> None: | ||
if ( | ||
not isinstance(exception, HTTPException) | ||
or exception.status_code >= status_codes.HTTP_500_INTERNAL_SERVER_ERROR | ||
): | ||
sentry_sdk.capture_exception(exception) | ||
|
||
def bootstrap_before(self) -> dict[str, typing.Any]: | ||
return {"after_exception": [self.sentry_exception_catcher_hook]} | ||
|
||
|
||
@LitestarBootstrapper.use_instrument() | ||
class LitetstarOpentelemetryInstrument(OpentelemetryInstrument): | ||
def bootstrap_before(self) -> dict[str, typing.Any]: | ||
return { | ||
"middleware": [ | ||
LitestarOpentelemetryConfig( | ||
tracer_provider=self.tracer_provider, | ||
exclude=self.instrument_config.opentelemetry_exclude_urls, | ||
).middleware, | ||
], | ||
} | ||
|
||
|
||
@LitestarBootstrapper.use_instrument() | ||
class LitestarLoggingInstrument(LoggingInstrument): | ||
def bootstrap_before(self) -> dict[str, typing.Any]: | ||
return {"middleware": [build_litestar_logging_middleware(self.instrument_config.logging_exclude_endpoints)]} | ||
|
||
|
||
@LitestarBootstrapper.use_instrument() | ||
class LitestarPrometheusInstrument(PrometheusInstrument): | ||
def bootstrap_before(self) -> dict[str, typing.Any]: | ||
class LitestarPrometheusController(PrometheusController): | ||
path = self.instrument_config.prometheus_metrics_path | ||
openmetrics_format = True | ||
|
||
litestar_prometheus_config: typing.Final = LitestarPrometheusConfig( | ||
app_name=self.instrument_config.service_name, | ||
**self.instrument_config.prometheus_additional_params, | ||
) | ||
|
||
return {"route_handlers": [LitestarPrometheusController], "middleware": [litestar_prometheus_config.middleware]} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class MicroBootstrapBaseError(Exception): | ||
"""Base for all exceptions.""" | ||
|
||
|
||
class ConfigMergeError(MicroBootstrapBaseError): | ||
"""Raises when it's impossible to merge configs due to type mismatch.""" | ||
|
||
|
||
class MissingInstrumentError(MicroBootstrapBaseError): | ||
"""Raises when attempting to configure instrument, that is not supported yet.""" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.