Skip to content

Commit d8c205f

Browse files
tercelclaude
andcommitted
fix: add 7 missing symbols to README API Overview tables
Add ObsLoggingMiddleware, UsageMiddleware, TraceContext, InMemoryExporter, StdoutExporter, OTLPExporter, ErrorCodeRegistry to API Overview section. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 50c8a36 commit d8c205f

1 file changed

Lines changed: 170 additions & 21 deletions

File tree

README.md

Lines changed: 170 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ A schema-enforced module standard for the AI-Perceivable era.
6262
| `RetryMiddleware` | Automatic retry with backoff |
6363
| `ErrorHistoryMiddleware` | Records errors into ErrorHistory |
6464
| `PlatformNotifyMiddleware` | Emits events on error rate/latency spikes |
65+
| `ObsLoggingMiddleware` | Observability-aware structured logging middleware |
66+
| `UsageMiddleware` | Per-call usage tracking middleware |
6567

6668
**Schema**
6769

@@ -81,6 +83,10 @@ A schema-enforced module standard for the AI-Perceivable era.
8183
| `ContextLogger` | Context-aware structured logging |
8284
| `ErrorHistory` | Ring buffer of recent errors with deduplication |
8385
| `UsageCollector` | Per-module usage statistics and trends |
86+
| `TraceContext` | W3C Trace Context propagation (traceparent/tracestate) |
87+
| `InMemoryExporter` | Span exporter that stores spans in memory |
88+
| `StdoutExporter` | Span exporter that writes spans to stdout |
89+
| `OTLPExporter` | Span exporter using OpenTelemetry Protocol |
8490

8591
**Events & Extensions**
8692

@@ -92,6 +98,7 @@ A schema-enforced module standard for the AI-Perceivable era.
9298
| `AsyncTaskManager` | Background module execution with status tracking |
9399
| `CancelToken` | Cooperative cancellation token |
94100
| `BindingLoader` | Load modules from YAML binding files |
101+
| `ErrorCodeRegistry` | Central registry for structured error codes |
95102

96103
## Documentation
97104

