-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1355581
Showing
16 changed files
with
445 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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,49 @@ | ||
name: main | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: {} | ||
|
||
concurrency: | ||
group: ${{ github.head_ref || github.run_id }} | ||
cancel-in-progress: true | ||
|
||
jobs: | ||
lint: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-python@v4 | ||
with: | ||
python-version: "3.10" | ||
- uses: extractions/setup-just@v2 | ||
- run: curl -LsSf https://astral.sh/uv/install.sh | sh | ||
- run: just install lint-ci | ||
|
||
pytest: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
python-version: | ||
- "3.10" | ||
- "3.11" | ||
- "3.12" | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- uses: extractions/setup-just@v2 | ||
- run: curl -LsSf https://astral.sh/uv/install.sh | sh | ||
- run: just install test . --cov=. --cov-report xml | ||
- name: Upload coverage to Codecov | ||
uses: codecov/[email protected] | ||
env: | ||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||
with: | ||
files: ./coverage.xml | ||
flags: unittests | ||
name: codecov-${{ matrix.python-version }} |
This file contains 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,24 @@ | ||
name: Publish Package | ||
|
||
on: | ||
release: | ||
types: | ||
- published | ||
|
||
jobs: | ||
publish: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: "3.12" | ||
- uses: actions/cache@v4 | ||
with: | ||
path: ~/.cache/uv | ||
key: publish-${{ hashFiles('pyproject.toml') }} | ||
- uses: extractions/setup-just@v2 | ||
- run: curl -LsSf https://astral.sh/uv/install.sh | sh | ||
- run: just publish | ||
env: | ||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} |
This file contains 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,22 @@ | ||
# Generic things | ||
*.pyc | ||
*~ | ||
__pycache__/* | ||
*.swp | ||
*.sqlite3 | ||
*.map | ||
.vscode | ||
.idea | ||
.DS_Store | ||
.env | ||
.mypy_cache | ||
.pytest_cache | ||
.ruff_cache | ||
.coverage | ||
htmlcov/ | ||
coverage.xml | ||
pytest.xml | ||
dist/ | ||
.python-version | ||
.venv | ||
uv.lock |
This file contains 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,24 @@ | ||
default: install lint test | ||
|
||
install: | ||
uv lock --upgrade | ||
uv sync --all-extras --frozen | ||
|
||
lint: | ||
uv run ruff format . | ||
uv run ruff check . --fix | ||
uv run mypy . | ||
|
||
lint-ci: | ||
uv run ruff format . --check | ||
uv run ruff check . --no-fix | ||
uv run mypy . | ||
|
||
test *args: | ||
uv run pytest {{ args }} | ||
|
||
publish: | ||
rm -rf dist/* | ||
uv tool run --from build python -m build --installer uv | ||
uv tool run twine check dist/* | ||
uv tool run twine upload dist/* --username __token__ --password $PYPI_TOKEN |
This file contains 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,16 @@ | ||
Lite-Bootstrap package | ||
== | ||
[![Test Coverage](https://codecov.io/gh/modern-python/lite-bootstrap/branch/main/graph/badge.svg)](https://codecov.io/gh/modern-python/lite-bootstrap) | ||
[![MyPy Strict](https://img.shields.io/badge/mypy-strict-blue)](https://mypy.readthedocs.io/en/stable/getting_started.html#strict-mode-and-configuration) | ||
[![Supported versions](https://img.shields.io/pypi/pyversions/lite-bootstrap.svg)](https://pypi.python.org/pypi/lite-bootstrap) | ||
[![downloads](https://img.shields.io/pypi/dm/lite-bootstrap.svg)](https://pypistats.org/packages/lite-bootstrap) | ||
[![GitHub stars](https://img.shields.io/github/stars/modern-python/lite-bootstrap)](https://github.com/modern-python/lite-bootstrap/stargazers) | ||
|
||
This package helps to build new microservices | ||
|
||
## Quickstart: | ||
### Installation | ||
|
||
```shell | ||
$ pip install lite-bootstrap | ||
``` |
Empty file.
This file contains 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,34 @@ | ||
import dataclasses | ||
|
||
import fastapi | ||
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor | ||
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware | ||
|
||
from lite_bootstrap.opentelemetry_bootstrap import OpenTelemetryBootstrap | ||
from lite_bootstrap.sentry_bootstrap import SentryBootstrap | ||
|
||
|
||
@dataclasses.dataclass(kw_only=True, slots=True) | ||
class FastAPIBootstrap: | ||
app: fastapi.FastAPI | ||
opentelemetry: OpenTelemetryBootstrap | ||
sentry: SentryBootstrap | ||
opentelemetry_excluded_urls: list[str] = dataclasses.field(default_factory=list) | ||
|
||
def bootstrap_init(self) -> None: | ||
if self.sentry.sentry_dsn: | ||
self.sentry.start_tracing() | ||
self.app.add_middleware(SentryAsgiMiddleware) | ||
|
||
self.opentelemetry.start_tracing() | ||
if self.opentelemetry.endpoint: | ||
FastAPIInstrumentor.instrument_app( | ||
app=self.app, | ||
tracer_provider=self.opentelemetry.tracer_provider, | ||
excluded_urls=",".join(self.opentelemetry_excluded_urls), | ||
) | ||
|
||
def teardown(self) -> None: | ||
self.opentelemetry.teardown() | ||
if self.opentelemetry.endpoint: | ||
FastAPIInstrumentor.uninstrument_app(self.app) |
This file contains 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,46 @@ | ||
import dataclasses | ||
|
||
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter | ||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor # type: ignore[attr-defined] | ||
from opentelemetry.sdk import resources | ||
from opentelemetry.sdk.trace import TracerProvider | ||
from opentelemetry.sdk.trace.export import BatchSpanProcessor | ||
from opentelemetry.trace import set_tracer_provider | ||
|
||
|
||
@dataclasses.dataclass(kw_only=True) | ||
class OpenTelemetryBootstrap: | ||
endpoint: str | ||
service_name: str | ||
instruments: list[BaseInstrumentor] = dataclasses.field(default_factory=list) | ||
tracer_provider: TracerProvider | None = dataclasses.field(init=False) | ||
|
||
def start_tracing(self) -> None: | ||
if not self.endpoint: | ||
return | ||
|
||
self.tracer_provider: TracerProvider = TracerProvider( | ||
resource=resources.Resource.create({resources.SERVICE_NAME: self.service_name}), | ||
) | ||
self.tracer_provider.add_span_processor( | ||
BatchSpanProcessor( | ||
OTLPSpanExporter( | ||
endpoint=self.endpoint, | ||
insecure=True, | ||
), | ||
), | ||
) | ||
|
||
for instrument in self.instruments: | ||
instrument.instrument( | ||
tracer_provider=self.tracer_provider, | ||
) | ||
|
||
set_tracer_provider(self.tracer_provider) | ||
|
||
def teardown(self) -> None: | ||
if not self.endpoint: | ||
return | ||
|
||
for instrument in self.instruments: | ||
instrument.uninstrument() |
Empty file.
This file contains 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,32 @@ | ||
import dataclasses | ||
import typing | ||
|
||
import sentry_sdk | ||
|
||
|
||
@dataclasses.dataclass(kw_only=True) | ||
class SentryBootstrap: | ||
sentry_dsn: str | ||
environment: str | None = None | ||
release: str | None = None | ||
max_breadcrumbs: int = 15 | ||
attach_stacktrace: bool = True | ||
default_integrations: bool = True | ||
sentry_params: dict[str, typing.Any] = dataclasses.field(default_factory=dict) | ||
tags: dict[str, str] | None = None | ||
|
||
def start_tracing(self) -> None: | ||
if not self.sentry_dsn: | ||
return | ||
|
||
sentry_sdk.init( | ||
dsn=self.sentry_dsn, | ||
environment=self.environment, | ||
max_breadcrumbs=self.max_breadcrumbs, | ||
attach_stacktrace=self.attach_stacktrace, | ||
default_integrations=self.default_integrations, | ||
release=self.release, | ||
**self.sentry_params, | ||
) | ||
tags: dict[str, str] = self.tags or {} | ||
sentry_sdk.set_tags(tags) |
This file contains 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,102 @@ | ||
[project] | ||
name = "lite-bootstrap" | ||
description = "Lite package for bootstrapping new microservices" | ||
authors = [ | ||
{ name = "Artur Shiriev", email = "[email protected]" }, | ||
] | ||
readme = "README.md" | ||
requires-python = ">=3.10,<4" | ||
license = "MIT" | ||
keywords = [ | ||
"python", | ||
"microservice", | ||
"bootstrap", | ||
"opentelemetry", | ||
"sentry", | ||
"error-tracing", | ||
"fastapi", | ||
] | ||
classifiers = [ | ||
"Programming Language :: Python :: 3.10", | ||
"Programming Language :: Python :: 3.11", | ||
"Programming Language :: Python :: 3.12", | ||
"Typing :: Typed", | ||
"Topic :: Software Development :: Libraries", | ||
] | ||
dynamic = ["version"] | ||
packages = [ | ||
{ include = "lite_bootstrap" }, | ||
] | ||
|
||
[project.urls] | ||
repository = "https://github.com/modern-python/lite-bootstrap" | ||
|
||
[project.optional-dependencies] | ||
tracing = [ | ||
"sentry-sdk", | ||
"opentelemetry-api", | ||
"opentelemetry-sdk", | ||
"opentelemetry-exporter-otlp", | ||
"opentelemetry-instrumentation", | ||
] | ||
fastapi = [ | ||
"fastapi", | ||
"sentry-sdk", | ||
"opentelemetry-api", | ||
"opentelemetry-sdk", | ||
"opentelemetry-exporter-otlp", | ||
"opentelemetry-instrumentation", | ||
"opentelemetry-instrumentation-fastapi", | ||
] | ||
|
||
[tool.uv] | ||
dev-dependencies = [ | ||
"pytest", | ||
"pytest-cov", | ||
"httpx", # for test client | ||
"mypy", | ||
"ruff", | ||
] | ||
|
||
[build-system] | ||
requires = ["hatchling", "hatch-vcs"] | ||
build-backend = "hatchling.build" | ||
|
||
[tool.hatch.version] | ||
source = "vcs" | ||
|
||
[tool.mypy] | ||
python_version = "3.10" | ||
strict = true | ||
|
||
[tool.ruff] | ||
fix = true | ||
unsafe-fixes = true | ||
line-length = 120 | ||
target-version = "py310" | ||
|
||
[tool.ruff.format] | ||
docstring-code-format = true | ||
|
||
[tool.ruff.lint] | ||
select = ["ALL"] | ||
ignore = [ | ||
"D1", # allow missing docstrings | ||
"S101", # allow asserts | ||
"TCH", # ignore flake8-type-checking | ||
"FBT", # allow boolean args | ||
"ANN101", # missing-type-self | ||
"ANN102", # missing-type-cls | ||
"D203", # "one-blank-line-before-class" conflicting with D211 | ||
"D213", # "multi-line-summary-second-line" conflicting with D212 | ||
"COM812", # flake8-commas "Trailing comma missing" | ||
"ISC001", # flake8-implicit-str-concat | ||
] | ||
isort.lines-after-imports = 2 | ||
isort.no-lines-before = ["standard-library", "local-folder"] | ||
|
||
[tool.pytest.ini_options] | ||
addopts = "--cov=. --cov-report term-missing" | ||
|
||
[tool.coverage.report] | ||
exclude_also = ["if typing.TYPE_CHECKING:"] |
Empty file.
This file contains 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,27 @@ | ||
import typing | ||
|
||
import pytest | ||
from fastapi import APIRouter, FastAPI | ||
from fastapi.responses import JSONResponse | ||
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor # type: ignore[attr-defined] | ||
|
||
|
||
class CustomInstrumentor(BaseInstrumentor): # type: ignore[misc] | ||
def instrumentation_dependencies(self) -> typing.Collection[str]: | ||
return [] | ||
|
||
def _uninstrument(self, **kwargs: typing.Mapping[str, typing.Any]) -> None: | ||
pass | ||
|
||
|
||
@pytest.fixture | ||
def fastapi_app() -> FastAPI: | ||
app: typing.Final = FastAPI() | ||
router: typing.Final = APIRouter() | ||
|
||
@router.get("/test") | ||
async def for_test_endpoint() -> JSONResponse: | ||
return JSONResponse(content={"key": "value"}) | ||
|
||
app.include_router(router) | ||
return app |
Oops, something went wrong.