diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index cf49a68..aad92b3 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -1,5 +1,10 @@ name: http-toolkit-build-and-push on: + workflow_run: + workflows: + - http-toolkit-test + types: + - completed push: tags: - '*' @@ -11,9 +16,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: python-build - uses: actions/setup-python@v5 - with: - python-version: '3.9' + uses: ./.github/actions/python-build - name: install-dependencies run: python3 -m pip install $BUILD_DEPENDENCIES $PUSH_DEPENDENCIES - name: build @@ -26,13 +29,12 @@ jobs: name: python-package-distributions path: dist/ publish-to-pypi: - if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes needs: - build runs-on: ubuntu-latest environment: name: pypi - url: https://pypi.org/p/kontur_http_toolkit_core # Replace with your PyPI project name + url: https://pypi.org/p/kontur_http_toolkit_core permissions: id-token: write steps: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 0130ada..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,7 +0,0 @@ -include: - - project: 'py-libs/gitlab-ci-templates' - file: '.gitlab-ci.yml' - -tox: - script: - - tox -m "${TOX_ENV}" diff --git a/README.md b/README.md index 3c7f88e..8da3a0f 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,167 @@ # kontur_http_toolkit_core Библиотека для создания HTTP-клиентов к различным сервисам. -## Поддержка asyncio -Да +## HTTPX_Service -## Установка +Если не нужно использовать сконфигурированный транспорт, используйте HTTPXService (для async -> AsyncHttpxService) -```bash -$ pip install --index-url https://pypi.kontur.host kontur_http_toolkit +```python +from kontur.httptoolkitcore import HttpxService +from kontur.httptoolkitcore import Header + +headers = ( + Header(name="My-Header", value="my-value", is_sensitive=False), +) +httpbin = HttpxService("http://httpbin.org", headers=headers) +httpbin.get("/get") +httpbin.post("/post") +``` + +## Service + +Если нужно использовать сконфигурированный transport, используйте Service. (Service -> HttpxTransport, AsyncService -> AsyncHttpxTransport) + +```python +### Sync + +from kontur.httptoolkitcore import Service, Header +from kontur.httptoolkitcore.transport import HttpxTransport + + +class DummyService(Service): + pass + + +DummyService( + headers=(Header(name="ServiceHeader", value="service-header", is_sensitive=False),), + transport=HttpxTransport(base_url="https://example.com:4321", proxies={"http://": "http://10.10.1.10:3128"}), + ## base_url в таком случае передается в transport +) +``` + +```python +### Async + +from kontur.httptoolkitcore import AsyncService, Header +from kontur.httptoolkitcore.transport import AsyncHttpxTransport + + +class DummyService(AsyncService): + pass + + +DummyService( + headers=(Header(name="ServiceHeader", value="service-header", is_sensitive=False),), + transport=AsyncHttpxTransport(base_url="https://example.com:4321", proxies={"http://": "http://10.10.1.10:3128"}), + ## base_url в таком случае передается в transport +) +``` + +### Отправка запроса + +```python +### Async + +from kontur.httptoolkitcore import Service, Header, HttpMethod +from kontur.httptoolkitcore.transport import HttpxTransport +from kontur.httptoolkitcore.request import Request + + +class DummyService(Service): + pass + + +service = DummyService( + headers=(Header(name="ServiceHeader", value="service-header", is_sensitive=False),), + transport=HttpxTransport(base_url="https://example.com:4321", proxies={"http://": "http://10.10.1.10:3128"}), + ## base_url в таком случае передается в transport +) + +# По методу +service.post( + path="/somewhere", + headers=(Header(name="SuperSecret", value="big_secret", is_sensitive=True, create_mask=lambda value: value[-4:])), + params={"over": "the rainbow"}, + body="Something", +) + +# По request +service.request(Request(method=HttpMethod.POST, body="Request", params={}, path="")) +``` + +### Отправка особых типов + +```python +from kontur.httptoolkitcore import Service, Header, HttpMethod +from kontur.httptoolkitcore.transport import HttpxTransport +from kontur.httptoolkitcore.request import Request + + +class DummyService(Service): + pass + + +service = DummyService( + headers=(Header(name="ServiceHeader", value="service-header", is_sensitive=False),), + transport=HttpxTransport(base_url="https://example.com:4321", proxies={"http://": "http://10.10.1.10:3128"}), + ## base_url в таком случае передается в transport +) + +# Отправить JSON (json_encoder задан по-умолчанию, но можно его поменять в transport) +# Не отправлять вместе с body и с files +service.post( + path="/somewhere", + headers=(Header(name="SuperSecret", value="big_secret", is_sensitive=True, create_mask=lambda value: value[-4:])), + params={"over": "the rainbow"}, + json={ + "param1": 1, + "param2": 2, + }, +) + +# Отправить multipart-files в формате Dict[str, Union[BinaryIO, Tuple[str, BinaryIO, str]]] +# Можно отправлять вместе с body, но нельзя с json +service.post( + path="/somewhere", + headers=(Header(name="SuperSecret", value="big_secret", is_sensitive=True, create_mask=lambda value: value[-4:]),), + params={"over": "the rainbow"}, + files={"upload-file": open("report.xls", "rb")}, + # другой формат files = {'upload-file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel')} +) +``` + +## Имя логгера библиотеки + +kontur.httptoolkitcore + +## Уровень логирования по-умолчанию + +logging.INFO + +## Пример настройки логирования + +```python +import logging +import kontur.httptoolkitcore + +logging.basicConfig(level="INFO") + + +class MyService(kontur.httptoolkit.HttpxService): + def test(self): + self.get("/") + + +service = MyService("https://test.ru") + +service.test() +``` +## Вывод +```python +INFO:kontur.httptoolkitcore.transport._sync:Sending GET https://test.ru/ ``` -Быстрый старт +Доп.информация - [HttpxService](docs/QUICKSTART.md#httpxservice) - [Service](docs/QUICKSTART.md#service) - [Отправка запросов](docs/QUICKSTART.md#отправка-запроса) @@ -20,7 +171,6 @@ $ pip install --index-url https://pypi.kontur.host kontur_http_toolkit Все про Transport - [HttpxTransport](docs/TRANSPORT.md#transport) - [Создание собственного Transport](docs/TRANSPORT.md#transport-не-от-httpx) -- [SingularTransport](https://git.skbkontur.ru/py-libs/kontur_http_toolkit_singular) OpenTelemetry - [OpenTelemetry](kontur/httptoolkitcoreopentelemetry/README.md) diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index ede8354..ba13d49 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -151,11 +151,11 @@ class MyService(kontur.httptoolkit.HttpxService): self.get("/") -service = MyService("https://kontur.ru") +service = MyService("https://test.ru") service.test() ``` ## Вывод ```python -INFO:kontur.httptoolkit.transport._sync:Sending GET https://kontur.ru/ +INFO:kontur.httptoolkitcore.transport._sync:Sending GET https://test.ru/ ``` \ No newline at end of file diff --git a/kontur/httptoolkitcoreopentelemetry/README.md b/kontur/httptoolkitcoreopentelemetry/README.md index 11abd7f..96f54fd 100644 --- a/kontur/httptoolkitcoreopentelemetry/README.md +++ b/kontur/httptoolkitcoreopentelemetry/README.md @@ -1,14 +1,5 @@ # Opentelemetry instrumentation -Позволяет при помощи [OpenTelemetry HTTPX](https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-httpx) добавить трассировку запросов через [kontur_http_toolkit](https://git.skbkontur.ru/py-libs/kontur_http_toolkit) в случае использования httpx транспорта. - -## Поддержка asyncio -Да - -## Установка - -```bash -$ pip install --index-url https://pypi.kontur.host kontur_http_toolkit[opentelemetry] -``` +Позволяет при помощи [OpenTelemetry HTTPX](https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-httpx) добавить трассировку запросов через [http_toolkit](https://github.com/skbkontur/http_toolkit) в случае использования httpx транспорта. ## Пример использования @@ -35,4 +26,4 @@ HttpxTransportInstrumentor.instrument(tracer_provider=provider) OTEL_PYTHON_DISABLED_INSTRUMENTATIONS="httptoolkit-httpx" ``` -Больше примеров можно найти [здесь](https://git.skbkontur.ru/py-libs/kontur_opentelemetry/-/tree/master/examples). +Пример можно найти [здесь](https://github.com/skbkontur/http_toolkit/tree/master/kontur/httptoolkitcoreopentelemetry/example). diff --git a/kontur/httptoolkitcoreopentelemetry/example/client.py b/kontur/httptoolkitcoreopentelemetry/example/client.py new file mode 100644 index 0000000..1210fe2 --- /dev/null +++ b/kontur/httptoolkitcoreopentelemetry/example/client.py @@ -0,0 +1,39 @@ +import asyncio + +from kontur.httptoolkitcore import AsyncService, Service +from kontur.httptoolkitcore.transport import HttpxTransport, AsyncHttpxTransport +from kontur.httptoolkitcoreopentelemetry import HttpxTransportInstrumentor + +from instrumentation import tracer + + +HttpxTransportInstrumentor.instrument() + + +def sync_request(): + with tracer.start_as_current_span("client-app-sync"): + response = Service( + transport=HttpxTransport( + "http://server:8888", + open_timeout_in_seconds=60, + read_timeout_in_seconds=60, + ) + ).get("/") + assert response.status_code == 200 + + +async def async_request(): + with tracer.start_as_current_span("client-app-async"): + response = await AsyncService( + transport=AsyncHttpxTransport( + "http://server:8888", + open_timeout_in_seconds=60, + read_timeout_in_seconds=60, + ) + ).get("/") + assert response.status_code == 200 + + +with tracer.start_as_current_span("client-app"): + sync_request() + asyncio.run(async_request()) diff --git a/kontur/httptoolkitcoreopentelemetry/example/docker-compose.yml b/kontur/httptoolkitcoreopentelemetry/example/docker-compose.yml new file mode 100644 index 0000000..b964265 --- /dev/null +++ b/kontur/httptoolkitcoreopentelemetry/example/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3.6' + +services: + client: + image: $PYTHON_IMAGE + env_file: + - .env.common + - clients/.env.clients + command: + - /bin/sh + - -c + - | + pip install -r requirements.txt + python client.py diff --git a/kontur/httptoolkitcoreopentelemetry/example/requirements.txt b/kontur/httptoolkitcoreopentelemetry/example/requirements.txt new file mode 100644 index 0000000..704037e --- /dev/null +++ b/kontur/httptoolkitcoreopentelemetry/example/requirements.txt @@ -0,0 +1,5 @@ +opentelemetry-api +opentelemetry-sdk +opentelemetry-exporter-otlp-proto-grpc + +kontur_http_toolkit_core[opentelemetry]~=1.0 diff --git a/pyproject.toml b/pyproject.toml index 6c8c788..80d492f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,8 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "kontur_http_toolkit_core" -authors = [{name="#python_help", email = "python@skbkontur.ru"}] -description = "Core-библиотека для kontur_http_toolkit" +description = "Библиотека для создания HTTP-клиентов к различным сервисам на основе HTTPX" readme = "README.md" requires-python = ">=3.8, <3.13" dependencies = ["httpx~=0.24.1"] @@ -20,7 +19,7 @@ opentelemetry = ["opentelemetry-instrumentation-httpx"] test = ["pytest==7.0.0", "pytest-cov==3.0.0", "testfixtures==6.18.3", "pytest-asyncio==0.18.3", "pytest-httpx==0.22.0"] [project.urls] -homepage = "https://git.skbkontur.ru/py-libs/kontur_http_toolkit_core" +homepage = "https://github.com/skbkontur/http_toolkit" [tool.pytest.ini_options] addopts = "-ra -q"