@@ -200,29 +207,171 @@ acl = ACL(rules=[
200207
executor = Executor(registry=registry, acl=acl)
201208
```
202209

203-
## Project Structure
210+
## Examples
204211

212+
The `examples/` directory contains runnable demos:
213+
214+
---
215+
216+
### `simple_client` — APCore client with decorator-based modules
217+
218+
Initializes an `APCore` client, registers modules with `@client.module()`, and calls them directly.
219+
220+
```python
221+
from apcore import APCore
222+
223+
client = APCore()
224+
225+
@client.module(id="math.add", description="Add two integers")
226+
def add(a: int, b: int) -> int:
227+
return a + b
228+
229+
result = client.call("math.add", {"a": 10, "b": 5})
230+
print(result) # {'result': 15}
231+
232+
@client.module(id="greet")
233+
def greet(name: str, greeting: str = "Hello") -> dict:
234+
return {"message": f"{greeting}, {name}!"}
235+
236+
result = client.call("greet", {"name": "Alice"})
237+
print(result) # {'message': 'Hello, Alice!'}
238+
```
239+
240+
---
241+
242+
### `global_client` — Minimal global client usage
243+
244+
No explicit initialization needed — use the default global client directly.
245+
246+
```python
247+
import apcore
248+
249+
@apcore.module(id="math.add")
250+
def add(a: int, b: int) -> int:
251+
return a + b
252+
253+
result = apcore.call("math.add", {"a": 10, "b": 5})
254+
print(result) # {'result': 15}
255+
```
256+
257+
---
258+
259+
### `greet` — Duck-typed module with Pydantic schemas
260+
261+
Demonstrates the class-based module interface with Pydantic `BaseModel` for input/output schemas.
262+
263+
```python
264+
from pydantic import BaseModel
265+
266+
class GreetInput(BaseModel):
267+
name: str
268+
269+
class GreetOutput(BaseModel):
270+
message: str
271+
272+
class GreetModule:
273+
input_schema = GreetInput
274+
output_schema = GreetOutput
275+
description = "Greet a user by name"
276+
277+
def execute(self, inputs: dict, context) -> dict:
278+
name = inputs["name"]
279+
return {"message": f"Hello, {name}!"}
280+
```
281+
282+
---
283+
284+
### `get_user` — Readonly module with `ModuleAnnotations`
285+
286+
Demonstrates behavioral annotations (`readonly`, `idempotent`) and simulated database lookup.
287+
288+
```python
289+
from pydantic import BaseModel
290+
from apcore.module import ModuleAnnotations
291+
292+
class GetUserInput(BaseModel):
293+
user_id: str
294+
295+
class GetUserOutput(BaseModel):
296+
id: str
297+
name: str
298+
email: str
299+
300+
class GetUserModule:
301+
input_schema = GetUserInput
302+
output_schema = GetUserOutput
303+
description = "Get user details by ID"
304+
annotations = ModuleAnnotations(readonly=True, idempotent=True)
305+
306+
_users = {
307+
"user-1": {"id": "user-1", "name": "Alice", "email": "alice@example.com"},
308+
"user-2": {"id": "user-2", "name": "Bob", "email": "bob@example.com"},
309+
}
310+
311+
def execute(self, inputs: dict, context) -> dict:
312+
user_id = inputs["user_id"]
313+
user = self._users.get(user_id)
314+
if user is None:
315+
return {"id": user_id, "name": "Unknown", "email": "unknown@example.com"}
316+
return dict(user)
317+
```
318+
319+
---
320+
321+
### `send_email` — Destructive module with sensitive fields and ContextLogger
322+
323+
Shows `x-sensitive` on schema fields (for log redaction), `ModuleAnnotations` with metadata, `ModuleExample` for AI-perceivable documentation, and `ContextLogger` usage.
324+
325+
```python
326+
from pydantic import BaseModel, Field
327+
from apcore.module import ModuleAnnotations, ModuleExample
328+
from apcore.observability import ContextLogger
329+
330+
class SendEmailInput(BaseModel):
331+
to: str
332+
subject: str
333+
body: str
334+
api_key: str = Field(..., json_schema_extra={"x-sensitive": True})
335+
336+
class SendEmailOutput(BaseModel):
337+
status: str
338+
message_id: str
339+
340+
class SendEmailModule:
341+
input_schema = SendEmailInput
342+
output_schema = SendEmailOutput
343+
description = "Send an email message"
344+
tags = ["email", "communication", "external"]
345+
version = "1.2.0"
346+
metadata = {"provider": "example-smtp", "max_retries": 3}
347+
annotations = ModuleAnnotations(destructive=True, idempotent=False, open_world=True)
348+
examples = [
349+
ModuleExample(
350+
title="Send a welcome email",
351+
inputs={"to": "user@example.com", "subject": "Welcome!", "body": "...", "api_key": "sk-xxx"},
352+
output={"status": "sent", "message_id": "msg-12345"},
353+
description="Sends a welcome email to a new user.",
354+
),
355+
]
356+
357+
def execute(self, inputs: dict, context) -> dict:
358+
logger = ContextLogger.from_context(context, name="send_email")
359+
logger.info("Sending email", extra={"to": inputs["to"], "subject": inputs["subject"]})
360+
message_id = f"msg-{hash(inputs['to']) % 100000:05d}"
361+
logger.info("Email sent successfully", extra={"message_id": message_id})
362+
return {"status": "sent", "message_id": message_id}
205363
```
206-
src/apcore/
207-
__init__.py # Public API
208-
async_task.py # Background task manager
209-
cancel.py # Cooperative cancellation primitives
210-
context.py # Execution context & identity
211-
executor.py # Core execution engine
212-
decorator.py # @module decorator
213-
bindings.py # YAML binding loader
214-
config.py # Configuration
215-
acl.py # Access control
216-
approval.py # Approval system
217-
extensions.py # Extension point manager
218-
errors.py # Error hierarchy
219-
module.py # Module annotations & metadata
220-
trace_context.py # W3C trace context helpers
221-
middleware/ # Middleware system
222-
observability/ # Tracing, metrics, logging
223-
registry/ # Module discovery & registration
224-
schema/ # Schema loading, validation, export
225-
utils/ # Utilities
364+
365+
---
366+
367+
### `decorated_add``@module` decorator for simple functions
368+
369+
```python
370+
from apcore.decorator import module
371+
372+
@module(description="Add two integers", tags=["math", "utility"])
373+
def add(a: int, b: int) -> int:
374+
return a + b
226375
```
227376

228377
## Development

0 commit comments

Comments
 (0)