missilya-sdk-sandbox
MISSILYA GROUP Sandbox SDK — the API-identical, deterministic, offline twin
of missilya-sdk. It installs
under the same import namespace (missilya_sdk), so application code switches
between real and mock behavior by which package is installed, not by changing a
single import.
- Package:
missilya-sdk-sandbox· Import namespace:missilya_sdk - Runtime: development & CI (mocks, no side effects)
- Python: 3.11 – 3.13
- Production twin:
missilya-sdk
Status: private, under review. After approval it is published to the MISSILYA private pip registry alongside the core package.
Table of contents
- What it is & why
- Guarantees (forbidden behaviors)
- Install
- Usage (identical to core)
- Deterministic behavior reference
- Configuration
- How apps swap core ⇄ sandbox by environment
- Parity contract
- Local development
- Project layout
1. What it is & why
The sandbox lets developers and CI run application code safely and for free. It
keeps the same imports, classes, functions, parameters, and return shapes as
missilya-sdk, but instead of calling real providers it returns deterministic
mocks. This means:
- Unit tests run with no network, no API cost, and no side effects.
- The same code that runs in production runs in tests — only the installed package differs — so tests written against the sandbox validate production logic.
- CI is fast and reproducible (fixtures are stable across runs).
| Sandbox SDK | Core SDK | |
|---|---|---|
| Package | missilya-sdk-sandbox |
missilya-sdk |
| Import | missilya_sdk |
missilya_sdk (same) |
| Where | development / CI | staging / production |
| Behavior | deterministic mocks | real providers via vault |
| Network | never (default) | yes |
2. Guarantees (forbidden behaviors)
The sandbox never:
- uses a production vault environment (it raises if asked to);
- uses a live credential (
sk_live…/rk_live…) — it raisesValidationError; - creates a real charge;
- sends a real email, SMS, or WhatsApp message;
- requires internet access for default unit tests.
It does raise the same typed exceptions as the core SDK
(ConfigurationError, ValidationError, ProviderError, …), so error-handling
paths are exercised exactly as in production.
3. Install
pip install missilya-sdk-sandbox # everything you need (offline)
pip install "missilya-sdk-sandbox[dev]" # + pytest / ruff / mypy / build
The [ai], [payments], [notifications], [monitoring], [all] extras exist
for parity with core (so requirements.txt matches), but they pull in nothing
extra — the sandbox never needs a provider library.
requirements-dev.txt:
missilya-sdk-sandbox==0.1.0
pytest
pytest-asyncio
ruff
mypy
4. Usage (identical to core)
The exact same code you ship to production:
from missilya_sdk.ai.chat import LlmChat, SystemMessage, UserMessage
chat = LlmChat(model="gpt-4o")
chat.add_message(SystemMessage("Be concise."))
chat.add_message(UserMessage("Hello"))
print(chat.chat()) # -> "[sandbox:gpt-4o] Hello" (deterministic)
from missilya_sdk.payments.stripe import StripeCheckout
from missilya_sdk.payments.checkout import CheckoutSessionRequest
session = StripeCheckout().create_session(CheckoutSessionRequest(
line_items=[{"price": "price_x", "quantity": 1}],
success_url="https://app/success",
cancel_url="https://app/cancel",
))
assert session.url.startswith("https://checkout.sandbox.missilya.com/") # mock, no charge
from missilya_sdk.notifications.email import send_email
result = send_email("user@example.com", "Hi", text="hello")
assert result.status == "logged" # logged, never actually sent
from missilya_sdk.auth.jwt import create_token, verify_token
token = create_token({"sub": "u"}) # real HS256, offline, deterministic
assert verify_token(token)["sub"] == "u"
5. Deterministic behavior reference
| Call | Sandbox result |
|---|---|
LlmChat(...).chat() |
"[sandbox:<model>] <last user message>" (stable echo) |
LlmChat(...).complete() |
ChatResponse with computed token counts, raw={"sandbox": True} |
generate_image(...) |
ImageResult(url="https://sandbox.missilya.com/fixtures/image.png") |
text_to_speech(...) |
SpeechResult(audio=<fixture bytes>) |
speech_to_text(...) |
TranscriptResult(text="This is a sandbox transcript fixture.") |
translate("hi", "FR") |
TranslationResult(text="[FR] hi") |
generate_video(...) |
VideoJob(status="queued", job_id="sandbox-video-…") |
StripeCheckout().create_session(...) |
mock cs_sandbox_… session, payment_status="unpaid" |
StripeCheckout().handle_webhook(payload, sig) |
parses JSON payload, no signature check |
send_email/sms/whatsapp(...) |
DeliveryResult(status="logged"/"queued"), only logged |
auth.jwt.* |
real HS256 round-trips (offline, deterministic) |
Auth uses real JWT crypto (deterministic and offline); everything else is a fixture.
6. Configuration
The sandbox resolves config offline:
- process environment variable (development/test values only)
- caller-supplied default
- deterministic fixture
sandbox-<key>(so a missing secret never crashes a test)
Guards:
MISSILYA_ENV=production→ the sandbox refuses to run (ConfigurationError).- A live credential in the environment (
sk_live…) →ValidationError.
# Optional; the sandbox works with no env at all.
MISSILYA_ENV=development
OPENAI_API_KEY= # test keys only, never sk_live_...
JWT_SECRET=
See .env.example.
7. How apps swap core ⇄ sandbox by environment
Pin different packages per environment — the import never changes:
# requirements.txt (staging / production)
missilya-sdk[ai,payments,notifications,monitoring]==0.1.0
# requirements-dev.txt (development / CI)
missilya-sdk-sandbox==0.1.0
# app code — identical everywhere
from missilya_sdk.ai.chat import LlmChat, UserMessage
CI installs the sandbox and runs the suite offline; staging/production installs the core package and runs against the real vault and providers.
8. Parity contract
The sandbox and core must expose an identical public API for the same version:
- same import namespace (
missilya_sdk), - same public modules, classes, functions,
- same function /
__init__parameter names, - same return shapes and dataclass fields,
- same typed exceptions,
- same version string (
0.1.0).
This is verified statically by repos/sdk-tools/check_sdk_parity.py (AST-based, no
install required) and enforced as a test. A feature cannot be added to core without
matching sandbox behavior, and vice versa.
9. Local development
python -m venv .venv
./.venv/Scripts/python -m pip install -e ".[dev]" # Windows
# source .venv/bin/activate && pip install -e ".[dev]" # macOS/Linux
ruff check src tests tools
mypy src/missilya_sdk
pytest -q
python -m build && twine check dist/*
10. Project layout
src/missilya_sdk/
├── __init__.py # public top-level exports (mirrors core)
├── config.py # offline config; refuses production + live keys
├── context.py # TenantContext, MissilyaSDK facade
├── exceptions.py # identical typed error hierarchy
├── ai/ # chat (deterministic), images, tts, stt, translation, video, _fixtures
├── payments/ # stripe (mock), checkout models
├── notifications/ # email, sms, whatsapp (logged only)
├── auth/ # jwt (real HS256, offline)
├── vault/ # offline VaultClient (fixtures, no network)
└── monitoring/ # logging shim, analytics, sentry (no-op)
tests/ # determinism + no-side-effect + parity tests
tools/check_forbidden_imports.py
.github/workflows/ # test, publish, docker-publish
Dockerfile · repo.classification.yml · .env.example
License
Proprietary — © 2026 MISSILYA GROUP. See LICENSE. Private to MISSILYA GROUP; redistribution requires written authorization from Yvon Kamach (CEO).
Metadata
Release files for missilya-sdk-sandbox 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| missilya_sdk_sandbox-0.2.4.tar.gz | 41.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| missilya_sdk_sandbox-0.2.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 85.9 kB
Release files / missilya_sdk_sandbox-0.2.4.tar.gz
| Download URL | missilya_sdk_sandbox-0.2.4.tar.gz |
|---|---|
| Size | 41.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6aa304997914414d36e3f6913d5d352bf200728c6d592f5720abce555a0738c9
|
|
BLAKE2b-256 checksum How to use checksums |
dbed1f953bf69316cfb0665d92d9b201c532b134d0ae0d8646e410baf16c50f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logRelease files / missilya_sdk_sandbox-0.2.4-py3-none-any.whl
| Download URL | missilya_sdk_sandbox-0.2.4-py3-none-any.whl |
|---|---|
| Size | 44.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
698436f4e5b6c164a6540df5153635d05226120b31efebbab19c7f226ed6cd2a
|
|
BLAKE2b-256 checksum How to use checksums |
76b748b342ded994d771fb4929fab6726f3e7ec610611ee453db297bf5c0167b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency log