# Story 6.6: Clean Up Public API Exports

## Status: Complete

## Summary

Clean up the public API exports to ensure `__all__` accurately reflects the stable public contract, hide internal imports, and document the API stability policy.

## Background

The codebase already has `__all__` defined in all key modules:

- ✅ `fapilog/__init__.py` — 7 exports
- ✅ `fapilog/core/__init__.py` — 121 exports
- ✅ `fapilog/plugins/__init__.py` — 22 exports
- ✅ `fapilog/testing/__init__.py` — 44 exports

However, a review identified several gaps that need addressing.

## Gaps Identified

### 1. Config Classes Leak Into Namespace

These are importable from `fapilog` but not declared in `__all__`:

- `AuditSinkConfig`, `CloudWatchSinkConfig`, `HttpSinkConfig`, `PostgresSinkConfig`
- `RotatingFileSinkConfig`, `WebhookSinkConfig`
- `FieldMaskConfig`, `RegexMaskConfig`, `UrlCredentialsConfig`, `SizeGuardConfig`

**Decision:** These should be hidden (internal use only). Users configure sinks via `Settings`, not by importing config classes directly.

### 2. Missing Public Exports

| Symbol        | Location         | Rationale                                                      |
| ------------- | ---------------- | -------------------------------------------------------------- |
| `DrainResult` | `core/logger.py` | Return type of `drain()` — users need this for type hints      |
| `LogEvent`    | `core/events.py` | Used in custom enrichers/processors — plugin authors need this |

### 3. Python Builtins Leak Into Namespace

These are accidentally exposed due to top-level imports:

- `Any`, `AsyncIterator`, `Iterator`, `Path`
- `asynccontextmanager`, `asyncio`, `annotations`

### 4. No Documentation of API Contract

No docs explicitly state that `__all__` defines the stable public API.

## Acceptance Criteria

- [ ] Config class imports use `_` prefix (e.g., `from .sinks.audit import AuditSinkConfig as _AuditSinkConfig`)
- [ ] `DrainResult` added to main `__all__` and importable from `fapilog`
- [ ] `LogEvent` added to main `__all__` and importable from `fapilog`
- [ ] Python stdlib/typing imports hidden with `_` prefix
- [ ] CONTRIBUTING.md updated with "Public API Policy" section explaining `__all__`
- [ ] `python -c "from fapilog import *"` only imports symbols from `__all__`

## Technical Approach

### Hide Internal Imports

```python
# Before
from typing import Any, AsyncIterator, Iterator
from pathlib import Path
from .plugins.sinks.audit import AuditSinkConfig

# After
from typing import Any as _Any, AsyncIterator as _AsyncIterator, Iterator as _Iterator
from pathlib import Path as _Path
from .plugins.sinks.audit import AuditSinkConfig as _AuditSinkConfig
```

### Add Missing Public Exports

```python
# In fapilog/__init__.py
from .core.logger import DrainResult
from .core.events import LogEvent

__all__ = [
    # Core API
    "get_logger",
    "get_async_logger",
    "runtime",
    "runtime_async",
    "Settings",
    # Types for plugin authors
    "DrainResult",
    "LogEvent",
    # Version info
    "__version__",
    "VERSION",
]
```

### Document API Policy

Add to CONTRIBUTING.md:

````markdown
## Public API Policy

The public API is defined by `__all__` in each module:

- **Stable:** Symbols in `__all__` follow semantic versioning
- **Internal:** Symbols not in `__all__` may change without notice
- **Convention:** Internal imports use `_` prefix

To check what's public:

```python
from fapilog import __all__
print(__all__)
```
````

````

## Files Changed

- `src/fapilog/__init__.py` — Hide internal imports, add `DrainResult`/`LogEvent`
- `CONTRIBUTING.md` — Add "Public API Policy" section

## Estimated Effort

1-2 hours

## Risk Assessment

**Risk Level: Low**

- Hiding imports is backward compatible (users shouldn't import internals)
- Adding exports is additive
- Documentation is informational

## Validation

```bash
# Verify only __all__ symbols are exported
python -c "from fapilog import *; print([x for x in dir() if not x.startswith('_')])"

# Should output: ['DrainResult', 'LogEvent', 'Settings', 'VERSION', 'get_async_logger', 'get_logger', 'runtime', 'runtime_async']
````

## Definition of Done

- [ ] All config imports prefixed with `_`
- [ ] All stdlib/typing imports prefixed with `_`
- [ ] `DrainResult` and `LogEvent` in `__all__`
- [ ] CONTRIBUTING.md has Public API Policy section
- [ ] Validation command produces expected output
