hexkit 8.4.1__tar.gz → 8.6.0__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.
- hexkit-8.6.0/PKG-INFO +209 -0
- hexkit-8.6.0/README.md +118 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/pyproject.toml +28 -22
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/log.py +1 -1
- hexkit-8.6.0/src/hexkit/opentelemetry/__init__.py +29 -0
- hexkit-8.6.0/src/hexkit/opentelemetry/instrumentation.py +122 -0
- hexkit-8.6.0/src/hexkit/opentelemetry/testutils.py +141 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/dao.py +8 -8
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/objstorage.py +28 -5
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/provider/daosub.py +3 -1
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/provider/eventpub.py +5 -3
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/provider/eventsub.py +16 -14
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/migrations/__init__.py +11 -2
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/migrations/_manager.py +40 -71
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/migrations/_utils.py +92 -3
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/provider/dao.py +10 -8
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongokafka/config.py +3 -1
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongokafka/provider/daopub.py +10 -8
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/provider/objstorage.py +83 -78
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/testutils/_fixtures.py +2 -4
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/testutils/_utils.py +6 -2
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/testing/dao.py +4 -6
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/testing/objstorage.py +17 -3
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/utils.py +1 -1
- hexkit-8.6.0/src/hexkit.egg-info/PKG-INFO +209 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit.egg-info/SOURCES.txt +3 -1
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit.egg-info/requires.txt +11 -11
- hexkit-8.4.1/PKG-INFO +0 -223
- hexkit-8.4.1/README.md +0 -132
- hexkit-8.4.1/src/hexkit/opentelemetry.py +0 -76
- hexkit-8.4.1/src/hexkit.egg-info/PKG-INFO +0 -223
- {hexkit-8.4.1 → hexkit-8.6.0}/LICENSE +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/MANIFEST.in +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/setup.cfg +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/__main__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/base.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/config.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/correlation.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/custom_types.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/daopub.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/daosub.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/eventpub.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/eventsub.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/protocols/kvstore.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/config.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/provider/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/provider/utils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/testcontainer.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/akafka/testutils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/config.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/migrations/helpers.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/provider/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/provider/client.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/provider/kvstore.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/provider/utils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongodb/testutils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongokafka/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongokafka/provider/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongokafka/provider/persistent_pub.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/mongokafka/testutils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/redis/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/redis/config.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/redis/provider/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/redis/provider/client.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/redis/provider/kvstore.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/redis/testutils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/config.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/provider/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/provider/kvstore.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/test_files/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/test_files/test_file1.yaml +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/test_files/test_file2.yaml +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/test_files/test_file3.yaml +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/test_files/test_file4.yaml +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/testutils/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/s3/testutils/_typical_workflow.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/testing/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/testing/eventpub.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/testing/kvstore.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/vault/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/vault/config.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/vault/provider/__init__.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/vault/provider/client.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/vault/provider/kvstore.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/providers/vault/testutils.py +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit/py.typed +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit.egg-info/dependency_links.txt +0 -0
- {hexkit-8.4.1 → hexkit-8.6.0}/src/hexkit.egg-info/top_level.txt +0 -0
hexkit-8.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hexkit
|
|
3
|
+
Version: 8.6.0
|
|
4
|
+
Summary: A Toolkit for Building Microservices using the Hexagonal Architecture
|
|
5
|
+
Author-email: "German Human Genome Phenome Archive (GHGA)" <contact@ghga.de>
|
|
6
|
+
License: Apache 2.0
|
|
7
|
+
Project-URL: Repository, https://github.com/ghga-de/hexkit
|
|
8
|
+
Project-URL: Documentation, https://ghga-de.github.io/hexkit/
|
|
9
|
+
Project-URL: Release Notes, https://github.com/ghga-de/hexkit/releases
|
|
10
|
+
Project-URL: Issue Tracker, https://github.com/ghga-de/hexkit/issues
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
18
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
20
|
+
Classifier: Intended Audience :: Developers
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: opentelemetry-api<2,>=1.44
|
|
25
|
+
Requires-Dist: pydantic<3,>=2.12
|
|
26
|
+
Requires-Dist: pydantic_settings<3,>=2.12
|
|
27
|
+
Requires-Dist: PyYAML<7,>=6
|
|
28
|
+
Provides-Extra: akafka
|
|
29
|
+
Requires-Dist: aiokafka[lz4,snappy,zstd]~=0.14.0; extra == "akafka"
|
|
30
|
+
Requires-Dist: jsonschema<5,>=4.25; extra == "akafka"
|
|
31
|
+
Provides-Extra: s3
|
|
32
|
+
Requires-Dist: boto3<2,>=1.42; extra == "s3"
|
|
33
|
+
Requires-Dist: botocore<2,>=1.42; extra == "s3"
|
|
34
|
+
Provides-Extra: mongodb
|
|
35
|
+
Requires-Dist: pymongo<5,>=4.16; extra == "mongodb"
|
|
36
|
+
Provides-Extra: redis
|
|
37
|
+
Requires-Dist: redis<8,>=7.1; extra == "redis"
|
|
38
|
+
Provides-Extra: vault
|
|
39
|
+
Requires-Dist: hvac<3,>=2.4; extra == "vault"
|
|
40
|
+
Provides-Extra: opentelemetry-base
|
|
41
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.44; extra == "opentelemetry-base"
|
|
42
|
+
Requires-Dist: opentelemetry-exporter-otlp<2,>=1.44; extra == "opentelemetry-base"
|
|
43
|
+
Requires-Dist: opentelemetry-instrumentation>=0.65b0; extra == "opentelemetry-base"
|
|
44
|
+
Requires-Dist: opentelemetry-instrumentation-httpx>=0.65b0; extra == "opentelemetry-base"
|
|
45
|
+
Requires-Dist: opentelemetry-distro>=0.65b0; extra == "opentelemetry-base"
|
|
46
|
+
Provides-Extra: opentelemetry-akafka
|
|
47
|
+
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-akafka"
|
|
48
|
+
Requires-Dist: hexkit[akafka]; extra == "opentelemetry-akafka"
|
|
49
|
+
Requires-Dist: opentelemetry-instrumentation-aiokafka>=0.65b0; extra == "opentelemetry-akafka"
|
|
50
|
+
Provides-Extra: opentelemetry-mongodb
|
|
51
|
+
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-mongodb"
|
|
52
|
+
Requires-Dist: hexkit[mongodb]; extra == "opentelemetry-mongodb"
|
|
53
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.65b0; extra == "opentelemetry-mongodb"
|
|
54
|
+
Provides-Extra: opentelemetry-fastapi
|
|
55
|
+
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-fastapi"
|
|
56
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.65b0; extra == "opentelemetry-fastapi"
|
|
57
|
+
Provides-Extra: opentelemetry-s3
|
|
58
|
+
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-s3"
|
|
59
|
+
Requires-Dist: hexkit[s3]; extra == "opentelemetry-s3"
|
|
60
|
+
Requires-Dist: opentelemetry-instrumentation-botocore>=0.65b0; extra == "opentelemetry-s3"
|
|
61
|
+
Provides-Extra: opentelemetry-redis
|
|
62
|
+
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-redis"
|
|
63
|
+
Requires-Dist: hexkit[redis]; extra == "opentelemetry-redis"
|
|
64
|
+
Requires-Dist: opentelemetry-instrumentation-redis>=0.65b0; extra == "opentelemetry-redis"
|
|
65
|
+
Provides-Extra: opentelemetry
|
|
66
|
+
Requires-Dist: hexkit[opentelemetry-akafka]; extra == "opentelemetry"
|
|
67
|
+
Requires-Dist: hexkit[opentelemetry-mongodb]; extra == "opentelemetry"
|
|
68
|
+
Requires-Dist: hexkit[opentelemetry-fastapi]; extra == "opentelemetry"
|
|
69
|
+
Requires-Dist: hexkit[opentelemetry-s3]; extra == "opentelemetry"
|
|
70
|
+
Provides-Extra: test-akafka
|
|
71
|
+
Requires-Dist: hexkit[akafka]; extra == "test-akafka"
|
|
72
|
+
Requires-Dist: testcontainers[kafka]<5,>=4.14; extra == "test-akafka"
|
|
73
|
+
Provides-Extra: test-s3
|
|
74
|
+
Requires-Dist: hexkit[s3]; extra == "test-s3"
|
|
75
|
+
Requires-Dist: testcontainers<5,>=4.14; extra == "test-s3"
|
|
76
|
+
Provides-Extra: test-mongodb
|
|
77
|
+
Requires-Dist: hexkit[mongodb]; extra == "test-mongodb"
|
|
78
|
+
Requires-Dist: testcontainers[mongo]<5,>=4.14; extra == "test-mongodb"
|
|
79
|
+
Provides-Extra: test-redis
|
|
80
|
+
Requires-Dist: hexkit[redis]; extra == "test-redis"
|
|
81
|
+
Requires-Dist: testcontainers[redis]<5,>=4.14; extra == "test-redis"
|
|
82
|
+
Provides-Extra: test-vault
|
|
83
|
+
Requires-Dist: hexkit[vault]; extra == "test-vault"
|
|
84
|
+
Requires-Dist: testcontainers<5,>=4.14; extra == "test-vault"
|
|
85
|
+
Provides-Extra: test
|
|
86
|
+
Requires-Dist: hexkit[test-akafka,test-mongodb,test-s3,test-vault]; extra == "test"
|
|
87
|
+
Provides-Extra: all
|
|
88
|
+
Requires-Dist: hexkit[test]; extra == "all"
|
|
89
|
+
Requires-Dist: hexkit[opentelemetry]; extra == "all"
|
|
90
|
+
Dynamic: license-file
|
|
91
|
+
|
|
92
|
+
[](https://pypi.python.org/pypi/hexkit/)
|
|
93
|
+
[](https://pypi.python.org/pypi/hexkit/)
|
|
94
|
+

|
|
95
|
+
[](https://coveralls.io/github/ghga-de/hexkit?branch=main)
|
|
96
|
+
[](https://github.com/astral-sh/ruff)
|
|
97
|
+
[](https://mypy-lang.org/)
|
|
98
|
+
|
|
99
|
+
# hexkit
|
|
100
|
+
|
|
101
|
+
*A chassis library for building domain-focused, infrastructure-agnostic,
|
|
102
|
+
and event-driven microservices in Python*
|
|
103
|
+
|
|
104
|
+
Read the short summary below, or jump straight to our full
|
|
105
|
+
📖 **[User Guide](https://ghga-de.github.io/hexkit/user-guide/)** to learn the abstract
|
|
106
|
+
concepts and patterns as well as the concrete infrastructure integrations and testing
|
|
107
|
+
tools that hexkit provides for building better microservices.
|
|
108
|
+
|
|
109
|
+
<!--
|
|
110
|
+
NOTE: This README doubles as the landing page of the documentation site built with
|
|
111
|
+
great-docs. Therefore, all links must be absolute URLs — repo-relative links like
|
|
112
|
+
./examples or ./src would resolve correctly on GitHub but break on the site.
|
|
113
|
+
-->
|
|
114
|
+
|
|
115
|
+
## In a Nutshell
|
|
116
|
+
|
|
117
|
+
hexkit implements the *Triple Hexagonal Architecture* pattern, an optimization of the
|
|
118
|
+
ordinary
|
|
119
|
+
[Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/) for
|
|
120
|
+
use with microservices: adapters (as per the hexagonal architecture) are divided into
|
|
121
|
+
two parts. One part called *translator* is specific to one individual microservice
|
|
122
|
+
and its domain-oriented ports. The other part called *provider* is service-agnostic
|
|
123
|
+
but specific to one technology of the surrounding infrastructure. Both parts interact
|
|
124
|
+
through a high-level interface called *protocol* (not to be confused with Python's
|
|
125
|
+
typing.Protocol) which is neither specific to the technology nor to the microservice.
|
|
126
|
+
|
|
127
|
+
As a chassis lib, hexkit reduces redundancy and boilerplate across microservices by
|
|
128
|
+
providing the service-independent building blocks — protocols and providers — ready
|
|
129
|
+
to use. The only task that remains for an individual service is to implement
|
|
130
|
+
service-specific translators between the service's ports and the general-purpose
|
|
131
|
+
protocols (in addition to implementing the domain functionality of the service, of
|
|
132
|
+
course). For an in-depth introduction to the pattern, please read the
|
|
133
|
+
[Architectural Concepts](https://ghga-de.github.io/hexkit/user-guide/arch_concepts/)
|
|
134
|
+
chapter of the User Guide.
|
|
135
|
+
|
|
136
|
+
The following protocols and providers are currently available:
|
|
137
|
+
|
|
138
|
+
| Protocol | Providers |
|
|
139
|
+
| ------------------ | -------------------------------------- |
|
|
140
|
+
| Event Publishing | Apache Kafka, MongoDB + Kafka (outbox) |
|
|
141
|
+
| Event Subscription | Apache Kafka |
|
|
142
|
+
| Data Access Object | MongoDB |
|
|
143
|
+
| Object Storage | S3(-compatible) |
|
|
144
|
+
| Key-Value Store | MongoDB, Redis, S3, HashiCorp Vault |
|
|
145
|
+
|
|
146
|
+
In-memory implementations and per-backend test utilities are also included to
|
|
147
|
+
support testing without real infrastructure.
|
|
148
|
+
|
|
149
|
+
You are not forced to go all-in on the idea of Triple Hexagonal Architecture.
|
|
150
|
+
You can use it just for the technologies where you see benefits and use another
|
|
151
|
+
approach for the rest. For example, you could use hexkit for simplifying the exchange
|
|
152
|
+
of events between microservices but use a classical web framework such as FastAPI for
|
|
153
|
+
designing REST APIs and an ORM like SQLAlchemy for interacting with databases.
|
|
154
|
+
|
|
155
|
+
## Getting Started
|
|
156
|
+
|
|
157
|
+
The 📖 [User Guide](https://ghga-de.github.io/hexkit/user-guide/) covers all
|
|
158
|
+
protocols, providers, testing utilities, and observability tools with example code,
|
|
159
|
+
and the [API Reference](https://ghga-de.github.io/hexkit/reference/) documents all
|
|
160
|
+
public classes and functions.
|
|
161
|
+
|
|
162
|
+
For a complete example service built with hexkit, have a look at the
|
|
163
|
+
[stream_calc](https://github.com/ghga-de/hexkit/tree/main/examples/stream_calc)
|
|
164
|
+
example application. We also put a lot of effort into making the code
|
|
165
|
+
self-documenting: you can find the protocols being defined at
|
|
166
|
+
[src/hexkit/protocols](https://github.com/ghga-de/hexkit/tree/main/src/hexkit/protocols)
|
|
167
|
+
and the providers being implemented at
|
|
168
|
+
[src/hexkit/providers](https://github.com/ghga-de/hexkit/tree/main/src/hexkit/providers).
|
|
169
|
+
|
|
170
|
+
## Installation
|
|
171
|
+
|
|
172
|
+
This package is available at PyPI:
|
|
173
|
+
<https://pypi.org/project/hexkit>
|
|
174
|
+
|
|
175
|
+
You can install it from there using:
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
pip install hexkit
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The following extras are available:
|
|
182
|
+
|
|
183
|
+
- `akafka`: when using the Apache Kafka-based event publishing or subscription
|
|
184
|
+
- `mongodb`: when using MongoDB as backend for the DAO protocol or key-value stores
|
|
185
|
+
- `s3`: when interacting with S3-compatible object storages or key-value stores
|
|
186
|
+
- `redis`: when using Redis-based key-value stores
|
|
187
|
+
- `vault`: when using HashiCorp Vault-based key-value stores
|
|
188
|
+
- `opentelemetry`: observability instrumentation (also available per backend, e.g.
|
|
189
|
+
`opentelemetry-akafka`, `opentelemetry-mongodb`, `opentelemetry-fastapi`)
|
|
190
|
+
- `test-akafka`, `test-mongodb`, `test-s3`, `test-redis`, `test-vault`: testing
|
|
191
|
+
utils for the respective backend (`test` is a union of all of them)
|
|
192
|
+
- `all`: a union of all the above
|
|
193
|
+
|
|
194
|
+
## Contributing
|
|
195
|
+
|
|
196
|
+
Contributions are welcome! Please see the
|
|
197
|
+
[contribution guide](https://github.com/ghga-de/hexkit/blob/main/CONTRIBUTING.md)
|
|
198
|
+
for how to set up the development environment and build the documentation locally.
|
|
199
|
+
|
|
200
|
+
## Credits
|
|
201
|
+
|
|
202
|
+
The hexkit library is developed and maintained by the developer team of GHGA. We would especially
|
|
203
|
+
like to thank its original author, Kersten Breuer, who came up with the idea for the
|
|
204
|
+
library and designed and coded its first versions.
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
This repository is free to use and modify according to the
|
|
209
|
+
[Apache 2.0 License](https://github.com/ghga-de/hexkit/blob/main/LICENSE).
|
hexkit-8.6.0/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
[](https://pypi.python.org/pypi/hexkit/)
|
|
2
|
+
[](https://pypi.python.org/pypi/hexkit/)
|
|
3
|
+

|
|
4
|
+
[](https://coveralls.io/github/ghga-de/hexkit?branch=main)
|
|
5
|
+
[](https://github.com/astral-sh/ruff)
|
|
6
|
+
[](https://mypy-lang.org/)
|
|
7
|
+
|
|
8
|
+
# hexkit
|
|
9
|
+
|
|
10
|
+
*A chassis library for building domain-focused, infrastructure-agnostic,
|
|
11
|
+
and event-driven microservices in Python*
|
|
12
|
+
|
|
13
|
+
Read the short summary below, or jump straight to our full
|
|
14
|
+
📖 **[User Guide](https://ghga-de.github.io/hexkit/user-guide/)** to learn the abstract
|
|
15
|
+
concepts and patterns as well as the concrete infrastructure integrations and testing
|
|
16
|
+
tools that hexkit provides for building better microservices.
|
|
17
|
+
|
|
18
|
+
<!--
|
|
19
|
+
NOTE: This README doubles as the landing page of the documentation site built with
|
|
20
|
+
great-docs. Therefore, all links must be absolute URLs — repo-relative links like
|
|
21
|
+
./examples or ./src would resolve correctly on GitHub but break on the site.
|
|
22
|
+
-->
|
|
23
|
+
|
|
24
|
+
## In a Nutshell
|
|
25
|
+
|
|
26
|
+
hexkit implements the *Triple Hexagonal Architecture* pattern, an optimization of the
|
|
27
|
+
ordinary
|
|
28
|
+
[Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/) for
|
|
29
|
+
use with microservices: adapters (as per the hexagonal architecture) are divided into
|
|
30
|
+
two parts. One part called *translator* is specific to one individual microservice
|
|
31
|
+
and its domain-oriented ports. The other part called *provider* is service-agnostic
|
|
32
|
+
but specific to one technology of the surrounding infrastructure. Both parts interact
|
|
33
|
+
through a high-level interface called *protocol* (not to be confused with Python's
|
|
34
|
+
typing.Protocol) which is neither specific to the technology nor to the microservice.
|
|
35
|
+
|
|
36
|
+
As a chassis lib, hexkit reduces redundancy and boilerplate across microservices by
|
|
37
|
+
providing the service-independent building blocks — protocols and providers — ready
|
|
38
|
+
to use. The only task that remains for an individual service is to implement
|
|
39
|
+
service-specific translators between the service's ports and the general-purpose
|
|
40
|
+
protocols (in addition to implementing the domain functionality of the service, of
|
|
41
|
+
course). For an in-depth introduction to the pattern, please read the
|
|
42
|
+
[Architectural Concepts](https://ghga-de.github.io/hexkit/user-guide/arch_concepts/)
|
|
43
|
+
chapter of the User Guide.
|
|
44
|
+
|
|
45
|
+
The following protocols and providers are currently available:
|
|
46
|
+
|
|
47
|
+
| Protocol | Providers |
|
|
48
|
+
| ------------------ | -------------------------------------- |
|
|
49
|
+
| Event Publishing | Apache Kafka, MongoDB + Kafka (outbox) |
|
|
50
|
+
| Event Subscription | Apache Kafka |
|
|
51
|
+
| Data Access Object | MongoDB |
|
|
52
|
+
| Object Storage | S3(-compatible) |
|
|
53
|
+
| Key-Value Store | MongoDB, Redis, S3, HashiCorp Vault |
|
|
54
|
+
|
|
55
|
+
In-memory implementations and per-backend test utilities are also included to
|
|
56
|
+
support testing without real infrastructure.
|
|
57
|
+
|
|
58
|
+
You are not forced to go all-in on the idea of Triple Hexagonal Architecture.
|
|
59
|
+
You can use it just for the technologies where you see benefits and use another
|
|
60
|
+
approach for the rest. For example, you could use hexkit for simplifying the exchange
|
|
61
|
+
of events between microservices but use a classical web framework such as FastAPI for
|
|
62
|
+
designing REST APIs and an ORM like SQLAlchemy for interacting with databases.
|
|
63
|
+
|
|
64
|
+
## Getting Started
|
|
65
|
+
|
|
66
|
+
The 📖 [User Guide](https://ghga-de.github.io/hexkit/user-guide/) covers all
|
|
67
|
+
protocols, providers, testing utilities, and observability tools with example code,
|
|
68
|
+
and the [API Reference](https://ghga-de.github.io/hexkit/reference/) documents all
|
|
69
|
+
public classes and functions.
|
|
70
|
+
|
|
71
|
+
For a complete example service built with hexkit, have a look at the
|
|
72
|
+
[stream_calc](https://github.com/ghga-de/hexkit/tree/main/examples/stream_calc)
|
|
73
|
+
example application. We also put a lot of effort into making the code
|
|
74
|
+
self-documenting: you can find the protocols being defined at
|
|
75
|
+
[src/hexkit/protocols](https://github.com/ghga-de/hexkit/tree/main/src/hexkit/protocols)
|
|
76
|
+
and the providers being implemented at
|
|
77
|
+
[src/hexkit/providers](https://github.com/ghga-de/hexkit/tree/main/src/hexkit/providers).
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
This package is available at PyPI:
|
|
82
|
+
<https://pypi.org/project/hexkit>
|
|
83
|
+
|
|
84
|
+
You can install it from there using:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
pip install hexkit
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The following extras are available:
|
|
91
|
+
|
|
92
|
+
- `akafka`: when using the Apache Kafka-based event publishing or subscription
|
|
93
|
+
- `mongodb`: when using MongoDB as backend for the DAO protocol or key-value stores
|
|
94
|
+
- `s3`: when interacting with S3-compatible object storages or key-value stores
|
|
95
|
+
- `redis`: when using Redis-based key-value stores
|
|
96
|
+
- `vault`: when using HashiCorp Vault-based key-value stores
|
|
97
|
+
- `opentelemetry`: observability instrumentation (also available per backend, e.g.
|
|
98
|
+
`opentelemetry-akafka`, `opentelemetry-mongodb`, `opentelemetry-fastapi`)
|
|
99
|
+
- `test-akafka`, `test-mongodb`, `test-s3`, `test-redis`, `test-vault`: testing
|
|
100
|
+
utils for the respective backend (`test` is a union of all of them)
|
|
101
|
+
- `all`: a union of all the above
|
|
102
|
+
|
|
103
|
+
## Contributing
|
|
104
|
+
|
|
105
|
+
Contributions are welcome! Please see the
|
|
106
|
+
[contribution guide](https://github.com/ghga-de/hexkit/blob/main/CONTRIBUTING.md)
|
|
107
|
+
for how to set up the development environment and build the documentation locally.
|
|
108
|
+
|
|
109
|
+
## Credits
|
|
110
|
+
|
|
111
|
+
The hexkit library is developed and maintained by the developer team of GHGA. We would especially
|
|
112
|
+
like to thank its original author, Kersten Breuer, who came up with the idea for the
|
|
113
|
+
library and designed and coded its first versions.
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
This repository is free to use and modify according to the
|
|
118
|
+
[Apache 2.0 License](https://github.com/ghga-de/hexkit/blob/main/LICENSE).
|
|
@@ -23,10 +23,10 @@ classifiers = [
|
|
|
23
23
|
"Intended Audience :: Developers",
|
|
24
24
|
]
|
|
25
25
|
name = "hexkit"
|
|
26
|
-
version = "8.
|
|
26
|
+
version = "8.6.0"
|
|
27
27
|
description = "A Toolkit for Building Microservices using the Hexagonal Architecture"
|
|
28
28
|
dependencies = [
|
|
29
|
-
"opentelemetry-api >=1.
|
|
29
|
+
"opentelemetry-api >=1.44, <2",
|
|
30
30
|
"pydantic >=2.12, <3",
|
|
31
31
|
"pydantic_settings >=2.12, <3",
|
|
32
32
|
"PyYAML >=6, <7",
|
|
@@ -54,35 +54,35 @@ vault = [
|
|
|
54
54
|
"hvac >=2.4, <3",
|
|
55
55
|
]
|
|
56
56
|
opentelemetry-base = [
|
|
57
|
-
"opentelemetry-sdk >=1.
|
|
58
|
-
"opentelemetry-exporter-otlp >=1.
|
|
59
|
-
"opentelemetry-instrumentation >=0.
|
|
60
|
-
"opentelemetry-instrumentation-httpx >=0.
|
|
61
|
-
"opentelemetry-distro >=0.
|
|
57
|
+
"opentelemetry-sdk >=1.44, <2",
|
|
58
|
+
"opentelemetry-exporter-otlp >=1.44, <2",
|
|
59
|
+
"opentelemetry-instrumentation >=0.65b0",
|
|
60
|
+
"opentelemetry-instrumentation-httpx >=0.65b0",
|
|
61
|
+
"opentelemetry-distro >=0.65b0",
|
|
62
62
|
]
|
|
63
63
|
opentelemetry-akafka = [
|
|
64
64
|
"hexkit[opentelemetry-base]",
|
|
65
65
|
"hexkit[akafka]",
|
|
66
|
-
"opentelemetry-instrumentation-aiokafka >=0.
|
|
66
|
+
"opentelemetry-instrumentation-aiokafka >=0.65b0",
|
|
67
67
|
]
|
|
68
68
|
opentelemetry-mongodb = [
|
|
69
69
|
"hexkit[opentelemetry-base]",
|
|
70
70
|
"hexkit[mongodb]",
|
|
71
|
-
"opentelemetry-instrumentation-pymongo >=0.
|
|
71
|
+
"opentelemetry-instrumentation-pymongo >=0.65b0",
|
|
72
72
|
]
|
|
73
73
|
opentelemetry-fastapi = [
|
|
74
74
|
"hexkit[opentelemetry-base]",
|
|
75
|
-
"opentelemetry-instrumentation-fastapi >=0.
|
|
75
|
+
"opentelemetry-instrumentation-fastapi >=0.65b0",
|
|
76
76
|
]
|
|
77
77
|
opentelemetry-s3 = [
|
|
78
78
|
"hexkit[opentelemetry-base]",
|
|
79
79
|
"hexkit[s3]",
|
|
80
|
-
"opentelemetry-instrumentation-botocore >=0.
|
|
80
|
+
"opentelemetry-instrumentation-botocore >=0.65b0",
|
|
81
81
|
]
|
|
82
82
|
opentelemetry-redis = [
|
|
83
83
|
"hexkit[opentelemetry-base]",
|
|
84
84
|
"hexkit[redis]",
|
|
85
|
-
"opentelemetry-instrumentation-redis >=0.
|
|
85
|
+
"opentelemetry-instrumentation-redis >=0.65b0",
|
|
86
86
|
]
|
|
87
87
|
opentelemetry = [
|
|
88
88
|
"hexkit[opentelemetry-akafka]",
|
|
@@ -157,6 +157,9 @@ ignore = [
|
|
|
157
157
|
"E111",
|
|
158
158
|
"E114",
|
|
159
159
|
"E116",
|
|
160
|
+
"E117",
|
|
161
|
+
"E501",
|
|
162
|
+
"W191",
|
|
160
163
|
"PLW",
|
|
161
164
|
"RUF001",
|
|
162
165
|
"RUF010",
|
|
@@ -185,6 +188,13 @@ select = [
|
|
|
185
188
|
"RUF",
|
|
186
189
|
"SIM",
|
|
187
190
|
"D",
|
|
191
|
+
"E",
|
|
192
|
+
"W",
|
|
193
|
+
"ASYNC",
|
|
194
|
+
"LOG",
|
|
195
|
+
"PERF",
|
|
196
|
+
"RET",
|
|
197
|
+
"C4",
|
|
188
198
|
]
|
|
189
199
|
|
|
190
200
|
[tool.ruff.lint.mccabe]
|
|
@@ -196,6 +206,7 @@ max-complexity = 10
|
|
|
196
206
|
"S",
|
|
197
207
|
"SIM",
|
|
198
208
|
"D",
|
|
209
|
+
"E402",
|
|
199
210
|
]
|
|
200
211
|
"tests/*" = [
|
|
201
212
|
"S",
|
|
@@ -256,19 +267,14 @@ legacy_tox_ini = """
|
|
|
256
267
|
|
|
257
268
|
[testenv:docs]
|
|
258
269
|
basepython = python3.13
|
|
259
|
-
allowlist_externals =
|
|
260
|
-
mv
|
|
261
|
-
rm
|
|
262
270
|
deps =
|
|
263
271
|
--no-deps -r ./lock/requirements-dev.txt
|
|
272
|
+
commands_pre =
|
|
273
|
+
# great-docs (Python >= 3.11 only) is kept out of the shared dev lock so it
|
|
274
|
+
# does not break the py310 test env; install it here where docs are built.
|
|
275
|
+
pip install great-docs==0.14.1
|
|
264
276
|
commands =
|
|
265
|
-
|
|
266
|
-
pdoc -d google -o docs/api hexkit
|
|
267
|
-
mv docs/api/index.html docs/api/index.md
|
|
268
|
-
mkdocs build
|
|
269
|
-
mv docs/api/index.md docs/api/index.html
|
|
270
|
-
rm -rf site/api
|
|
271
|
-
mv docs/api site/api
|
|
277
|
+
great-docs build
|
|
272
278
|
|
|
273
279
|
[testenv]
|
|
274
280
|
pass_env =
|
|
@@ -105,7 +105,7 @@ class JsonFormatter(Formatter):
|
|
|
105
105
|
"""
|
|
106
106
|
# Create a log record dictionary
|
|
107
107
|
log_record = record.__dict__
|
|
108
|
-
output: dict[str, Any] =
|
|
108
|
+
output: dict[str, Any] = {}
|
|
109
109
|
|
|
110
110
|
output["timestamp"] = log_record["timestamp"]
|
|
111
111
|
output["service"] = log_record["service"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln
|
|
2
|
+
# for the German Human Genome-Phenome Archive (GHGA)
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
"""Subpackage containing OpenTelemetry instrumentation and related utilities."""
|
|
18
|
+
|
|
19
|
+
from .instrumentation import (
|
|
20
|
+
OpenTelemetryConfig,
|
|
21
|
+
configure_opentelemetry,
|
|
22
|
+
instrument_installed_libraries,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"OpenTelemetryConfig",
|
|
27
|
+
"configure_opentelemetry",
|
|
28
|
+
"instrument_installed_libraries",
|
|
29
|
+
]
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln
|
|
2
|
+
# for the German Human Genome-Phenome Archive (GHGA)
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
"""OpenTelemetry specific configuration code. This is gated behind the opentelemetry extra."""
|
|
17
|
+
|
|
18
|
+
import importlib
|
|
19
|
+
import logging
|
|
20
|
+
from typing import Annotated
|
|
21
|
+
|
|
22
|
+
from opentelemetry import trace
|
|
23
|
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
24
|
+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
25
|
+
from opentelemetry.sdk.trace import SpanProcessor, TracerProvider
|
|
26
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
27
|
+
from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio
|
|
28
|
+
from pydantic import Field
|
|
29
|
+
from pydantic_settings import BaseSettings
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"OpenTelemetryConfig",
|
|
33
|
+
"configure_opentelemetry",
|
|
34
|
+
"instrument_installed_libraries",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
# Instrumentation modules corresponding to the `opentelemetry-*` optional extras.
|
|
40
|
+
# Each entry is only instrumented if its module is installed.
|
|
41
|
+
_INSTRUMENTOR_MODULES: tuple[tuple[str, str], ...] = (
|
|
42
|
+
("opentelemetry.instrumentation.httpx", "HTTPXClientInstrumentor"),
|
|
43
|
+
("opentelemetry.instrumentation.aiokafka", "AIOKafkaInstrumentor"),
|
|
44
|
+
("opentelemetry.instrumentation.pymongo", "PymongoInstrumentor"),
|
|
45
|
+
("opentelemetry.instrumentation.fastapi", "FastAPIInstrumentor"),
|
|
46
|
+
("opentelemetry.instrumentation.botocore", "BotocoreInstrumentor"),
|
|
47
|
+
("opentelemetry.instrumentation.redis", "RedisInstrumentor"),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def instrument_installed_libraries() -> None:
|
|
52
|
+
"""Run `.instrument()` for every instrumentation library that is installed."""
|
|
53
|
+
for module_name, class_name in _INSTRUMENTOR_MODULES:
|
|
54
|
+
try:
|
|
55
|
+
module = importlib.import_module(module_name)
|
|
56
|
+
except ImportError:
|
|
57
|
+
logger.debug("'%s' not installed, skipping instrumentation.", module_name)
|
|
58
|
+
continue
|
|
59
|
+
try:
|
|
60
|
+
instrumentor_class = getattr(module, class_name)
|
|
61
|
+
except AttributeError:
|
|
62
|
+
logger.warning(
|
|
63
|
+
"Could not instrument '%s' for '%s'.", class_name, module_name
|
|
64
|
+
)
|
|
65
|
+
instrumentor_class().instrument()
|
|
66
|
+
logger.info("Instrumented '%s' for '%s'.", class_name, module_name)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class OpenTelemetryConfig(BaseSettings):
|
|
70
|
+
"""OpenTelemetry specific configuration options"""
|
|
71
|
+
|
|
72
|
+
enable_opentelemetry: bool = Field(
|
|
73
|
+
default=False,
|
|
74
|
+
description="If set to true, this will run necessary setup code."
|
|
75
|
+
"If set to false, no setup code is run, which leaves tracing disabled.",
|
|
76
|
+
)
|
|
77
|
+
otel_trace_sampling_rate: Annotated[float, Field(strict=True, ge=0, le=1)] = Field(
|
|
78
|
+
default=1.0,
|
|
79
|
+
description="Determines which proportion of spans should be sampled. "
|
|
80
|
+
"A value of 1.0 means all and is equivalent to the previous behaviour. "
|
|
81
|
+
"Setting this to 0 will result in no spans being sampled, but this does not "
|
|
82
|
+
"automatically set `enable_opentelemetry` to False.",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def configure_opentelemetry(
|
|
87
|
+
*,
|
|
88
|
+
service_name: str,
|
|
89
|
+
config: OpenTelemetryConfig,
|
|
90
|
+
span_processor: SpanProcessor | None = None,
|
|
91
|
+
):
|
|
92
|
+
"""Configure all needed parts of OpenTelemetry.
|
|
93
|
+
|
|
94
|
+
This needs to be called before constructing any objects that are instrumented, e.g.
|
|
95
|
+
construction a FastAPI app before running this, will result in missing instrumentation.
|
|
96
|
+
|
|
97
|
+
Setup of the TracerProvider is done programmatically. If disabled, this is a no-op,
|
|
98
|
+
leaving the default no-op TracerProvider from the OpenTelemetry API in place.
|
|
99
|
+
|
|
100
|
+
By default, spans are exported via OTLP over HTTP using a `BatchSpanProcessor`.
|
|
101
|
+
"""
|
|
102
|
+
if not config.enable_opentelemetry:
|
|
103
|
+
logger.info("OpenTelemetry disabled via config.")
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
resource = Resource(attributes={SERVICE_NAME: service_name})
|
|
107
|
+
# Replace the default static sampler with a probabilistic one that honors parent
|
|
108
|
+
# span sampling decisions
|
|
109
|
+
# This should consistently yield full traces within a service but not necessarily
|
|
110
|
+
# across service boundaries
|
|
111
|
+
# With the default sampling rate, behaviour does not change, but this allows to
|
|
112
|
+
# introduce head sampling by adjusting a config option on the service side later on
|
|
113
|
+
sampler = ParentBasedTraceIdRatio(rate=config.otel_trace_sampling_rate)
|
|
114
|
+
|
|
115
|
+
# Initialize service specific TracerProvider
|
|
116
|
+
trace_provider = TracerProvider(resource=resource, sampler=sampler)
|
|
117
|
+
trace_provider.add_span_processor(
|
|
118
|
+
span_processor or BatchSpanProcessor(OTLPSpanExporter())
|
|
119
|
+
)
|
|
120
|
+
trace.set_tracer_provider(trace_provider)
|
|
121
|
+
|
|
122
|
+
instrument_installed_libraries()
|