# Audience Development common components

🚨 Deprecation Warning

The current library is deprecated, please use the following libraries instead:

`owsclient`: https://github.com/theorchard/python-owsclient

`jwtauth`: https://github.com/theorchard/python-jwtauth

Navigation:

- [Installation](#installation)
- [Context](#context)
  - [Correlation id](#correlation-id)
  - [Request context](#request-context)
  - [FastAPI or Starlette context](#fastapi-or-starlette-context)
- [Logger](#logger)
    - [FastAPI or Starlette request logger](#fastapi-or-starlette-request-logger)

## Installation

Using pip:

```shell
pip install -i https://pypi.theorchard.io/pypi/ audience-common
```

Using Poetry:

Add orchard repository to `pyproject.toml`:

```toml
[[tool.poetry.source]]
name = "theorchard"
url = "https://pypi.theorchard.io/pypi/"
secondary = true
```

Install using poetry:

```shell
poetry add audience-common
```

## Context

`audience-common` support 2 context variables that can be shared between logging, request lifecycle
using [PIP-0567- contextvars](https://peps.python.org/pep-0567/) library.

### Correlation id

Correlation id is current context unique identifier in UUID4 format.

Usage:

```python
from audience_common import context

# Set new correlation id (you can also pass argument value)
correlation_id, token = context.set_correlation_id("value")

# Get somewhere in the code current correlation id
print(context.get_correlation_id())

# Reset context variable
context.reset_correlation_id(token)
```

### Request context

Request context stores Orchard request headers, like profile type, profile id, profile uuid, etc.

Usage:

```python
from audience_common import context, constants

# Create new request context
request_context = context.RequestContext(
    context_type=constants.CONTEXT_TYPE_PROFILE,
    profile_type="AudienceProfile",
    profile_id=100,
)

# Set new request context
token = context.set_request_context(request_context)

# Reset request context
context.reset_request_context(token)
```

Getting request context from headers:

```python
from audience_common import context, constants

# Create new request context
request_context = context.request_context_from_headers(
    headers={
        "Orchard-Profile-Type": "AudienceProfile",
        "Orchard-Profile-Id": "100",
    },
)

assert request_context.context_type == constants.CONTEXT_TYPE_PROFILE
assert request_context.profile_type == "AudienceProfile"
assert request_context.profile_id == 100
```

### FastAPI or Starlette context

Usage:

```python
from starlette.applications import Starlette
from starlette.middleware import Middleware

from audience_common.context.asgi.middleware import (
    CorrelationIdMiddleware,
    RequestContextMiddleware,
)

app = Starlette(
    middleware=[
        Middleware(CorrelationIdMiddleware),
        Middleware(RequestContextMiddleware),
    ]
)
```

## Logger

`audience-common` logger uses DataDog compatible JSON format with output stream handler.

Usage:

```python
from audience_common.logger import configure_logging, LogFormat

LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "stream": {
            "level": "INFO",
            "class": "audience_common.logger.OwsStreamHandler",
        },
        "null": {
            "level": "INFO",
            "class": "logging.NullHandler",
        },
    },
    "loggers": {
        "dmp": {
            "handlers": ["stream"],
            "level": "INFO",
        },
        "audience_common.ext.starlette.middleware.logger": {
            "handlers": ["stream"],
            "level": "INFO",
        },
        "sqlalchemy.engine": {
            "handlers": ["stream"],
            "level": "WARNING",
        },
        "uvicorn": {
            "handlers": ["stream"],
            "level": "INFO",
        },
        "uvicorn.access": {
            "handlers": ["null"],
            "level": "INFO",
        },
    },
}

configure_logging(
    LOGGING_CONFIG,
    environment="dev",
    service_name="ows-permissions",
    service_version="1.0.0",
    log_format=LogFormat.JSON,
    logger_name="ows1",
    debug=False,  # Use debug=True to set all handlers level to DEBUG
)
```

Ows logger support different log formats:

* `LogFormat.JSON` - DataDog compatible JSON format
* `LogFormat.JSON_PRETTY` - DataDog compatible JSON format with ident (useful for local development)
* `LogFormat.DEBUG` - Colored stream formatter (local dev only)
* `LogFormat.DEBUG_EXTRA` - Colored stream formatter with log extra parameters output as a table (local dev only)

### FastAPI or Starlette request logger

Usage:

```python
from starlette.applications import Starlette
from starlette.middleware import Middleware

from audience_common.logger.asgi.middleware import RequestLoggerMiddleware

app = Starlette(middleware=[
    Middleware(RequestLoggerMiddleware, exclude_paths=["/hello/", "/openapi.json"])
])
```
