Skip to content

Commit 5251c92

Browse files
committed
init
0 parents  commit 5251c92

16 files changed

+445
-0
lines changed

.github/workflows/ci.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: main
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request: {}
8+
9+
concurrency:
10+
group: ${{ github.head_ref || github.run_id }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v3
18+
- uses: actions/setup-python@v4
19+
with:
20+
python-version: "3.10"
21+
- uses: extractions/setup-just@v2
22+
- run: curl -LsSf https://astral.sh/uv/install.sh | sh
23+
- run: just install lint-ci
24+
25+
pytest:
26+
runs-on: ubuntu-latest
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
python-version:
31+
- "3.10"
32+
- "3.11"
33+
- "3.12"
34+
steps:
35+
- uses: actions/checkout@v3
36+
- uses: actions/setup-python@v4
37+
with:
38+
python-version: ${{ matrix.python-version }}
39+
- uses: extractions/setup-just@v2
40+
- run: curl -LsSf https://astral.sh/uv/install.sh | sh
41+
- run: just install test . --cov=. --cov-report xml
42+
- name: Upload coverage to Codecov
43+
uses: codecov/[email protected]
44+
env:
45+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
46+
with:
47+
files: ./coverage.xml
48+
flags: unittests
49+
name: codecov-${{ matrix.python-version }}

.github/workflows/publish.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Publish Package
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-python@v5
14+
with:
15+
python-version: "3.12"
16+
- uses: actions/cache@v4
17+
with:
18+
path: ~/.cache/uv
19+
key: publish-${{ hashFiles('pyproject.toml') }}
20+
- uses: extractions/setup-just@v2
21+
- run: curl -LsSf https://astral.sh/uv/install.sh | sh
22+
- run: just publish
23+
env:
24+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}

.gitignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generic things
2+
*.pyc
3+
*~
4+
__pycache__/*
5+
*.swp
6+
*.sqlite3
7+
*.map
8+
.vscode
9+
.idea
10+
.DS_Store
11+
.env
12+
.mypy_cache
13+
.pytest_cache
14+
.ruff_cache
15+
.coverage
16+
htmlcov/
17+
coverage.xml
18+
pytest.xml
19+
dist/
20+
.python-version
21+
.venv
22+
uv.lock

Justfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
default: install lint test
2+
3+
install:
4+
uv lock --upgrade
5+
uv sync --all-extras --frozen
6+
7+
lint:
8+
uv run ruff format .
9+
uv run ruff check . --fix
10+
uv run mypy .
11+
12+
lint-ci:
13+
uv run ruff format . --check
14+
uv run ruff check . --no-fix
15+
uv run mypy .
16+
17+
test *args:
18+
uv run pytest {{ args }}
19+
20+
publish:
21+
rm -rf dist/*
22+
uv tool run --from build python -m build --installer uv
23+
uv tool run twine check dist/*
24+
uv tool run twine upload dist/* --username __token__ --password $PYPI_TOKEN

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Lite-Bootstrap package
2+
==
3+
[![Test Coverage](https://codecov.io/gh/modern-python/lite-bootstrap/branch/main/graph/badge.svg)](https://codecov.io/gh/modern-python/lite-bootstrap)
4+
[![MyPy Strict](https://img.shields.io/badge/mypy-strict-blue)](https://mypy.readthedocs.io/en/stable/getting_started.html#strict-mode-and-configuration)
5+
[![Supported versions](https://img.shields.io/pypi/pyversions/lite-bootstrap.svg)](https://pypi.python.org/pypi/lite-bootstrap)
6+
[![downloads](https://img.shields.io/pypi/dm/lite-bootstrap.svg)](https://pypistats.org/packages/lite-bootstrap)
7+
[![GitHub stars](https://img.shields.io/github/stars/modern-python/lite-bootstrap)](https://github.com/modern-python/lite-bootstrap/stargazers)
8+
9+
This package helps to build new microservices
10+
11+
## Quickstart:
12+
### Installation
13+
14+
```shell
15+
$ pip install lite-bootstrap
16+
```

lite_bootstrap/__init__.py

Whitespace-only changes.

lite_bootstrap/fastapi_bootstrap.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import dataclasses
2+
3+
import fastapi
4+
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
5+
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
6+
7+
from lite_bootstrap.opentelemetry_bootstrap import OpenTelemetryBootstrap
8+
from lite_bootstrap.sentry_bootstrap import SentryBootstrap
9+
10+
11+
@dataclasses.dataclass(kw_only=True, slots=True)
12+
class FastAPIBootstrap:
13+
app: fastapi.FastAPI
14+
opentelemetry: OpenTelemetryBootstrap
15+
sentry: SentryBootstrap
16+
opentelemetry_excluded_urls: list[str] = dataclasses.field(default_factory=list)
17+
18+
def bootstrap_init(self) -> None:
19+
if self.sentry.sentry_dsn:
20+
self.sentry.start_tracing()
21+
self.app.add_middleware(SentryAsgiMiddleware)
22+
23+
self.opentelemetry.start_tracing()
24+
if self.opentelemetry.endpoint:
25+
FastAPIInstrumentor.instrument_app(
26+
app=self.app,
27+
tracer_provider=self.opentelemetry.tracer_provider,
28+
excluded_urls=",".join(self.opentelemetry_excluded_urls),
29+
)
30+
31+
def teardown(self) -> None:
32+
self.opentelemetry.teardown()
33+
if self.opentelemetry.endpoint:
34+
FastAPIInstrumentor.uninstrument_app(self.app)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import dataclasses
2+
3+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
4+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor # type: ignore[attr-defined]
5+
from opentelemetry.sdk import resources
6+
from opentelemetry.sdk.trace import TracerProvider
7+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
8+
from opentelemetry.trace import set_tracer_provider
9+
10+
11+
@dataclasses.dataclass(kw_only=True, slots=True)
12+
class OpenTelemetryBootstrap:
13+
endpoint: str
14+
service_name: str
15+
instruments: list[BaseInstrumentor] = dataclasses.field(default_factory=list)
16+
tracer_provider: TracerProvider | None = dataclasses.field(init=False)
17+
18+
def start_tracing(self) -> None:
19+
if not self.endpoint:
20+
return
21+
22+
self.tracer_provider: TracerProvider = TracerProvider(
23+
resource=resources.Resource.create({resources.SERVICE_NAME: self.service_name}),
24+
)
25+
self.tracer_provider.add_span_processor(
26+
BatchSpanProcessor(
27+
OTLPSpanExporter(
28+
endpoint=self.endpoint,
29+
insecure=True,
30+
),
31+
),
32+
)
33+
34+
for instrument in self.instruments:
35+
instrument.instrument(
36+
tracer_provider=self.tracer_provider,
37+
)
38+
39+
set_tracer_provider(self.tracer_provider)
40+
41+
def teardown(self) -> None:
42+
if not self.endpoint:
43+
return
44+
45+
for instrument in self.instruments:
46+
instrument.uninstrument()

lite_bootstrap/py.typed

Whitespace-only changes.

lite_bootstrap/sentry_bootstrap.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import dataclasses
2+
import typing
3+
4+
import sentry_sdk
5+
6+
7+
@dataclasses.dataclass(kw_only=True, slots=True)
8+
class SentryBootstrap:
9+
sentry_dsn: str
10+
environment: str | None = None
11+
release: str | None = None
12+
max_breadcrumbs: int = 15
13+
attach_stacktrace: bool = True
14+
default_integrations: bool = True
15+
sentry_params: dict[str, typing.Any] = dataclasses.field(default_factory=dict)
16+
tags: dict[str, str] | None = None
17+
18+
def start_tracing(self) -> None:
19+
if not self.sentry_dsn:
20+
return
21+
22+
sentry_sdk.init(
23+
dsn=self.sentry_dsn,
24+
environment=self.environment,
25+
max_breadcrumbs=self.max_breadcrumbs,
26+
attach_stacktrace=self.attach_stacktrace,
27+
default_integrations=self.default_integrations,
28+
release=self.release,
29+
**self.sentry_params,
30+
)
31+
tags: dict[str, str] = self.tags or {}
32+
sentry_sdk.set_tags(tags)

0 commit comments

Comments
 (0)